| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +155 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2013-03-31  Filip Pizlo  <fpizlo@apple.com>
2
3
        fourthTier: FTL JIT should supply TBAA meta-data to LLVM
4
        https://bugs.webkit.org/show_bug.cgi?id=113656
5
6
        Reviewed by NOBODY (OOPS!).
7
        
8
        This adds support for performing strong typing on the LLVM IR that the FTL
9
        generates, by using TBAA meta-data. This will permit LLVM to do aggressive
10
        GVN, load elimination, and LICM optimization even if it sees pointer store
11
        side-effects. The goal is to precisely model all loads and stores we emit,
12
        except for the super crazy ones (GetById that can go all-out polymorphic,
13
        or for example a Call where we know nothing).
14
        
15
        This is accomplished by introducing the notion of an AbstractHeap
16
        typesystem. An AbstractHeap is a subset of all possible memory locations
17
        that we might store to. For example, JSCell::m_structure and
18
        JSObject::m_butterfly are two disjoint AbstractHeaps because we know that
19
        a store to one cannot clobber the other. AbstractHeaps follow a
20
        single-inheritance hierarchy. There is the root heap, which corresponds to
21
        any possible memory location accessible to the JS engine, and then there
22
        are heaps for all internal object fields, a heap for each global object,
23
        and so on.
24
        
25
        There are three other tidbits here that make this somewhat more interesting.
26
        We have a notion of an AbstractHeap-with-offset, called AbstractField.
27
        JSCell::m_structure is actually an AbstractField. This allows us to say
28
        things like m_out.loadPtr(base, m_heaps.JSCell_structure); this both
29
        gives you the offset of JSCell::m_structure and ascribes TBAA meta-data for
30
        the JSCell::m_structure heap to the generated load instrction.
31
        
32
        Another fun tidbit is the notion of Indexed, Numbered, and Absolute abstract
33
        heaps. An indexed abstract heap corresponds to a set of locations that you
34
        might access by index from some base. Virtual registers are a great example.
35
        Though I call them just "variables" in the FTL. When we access a virtual
36
        register, we know that we aren't interfering with accesses to
37
        Structure-managed named properties, or with JSCell::m_structure, or with
38
        other such disjoint heaps. But we also know that if we access a variable at
39
        offset X and then another variable at offset Y and we know that X and Y are
40
        unequal, then these two accesses are on disjoint subheaps of the variables
41
        heap. This works out naturally for interference between, say, scoped variable
42
        access and local variable access: if you access scoped variable r5 and then
43
        access a local variable r5, these might interfere - and they will get the
44
        same abstract subheap of the variables heap. IndexedAbstractHeaps
45
        conveniently remember the size of the elements and will give you an
46
        AbstractField (i.e. heap-with-offset) if you give it an index. This is great
47
        for conveniently writing code that accesses contiguous arrays of well-typed
48
        things. This allows you to literally do things like
49
        m_out.load64(callFrameRegister, m_heaps.variables[operand]) and the right
50
        thing will happen. You can also get the heap variables.atAnyIndex(), if
51
        you're doing an access with an unknown index.
52
        
53
        Numbered and Absolute abstract heaps are related except that they don't
54
        assume that the value used to get the abstract subheap corresponds to any
55
        meaningful offset from any base. Numbered heaps, like the properties heap
56
        (for named properties tracked by Structure), are "numbered" (not indexed)
57
        by the propertyNumber. So you can emit a GetByOffset by separately
58
        computing the offset and the propertyNumber (both values are stored in the
59
        StorageAccessData), and passing the offset directly to Output::address()
60
        and passing m_heaps.properties[propertyNumber] as the field. Absolute heaps
61
        are similar, but are keyed on absolute address. This is appropriate for
62
        global variables, and possibly other things.
63
        
64
        Finally, FTL::Output understands the notion of a pointer-with-TBAA-data,
65
        and calls it a TypedPointer. TypedPointer is a tuple of a LLVMValueRef
66
        referencing an intptr value and a pointer to an AbstractHeap. All load()
67
        and store() operations now take a TypedPointer, and will perform the access
68
        by casting the intptr to a pointer of the right type and then ascribing the
69
        TBAA meta-data from the AbstractHeap.
70
71
        * JavaScriptCore.xcodeproj/project.pbxproj:
72
        * ftl/FTLAbbreviations.h:
73
        (JSC::FTL::mdKindID):
74
        (JSC::FTL::mdString):
75
        (JSC::FTL::mdNode):
76
        (FTL):
77
        (JSC::FTL::setMetadata):
78
        * ftl/FTLAbstractHeap.cpp: Added.
79
        (FTL):
80
        (JSC::FTL::AbstractHeap::tbaaMetadataSlow):
81
        (JSC::FTL::AbstractHeap::decorateInstruction):
82
        (JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
83
        (JSC::FTL::IndexedAbstractHeap::~IndexedAbstractHeap):
84
        (JSC::FTL::IndexedAbstractHeap::atSlow):
85
        (JSC::FTL::IndexedAbstractHeap::initialize):
86
        (JSC::FTL::NumberedAbstractHeap::NumberedAbstractHeap):
87
        (JSC::FTL::NumberedAbstractHeap::~NumberedAbstractHeap):
88
        (JSC::FTL::AbsoluteAbstractHeap::AbsoluteAbstractHeap):
89
        (JSC::FTL::AbsoluteAbstractHeap::~AbsoluteAbstractHeap):
90
        * ftl/FTLAbstractHeap.h: Added.
91
        (FTL):
92
        (AbstractHeap):
93
        (JSC::FTL::AbstractHeap::AbstractHeap):
94
        (JSC::FTL::AbstractHeap::isInitialized):
95
        (JSC::FTL::AbstractHeap::initialize):
96
        (JSC::FTL::AbstractHeap::parent):
97
        (JSC::FTL::AbstractHeap::heapName):
98
        (JSC::FTL::AbstractHeap::tbaaMetadata):
99
        (AbstractField):
100
        (JSC::FTL::AbstractField::AbstractField):
101
        (JSC::FTL::AbstractField::initialize):
102
        (JSC::FTL::AbstractField::offset):
103
        (IndexedAbstractHeap):
104
        (JSC::FTL::IndexedAbstractHeap::atAnyIndex):
105
        (JSC::FTL::IndexedAbstractHeap::at):
106
        (JSC::FTL::IndexedAbstractHeap::operator[]):
107
        (JSC::FTL::IndexedAbstractHeap::returnInitialized):
108
        (JSC::FTL::IndexedAbstractHeap::MyHashTraits::constructDeletedValue):
109
        (JSC::FTL::IndexedAbstractHeap::MyHashTraits::isDeletedValue):
110
        (NumberedAbstractHeap):
111
        (JSC::FTL::NumberedAbstractHeap::atAnyNumber):
112
        (JSC::FTL::NumberedAbstractHeap::at):
113
        (JSC::FTL::NumberedAbstractHeap::operator[]):
114
        (AbsoluteAbstractHeap):
115
        (JSC::FTL::AbsoluteAbstractHeap::atAnyAddress):
116
        (JSC::FTL::AbsoluteAbstractHeap::at):
117
        (JSC::FTL::AbsoluteAbstractHeap::operator[]):
118
        * ftl/FTLAbstractHeapRepository.cpp: Added.
119
        (FTL):
120
        (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
121
        (JSC::FTL::AbstractHeapRepository::~AbstractHeapRepository):
122
        * ftl/FTLAbstractHeapRepository.h: Added.
123
        (FTL):
124
        (AbstractHeapRepository):
125
        * ftl/FTLLowerDFGToLLVM.cpp:
126
        (JSC::FTL::LowerDFGToLLVM::lower):
127
        (JSC::FTL::LowerDFGToLLVM::addressFor):
128
        (JSC::FTL::LowerDFGToLLVM::payloadFor):
129
        (JSC::FTL::LowerDFGToLLVM::tagFor):
130
        (LowerDFGToLLVM):
131
        * ftl/FTLOutput.h:
132
        (FTL):
133
        (JSC::FTL::Output::Output):
134
        (JSC::FTL::Output::initialize):
135
        (JSC::FTL::Output::set):
136
        (JSC::FTL::Output::load):
137
        (JSC::FTL::Output::store):
138
        (Output):
139
        (JSC::FTL::Output::load32):
140
        (JSC::FTL::Output::load64):
141
        (JSC::FTL::Output::loadPtr):
142
        (JSC::FTL::Output::store32):
143
        (JSC::FTL::Output::store64):
144
        (JSC::FTL::Output::storePtr):
145
        (JSC::FTL::Output::address):
146
        * ftl/FTLTypedPointer.h: Added.
147
        (FTL):
148
        (TypedPointer):
149
        (JSC::FTL::TypedPointer::TypedPointer):
150
        (JSC::FTL::TypedPointer::operator!):
151
        (JSC::FTL::TypedPointer::heap):
152
        (JSC::FTL::TypedPointer::value):
153
        * runtime/Options.h:
154
        (JSC):
155
1
2013-03-29  Filip Pizlo  <fpizlo@apple.com>
156
2013-03-29  Filip Pizlo  <fpizlo@apple.com>
2
157
3
        fourthTier: FTL JIT should be able to compile the Marsaglia random number generator
158
        fourthTier: FTL JIT should be able to compile the Marsaglia random number generator
- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +20 lines
Lines 293-298 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
293
		0FEA0A12170513DB00BB722C /* FTLState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A07170513DB00BB722C /* FTLState.h */; settings = {ATTRIBUTES = (Private, ); }; };
293
		0FEA0A12170513DB00BB722C /* FTLState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A07170513DB00BB722C /* FTLState.h */; settings = {ATTRIBUTES = (Private, ); }; };
294
		0FEA0A141706363600BB722C /* FTLLLVMHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A131706363600BB722C /* FTLLLVMHeaders.h */; settings = {ATTRIBUTES = (Private, ); }; };
294
		0FEA0A141706363600BB722C /* FTLLLVMHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A131706363600BB722C /* FTLLLVMHeaders.h */; settings = {ATTRIBUTES = (Private, ); }; };
295
		0FEA0A161706BB9000BB722C /* FTLState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A151706BB9000BB722C /* FTLState.cpp */; };
295
		0FEA0A161706BB9000BB722C /* FTLState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A151706BB9000BB722C /* FTLState.cpp */; };
296
		0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A171708B00700BB722C /* FTLAbstractHeap.cpp */; };
297
		0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A181708B00700BB722C /* FTLAbstractHeap.h */; settings = {ATTRIBUTES = (Private, ); }; };
298
		0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A191708B00700BB722C /* FTLAbstractHeapRepository.cpp */; };
299
		0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A1A1708B00700BB722C /* FTLAbstractHeapRepository.h */; settings = {ATTRIBUTES = (Private, ); }; };
300
		0FEA0A201708B00700BB722C /* FTLTypedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A1B1708B00700BB722C /* FTLTypedPointer.h */; };
296
		0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
301
		0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
297
		0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; };
302
		0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; };
298
		0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */; };
303
		0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */; };
Lines 1222-1227 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
1222
		0FEA0A07170513DB00BB722C /* FTLState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLState.h; path = ftl/FTLState.h; sourceTree = "<group>"; };
1227
		0FEA0A07170513DB00BB722C /* FTLState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLState.h; path = ftl/FTLState.h; sourceTree = "<group>"; };
1223
		0FEA0A131706363600BB722C /* FTLLLVMHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLLVMHeaders.h; path = ftl/FTLLLVMHeaders.h; sourceTree = "<group>"; };
1228
		0FEA0A131706363600BB722C /* FTLLLVMHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLLVMHeaders.h; path = ftl/FTLLLVMHeaders.h; sourceTree = "<group>"; };
1224
		0FEA0A151706BB9000BB722C /* FTLState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLState.cpp; path = ftl/FTLState.cpp; sourceTree = "<group>"; };
1229
		0FEA0A151706BB9000BB722C /* FTLState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLState.cpp; path = ftl/FTLState.cpp; sourceTree = "<group>"; };
1230
		0FEA0A171708B00700BB722C /* FTLAbstractHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLAbstractHeap.cpp; path = ftl/FTLAbstractHeap.cpp; sourceTree = "<group>"; };
1231
		0FEA0A181708B00700BB722C /* FTLAbstractHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLAbstractHeap.h; path = ftl/FTLAbstractHeap.h; sourceTree = "<group>"; };
1232
		0FEA0A191708B00700BB722C /* FTLAbstractHeapRepository.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLAbstractHeapRepository.cpp; path = ftl/FTLAbstractHeapRepository.cpp; sourceTree = "<group>"; };
1233
		0FEA0A1A1708B00700BB722C /* FTLAbstractHeapRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLAbstractHeapRepository.h; path = ftl/FTLAbstractHeapRepository.h; sourceTree = "<group>"; };
1234
		0FEA0A1B1708B00700BB722C /* FTLTypedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLTypedPointer.h; path = ftl/FTLTypedPointer.h; sourceTree = "<group>"; };
1225
		0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayDescriptor.h; sourceTree = "<group>"; };
1235
		0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayDescriptor.h; sourceTree = "<group>"; };
1226
		0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; };
1236
		0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; };
1227
		0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitJumpPlaceholder.cpp; path = dfg/DFGOSRExitJumpPlaceholder.cpp; sourceTree = "<group>"; };
1237
		0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitJumpPlaceholder.cpp; path = dfg/DFGOSRExitJumpPlaceholder.cpp; sourceTree = "<group>"; };
Lines 1991-1996 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
1991
		0FEA09FC1705137F00BB722C /* ftl */ = {
2001
		0FEA09FC1705137F00BB722C /* ftl */ = {
1992
			isa = PBXGroup;
2002
			isa = PBXGroup;
1993
			children = (
2003
			children = (
2004
				0FEA0A171708B00700BB722C /* FTLAbstractHeap.cpp */,
2005
				0FEA0A181708B00700BB722C /* FTLAbstractHeap.h */,
2006
				0FEA0A191708B00700BB722C /* FTLAbstractHeapRepository.cpp */,
2007
				0FEA0A1A1708B00700BB722C /* FTLAbstractHeapRepository.h */,
1994
				0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */,
2008
				0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */,
1995
				0FEA09FE170513DB00BB722C /* FTLCapabilities.cpp */,
2009
				0FEA09FE170513DB00BB722C /* FTLCapabilities.cpp */,
1996
				0FEA09FF170513DB00BB722C /* FTLCapabilities.h */,
2010
				0FEA09FF170513DB00BB722C /* FTLCapabilities.h */,
Lines 2004-2009 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
2004
				0FEA0A06170513DB00BB722C /* FTLOutput.h */,
2018
				0FEA0A06170513DB00BB722C /* FTLOutput.h */,
2005
				0FEA0A151706BB9000BB722C /* FTLState.cpp */,
2019
				0FEA0A151706BB9000BB722C /* FTLState.cpp */,
2006
				0FEA0A07170513DB00BB722C /* FTLState.h */,
2020
				0FEA0A07170513DB00BB722C /* FTLState.h */,
2021
				0FEA0A1B1708B00700BB722C /* FTLTypedPointer.h */,
2007
			);
2022
			);
2008
			name = ftl;
2023
			name = ftl;
2009
			sourceTree = "<group>";
2024
			sourceTree = "<group>";
Lines 3088-3093 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
3088
				0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */,
3103
				0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */,
3089
				0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
3104
				0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
3090
				0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
3105
				0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
3106
				0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
3091
				0FD81AD3154FB4F000983E72 /* DFGDominators.h in Headers */,
3107
				0FD81AD3154FB4F000983E72 /* DFGDominators.h in Headers */,
3092
				0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */,
3108
				0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */,
3093
				0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */,
3109
				0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */,
Lines 3171-3176 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
3171
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
3187
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
3172
				0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
3188
				0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
3173
				BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
3189
				BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
3190
				0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
3174
				969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
3191
				969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
3175
				BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
3192
				BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
3176
				1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
3193
				1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
Lines 3215-3220 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
3215
				86E3C614167BABD7006D760A /* JSExport.h in Headers */,
3232
				86E3C614167BABD7006D760A /* JSExport.h in Headers */,
3216
				A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
3233
				A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
3217
				BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */,
3234
				BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */,
3235
				0FEA0A201708B00700BB722C /* FTLTypedPointer.h in Headers */,
3218
				BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */,
3236
				BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */,
3219
				BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
3237
				BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
3220
				BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */,
3238
				BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */,
Lines 3839-3844 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
3839
				0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
3857
				0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
3840
				147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */,
3858
				147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */,
3841
				147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
3859
				147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
3860
				0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
3842
				146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
3861
				146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
3843
				1428082E107EC0570013E7B2 /* ConstructData.cpp in Sources */,
3862
				1428082E107EC0570013E7B2 /* ConstructData.cpp in Sources */,
3844
				C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
3863
				C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
Lines 4088-4093 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
4088
				BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
4107
				BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
4089
				0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
4108
				0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
4090
				A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */,
4109
				A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */,
4110
				0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
4091
				C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
4111
				C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
4092
				14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */,
4112
				14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */,
4093
				0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
4113
				0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
- Source/JavaScriptCore/ftl/FTLAbbreviations.h +14 lines
Lines 98-103 static inline LType functionType(LType r Source/JavaScriptCore/ftl/FTLAbbreviations.h_sec1
98
    return functionType(returnType, paramTypes, 2, variadicity);
98
    return functionType(returnType, paramTypes, 2, variadicity);
99
}
99
}
100
100
101
static inline unsigned mdKindID(const char* string) { return LLVMGetMDKindID(string, strlen(string)); }
102
static inline LValue mdString(const char* string, unsigned length) { return LLVMMDString(string, length); }
103
static inline LValue mdString(const char* string) { return mdString(string, strlen(string)); }
104
static inline LValue mdNode(LValue* args, unsigned numArgs) { return LLVMMDNode(args, numArgs); }
105
static inline LValue mdNode() { return mdNode(0, 0); }
106
static inline LValue mdNode(LValue arg1) { return mdNode(&arg1, 1); }
107
static inline LValue mdNode(LValue arg1, LValue arg2)
108
{
109
    LValue args[] = { arg1, arg2 };
110
    return mdNode(args, 2);
111
}
112
113
static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { LLVMSetMetadata(instruction, kind, metadata); }
114
101
static inline LValue addFunction(LModule module, const char* name, LType type) { return LLVMAddFunction(module, name, type); }
115
static inline LValue addFunction(LModule module, const char* name, LType type) { return LLVMAddFunction(module, name, type); }
102
static inline void setLinkage(LValue global, LLinkage linkage) { LLVMSetLinkage(global, linkage); }
116
static inline void setLinkage(LValue global, LLinkage linkage) { LLVMSetLinkage(global, linkage); }
103
static inline void setFunctionCallingConv(LValue function, LCallConv convention) { LLVMSetFunctionCallConv(function, convention); }
117
static inline void setFunctionCallingConv(LValue function, LCallConv convention) { LLVMSetFunctionCallConv(function, convention); }
- Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp +162 lines
Line 0 Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp_sec1
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 "Options.h"
34
35
namespace JSC { namespace FTL {
36
37
LValue AbstractHeap::tbaaMetadataSlow(const AbstractHeapRepository& repository) const
38
{
39
    m_tbaaMetadata = mdNode(mdString(m_heapName), m_parent->tbaaMetadata(repository));
40
    return m_tbaaMetadata;
41
}
42
43
void AbstractHeap::decorateInstruction(LValue instruction, const AbstractHeapRepository& repository) const
44
{
45
    if (!Options::useFTLTBAA())
46
        return;
47
    setMetadata(instruction, repository.m_tbaaKind, tbaaMetadata(repository));
48
}
49
50
IndexedAbstractHeap::IndexedAbstractHeap(AbstractHeap* parent, const char* heapName, size_t elementSize)
51
    : m_heapForAnyIndex(parent, heapName)
52
    , m_heapNameLength(strlen(heapName))
53
    , m_elementSize(elementSize)
54
{
55
}
56
57
IndexedAbstractHeap::~IndexedAbstractHeap()
58
{
59
}
60
61
const AbstractField& IndexedAbstractHeap::atSlow(ptrdiff_t index)
62
{
63
    ASSERT(static_cast<size_t>(index) >= m_smallIndices.size());
64
    
65
    if (UNLIKELY(!m_largeIndices))
66
        m_largeIndices = adoptPtr(new MapType());
67
    
68
    MapType::const_iterator iter = m_largeIndices->find(index);
69
    if (iter != m_largeIndices->end())
70
        return *iter->value;
71
    
72
    OwnPtr<AbstractField> field = adoptPtr(new AbstractField());
73
    AbstractField* result = field.get();
74
    initialize(*result, index);
75
    m_largeIndices->add(index, field.release());
76
    return *result;
77
}
78
79
void IndexedAbstractHeap::initialize(AbstractField& field, ptrdiff_t signedIndex)
80
{
81
    // Build up a name of the form:
82
    //
83
    //    heapName_hexIndex
84
    //
85
    // or:
86
    //
87
    //    heapName_neg_hexIndex
88
    //
89
    // For example if you access an indexed heap called FooBar at index 5, you'll
90
    // get:
91
    //
92
    //    FooBar_5
93
    //
94
    // Or if you access an indexed heap called Blah at index -10, you'll get:
95
    //
96
    //    Blah_neg_A
97
    //
98
    // This is important because LLVM uses the string to distinguish the types.
99
    
100
    bool negative;
101
    size_t index;
102
    if (signedIndex < 0) {
103
        negative = true;
104
        index = -signedIndex;
105
    } else {
106
        negative = false;
107
        index = signedIndex;
108
    }
109
    
110
    for (unsigned power = 4; power <= sizeof(void*) * 8; power += 4) {
111
        // The crazy way of testing of index >= 2 ** power
112
        // (where I use ** to denote pow()).
113
        if ((index >> 1) >> (power - 1))
114
            continue;
115
        
116
        unsigned numHexlets = power >> 2;
117
        
118
        size_t stringLength = m_heapNameLength + (negative ? 5 : 1) + numHexlets;
119
        char* characters;
120
        m_largeIndexNames.append(CString::newUninitialized(stringLength, characters));
121
        
122
        memcpy(characters, m_heapForAnyIndex.heapName(), m_heapNameLength);
123
        if (negative)
124
            memcpy(characters + m_heapNameLength, "_neg_", 5);
125
        else
126
            characters[m_heapNameLength] = '_';
127
        
128
        size_t accumulator = index;
129
        for (unsigned i = 0; i < numHexlets; ++i) {
130
            characters[stringLength - i - 1] = ("0123456789ABCDEF")[accumulator & 0xF];
131
            accumulator >>= 4;
132
        }
133
        
134
        field.initialize(&m_heapForAnyIndex, characters, signedIndex * m_elementSize);
135
        return;
136
    }
137
    
138
    RELEASE_ASSERT_NOT_REACHED();
139
}
140
141
NumberedAbstractHeap::NumberedAbstractHeap(AbstractHeap* heap, const char* heapName)
142
    : m_indexedHeap(heap, heapName, 1)
143
{
144
}
145
146
NumberedAbstractHeap::~NumberedAbstractHeap()
147
{
148
}
149
150
AbsoluteAbstractHeap::AbsoluteAbstractHeap(AbstractHeap* heap, const char* heapName)
151
    : m_indexedHeap(heap, heapName, 1)
152
{
153
}
154
155
AbsoluteAbstractHeap::~AbsoluteAbstractHeap()
156
{
157
}
158
159
} } // namespace JSC::FTL
160
161
#endif // ENABLE(FTL_JIT)
162
- Source/JavaScriptCore/ftl/FTLAbstractHeap.h +227 lines
Line 0 Source/JavaScriptCore/ftl/FTLAbstractHeap.h_sec1
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
#ifndef FTLAbstractHeap_h
27
#define FTLAbstractHeap_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLAbbreviations.h"
34
#include <wtf/FastAllocBase.h>
35
#include <wtf/FixedArray.h>
36
#include <wtf/HashMap.h>
37
#include <wtf/Noncopyable.h>
38
#include <wtf/OwnPtr.h>
39
#include <wtf/Vector.h>
40
#include <wtf/text/CString.h>
41
42
namespace JSC { namespace FTL {
43
44
// The FTL JIT tries to aid LLVM's TBAA. The FTL's notion of how this
45
// happens is the AbstractHeap. AbstractHeaps are a simple type system
46
// with sub-typing.
47
48
class AbstractHeapRepository;
49
50
class AbstractHeap {
51
    WTF_MAKE_NONCOPYABLE(AbstractHeap); WTF_MAKE_FAST_ALLOCATED;
52
public:
53
    AbstractHeap()
54
        : m_parent(0)
55
        , m_heapName(0)
56
        , m_tbaaMetadata(0)
57
    {
58
    }
59
    
60
    AbstractHeap(AbstractHeap* parent, const char* heapName)
61
        : m_parent(parent)
62
        , m_heapName(heapName)
63
        , m_tbaaMetadata(0)
64
    {
65
    }
66
    
67
    bool isInitialized() const { return !!m_heapName; }
68
    
69
    void initialize(AbstractHeap* parent, const char* heapName)
70
    {
71
        m_parent = parent;
72
        m_heapName = heapName;
73
    }
74
75
    AbstractHeap* parent() const
76
    {
77
        ASSERT(isInitialized());
78
        return m_parent;
79
    }
80
    
81
    const char* heapName() const
82
    {
83
        ASSERT(isInitialized());
84
        return m_heapName;
85
    }
86
    
87
    LValue tbaaMetadata(const AbstractHeapRepository& repository) const
88
    {
89
        ASSERT(isInitialized());
90
        if (LIKELY(!!m_tbaaMetadata))
91
            return m_tbaaMetadata;
92
        return tbaaMetadataSlow(repository);
93
    }
94
    
95
    void decorateInstruction(LValue instruction, const AbstractHeapRepository&) const;
96
97
private:
98
    friend class AbstractHeapRepository;
99
    
100
    LValue tbaaMetadataSlow(const AbstractHeapRepository&) const;
101
    
102
    AbstractHeap* m_parent;
103
    const char* m_heapName;
104
    mutable LValue m_tbaaMetadata;
105
};
106
107
// Think of "AbstractField" as being an "AbstractHeapWithOffset". I would have named
108
// it the latter except that I don't like typing that much.
109
class AbstractField : public AbstractHeap {
110
public:
111
    AbstractField()
112
    {
113
    }
114
    
115
    AbstractField(AbstractHeap* parent, const char* heapName, ptrdiff_t offset)
116
        : AbstractHeap(parent, heapName)
117
        , m_offset(offset)
118
    {
119
    }
120
    
121
    void initialize(AbstractHeap* parent, const char* heapName, ptrdiff_t offset)
122
    {
123
        AbstractHeap::initialize(parent, heapName);
124
        m_offset = offset;
125
    }
126
    
127
    ptrdiff_t offset() const
128
    {
129
        ASSERT(isInitialized());
130
        return m_offset;
131
    }
132
    
133
private:
134
    ptrdiff_t m_offset;
135
};
136
137
class IndexedAbstractHeap {
138
public:
139
    IndexedAbstractHeap(AbstractHeap* parent, const char* heapName, size_t elementSize);
140
    ~IndexedAbstractHeap();
141
    
142
    const AbstractHeap& atAnyIndex() const { return m_heapForAnyIndex; }
143
    
144
    const AbstractField& at(ptrdiff_t index)
145
    {
146
        if (static_cast<size_t>(index) < m_smallIndices.size())
147
            return returnInitialized(m_smallIndices[index], index);
148
        return atSlow(index);
149
    }
150
    
151
    const AbstractField& operator[](ptrdiff_t index) { return at(index); }
152
    
153
private:
154
    const AbstractField& returnInitialized(AbstractField& field, ptrdiff_t index)
155
    {
156
        if (UNLIKELY(!field.isInitialized()))
157
            initialize(field, index);
158
        return field;
159
    }
160
161
    const AbstractField& atSlow(ptrdiff_t index);
162
    void initialize(AbstractField& field, ptrdiff_t index);
163
164
    AbstractHeap m_heapForAnyIndex;
165
    size_t m_heapNameLength;
166
    size_t m_elementSize;
167
    FixedArray<AbstractField, 16> m_smallIndices;
168
    
169
    struct MyHashTraits : WTF::GenericHashTraits<ptrdiff_t> {
170
        static void constructDeletedValue(ptrdiff_t& slot) { slot = 1; }
171
        static bool isDeletedValue(ptrdiff_t value) { return value == 1; }
172
    };
173
    typedef HashMap<ptrdiff_t, OwnPtr<AbstractField>, WTF::IntHash<ptrdiff_t>, MyHashTraits> MapType;
174
    OwnPtr<MapType> m_largeIndices;
175
    Vector<CString, 16> m_largeIndexNames;
176
};
177
178
// A numbered abstract heap is like an indexed abstract heap, except that you
179
// can't rely on there being a relationship between the number you use to
180
// retrieve the sub-heap, and the offset that this heap has. (In particular,
181
// the sub-heaps don't have indices.)
182
183
class NumberedAbstractHeap {
184
public:
185
    NumberedAbstractHeap(AbstractHeap* parent, const char* heapName);
186
    ~NumberedAbstractHeap();
187
    
188
    const AbstractHeap& atAnyNumber() const { return m_indexedHeap.atAnyIndex(); }
189
    
190
    const AbstractHeap& at(unsigned number) { return m_indexedHeap.at(number); }
191
    const AbstractHeap& operator[](unsigned number) { return at(number); }
192
193
private:
194
    
195
    // We use the fact that the indexed heap already has a superset of the
196
    // functionality we need.
197
    IndexedAbstractHeap m_indexedHeap;
198
};
199
200
class AbsoluteAbstractHeap {
201
public:
202
    AbsoluteAbstractHeap(AbstractHeap* parent, const char* heapName);
203
    ~AbsoluteAbstractHeap();
204
    
205
    const AbstractHeap& atAnyAddress() const { return m_indexedHeap.atAnyIndex(); }
206
    
207
    const AbstractHeap& at(void* address)
208
    {
209
        return m_indexedHeap.at(bitwise_cast<ptrdiff_t>(address));
210
    }
211
    
212
    const AbstractHeap& operator[](void* address) { return at(address); }
213
214
private:
215
    
216
    // The trick here is that the indexed heap is "indexed" by a pointer-width
217
    // integer. Pointers are themselves pointer-width integers. So we can reuse
218
    // all of the functionality.
219
    IndexedAbstractHeap m_indexedHeap;
220
};
221
222
} } // namespace JSC::FTL
223
224
#endif // ENABLE(FTL_JIT)
225
226
#endif // FTLAbstractHeap_h
227
- Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp +73 lines
Line 0 Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp_sec1
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 "FTLAbstractHeapRepository.h"
28
29
#if ENABLE(FTL_JIT)
30
31
#include "Operations.h"
32
33
namespace JSC { namespace FTL {
34
35
AbstractHeapRepository::AbstractHeapRepository()
36
    : root(0, "root")
37
38
#define ABSTRACT_HEAP_DECLARATION(name) , name(&root, #name)
39
    FOR_EACH_ABSTRACT_HEAP(ABSTRACT_HEAP_DECLARATION)
40
#undef ABSTRACT_HEAP_DECLARATION
41
42
#define ABSTRACT_FIELD_DECLARATION(name, offset) , name(&root, #name, offset)
43
    FOR_EACH_ABSTRACT_FIELD(ABSTRACT_FIELD_DECLARATION)
44
#undef ABSTRACT_FIELD_DECLARATION
45
    
46
#define INDEXED_ABSTRACT_HEAP_DECLARATION(name, size) , name(&root, #name, size)
47
    FOR_EACH_INDEXED_ABSTRACT_HEAP(INDEXED_ABSTRACT_HEAP_DECLARATION)
48
#undef INDEXED_ABSTRACT_HEAP_DECLARATION
49
    
50
#define NUMBERED_ABSTRACT_HEAP_DECLARATION(name) , name(&root, #name)
51
    FOR_EACH_NUMBERED_ABSTRACT_HEAP(NUMBERED_ABSTRACT_HEAP_DECLARATION)
52
#undef NUMBERED_ABSTRACT_HEAP_DECLARATION
53
54
#define ABSOLUTE_ABSTRACT_HEAP_DECLARATION(name) , name(&root, #name)
55
    FOR_EACH_ABSOLUTE_ABSTRACT_HEAP(ABSOLUTE_ABSTRACT_HEAP_DECLARATION)
56
#undef ABSOLUTE_ABSTRACT_HEAP_DECLARATION
57
58
    , m_tbaaKind(mdKindID("tbaa"))
59
{
60
    root.m_tbaaMetadata = mdNode(mdString(root.m_heapName));
61
    
62
    RELEASE_ASSERT(m_tbaaKind);
63
    RELEASE_ASSERT(root.m_tbaaMetadata);
64
}
65
66
AbstractHeapRepository::~AbstractHeapRepository()
67
{
68
}
69
70
} } // namespace JSC::FTL
71
72
#endif // ENABLE(FTL_JIT)
73
- Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h +102 lines
Line 0 Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h_sec1
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
#ifndef FTLAbstractHeapRepository_h
27
#define FTLAbstractHeapRepository_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLAbstractHeap.h"
34
35
namespace JSC { namespace FTL {
36
37
#define FOR_EACH_ABSTRACT_HEAP(macro) \
38
    macro(typedArrayProperties) \
39
    macro(length)
40
41
#define FOR_EACH_ABSTRACT_FIELD(macro) \
42
    macro(JSCell_structure, JSCell::structureOffset()) \
43
    macro(JSObject_butterfly, JSObject::butterflyOffset()) \
44
    macro(Butterfly_publicLength, Butterfly::offsetOfPublicLength())
45
46
#define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
47
    macro(variables, sizeof(Register)) \
48
    macro(indexedInt32Properties, sizeof(EncodedJSValue)) \
49
    macro(indexedDoubleProperties, sizeof(double)) \
50
    macro(indexedContiguousProperties, sizeof(EncodedJSValue)) \
51
    macro(indexedArrayStorageProperties, sizeof(EncodedJSValue))
52
    
53
#define FOR_EACH_NUMBERED_ABSTRACT_HEAP(macro) \
54
    macro(properties)
55
    
56
#define FOR_EACH_ABSOLUTE_ABSTRACT_HEAP(macro) \
57
    macro(globalVariables)
58
    
59
// This class is meant to be cacheable between compilations, but it doesn't have to be.
60
// Doing so saves on creation of nodes. But clearing it will save memory.
61
62
class AbstractHeapRepository {
63
    WTF_MAKE_NONCOPYABLE(AbstractHeapRepository);
64
public:
65
    AbstractHeapRepository();
66
    ~AbstractHeapRepository();
67
    
68
    AbstractHeap root;
69
    
70
#define ABSTRACT_HEAP_DECLARATION(name) AbstractHeap name;
71
    FOR_EACH_ABSTRACT_HEAP(ABSTRACT_HEAP_DECLARATION)
72
#undef ABSTRACT_HEAP_DECLARATION
73
74
#define ABSTRACT_FIELD_DECLARATION(name, offset) AbstractField name;
75
    FOR_EACH_ABSTRACT_FIELD(ABSTRACT_FIELD_DECLARATION)
76
#undef ABSTRACT_FIELD_DECLARATION
77
    
78
#define INDEXED_ABSTRACT_HEAP_DECLARATION(name, size) IndexedAbstractHeap name;
79
    FOR_EACH_INDEXED_ABSTRACT_HEAP(INDEXED_ABSTRACT_HEAP_DECLARATION)
80
#undef INDEXED_ABSTRACT_HEAP_DECLARATION
81
    
82
#define NUMBERED_ABSTRACT_HEAP_DECLARATION(name) NumberedAbstractHeap name;
83
    FOR_EACH_NUMBERED_ABSTRACT_HEAP(NUMBERED_ABSTRACT_HEAP_DECLARATION)
84
#undef NUMBERED_ABSTRACT_HEAP_DECLARATION
85
86
#define ABSOLUTE_ABSTRACT_HEAP_DECLARATION(name) AbsoluteAbstractHeap name;
87
    FOR_EACH_ABSOLUTE_ABSTRACT_HEAP(ABSOLUTE_ABSTRACT_HEAP_DECLARATION)
88
#undef ABSOLUTE_ABSTRACT_HEAP_DECLARATION
89
90
private:
91
    friend class AbstractHeap;
92
    
93
    unsigned m_tbaaKind;
94
    
95
};
96
97
} } // namespace JSC::FTL
98
99
#endif // ENABLE(FTL_JIT)
100
101
#endif // FTLAbstractHeapRepository_h
102
- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp -10 / +12 lines
Lines 29-34 Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
29
#if ENABLE(FTL_JIT)
29
#if ENABLE(FTL_JIT)
30
30
31
#include "DFGAbstractState.h"
31
#include "DFGAbstractState.h"
32
#include "FTLAbstractHeapRepository.h"
32
#include "FTLOutput.h"
33
#include "FTLOutput.h"
33
#include "Operations.h"
34
#include "Operations.h"
34
35
Lines 68-74 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
68
            m_ftlState.module, name.data(), functionType(m_out.int64, m_out.intPtr));
69
            m_ftlState.module, name.data(), functionType(m_out.int64, m_out.intPtr));
69
        setFunctionCallingConv(m_ftlState.function, LLVMCCallConv);
70
        setFunctionCallingConv(m_ftlState.function, LLVMCCallConv);
70
        
71
        
71
        m_out.initialize(m_ftlState.module, m_ftlState.function);
72
        m_out.initialize(m_ftlState.module, m_ftlState.function, m_heaps);
72
        
73
        
73
        m_prologue = appendBasicBlock(m_ftlState.function);
74
        m_prologue = appendBasicBlock(m_ftlState.function);
74
        m_out.appendTo(m_prologue);
75
        m_out.appendTo(m_prologue);
Lines 731-757 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
731
        lowInt32(edge);
732
        lowInt32(edge);
732
    }
733
    }
733
    
734
    
734
    LValue addressFor(LValue base, int operand)
735
    TypedPointer addressFor(LValue base, int operand, ptrdiff_t offset = 0)
735
    {
736
    {
736
        return m_out.add(base, m_out.constIntPtr(operand * sizeof(Register)));
737
        return m_out.address(base, m_heaps.variables[operand], offset);
737
    }
738
    }
738
    LValue payloadFor(LValue base, int operand)
739
    TypedPointer payloadFor(LValue base, int operand)
739
    {
740
    {
740
        return m_out.add(base, m_out.constIntPtr(operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
741
        return addressFor(base, operand, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
741
    }
742
    }
742
    LValue tagFor(LValue base, int operand)
743
    TypedPointer tagFor(LValue base, int operand)
743
    {
744
    {
744
        return m_out.add(base, m_out.constIntPtr(operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
745
        return addressFor(base, operand, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
745
    }
746
    }
746
    LValue addressFor(int operand)
747
    TypedPointer addressFor(int operand)
747
    {
748
    {
748
        return addressFor(m_callFrame, operand);
749
        return addressFor(m_callFrame, operand);
749
    }
750
    }
750
    LValue payloadFor(int operand)
751
    TypedPointer payloadFor(int operand)
751
    {
752
    {
752
        return payloadFor(m_callFrame, operand);
753
        return payloadFor(m_callFrame, operand);
753
    }
754
    }
754
    LValue tagFor(int operand)
755
    TypedPointer tagFor(int operand)
755
    {
756
    {
756
        return tagFor(m_callFrame, operand);
757
        return tagFor(m_callFrame, operand);
757
    }
758
    }
Lines 761-766 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec4
761
    
762
    
762
    Graph& m_graph;
763
    Graph& m_graph;
763
    State& m_ftlState;
764
    State& m_ftlState;
765
    AbstractHeapRepository m_heaps;
764
    Output m_out;
766
    Output m_out;
765
    
767
    
766
    LBasicBlock m_prologue;
768
    LBasicBlock m_prologue;
- Source/JavaScriptCore/ftl/FTLOutput.h -15 / +52 lines
Lines 31-36 Source/JavaScriptCore/ftl/FTLOutput.h_sec1
31
#if ENABLE(FTL_JIT)
31
#if ENABLE(FTL_JIT)
32
32
33
#include "FTLAbbreviations.h"
33
#include "FTLAbbreviations.h"
34
#include "FTLAbstractHeapRepository.h"
35
#include "FTLTypedPointer.h"
34
36
35
namespace JSC { namespace FTL {
37
namespace JSC { namespace FTL {
36
38
Lines 44-55 namespace JSC { namespace FTL { Source/JavaScriptCore/ftl/FTLOutput.h_sec2
44
//
46
//
45
// We say that a "pointer" is what LLVM considers to be a pointer-width integer.
47
// We say that a "pointer" is what LLVM considers to be a pointer-width integer.
46
//
48
//
49
// We say that a "typed pointer" is a pointer that carries TBAA meta-data (i.e. an
50
// AbstractHeap). These should usually not have further computation performed on them
51
// prior to access, though there are exceptions (like offsetting into the payload of
52
// a typed pointer to a JSValue).
53
//
47
// We say that "get" and "set" are what LLVM considers to be "load" and "store". Get
54
// We say that "get" and "set" are what LLVM considers to be "load" and "store". Get
48
// and set take references.
55
// and set take references.
49
//
56
//
50
// We say that "load" and "store" are operations that take a pointer and an offset.
57
// We say that "load" and "store" are operations that take a typed pointer. These
51
// These translate the pointer + offset into a reference (or, a pointer in LLVM-speak)
58
// operations translate the pointer into a reference (or, a pointer in LLVM-speak),
52
// and use get and set on them (or, load and store in LLVM-speak).
59
// emit get or set on the reference (or, load and store in LLVM-speak), and apply the
60
// TBAA meta-data to the get or set.
53
61
54
class Output {
62
class Output {
55
public:
63
public:
Lines 67-73 public: Source/JavaScriptCore/ftl/FTLOutput.h_sec3
67
        , int32Zero(constInt(int32, 0, SignExtend))
75
        , int32Zero(constInt(int32, 0, SignExtend))
68
        , int64Zero(constInt(int64, 0, SignExtend))
76
        , int64Zero(constInt(int64, 0, SignExtend))
69
        , intPtrZero(constInt(intPtr, 0, SignExtend))
77
        , intPtrZero(constInt(intPtr, 0, SignExtend))
78
        , m_module(0)
70
        , m_function(0)
79
        , m_function(0)
80
        , m_heaps(0)
71
        , m_builder(LLVMCreateBuilder())
81
        , m_builder(LLVMCreateBuilder())
72
        , m_block(0)
82
        , m_block(0)
73
        , m_nextBlock(0)
83
        , m_nextBlock(0)
Lines 81-90 public: Source/JavaScriptCore/ftl/FTLOutput.h_sec4
81
        LLVMDisposeBuilder(m_builder);
91
        LLVMDisposeBuilder(m_builder);
82
    }
92
    }
83
    
93
    
84
    void initialize(LModule module, LValue function)
94
    void initialize(LModule module, LValue function, AbstractHeapRepository& heaps)
85
    {
95
    {
86
        m_module = module;
96
        m_module = module;
87
        m_function = function;
97
        m_function = function;
98
        m_heaps = &heaps;
88
    }
99
    }
89
    
100
    
90
    LBasicBlock appendTo(LBasicBlock block, LBasicBlock nextBlock)
101
    LBasicBlock appendTo(LBasicBlock block, LBasicBlock nextBlock)
Lines 137-158 public: Source/JavaScriptCore/ftl/FTLOutput.h_sec5
137
    LValue castToInt32(LValue value) { return intCast(value, int32); }
148
    LValue castToInt32(LValue value) { return intCast(value, int32); }
138
    
149
    
139
    LValue get(LValue reference) { return buildLoad(m_builder, reference); }
150
    LValue get(LValue reference) { return buildLoad(m_builder, reference); }
140
    void set(LValue value, LValue reference) { buildStore(m_builder, value, reference); }
151
    LValue set(LValue value, LValue reference) { return buildStore(m_builder, value, reference); }
152
    
153
    LValue load(TypedPointer pointer, LType refType)
154
    {
155
        LValue result = get(buildIntToPtr(m_builder, pointer.value(), refType));
156
        pointer.heap().decorateInstruction(result, *m_heaps);
157
        return result;
158
    }
159
    void store(LValue value, TypedPointer pointer, LType refType)
160
    {
161
        LValue result = set(value, buildIntToPtr(m_builder, pointer.value(), refType));
162
        pointer.heap().decorateInstruction(result, *m_heaps);
163
    }
141
    
164
    
142
    LValue load(LValue pointer, ptrdiff_t offset, LType refType)
165
    LValue load32(TypedPointer pointer) { return load(pointer, ref32); }
166
    LValue load64(TypedPointer pointer) { return load(pointer, ref64); }
167
    LValue loadPtr(TypedPointer pointer) { return load(pointer, refPtr); }
168
    void store32(LValue value, TypedPointer pointer) { store(value, pointer, ref32); }
169
    void store64(LValue value, TypedPointer pointer) { store(value, pointer, ref64); }
170
    void storePtr(LValue value, TypedPointer pointer) { store(value, pointer, refPtr); }
171
172
    // Construct an address by offsetting base by the requested amount and ascribing
173
    // the requested abstract heap to it.
174
    TypedPointer address(const AbstractHeap& heap, LValue base, ptrdiff_t offset = 0)
143
    {
175
    {
144
        return get(buildIntToPtr(m_builder, offset ? add(pointer, constIntPtr(offset)) : pointer, refType));
176
        return TypedPointer(heap, offset ? add(base, constIntPtr(offset)) : base);
145
    }
177
    }
146
    void store(LValue value, LValue pointer, ptrdiff_t offset, LType refType)
178
    // Construct an address by offsetting base by the amount specified by the field,
179
    // and optionally an additional amount (use this with care), and then creating
180
    // a TypedPointer with the given field as the heap.
181
    TypedPointer address(LValue base, const AbstractField& field, ptrdiff_t offset = 0)
147
    {
182
    {
148
        set(value, buildIntToPtr(m_builder, offset ? add(pointer, constIntPtr(offset)) : pointer, refType));
183
        return address(field, base, offset + field.offset());
149
    }
184
    }
150
    LValue load32(LValue pointer, ptrdiff_t offset = 0) { return load(pointer, offset, ref32); }
185
    
151
    LValue load64(LValue pointer, ptrdiff_t offset = 0) { return load(pointer, offset, ref64); }
186
    LValue load32(LValue base, const AbstractField& field) { return load32(address(base, field)); }
152
    LValue loadPtr(LValue pointer, ptrdiff_t offset = 0) { return load(pointer, offset, refPtr); }
187
    LValue load64(LValue base, const AbstractField& field) { return load64(address(base, field)); }
153
    void store32(LValue value, LValue pointer, ptrdiff_t offset = 0) { store(value, pointer, offset, ref32); }
188
    LValue loadPtr(LValue base, const AbstractField& field) { return loadPtr(address(base, field)); }
154
    void store64(LValue value, LValue pointer, ptrdiff_t offset = 0) { store(value, pointer, offset, ref64); }
189
    void store32(LValue value, LValue base, const AbstractField& field) { store32(value, address(base, field)); }
155
    void storePtr(LValue value, LValue pointer, ptrdiff_t offset = 0) { store(value, pointer, offset, refPtr); }
190
    void store64(LValue value, LValue base, const AbstractField& field) { store64(value, address(base, field)); }
191
    void storePtr(LValue value, LValue base, const AbstractField& field) { storePtr(value, address(base, field)); }
156
    
192
    
157
    LValue equal(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntEQ, left, right); }
193
    LValue equal(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntEQ, left, right); }
158
    LValue notEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntNE, left, right); }
194
    LValue notEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntNE, left, right); }
Lines 221-226 public: Source/JavaScriptCore/ftl/FTLOutput.h_sec6
221
    
257
    
222
    LModule m_module;
258
    LModule m_module;
223
    LValue m_function;
259
    LValue m_function;
260
    AbstractHeapRepository* m_heaps;
224
    LBuilder m_builder;
261
    LBuilder m_builder;
225
    LBasicBlock m_block;
262
    LBasicBlock m_block;
226
    LBasicBlock m_nextBlock;
263
    LBasicBlock m_nextBlock;
- Source/JavaScriptCore/ftl/FTLTypedPointer.h +71 lines
Line 0 Source/JavaScriptCore/ftl/FTLTypedPointer.h_sec1
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
#ifndef FTLTypedPointer_h
27
#define FTLTypedPointer_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLAbbreviations.h"
34
#include "FTLAbstractHeap.h"
35
36
namespace JSC { namespace FTL {
37
38
class TypedPointer {
39
public:
40
    TypedPointer()
41
        : m_heap(0)
42
        , m_value(0)
43
    {
44
    }
45
    
46
    TypedPointer(const AbstractHeap& heap, LValue value)
47
        : m_heap(&heap)
48
        , m_value(value)
49
    {
50
    }
51
    
52
    bool operator!() const
53
    {
54
        ASSERT(!m_heap == !m_value);
55
        return !m_heap;
56
    }
57
    
58
    const AbstractHeap& heap() const { return *m_heap; }
59
    LValue value() const { return m_value; }
60
61
private:
62
    const AbstractHeap* m_heap;
63
    LValue m_value;
64
};
65
66
} } // namespace JSC::FTL
67
68
#endif // ENABLE(FTL_JIT)
69
70
#endif // FTLTypedPointer_h
71
- Source/JavaScriptCore/runtime/Options.h +1 lines
Lines 83-88 namespace JSC { Source/JavaScriptCore/runtime/Options.h_sec1
83
    v(bool, validateGraphAtEachPhase, false) \
83
    v(bool, validateGraphAtEachPhase, false) \
84
    \
84
    \
85
    v(bool, useExperimentalFTL, false) \
85
    v(bool, useExperimentalFTL, false) \
86
    v(bool, useFTLTBAA, true) \
86
    \
87
    \
87
    v(bool, enableProfiler, false) \
88
    v(bool, enableProfiler, false) \
88
    \
89
    \

Return to Bug 113656