| Differences between
and this patch
- Source/JavaScriptCore/CMakeLists.txt +1 lines
Lines 89-94 set(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec1
89
    bytecode/SamplingTool.cpp
89
    bytecode/SamplingTool.cpp
90
    bytecode/SpecialPointer.cpp
90
    bytecode/SpecialPointer.cpp
91
    bytecode/SpeculatedType.cpp
91
    bytecode/SpeculatedType.cpp
92
    bytecode/StructureSet.cpp
92
    bytecode/StructureStubClearingWatchpoint.cpp
93
    bytecode/StructureStubClearingWatchpoint.cpp
93
    bytecode/StructureStubInfo.cpp
94
    bytecode/StructureStubInfo.cpp
94
    bytecode/UnlinkedCodeBlock.cpp
95
    bytecode/UnlinkedCodeBlock.cpp
- Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj +1 lines
Lines 343-348 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec1
343
    <ClCompile Include="..\bytecode\SamplingTool.cpp" />
343
    <ClCompile Include="..\bytecode\SamplingTool.cpp" />
344
    <ClCompile Include="..\bytecode\SpecialPointer.cpp" />
344
    <ClCompile Include="..\bytecode\SpecialPointer.cpp" />
345
    <ClCompile Include="..\bytecode\SpeculatedType.cpp" />
345
    <ClCompile Include="..\bytecode\SpeculatedType.cpp" />
346
    <ClCompile Include="..\bytecode\StructureSet.cpp" />
346
    <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp" />
347
    <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp" />
347
    <ClCompile Include="..\bytecode\StructureStubInfo.cpp" />
348
    <ClCompile Include="..\bytecode\StructureStubInfo.cpp" />
348
    <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" />
349
    <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" />
- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +4 lines
Lines 416-421 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
416
		0FB14E1F18124ACE009B6B4D /* JITInlineCacheGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
416
		0FB14E1F18124ACE009B6B4D /* JITInlineCacheGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
417
		0FB14E211812570B009B6B4D /* DFGInlineCacheWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
417
		0FB14E211812570B009B6B4D /* DFGInlineCacheWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
418
		0FB14E2318130955009B6B4D /* DFGInlineCacheWrapperInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
418
		0FB14E2318130955009B6B4D /* DFGInlineCacheWrapperInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
419
		0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */; };
419
		0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
420
		0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
420
		0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
421
		0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
421
		0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
422
		0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
Lines 2220-2225 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
2220
		0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineCacheGenerator.h; sourceTree = "<group>"; };
2221
		0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineCacheGenerator.h; sourceTree = "<group>"; };
2221
		0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapper.h; path = dfg/DFGInlineCacheWrapper.h; sourceTree = "<group>"; };
2222
		0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapper.h; path = dfg/DFGInlineCacheWrapper.h; sourceTree = "<group>"; };
2222
		0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapperInlines.h; path = dfg/DFGInlineCacheWrapperInlines.h; sourceTree = "<group>"; };
2223
		0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapperInlines.h; path = dfg/DFGInlineCacheWrapperInlines.h; sourceTree = "<group>"; };
2224
		0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureSet.cpp; sourceTree = "<group>"; };
2223
		0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = "<group>"; };
2225
		0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = "<group>"; };
2224
		0FB4B51916B62772003F696B /* DFGAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAllocator.h; path = dfg/DFGAllocator.h; sourceTree = "<group>"; };
2226
		0FB4B51916B62772003F696B /* DFGAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAllocator.h; path = dfg/DFGAllocator.h; sourceTree = "<group>"; };
2225
		0FB4B51A16B62772003F696B /* DFGCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCommon.cpp; path = dfg/DFGCommon.cpp; sourceTree = "<group>"; };
2227
		0FB4B51A16B62772003F696B /* DFGCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCommon.cpp; path = dfg/DFGCommon.cpp; sourceTree = "<group>"; };
Lines 5018-5023 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
5018
				0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */,
5020
				0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */,
5019
				0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
5021
				0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
5020
				0FD82E4F141DAEA100179C94 /* SpeculatedType.h */,
5022
				0FD82E4F141DAEA100179C94 /* SpeculatedType.h */,
5023
				0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */,
5021
				0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
5024
				0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
5022
				0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */,
5025
				0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */,
5023
				0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */,
5026
				0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */,
Lines 7178-7183 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
7178
				2A83638918D7D0FE0000EBCC /* FullGCActivityCallback.cpp in Sources */,
7181
				2A83638918D7D0FE0000EBCC /* FullGCActivityCallback.cpp in Sources */,
7179
				1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
7182
				1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
7180
				147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
7183
				147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
7184
				0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */,
7181
				2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
7185
				2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
7182
				1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
7186
				1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
7183
				146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
7187
				146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
- Source/JavaScriptCore/bytecode/StructureSet.cpp +323 lines
Line 0 Source/JavaScriptCore/bytecode/StructureSet.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "StructureSet.h"
28
29
#include <wtf/CommaPrinter.h>
30
31
namespace JSC {
32
33
void BorrowedStructureSet::clear()
34
{
35
    deleteStructureListIfNecessary();
36
    set(0, true);
37
}
38
39
bool BorrowedStructureSet::add(Structure* structure)
40
{
41
    ASSERT(structure);
42
    if (isThin()) {
43
        if (singleStructure() == structure)
44
            return false;
45
        if (!singleStructure()) {
46
            set(structure);
47
            return true;
48
        }
49
        OutOfLineList* list = OutOfLineList::create(defaultStartingSize);
50
        list->m_length = 2;
51
        list->list()[0] = singleStructure();
52
        list->list()[1] = structure;
53
        set(list);
54
        return true;
55
    }
56
    
57
    return addOutOfLine(structure);
58
}
59
60
bool BorrowedStructureSet::remove(Structure* structure)
61
{
62
    if (isThin()) {
63
        if (singleStructure() == structure) {
64
            set(0, true);
65
            return true;
66
        }
67
        return false;
68
    }
69
    
70
    OutOfLineList* list = structureList();
71
    for (unsigned i = 0; i < list->m_length; ++i) {
72
        if (list->list()[i] != structure)
73
            continue;
74
        list->list()[i] = list->list()[--list->m_length];
75
        if (!list->m_length) {
76
            OutOfLineList::destroy(list);
77
            set(0, true);
78
        }
79
        return true;
80
    }
81
    return false;
82
}
83
84
bool BorrowedStructureSet::contains(Structure* structure) const
85
{
86
    if (isThin()) {
87
        if (singleStructure() == structure)
88
            return true;
89
        return false;
90
    }
91
    
92
    return containsOutOfLine(structure);
93
}
94
95
bool BorrowedStructureSet::merge(const BorrowedStructureSet& other)
96
{
97
    if (other.isThin()) {
98
        if (other.singleStructure())
99
            return add(other.singleStructure());
100
        return false;
101
    }
102
    
103
    OutOfLineList* list = other.structureList();
104
    if (list->m_length >= 2) {
105
        if (isThin()) {
106
            OutOfLineList* myNewList = OutOfLineList::create(
107
                list->m_length + !!singleStructure());
108
            if (singleStructure()) {
109
                myNewList->m_length = 1;
110
                myNewList->list()[0] = singleStructure();
111
            }
112
        }
113
        bool changed = false;
114
        for (unsigned i = 0; i < list->m_length; ++i)
115
            changed |= addOutOfLine(list->list()[i]);
116
        return changed;
117
    }
118
    
119
    ASSERT(list->m_length);
120
    return add(list->list()[0]);
121
}
122
123
void BorrowedStructureSet::filter(const BorrowedStructureSet& other)
124
{
125
    if (other.isThin()) {
126
        if (!other.singleStructure() || !contains(other.singleStructure()))
127
            clear();
128
        else {
129
            clear();
130
            set(other.singleStructure());
131
        }
132
        return;
133
    }
134
    
135
    if (isThin()) {
136
        if (!singleStructure())
137
            return;
138
        if (other.containsOutOfLine(singleStructure()))
139
            return;
140
        clear();
141
        return;
142
    }
143
    
144
    OutOfLineList* list = structureList();
145
    for (unsigned i = 0; i < list->m_length; ++i) {
146
        if (other.containsOutOfLine(list->list()[i]))
147
            continue;
148
        list->list()[i--] = list->list()[--list->m_length];
149
    }
150
    if (!list->m_length)
151
        clear();
152
}
153
154
void BorrowedStructureSet::exclude(const BorrowedStructureSet& other)
155
{
156
    if (other.isThin()) {
157
        if (other.singleStructure())
158
            remove(other.singleStructure());
159
        return;
160
    }
161
    
162
    if (isThin()) {
163
        if (!singleStructure())
164
            return;
165
        if (other.contains(singleStructure()))
166
            clear();
167
        return;
168
    }
169
    
170
    OutOfLineList* list = structureList();
171
    for (unsigned i = 0; i < list->m_length; ++i) {
172
        if (!other.containsOutOfLine(list->list()[i]))
173
            continue;
174
        list->list()[i--] = list->list()[--list->m_length];
175
    }
176
    if (!list->m_length)
177
        clear();
178
}
179
180
bool BorrowedStructureSet::isSubsetOf(const BorrowedStructureSet& other) const
181
{
182
    if (isThin()) {
183
        if (!singleStructure())
184
            return true;
185
        return other.contains(singleStructure());
186
    }
187
    
188
    if (other.isThin()) {
189
        if (!other.singleStructure())
190
            return false;
191
        OutOfLineList* list = structureList();
192
        if (list->m_length >= 2)
193
            return false;
194
        if (list->list()[0] == other.singleStructure())
195
            return true;
196
        return false;
197
    }
198
    
199
    OutOfLineList* list = structureList();
200
    for (unsigned i = 0; i < list->m_length; ++i) {
201
        if (!other.containsOutOfLine(list->list()[i]))
202
            return false;
203
    }
204
    return true;
205
}
206
207
bool BorrowedStructureSet::overlaps(const BorrowedStructureSet& other) const
208
{
209
    if (isThin()) {
210
        if (!singleStructure())
211
            return false;
212
        return other.contains(singleStructure());
213
    }
214
    
215
    if (other.isThin()) {
216
        if (!other.singleStructure())
217
            return false;
218
        return containsOutOfLine(other.singleStructure());
219
    }
220
    
221
    OutOfLineList* list = structureList();
222
    for (unsigned i = 0; i < list->m_length; ++i) {
223
        if (other.containsOutOfLine(list->list()[i]))
224
            return true;
225
    }
226
    return false;
227
}
228
229
bool BorrowedStructureSet::operator==(const BorrowedStructureSet& other) const
230
{
231
    if (size() != other.size())
232
        return false;
233
    return isSubsetOf(other);
234
}
235
236
SpeculatedType BorrowedStructureSet::speculationFromStructures() const
237
{
238
    if (isThin()) {
239
        if (!singleStructure())
240
            return SpecNone;
241
        return speculationFromStructure(singleStructure());
242
    }
243
    
244
    SpeculatedType result = SpecNone;
245
    OutOfLineList* list = structureList();
246
    for (unsigned i = 0; i < list->m_length; ++i)
247
        mergeSpeculation(result, speculationFromStructure(list->list()[i]));
248
    return result;
249
}
250
251
ArrayModes BorrowedStructureSet::arrayModesFromStructures() const
252
{
253
    if (isThin()) {
254
        if (!singleStructure())
255
            return 0;
256
        return asArrayModes(singleStructure()->indexingType());
257
    }
258
    
259
    ArrayModes result = 0;
260
    OutOfLineList* list = structureList();
261
    for (unsigned i = 0; i < list->m_length; ++i)
262
        mergeArrayModes(result, asArrayModes(list->list()[i]->indexingType()));
263
    return result;
264
}
265
266
void BorrowedStructureSet::dumpInContext(PrintStream& out, DumpContext* context) const
267
{
268
    CommaPrinter comma;
269
    out.print("[");
270
    for (size_t i = 0; i < size(); ++i)
271
        out.print(comma, inContext(*at(i), context));
272
    out.print("]");
273
}
274
275
void BorrowedStructureSet::dump(PrintStream& out) const
276
{
277
    dumpInContext(out, nullptr);
278
}
279
280
bool BorrowedStructureSet::addOutOfLine(Structure* structure)
281
{
282
    OutOfLineList* list = structureList();
283
    for (unsigned i = 0; i < list->m_length; ++i) {
284
        if (list->list()[i] == structure)
285
            return false;
286
    }
287
    
288
    if (list->m_length < list->m_capacity) {
289
        list->list()[list->m_length++] = structure;
290
        return true;
291
    }
292
    
293
    OutOfLineList* newList = OutOfLineList::create(list->m_capacity * 2);
294
    newList->m_length = list->m_length + 1;
295
    for (unsigned i = list->m_length; i--;)
296
        newList->list()[i] = list->list()[i];
297
    newList->list()[list->m_length] = structure;
298
    set(newList);
299
    return true;
300
}
301
302
bool BorrowedStructureSet::containsOutOfLine(Structure* structure) const
303
{
304
    OutOfLineList* list = structureList();
305
    for (unsigned i = 0; i < list->m_length; ++i) {
306
        if (list->list()[i] == structure)
307
            return true;
308
    }
309
    return false;
310
}
311
312
BorrowedStructureSet::OutOfLineList* BorrowedStructureSet::OutOfLineList::create(unsigned capacity)
313
{
314
    return new (NotNull, fastMalloc(sizeof(OutOfLineList) + capacity * sizeof(Structure*))) OutOfLineList(0, capacity);
315
}
316
317
void BorrowedStructureSet::OutOfLineList::destroy(OutOfLineList* list)
318
{
319
    fastFree(list);
320
}
321
322
} // namespace JSC
323
- Source/JavaScriptCore/bytecode/StructureSet.h -110 / +121 lines
Lines 1-5 Source/JavaScriptCore/bytecode/StructureSet.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
2
 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 30-196 Source/JavaScriptCore/bytecode/StructureSet.h_sec2
30
#include "SpeculatedType.h"
30
#include "SpeculatedType.h"
31
#include "Structure.h"
31
#include "Structure.h"
32
#include "DumpContext.h"
32
#include "DumpContext.h"
33
#include <wtf/CommaPrinter.h>
34
#include <wtf/Vector.h>
35
33
36
namespace JSC {
34
namespace JSC {
37
35
38
namespace DFG {
36
// This is a structure set that doesn't own any memory. You can use it to wrap a
39
class StructureAbstractValue;
37
// uintptr_t, which it will then interpret as a structure set. This can be either
40
}
38
// subtyped to provide StructureSet functionality or it can be used as part of a
41
39
// more sophisticated data structure that revolves around a uintptr_t.
42
class StructureSet {
40
class BorrowedStructureSet {
43
public:
41
public:
44
    StructureSet() { }
42
    static const unsigned thinFlag = 1;
43
    static const unsigned reservedFlag = 2;
44
    static const unsigned flags = 3;
45
    static const unsigned reservedValue = 4;
45
    
46
    
46
    StructureSet(Structure* structure)
47
    explicit BorrowedStructureSet(uintptr_t pointer)
48
        : m_pointer(pointer)
47
    {
49
    {
48
        ASSERT(structure);
49
        m_structures.append(structure);
50
    }
50
    }
51
    
51
    
52
    void clear()
52
    void clear();
53
    {
54
        m_structures.clear();
55
    }
56
    
57
    void add(Structure* structure)
58
    {
59
        ASSERT(structure);
60
        ASSERT(!contains(structure));
61
        m_structures.append(structure);
62
    }
63
    
53
    
64
    bool addAll(const StructureSet& other)
54
    Structure* onlyStructure() const
65
    {
55
    {
66
        bool changed = false;
56
        if (isThin()) {
67
        for (size_t i = 0; i < other.size(); ++i) {
57
            ASSERT(singleStructure());
68
            if (contains(other[i]))
58
            return singleStructure();
69
                continue;
70
            add(other[i]);
71
            changed = true;
72
        }
59
        }
73
        return changed;
60
        ASSERT(structureList()->m_length == 1);
61
        return structureList()->list()[0];
74
    }
62
    }
75
    
63
    
76
    void remove(Structure* structure)
64
    bool isEmpty() const
77
    {
65
    {
78
        for (size_t i = 0; i < m_structures.size(); ++i) {
66
        return isThin() && !singleStructure();
79
            if (m_structures[i] != structure)
80
                continue;
81
            
82
            m_structures[i] = m_structures.last();
83
            m_structures.removeLast();
84
            return;
85
        }
86
    }
67
    }
87
    
68
    
88
    bool contains(Structure* structure) const
69
    bool add(Structure* structure);
70
    bool remove(Structure* structure);
71
    bool contains(Structure* structure) const;
72
    
73
    bool merge(const BorrowedStructureSet& other);
74
    void filter(const BorrowedStructureSet& other);
75
    void exclude(const BorrowedStructureSet& other);
76
    
77
    bool isSubsetOf(const BorrowedStructureSet& other) const;
78
    bool isSupersetOf(const BorrowedStructureSet& other) const
89
    {
79
    {
90
        for (size_t i = 0; i < m_structures.size(); ++i) {
80
        return other.isSubsetOf(*this);
91
            if (m_structures[i] == structure)
92
                return true;
93
        }
94
        return false;
95
    }
81
    }
96
    
82
    
97
    bool containsOnly(Structure* structure) const
83
    bool overlaps(const BorrowedStructureSet& other) const;
84
    
85
    size_t size() const
98
    {
86
    {
99
        if (size() != 1)
87
        if (isThin())
100
            return false;
88
            return !!singleStructure();
101
        return singletonStructure() == structure;
89
        return structureList()->m_length;
102
    }
90
    }
103
    
91
    
104
    bool isSubsetOf(const StructureSet& other) const
92
    Structure* at(size_t i) const
105
    {
93
    {
106
        for (size_t i = 0; i < m_structures.size(); ++i) {
94
        if (isThin()) {
107
            if (!other.contains(m_structures[i]))
95
            ASSERT(!i);
108
                return false;
96
            ASSERT(singleStructure());
97
            return singleStructure();
109
        }
98
        }
110
        return true;
99
        ASSERT(i < structureList()->m_length);
100
        return structureList()->list()[i];
111
    }
101
    }
112
    
102
    
113
    bool isSupersetOf(const StructureSet& other) const
103
    Structure* operator[](size_t i) const { return at(i); }
114
    {
115
        return other.isSubsetOf(*this);
116
    }
117
    
104
    
118
    bool overlaps(const StructureSet& other) const
105
    Structure* last() const
119
    {
106
    {
120
        for (size_t i = 0; i < m_structures.size(); ++i) {
107
        if (isThin()) {
121
            if (other.contains(m_structures[i]))
108
            ASSERT(singleStructure());
122
                return true;
109
            return singleStructure();
123
        }
110
        }
124
        return false;
111
        return structureList()->list()[structureList()->m_length - 1];
125
    }
112
    }
126
    
113
    
127
    size_t size() const { return m_structures.size(); }
114
    bool operator==(const BorrowedStructureSet& other) const;
128
    
115
    
129
    // Call this if you know that the structure set must consist of exactly
116
    SpeculatedType speculationFromStructures() const;
130
    // one structure.
117
    ArrayModes arrayModesFromStructures() const;
131
    Structure* singletonStructure() const
132
    {
133
        ASSERT(m_structures.size() == 1);
134
        return m_structures[0];
135
    }
136
    
118
    
137
    Structure* at(size_t i) const { return m_structures.at(i); }
119
    void dumpInContext(PrintStream& out, DumpContext* context) const;
120
    void dump(PrintStream& out) const;
138
    
121
    
139
    Structure* operator[](size_t i) const { return at(i); }
122
    uintptr_t encodedPointer() const { return m_pointer; }
140
    
123
    
141
    Structure* last() const { return m_structures.last(); }
124
protected:
142
125
    bool addOutOfLine(Structure* structure);
143
    SpeculatedType speculationFromStructures() const
126
    bool containsOutOfLine(Structure* structure) const;
144
    {
127
    
145
        SpeculatedType result = SpecNone;
128
    static const unsigned defaultStartingSize = 4;
129
    
130
    class OutOfLineList {
131
    public:
132
        static OutOfLineList* create(unsigned capacity);
133
        static void destroy(OutOfLineList* list);
146
        
134
        
147
        for (size_t i = 0; i < m_structures.size(); ++i)
135
        Structure** list() { return bitwise_cast<Structure**>(this + 1); }
148
            mergeSpeculation(result, speculationFromStructure(m_structures[i]));
149
        
136
        
150
        return result;
137
        OutOfLineList(unsigned length, unsigned capacity)
138
            : m_length(length)
139
            , m_capacity(capacity)
140
        {
141
        }
142
143
        unsigned m_length;
144
        unsigned m_capacity;
145
    };
146
    
147
    void deleteStructureListIfNecessary()
148
    {
149
        if (!isThin())
150
            OutOfLineList::destroy(structureList());
151
    }
151
    }
152
    
152
    
153
    ArrayModes arrayModesFromStructures() const
153
    bool isThin() const { return m_pointer & thinFlag; }
154
    
155
    void* pointer() const
154
    {
156
    {
155
        ArrayModes result = 0;
157
        return bitwise_cast<void*>(m_pointer & ~flags);
156
        
157
        for (size_t i = 0; i < m_structures.size(); ++i)
158
            mergeArrayModes(result, asArrayModes(m_structures[i]->indexingType()));
159
        
160
        return result;
161
    }
158
    }
162
    
159
    
163
    bool operator==(const StructureSet& other) const
160
    Structure* singleStructure() const
164
    {
161
    {
165
        if (m_structures.size() != other.m_structures.size())
162
        ASSERT(isThin());
166
            return false;
163
        return static_cast<Structure*>(pointer());
167
        
168
        for (size_t i = 0; i < m_structures.size(); ++i) {
169
            if (!other.contains(m_structures[i]))
170
                return false;
171
        }
172
        
173
        return true;
174
    }
164
    }
175
    
165
    
176
    void dumpInContext(PrintStream& out, DumpContext* context) const
166
    OutOfLineList* structureList() const
177
    {
167
    {
178
        CommaPrinter comma;
168
        ASSERT(!isThin());
179
        out.print("[");
169
        return static_cast<OutOfLineList*>(pointer());
180
        for (size_t i = 0; i < m_structures.size(); ++i)
181
            out.print(comma, inContext(*m_structures[i], context));
182
        out.print("]");
183
    }
170
    }
184
    
171
    
185
    void dump(PrintStream& out) const
172
    void set(Structure* structure)
173
    {
174
        set(bitwise_cast<uintptr_t>(structure), true);
175
    }
176
    void set(OutOfLineList* structures)
177
    {
178
        set(bitwise_cast<uintptr_t>(structures), false);
179
    }
180
    void set(uintptr_t pointer, bool singleStructure)
181
    {
182
        m_pointer = pointer | (singleStructure ? thinFlag : 0) | (m_pointer & reservedFlag);
183
    }
184
185
    uintptr_t m_pointer;
186
};
187
188
class StructureSet : public BorrowedStructureSet {
189
public:
190
    StructureSet()
191
        : BorrowedStructureSet(0)
186
    {
192
    {
187
        dumpInContext(out, 0);
188
    }
193
    }
189
    
194
    
190
private:
195
    StructureSet(Structure* structure)
191
    friend class DFG::StructureAbstractValue;
196
        : BorrowedStructureSet(0)
197
    {
198
        set(structure);
199
    }
192
    
200
    
193
    Vector<Structure*, 2> m_structures;
201
    ~StructureSet()
202
    {
203
        deleteStructureListIfNecessary();
204
    }
194
};
205
};
195
206
196
} // namespace JSC
207
} // namespace JSC
- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h -3 / +3 lines
Lines 1666-1672 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec1
1666
        
1666
        
1667
        StructureSet set;
1667
        StructureSet set;
1668
        for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;)
1668
        for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;)
1669
            set.addAll(node->multiGetByOffsetData().variants[i].structureSet());
1669
            set.merge(node->multiGetByOffsetData().variants[i].structureSet());
1670
        
1670
        
1671
        filter(node->child1(), set);
1671
        filter(node->child1(), set);
1672
        forNode(node).makeHeapTop();
1672
        forNode(node).makeHeapTop();
Lines 1715-1726 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec2
1715
            const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
1715
            const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
1716
            if (variant.kind() == PutByIdVariant::Replace) {
1716
            if (variant.kind() == PutByIdVariant::Replace) {
1717
                if (value.m_currentKnownStructure.contains(variant.structure()))
1717
                if (value.m_currentKnownStructure.contains(variant.structure()))
1718
                    newSet.addAll(variant.structure());
1718
                    newSet.add(variant.structure());
1719
                continue;
1719
                continue;
1720
            }
1720
            }
1721
            ASSERT(variant.kind() == PutByIdVariant::Transition);
1721
            ASSERT(variant.kind() == PutByIdVariant::Transition);
1722
            if (value.m_currentKnownStructure.contains(variant.oldStructure()))
1722
            if (value.m_currentKnownStructure.contains(variant.oldStructure()))
1723
                newSet.addAll(variant.newStructure());
1723
                newSet.add(variant.newStructure());
1724
        }
1724
        }
1725
        
1725
        
1726
        // Use filter(value, set) as a way of setting the structure set. This works because
1726
        // Use filter(value, set) as a way of setting the structure set. This works because
- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -3 / +4 lines
Lines 1894-1899 Node* ByteCodeParser::handlePutByOffset( Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
1894
Node* ByteCodeParser::emitPrototypeChecks(
1894
Node* ByteCodeParser::emitPrototypeChecks(
1895
    Structure* structure, IntendedStructureChain* chain)
1895
    Structure* structure, IntendedStructureChain* chain)
1896
{
1896
{
1897
    ASSERT(structure);
1897
    Node* base = 0;
1898
    Node* base = 0;
1898
    m_graph.chains().addLazily(chain);
1899
    m_graph.chains().addLazily(chain);
1899
    Structure* currentStructure = structure;
1900
    Structure* currentStructure = structure;
Lines 1934-1940 void ByteCodeParser::handleGetById( Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec2
1934
        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) {
1935
        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) {
1935
            if (getByIdStatus[variantIndex].chain()) {
1936
            if (getByIdStatus[variantIndex].chain()) {
1936
                emitPrototypeChecks(
1937
                emitPrototypeChecks(
1937
                    getByIdStatus[variantIndex].structureSet().singletonStructure(),
1938
                    getByIdStatus[variantIndex].structureSet().onlyStructure(),
1938
                    getByIdStatus[variantIndex].chain());
1939
                    getByIdStatus[variantIndex].chain());
1939
            }
1940
            }
1940
        }
1941
        }
Lines 1960-1966 void ByteCodeParser::handleGetById( Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec3
1960
    
1961
    
1961
    if (variant.chain()) {
1962
    if (variant.chain()) {
1962
        base = emitPrototypeChecks(
1963
        base = emitPrototypeChecks(
1963
            variant.structureSet().singletonStructure(), variant.chain());
1964
            variant.structureSet().onlyStructure(), variant.chain());
1964
    }
1965
    }
1965
    
1966
    
1966
    // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
1967
    // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
Lines 3062-3068 bool ByteCodeParser::parseBlock(unsigned Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec4
3062
                    set(VirtualRegister(dst), addToGraph(GetByIdFlush, OpInfo(identifierNumber), OpInfo(prediction), get(VirtualRegister(scope))));
3063
                    set(VirtualRegister(dst), addToGraph(GetByIdFlush, OpInfo(identifierNumber), OpInfo(prediction), get(VirtualRegister(scope))));
3063
                    break;
3064
                    break;
3064
                }
3065
                }
3065
                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().singletonStructure());
3066
                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().onlyStructure());
3066
                addToGraph(Phantom, get(VirtualRegister(scope)));
3067
                addToGraph(Phantom, get(VirtualRegister(scope)));
3067
                if (JSValue specificValue = status[0].specificValue())
3068
                if (JSValue specificValue = status[0].specificValue())
3068
                    set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
3069
                    set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
- Source/JavaScriptCore/dfg/DFGCSEPhase.cpp -1 / +1 lines
Lines 519-525 private: Source/JavaScriptCore/dfg/DFGCSEPhase.cpp_sec1
519
            switch (node->op()) {
519
            switch (node->op()) {
520
            case CheckStructure:
520
            case CheckStructure:
521
                if (node->child1() == child1
521
                if (node->child1() == child1
522
                    && node->structureSet().containsOnly(structure))
522
                    && node->structureSet().isSubsetOf(StructureSet(structure)))
523
                    return true;
523
                    return true;
524
                break;
524
                break;
525
                
525
                
- Source/JavaScriptCore/dfg/DFGNode.h -1 / +2 lines
Lines 490-502 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec1
490
        ASSERT(m_op == CheckStructure || m_op == ArrayifyToStructure);
490
        ASSERT(m_op == CheckStructure || m_op == ArrayifyToStructure);
491
        ASSERT(!child2());
491
        ASSERT(!child2());
492
        ASSERT(!child3());
492
        ASSERT(!child3());
493
        ASSERT(structure);
493
        m_opInfo = bitwise_cast<uintptr_t>(structure);
494
        m_opInfo = bitwise_cast<uintptr_t>(structure);
494
        m_op = StructureTransitionWatchpoint;
495
        m_op = StructureTransitionWatchpoint;
495
    }
496
    }
496
    
497
    
497
    void convertToStructureTransitionWatchpoint()
498
    void convertToStructureTransitionWatchpoint()
498
    {
499
    {
499
        convertToStructureTransitionWatchpoint(structureSet().singletonStructure());
500
        convertToStructureTransitionWatchpoint(structureSet().onlyStructure());
500
    }
501
    }
501
    
502
    
502
    void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
503
    void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
- Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp -1 / +1 lines
Lines 503-509 private: Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp_sec1
503
            noticeStructureCheck(variable, 0);
503
            noticeStructureCheck(variable, 0);
504
            return;
504
            return;
505
        }
505
        }
506
        noticeStructureCheck(variable, set.singletonStructure());
506
        noticeStructureCheck(variable, set.onlyStructure());
507
    }
507
    }
508
508
509
    void noticeCheckArray(VariableAccessData* variable, ArrayMode arrayMode)
509
    void noticeCheckArray(VariableAccessData* variable, ArrayMode arrayMode)

Return to Bug 133014