Remove remaining references to LLVM, and make sure comments refer to the backend...
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLAbstractHeap.cpp
1 /*
2  * Copyright (C) 2013, 2015 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 "DFGCommon.h"
32 #include "FTLAbbreviatedTypes.h"
33 #include "FTLAbstractHeapRepository.h"
34 #include "FTLOutput.h"
35 #include "FTLTypedPointer.h"
36 #include "JSCInlines.h"
37 #include "Options.h"
38
39 namespace JSC { namespace FTL {
40
41 void AbstractHeap::decorateInstruction(LValue instruction, const AbstractHeapRepository& repository) const
42 {
43     UNUSED_PARAM(instruction);
44     UNUSED_PARAM(repository);
45 }
46
47 void AbstractHeap::dump(PrintStream& out) const
48 {
49     out.print(heapName());
50     if (m_parent)
51         out.print("->", *m_parent);
52 }
53
54 void AbstractField::dump(PrintStream& out) const
55 {
56     out.print(heapName(), "(", m_offset, ")");
57     if (parent())
58         out.print("->", *parent());
59 }
60
61 IndexedAbstractHeap::IndexedAbstractHeap(AbstractHeap* parent, const char* heapName, ptrdiff_t offset, size_t elementSize)
62     : m_heapForAnyIndex(parent, heapName)
63     , m_heapNameLength(strlen(heapName))
64     , m_offset(offset)
65     , m_elementSize(elementSize)
66 {
67 }
68
69 IndexedAbstractHeap::~IndexedAbstractHeap()
70 {
71 }
72
73 TypedPointer IndexedAbstractHeap::baseIndex(Output& out, LValue base, LValue index, JSValue indexAsConstant, ptrdiff_t offset)
74 {
75     if (indexAsConstant.isInt32())
76         return out.address(base, at(indexAsConstant.asInt32()), offset);
77
78     LValue result = out.add(base, out.mul(index, out.constIntPtr(m_elementSize)));
79     
80     return TypedPointer(atAnyIndex(), out.addPtr(result, m_offset + offset));
81 }
82
83 const AbstractField& IndexedAbstractHeap::atSlow(ptrdiff_t index)
84 {
85     ASSERT(static_cast<size_t>(index) >= m_smallIndices.size());
86     
87     if (UNLIKELY(!m_largeIndices))
88         m_largeIndices = std::make_unique<MapType>();
89
90     std::unique_ptr<AbstractField>& field = m_largeIndices->add(index, nullptr).iterator->value;
91     if (!field) {
92         field = std::make_unique<AbstractField>();
93         initialize(*field, index);
94     }
95
96     return *field;
97 }
98
99 void IndexedAbstractHeap::initialize(AbstractField& field, ptrdiff_t signedIndex)
100 {
101     // Build up a name of the form:
102     //
103     //    heapName_hexIndex
104     //
105     // or:
106     //
107     //    heapName_neg_hexIndex
108     //
109     // For example if you access an indexed heap called FooBar at index 5, you'll
110     // get:
111     //
112     //    FooBar_5
113     //
114     // Or if you access an indexed heap called Blah at index -10, you'll get:
115     //
116     //    Blah_neg_A
117     //
118     // This used to be important because we used to use the string to distinguish the types. This is
119     // not relevant anymore, and this code will be removed eventually.
120     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=154319
121     
122     static const char* negSplit = "_neg_";
123     static const char* posSplit = "_";
124     
125     bool negative;
126     size_t index;
127     if (signedIndex < 0) {
128         negative = true;
129         index = -signedIndex;
130     } else {
131         negative = false;
132         index = signedIndex;
133     }
134     
135     for (unsigned power = 4; power <= sizeof(void*) * 8; power += 4) {
136         if (isGreaterThanNonZeroPowerOfTwo(index, power))
137             continue;
138         
139         unsigned numHexlets = power >> 2;
140         
141         size_t stringLength = m_heapNameLength + (negative ? strlen(negSplit) : strlen(posSplit)) + numHexlets;
142         char* characters;
143         m_largeIndexNames.append(CString::newUninitialized(stringLength, characters));
144         
145         memcpy(characters, m_heapForAnyIndex.heapName(), m_heapNameLength);
146         if (negative)
147             memcpy(characters + m_heapNameLength, negSplit, strlen(negSplit));
148         else
149             memcpy(characters + m_heapNameLength, posSplit, strlen(posSplit));
150         
151         size_t accumulator = index;
152         for (unsigned i = 0; i < numHexlets; ++i) {
153             characters[stringLength - i - 1] = lowerNibbleToASCIIHexDigit(accumulator);
154             accumulator >>= 4;
155         }
156         
157         field.initialize(&m_heapForAnyIndex, characters, m_offset + signedIndex * m_elementSize);
158         return;
159     }
160     
161     RELEASE_ASSERT_NOT_REACHED();
162 }
163
164 void IndexedAbstractHeap::dump(PrintStream& out) const
165 {
166     out.print("Indexed:", atAnyIndex());
167 }
168
169 NumberedAbstractHeap::NumberedAbstractHeap(AbstractHeap* heap, const char* heapName)
170     : m_indexedHeap(heap, heapName, 0, 1)
171 {
172 }
173
174 NumberedAbstractHeap::~NumberedAbstractHeap()
175 {
176 }
177
178 void NumberedAbstractHeap::dump(PrintStream& out) const
179 {
180     out.print("Numbered: ", atAnyNumber());
181 }
182
183 AbsoluteAbstractHeap::AbsoluteAbstractHeap(AbstractHeap* heap, const char* heapName)
184     : m_indexedHeap(heap, heapName, 0, 1)
185 {
186 }
187
188 AbsoluteAbstractHeap::~AbsoluteAbstractHeap()
189 {
190 }
191
192 void AbsoluteAbstractHeap::dump(PrintStream& out) const
193 {
194     out.print("Absolute:", atAnyAddress());
195 }
196
197 } } // namespace JSC::FTL
198
199 #endif // ENABLE(FTL_JIT)
200