]>
git.saurik.com Git - apple/javascriptcore.git/blob - ftl/FTLAbstractHeap.cpp
2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "FTLAbstractHeap.h"
31 #include "FTLAbbreviations.h"
32 #include "FTLAbstractHeapRepository.h"
33 #include "FTLOutput.h"
34 #include "FTLTypedPointer.h"
35 #include "JSCInlines.h"
38 namespace JSC
{ namespace FTL
{
40 LValue
AbstractHeap::tbaaMetadataSlow(const AbstractHeapRepository
& repository
) const
42 m_tbaaMetadata
= mdNode(
44 mdString(repository
.m_context
, m_heapName
),
45 m_parent
->tbaaMetadata(repository
));
46 return m_tbaaMetadata
;
49 void AbstractHeap::decorateInstruction(LValue instruction
, const AbstractHeapRepository
& repository
) const
51 if (!Options::useFTLTBAA())
53 setMetadata(instruction
, repository
.m_tbaaKind
, tbaaMetadata(repository
));
56 void AbstractHeap::dump(PrintStream
& out
) const
58 out
.print(heapName());
60 out
.print("->", *m_parent
);
63 void AbstractField::dump(PrintStream
& out
) const
65 out
.print(heapName(), "(", m_offset
, ")");
67 out
.print("->", *parent());
70 IndexedAbstractHeap::IndexedAbstractHeap(LContext context
, AbstractHeap
* parent
, const char* heapName
, ptrdiff_t offset
, size_t elementSize
)
71 : m_heapForAnyIndex(parent
, heapName
)
72 , m_heapNameLength(strlen(heapName
))
74 , m_elementSize(elementSize
)
78 // See if there is a common shift amount we could use instead of multiplying. Don't
79 // try too hard. This is just a speculative optimization to reduce load on LLVM.
80 for (unsigned i
= 0; i
< 4; ++i
) {
81 if (1U << i
== m_elementSize
) {
83 m_scaleTerm
= constInt(intPtrType(context
), i
, ZeroExtend
);
90 m_scaleTerm
= constInt(intPtrType(context
), m_elementSize
, ZeroExtend
);
93 IndexedAbstractHeap::~IndexedAbstractHeap()
97 TypedPointer
IndexedAbstractHeap::baseIndex(Output
& out
, LValue base
, LValue index
, JSValue indexAsConstant
, ptrdiff_t offset
)
99 if (indexAsConstant
.isInt32())
100 return out
.address(base
, at(indexAsConstant
.asInt32()), offset
);
105 result
= out
.add(base
, index
);
107 result
= out
.add(base
, out
.shl(index
, m_scaleTerm
));
109 result
= out
.add(base
, out
.mul(index
, m_scaleTerm
));
111 return TypedPointer(atAnyIndex(), out
.addPtr(result
, m_offset
+ offset
));
114 const AbstractField
& IndexedAbstractHeap::atSlow(ptrdiff_t index
)
116 ASSERT(static_cast<size_t>(index
) >= m_smallIndices
.size());
118 if (UNLIKELY(!m_largeIndices
))
119 m_largeIndices
= std::make_unique
<MapType
>();
121 std::unique_ptr
<AbstractField
>& field
= m_largeIndices
->add(index
, nullptr).iterator
->value
;
123 field
= std::make_unique
<AbstractField
>();
124 initialize(*field
, index
);
130 void IndexedAbstractHeap::initialize(AbstractField
& field
, ptrdiff_t signedIndex
)
132 // Build up a name of the form:
138 // heapName_neg_hexIndex
140 // For example if you access an indexed heap called FooBar at index 5, you'll
145 // Or if you access an indexed heap called Blah at index -10, you'll get:
149 // This is important because LLVM uses the string to distinguish the types.
151 static const char* negSplit
= "_neg_";
152 static const char* posSplit
= "_";
156 if (signedIndex
< 0) {
158 index
= -signedIndex
;
164 for (unsigned power
= 4; power
<= sizeof(void*) * 8; power
+= 4) {
165 if (isGreaterThanNonZeroPowerOfTwo(index
, power
))
168 unsigned numHexlets
= power
>> 2;
170 size_t stringLength
= m_heapNameLength
+ (negative
? strlen(negSplit
) : strlen(posSplit
)) + numHexlets
;
172 m_largeIndexNames
.append(CString::newUninitialized(stringLength
, characters
));
174 memcpy(characters
, m_heapForAnyIndex
.heapName(), m_heapNameLength
);
176 memcpy(characters
+ m_heapNameLength
, negSplit
, strlen(negSplit
));
178 memcpy(characters
+ m_heapNameLength
, posSplit
, strlen(posSplit
));
180 size_t accumulator
= index
;
181 for (unsigned i
= 0; i
< numHexlets
; ++i
) {
182 characters
[stringLength
- i
- 1] = lowerNibbleToASCIIHexDigit(accumulator
);
186 field
.initialize(&m_heapForAnyIndex
, characters
, m_offset
+ signedIndex
* m_elementSize
);
190 RELEASE_ASSERT_NOT_REACHED();
193 void IndexedAbstractHeap::dump(PrintStream
& out
) const
195 out
.print("Indexed:", atAnyIndex());
198 NumberedAbstractHeap::NumberedAbstractHeap(LContext context
, AbstractHeap
* heap
, const char* heapName
)
199 : m_indexedHeap(context
, heap
, heapName
, 0, 1)
203 NumberedAbstractHeap::~NumberedAbstractHeap()
207 void NumberedAbstractHeap::dump(PrintStream
& out
) const
209 out
.print("Numbered: ", atAnyNumber());
212 AbsoluteAbstractHeap::AbsoluteAbstractHeap(LContext context
, AbstractHeap
* heap
, const char* heapName
)
213 : m_indexedHeap(context
, heap
, heapName
, 0, 1)
217 AbsoluteAbstractHeap::~AbsoluteAbstractHeap()
221 void AbsoluteAbstractHeap::dump(PrintStream
& out
) const
223 out
.print("Absolute:", atAnyAddress());
226 } } // namespace JSC::FTL
228 #endif // ENABLE(FTL_JIT)