]>
git.saurik.com Git - apple/javascriptcore.git/blob - ftl/FTLAbstractHeap.cpp
2 * Copyright (C) 2013 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 IndexedAbstractHeap::IndexedAbstractHeap(LContext context
, AbstractHeap
* parent
, const char* heapName
, ptrdiff_t offset
, size_t elementSize
)
57 : m_heapForAnyIndex(parent
, heapName
)
58 , m_heapNameLength(strlen(heapName
))
60 , m_elementSize(elementSize
)
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
) {
69 m_scaleTerm
= constInt(intPtrType(context
), i
, ZeroExtend
);
76 m_scaleTerm
= constInt(intPtrType(context
), m_elementSize
, ZeroExtend
);
79 IndexedAbstractHeap::~IndexedAbstractHeap()
83 TypedPointer
IndexedAbstractHeap::baseIndex(Output
& out
, LValue base
, LValue index
, JSValue indexAsConstant
, ptrdiff_t offset
)
85 if (indexAsConstant
.isInt32())
86 return out
.address(base
, at(indexAsConstant
.asInt32()), offset
);
91 result
= out
.add(base
, index
);
93 result
= out
.add(base
, out
.shl(index
, m_scaleTerm
));
95 result
= out
.add(base
, out
.mul(index
, m_scaleTerm
));
97 return TypedPointer(atAnyIndex(), out
.addPtr(result
, m_offset
+ offset
));
100 const AbstractField
& IndexedAbstractHeap::atSlow(ptrdiff_t index
)
102 ASSERT(static_cast<size_t>(index
) >= m_smallIndices
.size());
104 if (UNLIKELY(!m_largeIndices
))
105 m_largeIndices
= adoptPtr(new MapType());
107 std::unique_ptr
<AbstractField
>& field
= m_largeIndices
->add(index
, nullptr).iterator
->value
;
109 field
= std::make_unique
<AbstractField
>();
110 initialize(*field
, index
);
116 void IndexedAbstractHeap::initialize(AbstractField
& field
, ptrdiff_t signedIndex
)
118 // Build up a name of the form:
124 // heapName_neg_hexIndex
126 // For example if you access an indexed heap called FooBar at index 5, you'll
131 // Or if you access an indexed heap called Blah at index -10, you'll get:
135 // This is important because LLVM uses the string to distinguish the types.
137 static const char* negSplit
= "_neg_";
138 static const char* posSplit
= "_";
142 if (signedIndex
< 0) {
144 index
= -signedIndex
;
150 for (unsigned power
= 4; power
<= sizeof(void*) * 8; power
+= 4) {
151 if (isGreaterThanNonZeroPowerOfTwo(index
, power
))
154 unsigned numHexlets
= power
>> 2;
156 size_t stringLength
= m_heapNameLength
+ (negative
? strlen(negSplit
) : strlen(posSplit
)) + numHexlets
;
158 m_largeIndexNames
.append(CString::newUninitialized(stringLength
, characters
));
160 memcpy(characters
, m_heapForAnyIndex
.heapName(), m_heapNameLength
);
162 memcpy(characters
+ m_heapNameLength
, negSplit
, strlen(negSplit
));
164 memcpy(characters
+ m_heapNameLength
, posSplit
, strlen(posSplit
));
166 size_t accumulator
= index
;
167 for (unsigned i
= 0; i
< numHexlets
; ++i
) {
168 characters
[stringLength
- i
- 1] = lowerNibbleToASCIIHexDigit(accumulator
);
172 field
.initialize(&m_heapForAnyIndex
, characters
, m_offset
+ signedIndex
* m_elementSize
);
176 RELEASE_ASSERT_NOT_REACHED();
179 NumberedAbstractHeap::NumberedAbstractHeap(LContext context
, AbstractHeap
* heap
, const char* heapName
)
180 : m_indexedHeap(context
, heap
, heapName
, 0, 1)
184 NumberedAbstractHeap::~NumberedAbstractHeap()
188 AbsoluteAbstractHeap::AbsoluteAbstractHeap(LContext context
, AbstractHeap
* heap
, const char* heapName
)
189 : m_indexedHeap(context
, heap
, heapName
, 0, 1)
193 AbsoluteAbstractHeap::~AbsoluteAbstractHeap()
197 } } // namespace JSC::FTL
199 #endif // ENABLE(FTL_JIT)