]> git.saurik.com Git - apple/javascriptcore.git/blame - ftl/FTLAbstractHeap.cpp
JavaScriptCore-7600.1.4.11.8.tar.gz
[apple/javascriptcore.git] / ftl / FTLAbstractHeap.cpp
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "FTLAbstractHeap.h"
28
29#if ENABLE(FTL_JIT)
30
31#include "FTLAbbreviations.h"
32#include "FTLAbstractHeapRepository.h"
33#include "FTLOutput.h"
34#include "FTLTypedPointer.h"
35#include "JSCInlines.h"
36#include "Options.h"
37
38namespace JSC { namespace FTL {
39
40LValue AbstractHeap::tbaaMetadataSlow(const AbstractHeapRepository& repository) const
41{
42 m_tbaaMetadata = mdNode(
43 repository.m_context,
44 mdString(repository.m_context, m_heapName),
45 m_parent->tbaaMetadata(repository));
46 return m_tbaaMetadata;
47}
48
49void AbstractHeap::decorateInstruction(LValue instruction, const AbstractHeapRepository& repository) const
50{
51 if (!Options::useFTLTBAA())
52 return;
53 setMetadata(instruction, repository.m_tbaaKind, tbaaMetadata(repository));
54}
55
56IndexedAbstractHeap::IndexedAbstractHeap(LContext context, AbstractHeap* parent, const char* heapName, ptrdiff_t offset, size_t elementSize)
57 : m_heapForAnyIndex(parent, heapName)
58 , m_heapNameLength(strlen(heapName))
59 , m_offset(offset)
60 , m_elementSize(elementSize)
61 , m_scaleTerm(0)
62 , m_canShift(false)
63{
64 // See if there is a common shift amount we could use instead of multiplying. Don't
65 // try too hard. This is just a speculative optimization to reduce load on LLVM.
66 for (unsigned i = 0; i < 4; ++i) {
67 if (1U << i == m_elementSize) {
68 if (i)
69 m_scaleTerm = constInt(intPtrType(context), i, ZeroExtend);
70 m_canShift = true;
71 break;
72 }
73 }
74
75 if (!m_canShift)
76 m_scaleTerm = constInt(intPtrType(context), m_elementSize, ZeroExtend);
77}
78
79IndexedAbstractHeap::~IndexedAbstractHeap()
80{
81}
82
83TypedPointer IndexedAbstractHeap::baseIndex(Output& out, LValue base, LValue index, JSValue indexAsConstant, ptrdiff_t offset)
84{
85 if (indexAsConstant.isInt32())
86 return out.address(base, at(indexAsConstant.asInt32()), offset);
87
88 LValue result;
89 if (m_canShift) {
90 if (!m_scaleTerm)
91 result = out.add(base, index);
92 else
93 result = out.add(base, out.shl(index, m_scaleTerm));
94 } else
95 result = out.add(base, out.mul(index, m_scaleTerm));
96
97 return TypedPointer(atAnyIndex(), out.addPtr(result, m_offset + offset));
98}
99
100const AbstractField& IndexedAbstractHeap::atSlow(ptrdiff_t index)
101{
102 ASSERT(static_cast<size_t>(index) >= m_smallIndices.size());
103
104 if (UNLIKELY(!m_largeIndices))
105 m_largeIndices = adoptPtr(new MapType());
106
107 std::unique_ptr<AbstractField>& field = m_largeIndices->add(index, nullptr).iterator->value;
108 if (!field) {
109 field = std::make_unique<AbstractField>();
110 initialize(*field, index);
111 }
112
113 return *field;
114}
115
116void IndexedAbstractHeap::initialize(AbstractField& field, ptrdiff_t signedIndex)
117{
118 // Build up a name of the form:
119 //
120 // heapName_hexIndex
121 //
122 // or:
123 //
124 // heapName_neg_hexIndex
125 //
126 // For example if you access an indexed heap called FooBar at index 5, you'll
127 // get:
128 //
129 // FooBar_5
130 //
131 // Or if you access an indexed heap called Blah at index -10, you'll get:
132 //
133 // Blah_neg_A
134 //
135 // This is important because LLVM uses the string to distinguish the types.
136
137 static const char* negSplit = "_neg_";
138 static const char* posSplit = "_";
139
140 bool negative;
141 size_t index;
142 if (signedIndex < 0) {
143 negative = true;
144 index = -signedIndex;
145 } else {
146 negative = false;
147 index = signedIndex;
148 }
149
150 for (unsigned power = 4; power <= sizeof(void*) * 8; power += 4) {
151 if (isGreaterThanNonZeroPowerOfTwo(index, power))
152 continue;
153
154 unsigned numHexlets = power >> 2;
155
156 size_t stringLength = m_heapNameLength + (negative ? strlen(negSplit) : strlen(posSplit)) + numHexlets;
157 char* characters;
158 m_largeIndexNames.append(CString::newUninitialized(stringLength, characters));
159
160 memcpy(characters, m_heapForAnyIndex.heapName(), m_heapNameLength);
161 if (negative)
162 memcpy(characters + m_heapNameLength, negSplit, strlen(negSplit));
163 else
164 memcpy(characters + m_heapNameLength, posSplit, strlen(posSplit));
165
166 size_t accumulator = index;
167 for (unsigned i = 0; i < numHexlets; ++i) {
168 characters[stringLength - i - 1] = lowerNibbleToASCIIHexDigit(accumulator);
169 accumulator >>= 4;
170 }
171
172 field.initialize(&m_heapForAnyIndex, characters, m_offset + signedIndex * m_elementSize);
173 return;
174 }
175
176 RELEASE_ASSERT_NOT_REACHED();
177}
178
179NumberedAbstractHeap::NumberedAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
180 : m_indexedHeap(context, heap, heapName, 0, 1)
181{
182}
183
184NumberedAbstractHeap::~NumberedAbstractHeap()
185{
186}
187
188AbsoluteAbstractHeap::AbsoluteAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
189 : m_indexedHeap(context, heap, heapName, 0, 1)
190{
191}
192
193AbsoluteAbstractHeap::~AbsoluteAbstractHeap()
194{
195}
196
197} } // namespace JSC::FTL
198
199#endif // ENABLE(FTL_JIT)
200