| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +394 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2012-01-26  Filip Pizlo  <fpizlo@apple.com>
2
3
        JSC should be a triple-tier VM
4
        https://bugs.webkit.org/show_bug.cgi?id=75812
5
        <rdar://problem/10079694>
6
7
        Reviewed by NOBODY (OOPS!).
8
        
9
        Implemented an interpreter that uses the JIT's calling convention. This
10
        interpreter is called LLInt, or the Low Level Interpreter. JSC will now
11
        will start by executing code in LLInt and will only tier up to the old
12
        JIT after the code is proven hot.
13
        
14
        LLInt is written in a modified form of our macro assembly. This new macro
15
        assembly is compiled by an offline assembler (see offlineasm), which
16
        implements many modern conveniences such as a Turing-complete CPS-based
17
        macro language and direct access to relevant C++ type information
18
        (basically offsets of fields and sizes of structs/classes).
19
        
20
        Code executing in LLInt appears to the rest of the JSC world "as if" it
21
        were executing in the old JIT. Hence, things like exception handling and
22
        cross-execution-engine calls just work and require pretty much no
23
        additional overhead.
24
        
25
        This interpreter is 2-2.5x faster than our old interpreter on SunSpider,
26
        V8, and Kraken. With triple-tiering turned on, we're neutral on SunSpider,
27
        V8, and Kraken, but appear to get a double-digit improvement on real-world
28
        websites due to a huge reduction in the amount of JIT'ing.
29
        
30
        As an additional change, this patch makes bytecode dumping and JSValue
31
        dumping work in release builds, since debugging some of the nastier
32
        aspects of this patch would have been impossible without that. And I
33
        don't believe that we care about the miniscule code bloat that this
34
        introduces.
35
36
        * CMakeLists.txt:
37
        * GNUmakefile.am:
38
        * GNUmakefile.list.am:
39
        * JavaScriptCore.pri:
40
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
41
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
42
        * JavaScriptCore.xcodeproj/project.pbxproj:
43
        * Target.pri:
44
        * assembler/LinkBuffer.h:
45
        * bytecode/BytecodeConventions.h: Added.
46
        * bytecode/CallLinkStatus.cpp:
47
        (JSC::CallLinkStatus::computeFromLLInt):
48
        (JSC):
49
        (JSC::CallLinkStatus::computeFor):
50
        * bytecode/CallLinkStatus.h:
51
        (JSC::CallLinkStatus::isSet):
52
        (JSC::CallLinkStatus::operator!):
53
        (CallLinkStatus):
54
        * bytecode/CodeBlock.cpp:
55
        (JSC):
56
        (JSC::escapeQuotes):
57
        (JSC::CodeBlock::dump):
58
        (JSC::CodeBlock::CodeBlock):
59
        (JSC::CodeBlock::~CodeBlock):
60
        (JSC::CodeBlock::finalizeUnconditionally):
61
        (JSC::CodeBlock::stronglyVisitStrongReferences):
62
        (JSC::CodeBlock::unlinkCalls):
63
        (JSC::CodeBlock::unlinkIncomingCalls):
64
        (JSC::CodeBlock::bytecodeOffset):
65
        (JSC::ProgramCodeBlock::jettison):
66
        (JSC::EvalCodeBlock::jettison):
67
        (JSC::FunctionCodeBlock::jettison):
68
        (JSC::ProgramCodeBlock::jitCompileImpl):
69
        (JSC::EvalCodeBlock::jitCompileImpl):
70
        (JSC::FunctionCodeBlock::jitCompileImpl):
71
        (JSC::CodeBlock::handleBytecodeDiscardingOpportunity):
72
        (JSC::CodeBlock::usesOpcode):
73
        * bytecode/CodeBlock.h:
74
        (JSC):
75
        (CodeBlock):
76
        ():
77
        (JSC::CodeBlock::baselineVersion):
78
        (JSC::CodeBlock::linkIncomingCall):
79
        (JSC::CodeBlock::bytecodeOffset):
80
        (JSC::CodeBlock::jitCompile):
81
        (JSC::CodeBlock::hasOptimizedReplacement):
82
        (JSC::CodeBlock::addPropertyAccessInstruction):
83
        (JSC::CodeBlock::addGlobalResolveInstruction):
84
        (JSC::CodeBlock::addLLIntCallLinkInfo):
85
        (JSC::CodeBlock::addGlobalResolveInfo):
86
        (JSC::CodeBlock::numberOfMethodCallLinkInfos):
87
        (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
88
        (JSC::CodeBlock::likelyToTakeSlowCase):
89
        (JSC::CodeBlock::couldTakeSlowCase):
90
        (JSC::CodeBlock::likelyToTakeSpecialFastCase):
91
        (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
92
        (JSC::CodeBlock::likelyToTakeAnySlowCase):
93
        (JSC::CodeBlock::addFrequentExitSite):
94
        (JSC::CodeBlock::dontJITAnytimeSoon):
95
        (JSC::CodeBlock::jitAfterWarmUp):
96
        (JSC::CodeBlock::jitSoon):
97
        (JSC::CodeBlock::llintExecuteCounter):
98
        (ProgramCodeBlock):
99
        (EvalCodeBlock):
100
        (FunctionCodeBlock):
101
        * bytecode/GetByIdStatus.cpp:
102
        (JSC::GetByIdStatus::computeFromLLInt):
103
        (JSC):
104
        (JSC::GetByIdStatus::computeFor):
105
        * bytecode/GetByIdStatus.h:
106
        (JSC::GetByIdStatus::GetByIdStatus):
107
        (JSC::GetByIdStatus::wasSeenInJIT):
108
        (GetByIdStatus):
109
        * bytecode/Instruction.h:
110
        (JSC):
111
        (JSC::Instruction::Instruction):
112
        (Instruction):
113
        ():
114
        * bytecode/LLIntCallLinkInfo.h: Added.
115
        (JSC):
116
        (JSC::LLIntCallLinkInfo::LLIntCallLinkInfo):
117
        (LLIntCallLinkInfo):
118
        (JSC::LLIntCallLinkInfo::~LLIntCallLinkInfo):
119
        (JSC::LLIntCallLinkInfo::isLinked):
120
        (JSC::LLIntCallLinkInfo::unlink):
121
        * bytecode/MethodCallLinkStatus.cpp:
122
        (JSC::MethodCallLinkStatus::computeFor):
123
        * bytecode/Opcode.h:
124
        (JSC):
125
        ():
126
        * bytecode/PutByIdStatus.cpp:
127
        (JSC::PutByIdStatus::computeFromLLInt):
128
        (JSC):
129
        (JSC::PutByIdStatus::computeFor):
130
        * bytecode/PutByIdStatus.h:
131
        (PutByIdStatus):
132
        * bytecompiler/BytecodeGenerator.cpp:
133
        (JSC):
134
        (JSC::BytecodeGenerator::setDumpsGeneratedCode):
135
        (JSC::BytecodeGenerator::dumpsGeneratedCode):
136
        (JSC::BytecodeGenerator::generate):
137
        (JSC::BytecodeGenerator::emitResolve):
138
        (JSC::BytecodeGenerator::emitResolveWithBase):
139
        (JSC::BytecodeGenerator::emitResolveWithThis):
140
        (JSC::BytecodeGenerator::emitGetById):
141
        (JSC::BytecodeGenerator::emitPutById):
142
        (JSC::BytecodeGenerator::emitDirectPutById):
143
        (JSC::BytecodeGenerator::emitCall):
144
        (JSC::BytecodeGenerator::emitConstruct):
145
        (JSC::BytecodeGenerator::emitCatch):
146
        * dfg/DFGByteCodeParser.cpp:
147
        (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
148
        (JSC::DFG::ByteCodeParser::handleInlining):
149
        (JSC::DFG::ByteCodeParser::parseBlock):
150
        * dfg/DFGCapabilities.h:
151
        (JSC::DFG::canCompileOpcode):
152
        * dfg/DFGOSRExitCompiler.cpp:
153
        ():
154
        * dfg/DFGOperations.cpp:
155
        ():
156
        * heap/AllocationSpace.h:
157
        (JSC):
158
        (AllocationSpace):
159
        ():
160
        * heap/Heap.cpp:
161
        (JSC::Heap::collect):
162
        * heap/Heap.h:
163
        (JSC):
164
        ():
165
        (Heap):
166
        * heap/MarkStack.cpp:
167
        (JSC::visitChildren):
168
        * heap/MarkedSpace.h:
169
        (JSC):
170
        (MarkedSpace):
171
        * interpreter/CallFrame.h:
172
        (ExecState):
173
        (JSC::ExecState::currentVPC):
174
        * interpreter/Interpreter.cpp:
175
        (JSC::Interpreter::~Interpreter):
176
        (JSC):
177
        (JSC::Interpreter::initialize):
178
        (JSC::Interpreter::isOpcode):
179
        (JSC::Interpreter::unwindCallFrame):
180
        (JSC::Interpreter::retrieveLastCaller):
181
        * interpreter/Interpreter.h:
182
        (JSC):
183
        ():
184
        (Interpreter):
185
        (JSC::Interpreter::getOpcode):
186
        (JSC::Interpreter::getOpcodeID):
187
        (JSC::Interpreter::enabled):
188
        * interpreter/RegisterFile.h:
189
        (JSC):
190
        (RegisterFile):
191
        * jit/HostCallReturnValue.cpp: Added.
192
        (JSC):
193
        (JSC::getHostCallReturnValueWithExecState):
194
        * jit/HostCallReturnValue.h: Added.
195
        (JSC):
196
        * jit/JIT.cpp:
197
        (JSC::JIT::privateCompileMainPass):
198
        (JSC::JIT::privateCompileSlowCases):
199
        (JSC::JIT::privateCompile):
200
        * jit/JITCode.h:
201
        ():
202
        (JSC::JITCode::isOptimizingJIT):
203
        (JITCode):
204
        (JSC::JITCode::isBaselineCode):
205
        (JSC::JITCode::JITCode):
206
        * jit/JITDriver.h:
207
        (JSC::jitCompileIfAppropriate):
208
        (JSC::jitCompileFunctionIfAppropriate):
209
        * jit/JITExceptions.cpp:
210
        (JSC::jitThrow):
211
        * jit/JITStubs.cpp:
212
        (JSC::DEFINE_STUB_FUNCTION):
213
        (JSC):
214
        * jit/JSInterfaceJIT.h:
215
        * llint: Added.
216
        * llint/LLIntCommon.h: Added.
217
        * llint/LLIntData.cpp: Added.
218
        (LLInt):
219
        (JSC::LLInt::Data::Data):
220
        (JSC::LLInt::Data::~Data):
221
        * llint/LLIntData.h: Added.
222
        (JSC):
223
        (LLInt):
224
        (Data):
225
        (JSC::LLInt::Data::exceptionInstructions):
226
        (JSC::LLInt::Data::opcodeMap):
227
        * llint/LLIntEntrypoints.cpp: Added.
228
        (LLInt):
229
        (JSC::LLInt::getFunctionEntrypoint):
230
        (JSC::LLInt::getEvalEntrypoint):
231
        (JSC::LLInt::getProgramEntrypoint):
232
        * llint/LLIntEntrypoints.h: Added.
233
        (JSC):
234
        (LLInt):
235
        (JSC::LLInt::getEntrypoint):
236
        * llint/LLIntExceptions.cpp: Added.
237
        (LLInt):
238
        (JSC::LLInt::interpreterThrowInCaller):
239
        (JSC::LLInt::returnToThrowForThrownException):
240
        (JSC::LLInt::returnToThrow):
241
        (JSC::LLInt::callToThrow):
242
        * llint/LLIntExceptions.h: Added.
243
        (JSC):
244
        (LLInt):
245
        * llint/LLIntHelpers.cpp: Added.
246
        (LLInt):
247
        (JSC::LLInt::llint_trace_operand):
248
        (JSC::LLInt::llint_trace_value):
249
        (JSC::LLInt::LLINT_HELPER_DECL):
250
        (JSC::LLInt::traceFunctionPrologue):
251
        (JSC::LLInt::shouldJIT):
252
        ():
253
        (JSC::LLInt::entryOSR):
254
        (JSC::LLInt::resolveGlobal):
255
        (JSC::LLInt::getByVal):
256
        (JSC::LLInt::handleHostCall):
257
        (JSC::LLInt::setUpCall):
258
        (JSC::LLInt::genericCall):
259
        * llint/LLIntHelpers.h: Added.
260
        (JSC):
261
        (LLInt):
262
        * llint/LLIntOfflineAsmConfig.h: Added.
263
        * llint/LLIntOffsetsExtractor.cpp: Added.
264
        (JSC):
265
        (LLIntOffsetsExtractor):
266
        (JSC::LLIntOffsetsExtractor::dummy):
267
        (main):
268
        * llint/LLIntThunks.cpp: Added.
269
        (LLInt):
270
        (JSC::LLInt::generateThunkWithJumpTo):
271
        (JSC::LLInt::functionForCallEntryThunkGenerator):
272
        (JSC::LLInt::functionForConstructEntryThunkGenerator):
273
        (JSC::LLInt::functionForCallArityCheckThunkGenerator):
274
        (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
275
        (JSC::LLInt::evalEntryThunkGenerator):
276
        (JSC::LLInt::programEntryThunkGenerator):
277
        * llint/LLIntThunks.h: Added.
278
        (JSC):
279
        (LLInt):
280
        * llint/LowLevelInterpreter.asm: Added.
281
        * llint/LowLevelInterpreter.cpp: Added.
282
        * llint/LowLevelInterpreter.h: Added.
283
        * offlineasm: Added.
284
        * offlineasm/armv7.rb: Added.
285
        * offlineasm/asm.rb: Added.
286
        * offlineasm/ast.rb: Added.
287
        * offlineasm/backends.rb: Added.
288
        * offlineasm/generate_offset_extractor.rb: Added.
289
        * offlineasm/instructions.rb: Added.
290
        * offlineasm/offset_extractor_constants.rb: Added.
291
        * offlineasm/offsets.rb: Added.
292
        * offlineasm/parser.rb: Added.
293
        * offlineasm/registers.rb: Added.
294
        * offlineasm/settings.rb: Added.
295
        * offlineasm/transform.rb: Added.
296
        * offlineasm/x86.rb: Added.
297
        * runtime/CodeSpecializationKind.h: Added.
298
        (JSC):
299
        ():
300
        * runtime/CommonSlowPaths.h:
301
        (JSC::CommonSlowPaths::arityCheckFor):
302
        (CommonSlowPaths):
303
        (JSC::CommonSlowPaths::opInstanceOfSlow):
304
        * runtime/Executable.cpp:
305
        (JSC::jettisonCodeBlock):
306
        (JSC::EvalExecutable::jitCompile):
307
        (JSC):
308
        (JSC::samplingDescription):
309
        (JSC::EvalExecutable::compileInternal):
310
        (JSC::ProgramExecutable::jitCompile):
311
        (JSC::ProgramExecutable::compileInternal):
312
        (JSC::FunctionExecutable::baselineCodeBlockFor):
313
        (JSC::FunctionExecutable::jitCompileForCall):
314
        (JSC::FunctionExecutable::jitCompileForConstruct):
315
        (JSC::FunctionExecutable::compileForCallInternal):
316
        (JSC::FunctionExecutable::compileForConstructInternal):
317
        * runtime/Executable.h:
318
        (JSC):
319
        ():
320
        (EvalExecutable):
321
        (ProgramExecutable):
322
        (FunctionExecutable):
323
        (JSC::FunctionExecutable::jitCompileFor):
324
        * runtime/ExecutionHarness.h: Added.
325
        (JSC):
326
        (JSC::prepareForExecution):
327
        (JSC::prepareFunctionForExecution):
328
        * runtime/JSActivation.h:
329
        (JSC::JSActivation::tearOff):
330
        * runtime/JSArray.h:
331
        (JSC):
332
        (JSArray):
333
        * runtime/JSCell.h:
334
        (JSC):
335
        ():
336
        (JSCell):
337
        * runtime/JSFunction.h:
338
        (JSC):
339
        (JSFunction):
340
        * runtime/JSGlobalData.cpp:
341
        (JSC::JSGlobalData::JSGlobalData):
342
        * runtime/JSGlobalData.h:
343
        (JSC):
344
        (JSGlobalData):
345
        (JSC::JSGlobalData::scratchBufferForSize):
346
        * runtime/JSGlobalObject.h:
347
        (JSC):
348
        (JSGlobalObject):
349
        * runtime/JSObject.h:
350
        (JSC):
351
        ():
352
        (JSObject):
353
        (JSFinalObject):
354
        * runtime/JSPropertyNameIterator.h:
355
        (JSC):
356
        (JSPropertyNameIterator):
357
        * runtime/JSString.h:
358
        (JSC):
359
        (JSString):
360
        * runtime/JSTypeInfo.h:
361
        (JSC):
362
        (TypeInfo):
363
        * runtime/JSValue.cpp:
364
        (JSC):
365
        (JSC::JSValue::description):
366
        * runtime/JSValue.h:
367
        (JSValue):
368
        ():
369
        * runtime/JSVariableObject.h:
370
        (JSC):
371
        (JSVariableObject):
372
        * runtime/Options.cpp:
373
        (Options):
374
        (JSC::Options::initializeOptions):
375
        * runtime/Options.h:
376
        (Options):
377
        * runtime/ScopeChain.h:
378
        (JSC):
379
        (ScopeChainNode):
380
        * runtime/Structure.h:
381
        (JSC):
382
        (Structure):
383
        * runtime/StructureChain.h:
384
        (JSC):
385
        (StructureChain):
386
        * wtf/Platform.h:
387
        * wtf/SentinelLinkedList.h:
388
        (SentinelLinkedList):
389
        (WTF::SentinelLinkedList::isEmpty):
390
        * wtf/text/StringImpl.h:
391
        (JSC):
392
        (StringImpl):
393
        ():
394
1
2012-01-26  Filip Pizlo  <fpizlo@apple.com>
395
2012-01-26  Filip Pizlo  <fpizlo@apple.com>
2
396
3
        All DFG helpers that may call out to arbitrary JS code must know where they
397
        All DFG helpers that may call out to arbitrary JS code must know where they
- Source/JavaScriptCore/CMakeLists.txt +2 lines
Lines 11-16 SET(JavaScriptCore_INCLUDE_DIRECTORIES Source/JavaScriptCore/CMakeLists.txt_sec1
11
    "${JAVASCRIPTCORE_DIR}/debugger"
11
    "${JAVASCRIPTCORE_DIR}/debugger"
12
    "${JAVASCRIPTCORE_DIR}/interpreter"
12
    "${JAVASCRIPTCORE_DIR}/interpreter"
13
    "${JAVASCRIPTCORE_DIR}/jit"
13
    "${JAVASCRIPTCORE_DIR}/jit"
14
    "${JAVASCRIPTCORE_DIR}/llint"
14
    "${JAVASCRIPTCORE_DIR}/parser"
15
    "${JAVASCRIPTCORE_DIR}/parser"
15
    "${JAVASCRIPTCORE_DIR}/profiler"
16
    "${JAVASCRIPTCORE_DIR}/profiler"
16
    "${JAVASCRIPTCORE_DIR}/runtime"
17
    "${JAVASCRIPTCORE_DIR}/runtime"
Lines 95-100 SET(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec2
95
    interpreter/RegisterFile.cpp
96
    interpreter/RegisterFile.cpp
96
97
97
    jit/ExecutableAllocator.cpp
98
    jit/ExecutableAllocator.cpp
99
    jit/HostCallReturnValue.cpp
98
    jit/JITArithmetic32_64.cpp
100
    jit/JITArithmetic32_64.cpp
99
    jit/JITArithmetic.cpp
101
    jit/JITArithmetic.cpp
100
    jit/JITCall32_64.cpp
102
    jit/JITCall32_64.cpp
- Source/JavaScriptCore/GNUmakefile.am +1 lines
Lines 57-62 javascriptcore_cppflags += \ Source/JavaScriptCore/GNUmakefile.am_sec1
57
	-I$(srcdir)/Source/JavaScriptCore/interpreter \
57
	-I$(srcdir)/Source/JavaScriptCore/interpreter \
58
	-I$(srcdir)/Source/JavaScriptCore/jit \
58
	-I$(srcdir)/Source/JavaScriptCore/jit \
59
	-I$(srcdir)/Source/JavaScriptCore/jit \
59
	-I$(srcdir)/Source/JavaScriptCore/jit \
60
	-I$(srcdir)/Source/JavaScriptCore/llint \
60
	-I$(srcdir)/Source/JavaScriptCore/parser \
61
	-I$(srcdir)/Source/JavaScriptCore/parser \
61
	-I$(srcdir)/Source/JavaScriptCore/profiler \
62
	-I$(srcdir)/Source/JavaScriptCore/profiler \
62
	-I$(srcdir)/Source/JavaScriptCore/runtime \
63
	-I$(srcdir)/Source/JavaScriptCore/runtime \
- Source/JavaScriptCore/GNUmakefile.list.am +7 lines
Lines 81-86 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec1
81
	Source/JavaScriptCore/assembler/RepatchBuffer.h \
81
	Source/JavaScriptCore/assembler/RepatchBuffer.h \
82
	Source/JavaScriptCore/assembler/SH4Assembler.h \
82
	Source/JavaScriptCore/assembler/SH4Assembler.h \
83
	Source/JavaScriptCore/assembler/X86Assembler.h \
83
	Source/JavaScriptCore/assembler/X86Assembler.h \
84
	Source/JavaScriptCore/bytecode/BytecodeConventions.h \
84
	Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \
85
	Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \
85
	Source/JavaScriptCore/bytecode/CallLinkInfo.h \
86
	Source/JavaScriptCore/bytecode/CallLinkInfo.h \
86
	Source/JavaScriptCore/bytecode/CallLinkStatus.cpp \
87
	Source/JavaScriptCore/bytecode/CallLinkStatus.cpp \
Lines 102-107 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec2
102
	Source/JavaScriptCore/bytecode/Instruction.h \
103
	Source/JavaScriptCore/bytecode/Instruction.h \
103
	Source/JavaScriptCore/bytecode/JumpTable.cpp \
104
	Source/JavaScriptCore/bytecode/JumpTable.cpp \
104
	Source/JavaScriptCore/bytecode/JumpTable.h \
105
	Source/JavaScriptCore/bytecode/JumpTable.h \
106
	Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h \
105
	Source/JavaScriptCore/bytecode/LineInfo.h \
107
	Source/JavaScriptCore/bytecode/LineInfo.h \
106
	Source/JavaScriptCore/bytecode/MethodCallLinkInfo.cpp \
108
	Source/JavaScriptCore/bytecode/MethodCallLinkInfo.cpp \
107
	Source/JavaScriptCore/bytecode/MethodCallLinkInfo.h \
109
	Source/JavaScriptCore/bytecode/MethodCallLinkInfo.h \
Lines 279-284 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec3
279
	Source/JavaScriptCore/jit/CompactJITCodeMap.h \
281
	Source/JavaScriptCore/jit/CompactJITCodeMap.h \
280
	Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
282
	Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
281
	Source/JavaScriptCore/jit/ExecutableAllocator.h \
283
	Source/JavaScriptCore/jit/ExecutableAllocator.h \
284
	Source/JavaScriptCore/jit/HostCallReturnValue.cpp \
285
	Source/JavaScriptCore/jit/HostCallReturnValue.h \
282
	Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \
286
	Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \
283
	Source/JavaScriptCore/jit/JITArithmetic.cpp \
287
	Source/JavaScriptCore/jit/JITArithmetic.cpp \
284
	Source/JavaScriptCore/jit/JITCall32_64.cpp \
288
	Source/JavaScriptCore/jit/JITCall32_64.cpp \
Lines 302-307 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec4
302
	Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
306
	Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
303
	Source/JavaScriptCore/jit/ThunkGenerators.cpp \
307
	Source/JavaScriptCore/jit/ThunkGenerators.cpp \
304
	Source/JavaScriptCore/jit/ThunkGenerators.h \
308
	Source/JavaScriptCore/jit/ThunkGenerators.h \
309
	Source/JavaScriptCore/llint/LLIntData.h \
305
	Source/JavaScriptCore/os-win32/stdbool.h \
310
	Source/JavaScriptCore/os-win32/stdbool.h \
306
	Source/JavaScriptCore/os-win32/stdint.h \
311
	Source/JavaScriptCore/os-win32/stdint.h \
307
	Source/JavaScriptCore/parser/ASTBuilder.h \
312
	Source/JavaScriptCore/parser/ASTBuilder.h \
Lines 352-357 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec5
352
	Source/JavaScriptCore/runtime/CallData.cpp \
357
	Source/JavaScriptCore/runtime/CallData.cpp \
353
	Source/JavaScriptCore/runtime/CallData.h \
358
	Source/JavaScriptCore/runtime/CallData.h \
354
	Source/JavaScriptCore/runtime/ClassInfo.h \
359
	Source/JavaScriptCore/runtime/ClassInfo.h \
360
	Source/JavaScriptCore/runtime/CodeSpecializationKind.h \
355
	Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
361
	Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
356
	Source/JavaScriptCore/runtime/CommonIdentifiers.h \
362
	Source/JavaScriptCore/runtime/CommonIdentifiers.h \
357
	Source/JavaScriptCore/runtime/CommonSlowPaths.h \
363
	Source/JavaScriptCore/runtime/CommonSlowPaths.h \
Lines 380-385 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec6
380
	Source/JavaScriptCore/runtime/ExceptionHelpers.h \
386
	Source/JavaScriptCore/runtime/ExceptionHelpers.h \
381
	Source/JavaScriptCore/runtime/Executable.cpp \
387
	Source/JavaScriptCore/runtime/Executable.cpp \
382
	Source/JavaScriptCore/runtime/Executable.h \
388
	Source/JavaScriptCore/runtime/Executable.h \
389
	Source/JavaScriptCore/runtime/ExecutionHarness.h \
383
	Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
390
	Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
384
	Source/JavaScriptCore/runtime/FunctionConstructor.h \
391
	Source/JavaScriptCore/runtime/FunctionConstructor.h \
385
	Source/JavaScriptCore/runtime/FunctionPrototype.cpp \
392
	Source/JavaScriptCore/runtime/FunctionPrototype.cpp \
- Source/JavaScriptCore/JavaScriptCore.pri +1 lines
Lines 20-25 INCLUDEPATH += \ Source/JavaScriptCore/JavaScriptCore.pri_sec1
20
    $$SOURCE_DIR/debugger \
20
    $$SOURCE_DIR/debugger \
21
    $$SOURCE_DIR/interpreter \
21
    $$SOURCE_DIR/interpreter \
22
    $$SOURCE_DIR/jit \
22
    $$SOURCE_DIR/jit \
23
    $$SOURCE_DIR/llint \
23
    $$SOURCE_DIR/parser \
24
    $$SOURCE_DIR/parser \
24
    $$SOURCE_DIR/profiler \
25
    $$SOURCE_DIR/profiler \
25
    $$SOURCE_DIR/runtime \
26
    $$SOURCE_DIR/runtime \
- Source/JavaScriptCore/Target.pri +1 lines
Lines 107-112 SOURCES += \ Source/JavaScriptCore/Target.pri_sec1
107
    interpreter/RegisterFile.cpp \
107
    interpreter/RegisterFile.cpp \
108
    jit/ExecutableAllocatorFixedVMPool.cpp \
108
    jit/ExecutableAllocatorFixedVMPool.cpp \
109
    jit/ExecutableAllocator.cpp \
109
    jit/ExecutableAllocator.cpp \
110
    jit/HostCallReturnValue.cpp \
110
    jit/JITArithmetic.cpp \
111
    jit/JITArithmetic.cpp \
111
    jit/JITArithmetic32_64.cpp \
112
    jit/JITArithmetic32_64.cpp \
112
    jit/JITCall.cpp \
113
    jit/JITCall.cpp \
- Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +12 lines
Lines 1730-1735 Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj_sec1
1730
				>
1730
				>
1731
			</File>
1731
			</File>
1732
			<File
1732
			<File
1733
				RelativePath="..\..\jit\HostCallReturnValue.cpp"
1734
				>
1735
			</File>
1736
			<File
1733
				RelativePath="..\..\jit\JIT.cpp"
1737
				RelativePath="..\..\jit\JIT.cpp"
1734
				>
1738
				>
1735
			</File>
1739
			</File>
Lines 1815-1820 Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj_sec2
1815
			</File>
1819
			</File>
1816
		</Filter>
1820
		</Filter>
1817
		<Filter
1821
		<Filter
1822
			Name="llint"
1823
			>
1824
			<File
1825
				RelativePath="..\..\llint\LLIntData.h"
1826
				>
1827
			</File>
1828
		</Filter>
1829
		<Filter
1818
			Name="interpreter"
1830
			Name="interpreter"
1819
			>
1831
			>
1820
			<File
1832
			<File
- Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops -1 / +1 lines
Lines 6-12 Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops_sec1
6
	>
6
	>
7
	<Tool
7
	<Tool
8
		Name="VCCLCompilerTool"
8
		Name="VCCLCompilerTool"
9
		AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../parser/;../../bytecompiler/;../../dfg/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../heap/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
9
		AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../parser/;../../bytecompiler/;../../dfg/;../../jit/;../../llint/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../heap/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
10
		PreprocessorDefinitions="__STD_C"
10
		PreprocessorDefinitions="__STD_C"
11
		ForcedIncludeFiles="ICUVersion.h"
11
		ForcedIncludeFiles="ICUVersion.h"
12
	/>
12
	/>
- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj -2 / +355 lines
Lines 7-12 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
7
	objects = {
7
	objects = {
8
8
9
/* Begin PBXAggregateTarget section */
9
/* Begin PBXAggregateTarget section */
10
		0F4680A914BA7FD900BFE272 /* LLInt Offsets */ = {
11
			isa = PBXAggregateTarget;
12
			buildConfigurationList = 0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */;
13
			buildPhases = (
14
				0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */,
15
			);
16
			name = "LLInt Offsets";
17
			productName = "Derived Sources";
18
		};
10
		65FB3F6609D11E9100F49DEB /* Derived Sources */ = {
19
		65FB3F6609D11E9100F49DEB /* Derived Sources */ = {
11
			isa = PBXAggregateTarget;
20
			isa = PBXAggregateTarget;
12
			buildConfigurationList = 65FB3F7709D11EBD00F49DEB /* Build configuration list for PBXAggregateTarget "Derived Sources" */;
21
			buildConfigurationList = 65FB3F7709D11EBD00F49DEB /* Build configuration list for PBXAggregateTarget "Derived Sources" */;
Lines 14-19 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
14
				65FB3F6509D11E9100F49DEB /* Generate Derived Sources */,
23
				65FB3F6509D11E9100F49DEB /* Generate Derived Sources */,
15
				5D35DEE10C7C140B008648B2 /* Generate DTrace header */,
24
				5D35DEE10C7C140B008648B2 /* Generate DTrace header */,
16
			);
25
			);
26
			dependencies = (
27
				0F4680B414BA821400BFE272 /* PBXTargetDependency */,
28
			);
17
			name = "Derived Sources";
29
			name = "Derived Sources";
18
			productName = "Derived Sources";
30
			productName = "Derived Sources";
19
		};
31
		};
Lines 48-53 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
48
		0BAC94A01338728400CF135B /* ThreadRestrictionVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
60
		0BAC94A01338728400CF135B /* ThreadRestrictionVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
49
		0BCD83571485845200EA2003 /* TemporaryChange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BCD83541485841200EA2003 /* TemporaryChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
61
		0BCD83571485845200EA2003 /* TemporaryChange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BCD83541485841200EA2003 /* TemporaryChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
50
		0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
62
		0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
63
		0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */; };
64
		0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
65
		0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */; };
66
		0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839814BCF45A00885B4F /* LLIntThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
51
		0F0B83A714BCF50700885B4F /* CodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A514BCF50400885B4F /* CodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
67
		0F0B83A714BCF50700885B4F /* CodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A514BCF50400885B4F /* CodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
52
		0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
68
		0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
53
		0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
69
		0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
Lines 58-66 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
58
		0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
74
		0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
59
		0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
75
		0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
60
		0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
76
		0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
77
		0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
61
		0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
78
		0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
62
		0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
79
		0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
63
		0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };
80
		0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };
81
		0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; };
82
		0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
83
		0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
64
		0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
84
		0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
65
		0F2C556F14738F3100121E4F /* DFGCodeBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */; settings = {ATTRIBUTES = (Private, ); }; };
85
		0F2C556F14738F3100121E4F /* DFGCodeBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */; settings = {ATTRIBUTES = (Private, ); }; };
66
		0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */; };
86
		0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */; };
Lines 71-76 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
71
		0F431738146BAC69007E3890 /* ListableHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F431736146BAC65007E3890 /* ListableHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
91
		0F431738146BAC69007E3890 /* ListableHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F431736146BAC65007E3890 /* ListableHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
72
		0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46808014BA572700BFE272 /* JITExceptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
92
		0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46808014BA572700BFE272 /* JITExceptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
73
		0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46807F14BA572700BFE272 /* JITExceptions.cpp */; };
93
		0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46807F14BA572700BFE272 /* JITExceptions.cpp */; };
94
		0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
95
		0F4680A414BA7F8D00BFE272 /* LLIntHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */; settings = {COMPILER_FLAGS = "-Wno-unused-parameter"; }; };
96
		0F4680A514BA7F8D00BFE272 /* LLIntHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
97
		0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
98
		0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */; };
99
		0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C514BBB16900BFE272 /* LLIntCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
100
		0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */; settings = {ATTRIBUTES = (Private, ); }; };
101
		0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */; };
102
		0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
103
		0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */; };
104
		0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; settings = {ATTRIBUTES = (Private, ); }; };
105
		0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */; };
106
		0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
74
		0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */; };
107
		0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */; };
75
		0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55F0F214D1063600AC7649 /* AbstractPC.h */; settings = {ATTRIBUTES = (Private, ); }; };
108
		0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55F0F214D1063600AC7649 /* AbstractPC.h */; settings = {ATTRIBUTES = (Private, ); }; };
76
		0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
109
		0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
Lines 385-391 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
385
		86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
418
		86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
386
		86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
419
		86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
387
		86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
420
		86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
388
		86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
421
		86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
389
		86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
422
		86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
390
		86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; };
423
		86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; };
391
		86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; };
424
		86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; };
Lines 754-759 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
754
/* End PBXBuildFile section */
787
/* End PBXBuildFile section */
755
788
756
/* Begin PBXContainerItemProxy section */
789
/* Begin PBXContainerItemProxy section */
790
		0F4680B114BA811500BFE272 /* PBXContainerItemProxy */ = {
791
			isa = PBXContainerItemProxy;
792
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
793
			proxyType = 1;
794
			remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
795
			remoteInfo = "LLInt Offsets";
796
		};
797
		0F4680B314BA821400BFE272 /* PBXContainerItemProxy */ = {
798
			isa = PBXContainerItemProxy;
799
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
800
			proxyType = 1;
801
			remoteGlobalIDString = 0F46808E14BA7E5E00BFE272;
802
			remoteInfo = JSCLLIntOffsetsExtractor;
803
		};
757
		141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
804
		141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
758
			isa = PBXContainerItemProxy;
805
			isa = PBXContainerItemProxy;
759
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
806
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
Lines 799-804 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
799
/* End PBXContainerItemProxy section */
846
/* End PBXContainerItemProxy section */
800
847
801
/* Begin PBXCopyFilesBuildPhase section */
848
/* Begin PBXCopyFilesBuildPhase section */
849
		0F46808D14BA7E5E00BFE272 /* CopyFiles */ = {
850
			isa = PBXCopyFilesBuildPhase;
851
			buildActionMask = 2147483647;
852
			dstPath = /usr/share/man/man1/;
853
			dstSubfolderSpec = 0;
854
			files = (
855
			);
856
			runOnlyForDeploymentPostprocessing = 1;
857
		};
802
		5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
858
		5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
803
			isa = PBXCopyFilesBuildPhase;
859
			isa = PBXCopyFilesBuildPhase;
804
			buildActionMask = 12;
860
			buildActionMask = 12;
Lines 839-844 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
839
		0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
895
		0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
840
		0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
896
		0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
841
		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
897
		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
898
		0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
899
		0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
900
		0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
901
		0F0B839814BCF45A00885B4F /* LLIntThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntThunks.h; path = llint/LLIntThunks.h; sourceTree = "<group>"; };
842
		0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
902
		0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
843
		0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
903
		0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
844
		0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };
904
		0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };
Lines 849-857 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec10
849
		0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
909
		0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
850
		0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
910
		0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
851
		0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
911
		0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
912
		0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
852
		0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
913
		0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
853
		0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
914
		0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
854
		0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
915
		0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
916
		0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
917
		0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
918
		0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
855
		0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
919
		0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
856
		0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
920
		0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
857
		0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };
921
		0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };
Lines 862-867 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec11
862
		0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
926
		0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
863
		0F46807F14BA572700BFE272 /* JITExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITExceptions.cpp; sourceTree = "<group>"; };
927
		0F46807F14BA572700BFE272 /* JITExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITExceptions.cpp; sourceTree = "<group>"; };
864
		0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
928
		0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
929
		0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
930
		0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntExceptions.cpp; path = llint/LLIntExceptions.cpp; sourceTree = "<group>"; };
931
		0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntExceptions.h; path = llint/LLIntExceptions.h; sourceTree = "<group>"; };
932
		0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntHelpers.cpp; path = llint/LLIntHelpers.cpp; sourceTree = "<group>"; };
933
		0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntHelpers.h; path = llint/LLIntHelpers.h; sourceTree = "<group>"; };
934
		0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntOffsetsExtractor.cpp; path = llint/LLIntOffsetsExtractor.cpp; sourceTree = "<group>"; };
935
		0F4680C514BBB16900BFE272 /* LLIntCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCommon.h; path = llint/LLIntCommon.h; sourceTree = "<group>"; };
936
		0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOfflineAsmConfig.h; path = llint/LLIntOfflineAsmConfig.h; sourceTree = "<group>"; };
937
		0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LowLevelInterpreter.cpp; path = llint/LowLevelInterpreter.cpp; sourceTree = "<group>"; };
938
		0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LowLevelInterpreter.h; path = llint/LowLevelInterpreter.h; sourceTree = "<group>"; };
939
		0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntData.cpp; path = llint/LLIntData.cpp; sourceTree = "<group>"; };
940
		0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; };
941
		0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; };
942
		0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
865
		0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; };
943
		0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; };
866
		0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; };
944
		0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; };
867
		0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
945
		0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
Lines 1583-1588 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec12
1583
/* End PBXFileReference section */
1661
/* End PBXFileReference section */
1584
1662
1585
/* Begin PBXFrameworksBuildPhase section */
1663
/* Begin PBXFrameworksBuildPhase section */
1664
		0F46808C14BA7E5E00BFE272 /* Frameworks */ = {
1665
			isa = PBXFrameworksBuildPhase;
1666
			buildActionMask = 2147483647;
1667
			files = (
1668
			);
1669
			runOnlyForDeploymentPostprocessing = 0;
1670
		};
1586
		1412111E0A48793C00480255 /* Frameworks */ = {
1671
		1412111E0A48793C00480255 /* Frameworks */ = {
1587
			isa = PBXFrameworksBuildPhase;
1672
			isa = PBXFrameworksBuildPhase;
1588
			buildActionMask = 2147483647;
1673
			buildActionMask = 2147483647;
Lines 1641-1646 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec13
1641
				141211200A48793C00480255 /* minidom */,
1726
				141211200A48793C00480255 /* minidom */,
1642
				14BD59BF0A3E8F9000BAF59C /* testapi */,
1727
				14BD59BF0A3E8F9000BAF59C /* testapi */,
1643
				6511230514046A4C002B101D /* testRegExp */,
1728
				6511230514046A4C002B101D /* testRegExp */,
1729
				0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
1644
			);
1730
			);
1645
			name = Products;
1731
			name = Products;
1646
			sourceTree = "<group>";
1732
			sourceTree = "<group>";
Lines 1671-1676 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec14
1671
				F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
1757
				F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
1672
				45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
1758
				45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
1673
				F68EBB8C0255D4C601FF60F7 /* config.h */,
1759
				F68EBB8C0255D4C601FF60F7 /* config.h */,
1760
				0F46809C14BA7F4D00BFE272 /* llint */,
1674
				1432EBD70A34CAD400717B9F /* API */,
1761
				1432EBD70A34CAD400717B9F /* API */,
1675
				9688CB120ED12B4E001D649F /* assembler */,
1762
				9688CB120ED12B4E001D649F /* assembler */,
1676
				969A078F0ED1D3AE00F1F681 /* bytecode */,
1763
				969A078F0ED1D3AE00F1F681 /* bytecode */,
Lines 1709-1714 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec15
1709
			tabWidth = 4;
1796
			tabWidth = 4;
1710
			usesTabs = 0;
1797
			usesTabs = 0;
1711
		};
1798
		};
1799
		0F46809C14BA7F4D00BFE272 /* llint */ = {
1800
			isa = PBXGroup;
1801
			children = (
1802
				0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
1803
				0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
1804
				0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
1805
				0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
1806
				0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
1807
				0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
1808
				0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
1809
				0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
1810
				0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
1811
				0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
1812
				0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
1813
				0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
1814
				0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */,
1815
				0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */,
1816
				0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
1817
			);
1818
			name = llint;
1819
			sourceTree = "<group>";
1820
		};
1712
		141211000A48772600480255 /* tests */ = {
1821
		141211000A48772600480255 /* tests */ = {
1713
			isa = PBXGroup;
1822
			isa = PBXGroup;
1714
			children = (
1823
			children = (
Lines 1743-1748 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec16
1743
		1429D92C0ED22D7000B89619 /* jit */ = {
1852
		1429D92C0ED22D7000B89619 /* jit */ = {
1744
			isa = PBXGroup;
1853
			isa = PBXGroup;
1745
			children = (
1854
			children = (
1855
				0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
1856
				0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
1746
				0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
1857
				0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
1747
				0F46808014BA572700BFE272 /* JITExceptions.h */,
1858
				0F46808014BA572700BFE272 /* JITExceptions.h */,
1748
				0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
1859
				0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
Lines 2172-2177 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec17
2172
		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
2283
		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
2173
			isa = PBXGroup;
2284
			isa = PBXGroup;
2174
			children = (
2285
			children = (
2286
				0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
2287
				0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
2175
				0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
2288
				0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
2176
				BCF605110E203EF800B9A64D /* ArgList.cpp */,
2289
				BCF605110E203EF800B9A64D /* ArgList.cpp */,
2177
				BCF605120E203EF800B9A64D /* ArgList.h */,
2290
				BCF605120E203EF800B9A64D /* ArgList.h */,
Lines 2531-2536 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec18
2531
		969A078F0ED1D3AE00F1F681 /* bytecode */ = {
2644
		969A078F0ED1D3AE00F1F681 /* bytecode */ = {
2532
			isa = PBXGroup;
2645
			isa = PBXGroup;
2533
			children = (
2646
			children = (
2647
				0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
2648
				0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
2534
				0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
2649
				0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
2535
				0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
2650
				0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
2536
				0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,
2651
				0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,
Lines 3082-3088 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec19
3082
				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
3197
				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
3083
				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
3198
				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
3084
				0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
3199
				0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
3200
				0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
3201
				0F4680A514BA7F8D00BFE272 /* LLIntHelpers.h in Headers */,
3085
				0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
3202
				0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
3203
				0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
3204
				0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
3205
				0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
3206
				0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
3207
				0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
3208
				0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
3209
				0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
3086
				0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
3210
				0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
3087
				0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
3211
				0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
3088
				0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
3212
				0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
Lines 3091-3097 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec20
3091
				0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
3215
				0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
3092
				0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
3216
				0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
3093
				0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
3217
				0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
3218
				0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
3094
				0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
3219
				0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
3220
				0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
3221
				0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
3222
				0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
3095
				0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
3223
				0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
3096
				0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
3224
				0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
3097
				0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,
3225
				0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,
Lines 3110-3115 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec21
3110
/* End PBXHeadersBuildPhase section */
3238
/* End PBXHeadersBuildPhase section */
3111
3239
3112
/* Begin PBXNativeTarget section */
3240
/* Begin PBXNativeTarget section */
3241
		0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {
3242
			isa = PBXNativeTarget;
3243
			buildConfigurationList = 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */;
3244
			buildPhases = (
3245
				0F46808B14BA7E5E00BFE272 /* Sources */,
3246
				0F46808C14BA7E5E00BFE272 /* Frameworks */,
3247
				0F46808D14BA7E5E00BFE272 /* CopyFiles */,
3248
			);
3249
			buildRules = (
3250
			);
3251
			dependencies = (
3252
				0F4680B214BA811500BFE272 /* PBXTargetDependency */,
3253
			);
3254
			name = JSCLLIntOffsetsExtractor;
3255
			productName = JSCLLIntOffsetsExtractor;
3256
			productReference = 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
3257
			productType = "com.apple.product-type.tool";
3258
		};
3113
		1412111F0A48793C00480255 /* minidom */ = {
3259
		1412111F0A48793C00480255 /* minidom */ = {
3114
			isa = PBXNativeTarget;
3260
			isa = PBXNativeTarget;
3115
			buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;
3261
			buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;
Lines 3236-3246 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec22
3236
				14BD59BE0A3E8F9000BAF59C /* testapi */,
3382
				14BD59BE0A3E8F9000BAF59C /* testapi */,
3237
				932F5BDA0822A1C700736975 /* jsc */,
3383
				932F5BDA0822A1C700736975 /* jsc */,
3238
				651122F714046A4C002B101D /* testRegExp */,
3384
				651122F714046A4C002B101D /* testRegExp */,
3385
				0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
3386
				0F4680A914BA7FD900BFE272 /* LLInt Offsets */,
3239
			);
3387
			);
3240
		};
3388
		};
3241
/* End PBXProject section */
3389
/* End PBXProject section */
3242
3390
3243
/* Begin PBXShellScriptBuildPhase section */
3391
/* Begin PBXShellScriptBuildPhase section */
3392
		0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */ = {
3393
			isa = PBXShellScriptBuildPhase;
3394
			buildActionMask = 2147483647;
3395
			files = (
3396
			);
3397
			inputPaths = (
3398
				"$(SRCROOT)/llint/LowLevelAssembler.asm",
3399
			);
3400
			name = "Generate Derived Sources";
3401
			outputPaths = (
3402
				"$(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h",
3403
			);
3404
			runOnlyForDeploymentPostprocessing = 0;
3405
			shellPath = /bin/sh;
3406
			shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/\"\n\n/usr/bin/env ruby \"${SRCROOT}/offlineasm/generate_offset_extractor.rb\" \"${SRCROOT}/llint/LowLevelInterpreter.asm\" \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/LLIntDesiredOffsets.h\"\n";
3407
		};
3244
		3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
3408
		3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
3245
			isa = PBXShellScriptBuildPhase;
3409
			isa = PBXShellScriptBuildPhase;
3246
			buildActionMask = 2147483647;
3410
			buildActionMask = 2147483647;
Lines 3346-3352 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec23
3346
			);
3510
			);
3347
			runOnlyForDeploymentPostprocessing = 0;
3511
			runOnlyForDeploymentPostprocessing = 0;
3348
			shellPath = /bin/sh;
3512
			shellPath = /bin/sh;
3349
			shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake --no-builtin-rules -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu`\n";
3513
			shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake --no-builtin-rules -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu`\n\n/usr/bin/env ruby JavaScriptCore/offlineasm/asm.rb JavaScriptCore/llint/LowLevelInterpreter.asm ${BUILT_PRODUCTS_DIR}/JSCLLIntOffsetsExtractor LLIntAssembly.h\n";
3350
		};
3514
		};
3351
		9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
3515
		9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
3352
			isa = PBXShellScriptBuildPhase;
3516
			isa = PBXShellScriptBuildPhase;
Lines 3381-3386 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec24
3381
/* End PBXShellScriptBuildPhase section */
3545
/* End PBXShellScriptBuildPhase section */
3382
3546
3383
/* Begin PBXSourcesBuildPhase section */
3547
/* Begin PBXSourcesBuildPhase section */
3548
		0F46808B14BA7E5E00BFE272 /* Sources */ = {
3549
			isa = PBXSourcesBuildPhase;
3550
			buildActionMask = 2147483647;
3551
			files = (
3552
				0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */,
3553
			);
3554
			runOnlyForDeploymentPostprocessing = 0;
3555
		};
3384
		1412111D0A48793C00480255 /* Sources */ = {
3556
		1412111D0A48793C00480255 /* Sources */ = {
3385
			isa = PBXSourcesBuildPhase;
3557
			isa = PBXSourcesBuildPhase;
3386
			buildActionMask = 2147483647;
3558
			buildActionMask = 2147483647;
Lines 3639-3645 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec25
3639
				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
3811
				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
3640
				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
3812
				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
3641
				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
3813
				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
3814
				0F4680A414BA7F8D00BFE272 /* LLIntHelpers.cpp in Sources */,
3815
				0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
3642
				0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
3816
				0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
3817
				0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
3818
				0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
3819
				0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
3820
				0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
3821
				0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
3643
				0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
3822
				0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
3644
				0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
3823
				0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
3645
				F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,
3824
				F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,
Lines 3662-3667 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec26
3662
/* End PBXSourcesBuildPhase section */
3841
/* End PBXSourcesBuildPhase section */
3663
3842
3664
/* Begin PBXTargetDependency section */
3843
/* Begin PBXTargetDependency section */
3844
		0F4680B214BA811500BFE272 /* PBXTargetDependency */ = {
3845
			isa = PBXTargetDependency;
3846
			target = 0F4680A914BA7FD900BFE272 /* LLInt Offsets */;
3847
			targetProxy = 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */;
3848
		};
3849
		0F4680B414BA821400BFE272 /* PBXTargetDependency */ = {
3850
			isa = PBXTargetDependency;
3851
			target = 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
3852
			targetProxy = 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */;
3853
		};
3665
		141214BF0A49190E00480255 /* PBXTargetDependency */ = {
3854
		141214BF0A49190E00480255 /* PBXTargetDependency */ = {
3666
			isa = PBXTargetDependency;
3855
			isa = PBXTargetDependency;
3667
			target = 1412111F0A48793C00480255 /* minidom */;
3856
			target = 1412111F0A48793C00480255 /* minidom */;
Lines 3695-3700 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec27
3695
/* End PBXTargetDependency section */
3884
/* End PBXTargetDependency section */
3696
3885
3697
/* Begin XCBuildConfiguration section */
3886
/* Begin XCBuildConfiguration section */
3887
		0F46809614BA7E5E00BFE272 /* Debug */ = {
3888
			isa = XCBuildConfiguration;
3889
			buildSettings = {
3890
				ALWAYS_SEARCH_USER_PATHS = NO;
3891
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
3892
				COPY_PHASE_STRIP = NO;
3893
				GCC_C_LANGUAGE_STANDARD = gnu99;
3894
				GCC_DYNAMIC_NO_PIC = NO;
3895
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
3896
				GCC_OPTIMIZATION_LEVEL = 0;
3897
				GCC_PREPROCESSOR_DEFINITIONS = (
3898
					"DEBUG=1",
3899
					"$(inherited)",
3900
				);
3901
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
3902
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
3903
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
3904
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
3905
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
3906
				GCC_WARN_UNUSED_VARIABLE = YES;
3907
				"HEADER_SEARCH_PATHS[arch=*]" = (
3908
					.,
3909
					icu,
3910
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
3911
					"$(HEADER_SEARCH_PATHS)",
3912
				);
3913
				MACOSX_DEPLOYMENT_TARGET = 10.7;
3914
				ONLY_ACTIVE_ARCH = YES;
3915
				PRODUCT_NAME = "$(TARGET_NAME)";
3916
				SDKROOT = macosx;
3917
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
3918
			};
3919
			name = Debug;
3920
		};
3921
		0F46809714BA7E5E00BFE272 /* Release */ = {
3922
			isa = XCBuildConfiguration;
3923
			buildSettings = {
3924
				ALWAYS_SEARCH_USER_PATHS = NO;
3925
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
3926
				COPY_PHASE_STRIP = YES;
3927
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
3928
				GCC_C_LANGUAGE_STANDARD = gnu99;
3929
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
3930
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
3931
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
3932
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
3933
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
3934
				GCC_WARN_UNUSED_VARIABLE = YES;
3935
				"HEADER_SEARCH_PATHS[arch=*]" = (
3936
					.,
3937
					icu,
3938
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets$(HEADER_SEARCH_PATHS)",
3939
				);
3940
				MACOSX_DEPLOYMENT_TARGET = 10.7;
3941
				PRODUCT_NAME = "$(TARGET_NAME)";
3942
				SDKROOT = macosx;
3943
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
3944
			};
3945
			name = Release;
3946
		};
3947
		0F46809814BA7E5E00BFE272 /* Profiling */ = {
3948
			isa = XCBuildConfiguration;
3949
			buildSettings = {
3950
				ALWAYS_SEARCH_USER_PATHS = NO;
3951
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
3952
				COPY_PHASE_STRIP = YES;
3953
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
3954
				GCC_C_LANGUAGE_STANDARD = gnu99;
3955
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
3956
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
3957
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
3958
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
3959
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
3960
				GCC_WARN_UNUSED_VARIABLE = YES;
3961
				"HEADER_SEARCH_PATHS[arch=*]" = (
3962
					.,
3963
					icu,
3964
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
3965
					"$(HEADER_SEARCH_PATHS)",
3966
				);
3967
				MACOSX_DEPLOYMENT_TARGET = 10.7;
3968
				PRODUCT_NAME = "$(TARGET_NAME)";
3969
				SDKROOT = macosx;
3970
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
3971
			};
3972
			name = Profiling;
3973
		};
3974
		0F46809914BA7E5E00BFE272 /* Production */ = {
3975
			isa = XCBuildConfiguration;
3976
			buildSettings = {
3977
				ALWAYS_SEARCH_USER_PATHS = NO;
3978
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
3979
				COPY_PHASE_STRIP = YES;
3980
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
3981
				GCC_C_LANGUAGE_STANDARD = gnu99;
3982
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
3983
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
3984
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
3985
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
3986
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
3987
				GCC_WARN_UNUSED_VARIABLE = YES;
3988
				"HEADER_SEARCH_PATHS[arch=*]" = (
3989
					.,
3990
					icu,
3991
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
3992
					"$(HEADER_SEARCH_PATHS)",
3993
				);
3994
				MACOSX_DEPLOYMENT_TARGET = 10.7;
3995
				PRODUCT_NAME = "$(TARGET_NAME)";
3996
				SDKROOT = macosx;
3997
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
3998
			};
3999
			name = Production;
4000
		};
4001
		0F4680AD14BA7FD900BFE272 /* Debug */ = {
4002
			isa = XCBuildConfiguration;
4003
			buildSettings = {
4004
				PRODUCT_NAME = "Derived Sources copy";
4005
			};
4006
			name = Debug;
4007
		};
4008
		0F4680AE14BA7FD900BFE272 /* Release */ = {
4009
			isa = XCBuildConfiguration;
4010
			buildSettings = {
4011
				PRODUCT_NAME = "Derived Sources copy";
4012
			};
4013
			name = Release;
4014
		};
4015
		0F4680AF14BA7FD900BFE272 /* Profiling */ = {
4016
			isa = XCBuildConfiguration;
4017
			buildSettings = {
4018
				PRODUCT_NAME = "Derived Sources copy";
4019
			};
4020
			name = Profiling;
4021
		};
4022
		0F4680B014BA7FD900BFE272 /* Production */ = {
4023
			isa = XCBuildConfiguration;
4024
			buildSettings = {
4025
				PRODUCT_NAME = "Derived Sources copy";
4026
			};
4027
			name = Production;
4028
		};
3698
		1412113A0A48798400480255 /* Debug */ = {
4029
		1412113A0A48798400480255 /* Debug */ = {
3699
			isa = XCBuildConfiguration;
4030
			isa = XCBuildConfiguration;
3700
			buildSettings = {
4031
			buildSettings = {
Lines 3936-3941 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec28
3936
/* End XCBuildConfiguration section */
4267
/* End XCBuildConfiguration section */
3937
4268
3938
/* Begin XCConfigurationList section */
4269
/* Begin XCConfigurationList section */
4270
		0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */ = {
4271
			isa = XCConfigurationList;
4272
			buildConfigurations = (
4273
				0F46809614BA7E5E00BFE272 /* Debug */,
4274
				0F46809714BA7E5E00BFE272 /* Release */,
4275
				0F46809814BA7E5E00BFE272 /* Profiling */,
4276
				0F46809914BA7E5E00BFE272 /* Production */,
4277
			);
4278
			defaultConfigurationIsVisible = 0;
4279
			defaultConfigurationName = Production;
4280
		};
4281
		0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */ = {
4282
			isa = XCConfigurationList;
4283
			buildConfigurations = (
4284
				0F4680AD14BA7FD900BFE272 /* Debug */,
4285
				0F4680AE14BA7FD900BFE272 /* Release */,
4286
				0F4680AF14BA7FD900BFE272 /* Profiling */,
4287
				0F4680B014BA7FD900BFE272 /* Production */,
4288
			);
4289
			defaultConfigurationIsVisible = 0;
4290
			defaultConfigurationName = Production;
4291
		};
3939
		141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
4292
		141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
3940
			isa = XCConfigurationList;
4293
			isa = XCConfigurationList;
3941
			buildConfigurations = (
4294
			buildConfigurations = (
- Source/JavaScriptCore/assembler/LinkBuffer.h -1 / +1 lines
Lines 34-40 Source/JavaScriptCore/assembler/LinkBuffer.h_sec1
34
#define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1))
34
#define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1))
35
#define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2))
35
#define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2))
36
36
37
#include <MacroAssembler.h>
37
#include "MacroAssembler.h"
38
#include <wtf/Noncopyable.h>
38
#include <wtf/Noncopyable.h>
39
39
40
namespace JSC {
40
namespace JSC {
- Source/JavaScriptCore/bytecode/BytecodeConventions.h +36 lines
Line 0 Source/JavaScriptCore/bytecode/BytecodeConventions.h_sec1
1
/*
2
 * Copyright (C) 2012 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 BytecodeConventions_h
27
#define BytecodeConventions_h
28
29
// Register numbers used in bytecode operations have different meaning according to their ranges:
30
//      0x80000000-0xFFFFFFFF  Negative indices from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
31
//      0x00000000-0x3FFFFFFF  Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
32
//      0x40000000-0x7FFFFFFF  Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
33
static const int FirstConstantRegisterIndex = 0x40000000;
34
35
#endif // BytecodeConventions_h
36
- Source/JavaScriptCore/bytecode/CallLinkStatus.cpp -3 / +26 lines
Lines 27-43 Source/JavaScriptCore/bytecode/CallLinkStatus.cpp_sec1
27
#include "CallLinkStatus.h"
27
#include "CallLinkStatus.h"
28
28
29
#include "CodeBlock.h"
29
#include "CodeBlock.h"
30
#include "LLIntCallLinkInfo.h"
30
31
31
namespace JSC {
32
namespace JSC {
32
33
34
CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex)
35
{
36
    UNUSED_PARAM(profiledBlock);
37
    UNUSED_PARAM(bytecodeIndex);
38
#if ENABLE(LLINT)
39
    Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
40
    LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo;
41
    
42
    return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false);
43
#else
44
    return CallLinkStatus(0, false);
45
#endif
46
}
47
33
CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
48
CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
34
{
49
{
35
    UNUSED_PARAM(profiledBlock);
50
    UNUSED_PARAM(profiledBlock);
36
    UNUSED_PARAM(bytecodeIndex);
51
    UNUSED_PARAM(bytecodeIndex);
37
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
52
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
38
    return CallLinkStatus(
53
    if (!profiledBlock->numberOfCallLinkInfos())
39
        profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get(),
54
        return computeFromLLInt(profiledBlock, bytecodeIndex);
40
        profiledBlock->couldTakeSlowCase(bytecodeIndex));
55
    
56
    if (profiledBlock->couldTakeSlowCase(bytecodeIndex))
57
        return CallLinkStatus(0, true);
58
    
59
    JSFunction* target = profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get();
60
    if (!target)
61
        return computeFromLLInt(profiledBlock, bytecodeIndex);
62
    
63
    return CallLinkStatus(target, false);
41
#else
64
#else
42
    return CallLinkStatus(0, false);
65
    return CallLinkStatus(0, false);
43
#endif
66
#endif
- Source/JavaScriptCore/bytecode/CallLinkStatus.h -2 / +4 lines
Lines 47-61 public: Source/JavaScriptCore/bytecode/CallLinkStatus.h_sec1
47
    
47
    
48
    static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
48
    static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
49
    
49
    
50
    bool isSet() const { return !!m_callTarget; }
50
    bool isSet() const { return !!m_callTarget || m_couldTakeSlowPath; }
51
    
51
    
52
    bool operator!() const { return !m_callTarget; }
52
    bool operator!() const { return !isSet(); }
53
    
53
    
54
    bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
54
    bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
55
    
55
    
56
    JSFunction* callTarget() const { return m_callTarget; }
56
    JSFunction* callTarget() const { return m_callTarget; }
57
    
57
    
58
private:
58
private:
59
    static CallLinkStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex);
60
    
59
    JSFunction* m_callTarget;
61
    JSFunction* m_callTarget;
60
    bool m_couldTakeSlowPath;
62
    bool m_couldTakeSlowPath;
61
};
63
};
- Source/JavaScriptCore/bytecode/CodeBlock.cpp -15 / +147 lines
Lines 42-47 Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec1
42
#include "JSFunction.h"
42
#include "JSFunction.h"
43
#include "JSStaticScopeObject.h"
43
#include "JSStaticScopeObject.h"
44
#include "JSValue.h"
44
#include "JSValue.h"
45
#include "LowLevelInterpreter.h"
45
#include "RepatchBuffer.h"
46
#include "RepatchBuffer.h"
46
#include "UStringConcatenate.h"
47
#include "UStringConcatenate.h"
47
#include <stdio.h>
48
#include <stdio.h>
Lines 59-66 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec2
59
using namespace DFG;
60
using namespace DFG;
60
#endif
61
#endif
61
62
62
#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
63
64
static UString escapeQuotes(const UString& str)
63
static UString escapeQuotes(const UString& str)
65
{
64
{
66
    UString result = str;
65
    UString result = str;
Lines 358-367 void CodeBlock::dump(ExecState* exec) co Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec3
358
    for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
357
    for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
359
        ++instructionCount;
358
        ++instructionCount;
360
359
361
    printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
360
    printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s); %d variable(s)\n\n",
362
        static_cast<unsigned long>(instructionCount),
361
        static_cast<unsigned long>(instructionCount),
363
        static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
362
        static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
364
        this, m_numParameters, m_numCalleeRegisters);
363
        this, m_numParameters, m_numCalleeRegisters, m_numVars);
365
364
366
    Vector<Instruction>::const_iterator begin = instructions().begin();
365
    Vector<Instruction>::const_iterator begin = instructions().begin();
367
    Vector<Instruction>::const_iterator end = instructions().end();
366
    Vector<Instruction>::const_iterator end = instructions().end();
Lines 898-903 void CodeBlock::dump(ExecState* exec, co Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec4
898
            printPutByIdOp(exec, location, it, "put_by_id_transition");
897
            printPutByIdOp(exec, location, it, "put_by_id_transition");
899
            break;
898
            break;
900
        }
899
        }
900
        case op_put_by_id_transition_direct: {
901
            printPutByIdOp(exec, location, it, "put_by_id_transition_direct");
902
            break;
903
        }
904
        case op_put_by_id_transition_normal: {
905
            printPutByIdOp(exec, location, it, "put_by_id_transition_normal");
906
            break;
907
        }
901
        case op_put_by_id_generic: {
908
        case op_put_by_id_generic: {
902
            printPutByIdOp(exec, location, it, "put_by_id_generic");
909
            printPutByIdOp(exec, location, it, "put_by_id_generic");
903
            break;
910
            break;
Lines 1291-1298 void CodeBlock::dump(ExecState* exec, co Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec5
1291
    }
1298
    }
1292
}
1299
}
1293
1300
1294
#endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
1295
1296
#if DUMP_CODE_BLOCK_STATISTICS
1301
#if DUMP_CODE_BLOCK_STATISTICS
1297
static HashSet<CodeBlock*> liveCodeBlockSet;
1302
static HashSet<CodeBlock*> liveCodeBlockSet;
1298
#endif
1303
#endif
Lines 1459-1464 CodeBlock::CodeBlock(CopyParsedBlockTag, Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec6
1459
{
1464
{
1460
    setNumParameters(other.numParameters());
1465
    setNumParameters(other.numParameters());
1461
    optimizeAfterWarmUp();
1466
    optimizeAfterWarmUp();
1467
    jitAfterWarmUp();
1462
    
1468
    
1463
    if (other.m_rareData) {
1469
    if (other.m_rareData) {
1464
        createRareDataIfNecessary();
1470
        createRareDataIfNecessary();
Lines 1507-1512 CodeBlock::CodeBlock(ScriptExecutable* o Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec7
1507
    ASSERT(m_source);
1513
    ASSERT(m_source);
1508
    
1514
    
1509
    optimizeAfterWarmUp();
1515
    optimizeAfterWarmUp();
1516
    jitAfterWarmUp();
1510
1517
1511
#if DUMP_CODE_BLOCK_STATISTICS
1518
#if DUMP_CODE_BLOCK_STATISTICS
1512
    liveCodeBlockSet.add(this);
1519
    liveCodeBlockSet.add(this);
Lines 1524-1530 CodeBlock::~CodeBlock() Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec8
1524
#if ENABLE(VERBOSE_VALUE_PROFILE)
1531
#if ENABLE(VERBOSE_VALUE_PROFILE)
1525
    dumpValueProfiles();
1532
    dumpValueProfiles();
1526
#endif
1533
#endif
1527
    
1534
1535
#if ENABLE(LLINT)    
1536
    while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
1537
        m_incomingLLIntCalls.begin()->remove();
1538
#endif // ENABLE(LLINT)
1528
#if ENABLE(JIT)
1539
#if ENABLE(JIT)
1529
    // We may be destroyed before any CodeBlocks that refer to us are destroyed.
1540
    // We may be destroyed before any CodeBlocks that refer to us are destroyed.
1530
    // Consider that two CodeBlocks become unreachable at the same time. There
1541
    // Consider that two CodeBlocks become unreachable at the same time. There
Lines 1736-1743 void CodeBlock::finalizeUnconditionally( Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec9
1736
#else
1747
#else
1737
    static const bool verboseUnlinking = false;
1748
    static const bool verboseUnlinking = false;
1738
#endif
1749
#endif
1739
#endif
1750
#endif // ENABLE(JIT)
1740
    
1751
    
1752
#if ENABLE(LLINT)
1753
    Interpreter* interpreter = m_globalData->interpreter;
1754
    // interpreter->enabled() returns true if the old C++ interpreter is enabled. If that's enabled
1755
    // then we're not using LLInt.
1756
    if (!interpreter->enabled()) {
1757
        for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
1758
            Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
1759
            switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
1760
            case op_get_by_id:
1761
            case op_put_by_id:
1762
                if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
1763
                    break;
1764
                curInstruction[4].u.structure.clear();
1765
                curInstruction[5].u.operand = 0;
1766
                break;
1767
            case op_put_by_id_transition_direct:
1768
            case op_put_by_id_transition_normal:
1769
                if (Heap::isMarked(curInstruction[4].u.structure.get())
1770
                    && Heap::isMarked(curInstruction[6].u.structure.get())
1771
                    && Heap::isMarked(curInstruction[7].u.structureChain.get()))
1772
                    break;
1773
                curInstruction[4].u.structure.clear();
1774
                curInstruction[6].u.structure.clear();
1775
                curInstruction[7].u.structureChain.clear();
1776
                curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
1777
                break;
1778
            default:
1779
                ASSERT_NOT_REACHED();
1780
            }
1781
        }
1782
        for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) {
1783
            Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]];
1784
            ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global
1785
                   || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic);
1786
            if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get()))
1787
                continue;
1788
            curInstruction[3].u.structure.clear();
1789
            curInstruction[4].u.operand = 0;
1790
        }
1791
        for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
1792
            if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
1793
                if (verboseUnlinking)
1794
                    printf("Clearing LLInt call from %p.\n", this);
1795
                m_llintCallLinkInfos[i].unlink();
1796
            }
1797
            if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
1798
                m_llintCallLinkInfos[i].lastSeenCallee.clear();
1799
        }
1800
    }
1801
#endif // ENABLE(LLINT)
1802
1741
#if ENABLE(DFG_JIT)
1803
#if ENABLE(DFG_JIT)
1742
    // Check if we're not live. If we are, then jettison.
1804
    // Check if we're not live. If we are, then jettison.
1743
    if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {
1805
    if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {
Lines 1858-1867 void CodeBlock::stronglyVisitStrongRefer Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec10
1858
    for (size_t i = 0; i < m_functionDecls.size(); ++i)
1920
    for (size_t i = 0; i < m_functionDecls.size(); ++i)
1859
        visitor.append(&m_functionDecls[i]);
1921
        visitor.append(&m_functionDecls[i]);
1860
#if ENABLE(INTERPRETER)
1922
#if ENABLE(INTERPRETER)
1861
    for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1923
    if (m_globalData->interpreter->enabled()) {
1862
        visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1924
        for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1863
    for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1925
            visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1864
        visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
1926
        for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1927
            visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
1928
    }
1865
#endif
1929
#endif
1866
1930
1867
#if ENABLE(DFG_JIT)
1931
#if ENABLE(DFG_JIT)
Lines 2070-2075 void CodeBlock::unlinkCalls() Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec11
2070
{
2134
{
2071
    if (!!m_alternative)
2135
    if (!!m_alternative)
2072
        m_alternative->unlinkCalls();
2136
        m_alternative->unlinkCalls();
2137
#if ENABLE(LLINT)
2138
    for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2139
        if (m_llintCallLinkInfos[i].isLinked())
2140
            m_llintCallLinkInfos[i].unlink();
2141
    }
2142
#endif
2073
    if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
2143
    if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
2074
        return;
2144
        return;
2075
    if (!m_globalData->canUseJIT())
2145
    if (!m_globalData->canUseJIT())
Lines 2084-2093 void CodeBlock::unlinkCalls() Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec12
2084
2154
2085
void CodeBlock::unlinkIncomingCalls()
2155
void CodeBlock::unlinkIncomingCalls()
2086
{
2156
{
2157
#if ENABLE(LLINT)
2158
    while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
2159
        m_incomingLLIntCalls.begin()->unlink();
2160
#endif
2161
    if (m_incomingCalls.isEmpty())
2162
        return;
2087
    RepatchBuffer repatchBuffer(this);
2163
    RepatchBuffer repatchBuffer(this);
2088
    while (m_incomingCalls.begin() != m_incomingCalls.end())
2164
    while (m_incomingCalls.begin() != m_incomingCalls.end())
2089
        m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
2165
        m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
2090
}
2166
}
2167
2168
unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
2169
{
2170
#if ENABLE(LLINT)
2171
    if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin)
2172
        && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) {
2173
        ASSERT(exec->codeBlock());
2174
        ASSERT(exec->codeBlock() == this);
2175
        ASSERT(JITCode::isBaselineCode(getJITType()));
2176
        Instruction* instruction = exec->currentVPC();
2177
        ASSERT(instruction);
2178
        return bytecodeOffset(instruction);
2179
    }
2180
#else
2181
    UNUSED_PARAM(exec);
2182
#endif
2183
    if (!m_rareData)
2184
        return 1;
2185
    Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
2186
    if (!callIndices.size())
2187
        return 1;
2188
    return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
2189
}
2091
#endif
2190
#endif
2092
2191
2093
void CodeBlock::clearEvalCache()
2192
void CodeBlock::clearEvalCache()
Lines 2183-2206 bool FunctionCodeBlock::canCompileWithDF Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec13
2183
2282
2184
void ProgramCodeBlock::jettison()
2283
void ProgramCodeBlock::jettison()
2185
{
2284
{
2186
    ASSERT(getJITType() != JITCode::BaselineJIT);
2285
    ASSERT(JITCode::isOptimizingJIT(getJITType()));
2187
    ASSERT(this == replacement());
2286
    ASSERT(this == replacement());
2188
    static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2287
    static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2189
}
2288
}
2190
2289
2191
void EvalCodeBlock::jettison()
2290
void EvalCodeBlock::jettison()
2192
{
2291
{
2193
    ASSERT(getJITType() != JITCode::BaselineJIT);
2292
    ASSERT(JITCode::isOptimizingJIT(getJITType()));
2194
    ASSERT(this == replacement());
2293
    ASSERT(this == replacement());
2195
    static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2294
    static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2196
}
2295
}
2197
2296
2198
void FunctionCodeBlock::jettison()
2297
void FunctionCodeBlock::jettison()
2199
{
2298
{
2200
    ASSERT(getJITType() != JITCode::BaselineJIT);
2299
    ASSERT(JITCode::isOptimizingJIT(getJITType()));
2201
    ASSERT(this == replacement());
2300
    ASSERT(this == replacement());
2202
    static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
2301
    static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
2203
}
2302
}
2303
2304
void ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData)
2305
{
2306
    ASSERT(getJITType() == JITCode::InterpreterThunk);
2307
    ASSERT(this == replacement());
2308
    return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(globalData);
2309
}
2310
2311
void EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData)
2312
{
2313
    ASSERT(getJITType() == JITCode::InterpreterThunk);
2314
    ASSERT(this == replacement());
2315
    return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(globalData);
2316
}
2317
2318
void FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData)
2319
{
2320
    ASSERT(getJITType() == JITCode::InterpreterThunk);
2321
    ASSERT(this == replacement());
2322
    return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(globalData, m_isConstructor ? CodeForConstruct : CodeForCall);
2323
}
2204
#endif
2324
#endif
2205
2325
2206
#if ENABLE(VALUE_PROFILER)
2326
#if ENABLE(VALUE_PROFILER)
Lines 2303-2308 void CodeBlock::dumpValueProfiles() Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec14
2303
}
2423
}
2304
#endif
2424
#endif
2305
2425
2426
void CodeBlock::handleBytecodeDiscardingOpportunity()
2427
{
2428
#if !ENABLE(OPCODE_SAMPLING) && !ENABLE(LLINT)
2429
    if (BytecodeGenerator::dumpsGeneratedCode())
2430
        return;
2431
    if (!!alternative())
2432
        discardBytecode();
2433
    else
2434
        discardBytecodeLater();
2435
#endif
2436
}
2437
2306
#ifndef NDEBUG
2438
#ifndef NDEBUG
2307
bool CodeBlock::usesOpcode(OpcodeID opcodeID)
2439
bool CodeBlock::usesOpcode(OpcodeID opcodeID)
2308
{
2440
{
- Source/JavaScriptCore/bytecode/CodeBlock.h -48 / +91 lines
Lines 30-35 Source/JavaScriptCore/bytecode/CodeBlock.h_sec1
30
#ifndef CodeBlock_h
30
#ifndef CodeBlock_h
31
#define CodeBlock_h
31
#define CodeBlock_h
32
32
33
#include "BytecodeConventions.h"
33
#include "CallLinkInfo.h"
34
#include "CallLinkInfo.h"
34
#include "CallReturnOffsetToBytecodeOffset.h"
35
#include "CallReturnOffsetToBytecodeOffset.h"
35
#include "CodeOrigin.h"
36
#include "CodeOrigin.h"
Lines 50-55 Source/JavaScriptCore/bytecode/CodeBlock.h_sec2
50
#include "JITWriteBarrier.h"
51
#include "JITWriteBarrier.h"
51
#include "JSGlobalObject.h"
52
#include "JSGlobalObject.h"
52
#include "JumpTable.h"
53
#include "JumpTable.h"
54
#include "LLIntCallLinkInfo.h"
53
#include "LineInfo.h"
55
#include "LineInfo.h"
54
#include "Nodes.h"
56
#include "Nodes.h"
55
#include "PredictionTracker.h"
57
#include "PredictionTracker.h"
Lines 65-80 Source/JavaScriptCore/bytecode/CodeBlock.h_sec3
65
#include <wtf/Vector.h>
67
#include <wtf/Vector.h>
66
#include "StructureStubInfo.h"
68
#include "StructureStubInfo.h"
67
69
68
// Register numbers used in bytecode operations have different meaning according to their ranges:
69
//      0x80000000-0xFFFFFFFF  Negative indices from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
70
//      0x00000000-0x3FFFFFFF  Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
71
//      0x40000000-0x7FFFFFFF  Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
72
static const int FirstConstantRegisterIndex = 0x40000000;
73
74
namespace JSC {
70
namespace JSC {
75
71
76
    class ExecState;
77
    class DFGCodeBlocks;
72
    class DFGCodeBlocks;
73
    class ExecState;
74
    class LLIntOffsetsExtractor;
78
75
79
    inline int unmodifiedArgumentsRegister(int argumentsRegister) { return argumentsRegister - 1; }
76
    inline int unmodifiedArgumentsRegister(int argumentsRegister) { return argumentsRegister - 1; }
80
77
Lines 83-88 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec4
83
    class CodeBlock : public UnconditionalFinalizer, public WeakReferenceHarvester {
80
    class CodeBlock : public UnconditionalFinalizer, public WeakReferenceHarvester {
84
        WTF_MAKE_FAST_ALLOCATED;
81
        WTF_MAKE_FAST_ALLOCATED;
85
        friend class JIT;
82
        friend class JIT;
83
        friend class LLIntOffsetsExtractor;
86
    public:
84
    public:
87
        enum CopyParsedBlockTag { CopyParsedBlock };
85
        enum CopyParsedBlockTag { CopyParsedBlock };
88
    protected:
86
    protected:
Lines 123-129 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec5
123
            while (result->alternative())
121
            while (result->alternative())
124
                result = result->alternative();
122
                result = result->alternative();
125
            ASSERT(result);
123
            ASSERT(result);
126
            ASSERT(result->getJITType() == JITCode::BaselineJIT);
124
            ASSERT(JITCode::isBaselineCode(result->getJITType()));
127
            return result;
125
            return result;
128
        }
126
        }
129
#endif
127
#endif
Lines 134-144 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec6
134
132
135
        static void dumpStatistics();
133
        static void dumpStatistics();
136
134
137
#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
138
        void dump(ExecState*) const;
135
        void dump(ExecState*) const;
139
        void printStructures(const Instruction*) const;
136
        void printStructures(const Instruction*) const;
140
        void printStructure(const char* name, const Instruction*, int operand) const;
137
        void printStructure(const char* name, const Instruction*, int operand) const;
141
#endif
142
138
143
        bool isStrictMode() const { return m_isStrictMode; }
139
        bool isStrictMode() const { return m_isStrictMode; }
144
140
Lines 194-208 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec7
194
            return *(binarySearch<MethodCallLinkInfo, unsigned, getMethodCallLinkInfoBytecodeIndex>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), bytecodeIndex));
190
            return *(binarySearch<MethodCallLinkInfo, unsigned, getMethodCallLinkInfoBytecodeIndex>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), bytecodeIndex));
195
        }
191
        }
196
192
197
        unsigned bytecodeOffset(ReturnAddressPtr returnAddress)
193
        unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
198
        {
199
            if (!m_rareData)
200
                return 1;
201
            Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
202
            if (!callIndices.size())
203
                return 1;
204
            return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
205
        }
206
194
207
        unsigned bytecodeOffsetForCallAtIndex(unsigned index)
195
        unsigned bytecodeOffsetForCallAtIndex(unsigned index)
208
        {
196
        {
Lines 223-233 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec8
223
        {
211
        {
224
            m_incomingCalls.push(incoming);
212
            m_incomingCalls.push(incoming);
225
        }
213
        }
214
#if ENABLE(LLINT)
215
        void linkIncomingCall(LLIntCallLinkInfo* incoming)
216
        {
217
            m_incomingLLIntCalls.push(incoming);
218
        }
219
#endif // ENABLE(LLINT)
226
        
220
        
227
        void unlinkIncomingCalls();
221
        void unlinkIncomingCalls();
228
#endif
222
#endif // ENABLE(JIT)
229
223
230
#if ENABLE(DFG_JIT)
224
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
231
        void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
225
        void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
232
        {
226
        {
233
            m_jitCodeMap = jitCodeMap;
227
            m_jitCodeMap = jitCodeMap;
Lines 236-242 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec9
236
        {
230
        {
237
            return m_jitCodeMap.get();
231
            return m_jitCodeMap.get();
238
        }
232
        }
233
#endif
239
        
234
        
235
#if ENABLE(DFG_JIT)
240
        void createDFGDataIfNecessary()
236
        void createDFGDataIfNecessary()
241
        {
237
        {
242
            if (!!m_dfgData)
238
            if (!!m_dfgData)
Lines 335-346 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec10
335
        }
331
        }
336
#endif
332
#endif
337
333
338
#if ENABLE(INTERPRETER)
339
        unsigned bytecodeOffset(Instruction* returnAddress)
334
        unsigned bytecodeOffset(Instruction* returnAddress)
340
        {
335
        {
336
            ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end());
341
            return static_cast<Instruction*>(returnAddress) - instructions().begin();
337
            return static_cast<Instruction*>(returnAddress) - instructions().begin();
342
        }
338
        }
343
#endif
344
339
345
        void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
340
        void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
346
        bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
341
        bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
Lines 354-370 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec11
354
        {
349
        {
355
            m_shouldDiscardBytecode = true;
350
            m_shouldDiscardBytecode = true;
356
        }
351
        }
357
        void handleBytecodeDiscardingOpportunity()
352
        void handleBytecodeDiscardingOpportunity();
358
        {
359
            if (!!alternative())
360
                discardBytecode();
361
            else
362
                discardBytecodeLater();
363
        }
364
        
353
        
365
#ifndef NDEBUG
366
        bool usesOpcode(OpcodeID);
354
        bool usesOpcode(OpcodeID);
367
#endif
368
355
369
        unsigned instructionCount() { return m_instructionCount; }
356
        unsigned instructionCount() { return m_instructionCount; }
370
        void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
357
        void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
Lines 387-403 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec12
387
        ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
374
        ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
388
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
375
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
389
        virtual void jettison() = 0;
376
        virtual void jettison() = 0;
377
        bool jitCompile(JSGlobalData& globalData)
378
        {
379
            if (getJITType() != JITCode::InterpreterThunk) {
380
                ASSERT(getJITType() == JITCode::BaselineJIT);
381
                return false;
382
            }
383
            jitCompileImpl(globalData);
384
            return true;
385
        }
390
        virtual CodeBlock* replacement() = 0;
386
        virtual CodeBlock* replacement() = 0;
391
        virtual bool canCompileWithDFG() = 0;
387
        virtual bool canCompileWithDFG() = 0;
392
        bool hasOptimizedReplacement()
388
        bool hasOptimizedReplacement()
393
        {
389
        {
394
            ASSERT(getJITType() == JITCode::BaselineJIT);
390
            ASSERT(JITCode::isBaselineCode(getJITType()));
395
            bool result = replacement()->getJITType() > getJITType();
391
            bool result = replacement()->getJITType() > getJITType();
396
#if !ASSERT_DISABLED
392
#if !ASSERT_DISABLED
397
            if (result)
393
            if (result)
398
                ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
394
                ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
399
            else {
395
            else {
400
                ASSERT(replacement()->getJITType() == JITCode::BaselineJIT);
396
                ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
401
                ASSERT(replacement() == this);
397
                ASSERT(replacement() == this);
402
            }
398
            }
403
#endif
399
#endif
Lines 456-473 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec13
456
452
457
        void clearEvalCache();
453
        void clearEvalCache();
458
454
459
#if ENABLE(INTERPRETER)
460
        void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
455
        void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
461
        {
456
        {
462
            if (!m_globalData->canUseJIT())
457
            m_propertyAccessInstructions.append(propertyAccessInstruction);
463
                m_propertyAccessInstructions.append(propertyAccessInstruction);
464
        }
458
        }
465
        void addGlobalResolveInstruction(unsigned globalResolveInstruction)
459
        void addGlobalResolveInstruction(unsigned globalResolveInstruction)
466
        {
460
        {
467
            if (!m_globalData->canUseJIT())
461
            m_globalResolveInstructions.append(globalResolveInstruction);
468
                m_globalResolveInstructions.append(globalResolveInstruction);
469
        }
462
        }
470
        bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
463
        bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
464
#if ENABLE(LLINT)
465
        LLIntCallLinkInfo* addLLIntCallLinkInfo()
466
        {
467
            m_llintCallLinkInfos.append(LLIntCallLinkInfo());
468
            return &m_llintCallLinkInfos.last();
469
        }
471
#endif
470
#endif
472
#if ENABLE(JIT)
471
#if ENABLE(JIT)
473
        void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
472
        void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
Lines 476-483 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec14
476
475
477
        void addGlobalResolveInfo(unsigned globalResolveInstruction)
476
        void addGlobalResolveInfo(unsigned globalResolveInstruction)
478
        {
477
        {
479
            if (m_globalData->canUseJIT())
478
            m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
480
                m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
481
        }
479
        }
482
        GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
480
        GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
483
        bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
481
        bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
Lines 488-493 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec15
488
486
489
        void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); }
487
        void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); }
490
        MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
488
        MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
489
        size_t numberOfMethodCallLinkInfos() { return m_methodCallLinkInfos.size(); }
491
#endif
490
#endif
492
        
491
        
493
#if ENABLE(VALUE_PROFILER)
492
#if ENABLE(VALUE_PROFILER)
Lines 528-533 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec16
528
                                   bytecodeOffset].u.opcode)) - 1].u.profile == result);
527
                                   bytecodeOffset].u.opcode)) - 1].u.profile == result);
529
            return result;
528
            return result;
530
        }
529
        }
530
        PredictedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
531
        {
532
            return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction();
533
        }
531
        
534
        
532
        unsigned totalNumberOfValueProfiles()
535
        unsigned totalNumberOfValueProfiles()
533
        {
536
        {
Lines 554-565 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec17
554
        
557
        
555
        bool likelyToTakeSlowCase(int bytecodeOffset)
558
        bool likelyToTakeSlowCase(int bytecodeOffset)
556
        {
559
        {
560
            if (!numberOfRareCaseProfiles())
561
                return false;
557
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
562
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
558
            return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
563
            return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
559
        }
564
        }
560
        
565
        
561
        bool couldTakeSlowCase(int bytecodeOffset)
566
        bool couldTakeSlowCase(int bytecodeOffset)
562
        {
567
        {
568
            if (!numberOfRareCaseProfiles())
569
                return false;
563
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
570
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
564
            return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
571
            return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
565
        }
572
        }
Lines 578-589 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec18
578
        
585
        
579
        bool likelyToTakeSpecialFastCase(int bytecodeOffset)
586
        bool likelyToTakeSpecialFastCase(int bytecodeOffset)
580
        {
587
        {
588
            if (!numberOfRareCaseProfiles())
589
                return false;
581
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
590
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
582
            return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
591
            return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
583
        }
592
        }
584
        
593
        
585
        bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
594
        bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
586
        {
595
        {
596
            if (!numberOfRareCaseProfiles())
597
                return false;
587
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
598
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
588
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
599
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
589
            unsigned value = slowCaseCount - specialFastCaseCount;
600
            unsigned value = slowCaseCount - specialFastCaseCount;
Lines 592-597 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec19
592
        
603
        
593
        bool likelyToTakeAnySlowCase(int bytecodeOffset)
604
        bool likelyToTakeAnySlowCase(int bytecodeOffset)
594
        {
605
        {
606
            if (!numberOfRareCaseProfiles())
607
                return false;
595
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
608
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
596
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
609
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
597
            unsigned value = slowCaseCount + specialFastCaseCount;
610
            unsigned value = slowCaseCount + specialFastCaseCount;
Lines 689-695 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec20
689
        
702
        
690
        bool addFrequentExitSite(const DFG::FrequentExitSite& site)
703
        bool addFrequentExitSite(const DFG::FrequentExitSite& site)
691
        {
704
        {
692
            ASSERT(getJITType() == JITCode::BaselineJIT);
705
            ASSERT(JITCode::isBaselineCode(getJITType()));
693
            return m_exitProfile.add(site);
706
            return m_exitProfile.add(site);
694
        }
707
        }
695
708
Lines 794-799 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec21
794
        void copyPostParseDataFrom(CodeBlock* alternative);
807
        void copyPostParseDataFrom(CodeBlock* alternative);
795
        void copyPostParseDataFromAlternative();
808
        void copyPostParseDataFromAlternative();
796
        
809
        
810
        // Functions for controlling when JITting kicks in, in a mixed mode
811
        // execution world.
812
        
813
        void dontJITAnytimeSoon()
814
        {
815
            m_llintExecuteCounter = Options::executionCounterValueForDontJITAnytimeSoon;
816
        }
817
        
818
        void jitAfterWarmUp()
819
        {
820
            m_llintExecuteCounter = Options::executionCounterValueForJITAfterWarmUp;
821
        }
822
        
823
        void jitSoon()
824
        {
825
            m_llintExecuteCounter = Options::executionCounterValueForJITSoon;
826
        }
827
        
828
        int32_t llintExecuteCounter() const
829
        {
830
            return m_llintExecuteCounter;
831
        }
832
        
797
        // Functions for controlling when tiered compilation kicks in. This
833
        // Functions for controlling when tiered compilation kicks in. This
798
        // controls both when the optimizing compiler is invoked and when OSR
834
        // controls both when the optimizing compiler is invoked and when OSR
799
        // entry happens. Two triggers exist: the loop trigger and the return
835
        // entry happens. Two triggers exist: the loop trigger and the return
Lines 986-991 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec22
986
        bool m_shouldDiscardBytecode;
1022
        bool m_shouldDiscardBytecode;
987
1023
988
    protected:
1024
    protected:
1025
        virtual void jitCompileImpl(JSGlobalData&) = 0;
989
        virtual void visitWeakReferences(SlotVisitor&);
1026
        virtual void visitWeakReferences(SlotVisitor&);
990
        virtual void finalizeUnconditionally();
1027
        virtual void finalizeUnconditionally();
991
        
1028
        
Lines 998-1004 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec23
998
        void tallyFrequentExitSites() { }
1035
        void tallyFrequentExitSites() { }
999
#endif
1036
#endif
1000
        
1037
        
1001
#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
1002
        void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
1038
        void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
1003
1039
1004
        CString registerName(ExecState*, int r) const;
1040
        CString registerName(ExecState*, int r) const;
Lines 1008-1014 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec24
1008
        void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1044
        void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1009
        void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1045
        void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1010
        void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1046
        void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1011
#endif
1012
        void visitStructures(SlotVisitor&, Instruction* vPC) const;
1047
        void visitStructures(SlotVisitor&, Instruction* vPC) const;
1013
        
1048
        
1014
#if ENABLE(DFG_JIT)
1049
#if ENABLE(DFG_JIT)
Lines 1069-1077 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec25
1069
        RefPtr<SourceProvider> m_source;
1104
        RefPtr<SourceProvider> m_source;
1070
        unsigned m_sourceOffset;
1105
        unsigned m_sourceOffset;
1071
1106
1072
#if ENABLE(INTERPRETER)
1073
        Vector<unsigned> m_propertyAccessInstructions;
1107
        Vector<unsigned> m_propertyAccessInstructions;
1074
        Vector<unsigned> m_globalResolveInstructions;
1108
        Vector<unsigned> m_globalResolveInstructions;
1109
#if ENABLE(LLINT)
1110
        SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
1111
        SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
1075
#endif
1112
#endif
1076
#if ENABLE(JIT)
1113
#if ENABLE(JIT)
1077
        Vector<StructureStubInfo> m_structureStubInfos;
1114
        Vector<StructureStubInfo> m_structureStubInfos;
Lines 1082-1090 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec26
1082
        MacroAssemblerCodePtr m_jitCodeWithArityCheck;
1119
        MacroAssemblerCodePtr m_jitCodeWithArityCheck;
1083
        SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
1120
        SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
1084
#endif
1121
#endif
1085
#if ENABLE(DFG_JIT)
1122
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
1086
        OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1123
        OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1087
        
1124
#endif
1125
#if ENABLE(DFG_JIT)
1088
        struct WeakReferenceTransition {
1126
        struct WeakReferenceTransition {
1089
            WeakReferenceTransition() { }
1127
            WeakReferenceTransition() { }
1090
            
1128
            
Lines 1147-1158 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec27
1147
1185
1148
        OwnPtr<CodeBlock> m_alternative;
1186
        OwnPtr<CodeBlock> m_alternative;
1149
        
1187
        
1188
        int32_t m_llintExecuteCounter;
1189
        
1150
        int32_t m_jitExecuteCounter;
1190
        int32_t m_jitExecuteCounter;
1151
        uint32_t m_speculativeSuccessCounter;
1191
        uint32_t m_speculativeSuccessCounter;
1152
        uint32_t m_speculativeFailCounter;
1192
        uint32_t m_speculativeFailCounter;
1153
        uint8_t m_optimizationDelayCounter;
1193
        uint8_t m_optimizationDelayCounter;
1154
        uint8_t m_reoptimizationRetryCounter;
1194
        uint8_t m_reoptimizationRetryCounter;
1155
1195
        
1156
        struct RareData {
1196
        struct RareData {
1157
           WTF_MAKE_FAST_ALLOCATED;
1197
           WTF_MAKE_FAST_ALLOCATED;
1158
        public:
1198
        public:
Lines 1225-1230 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec28
1225
    protected:
1265
    protected:
1226
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1266
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1227
        virtual void jettison();
1267
        virtual void jettison();
1268
        virtual void jitCompileImpl(JSGlobalData&);
1228
        virtual CodeBlock* replacement();
1269
        virtual CodeBlock* replacement();
1229
        virtual bool canCompileWithDFG();
1270
        virtual bool canCompileWithDFG();
1230
#endif
1271
#endif
Lines 1259-1264 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec29
1259
    protected:
1300
    protected:
1260
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1301
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1261
        virtual void jettison();
1302
        virtual void jettison();
1303
        virtual void jitCompileImpl(JSGlobalData&);
1262
        virtual CodeBlock* replacement();
1304
        virtual CodeBlock* replacement();
1263
        virtual bool canCompileWithDFG();
1305
        virtual bool canCompileWithDFG();
1264
#endif
1306
#endif
Lines 1296-1301 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec30
1296
    protected:
1338
    protected:
1297
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1339
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1298
        virtual void jettison();
1340
        virtual void jettison();
1341
        virtual void jitCompileImpl(JSGlobalData&);
1299
        virtual CodeBlock* replacement();
1342
        virtual CodeBlock* replacement();
1300
        virtual bool canCompileWithDFG();
1343
        virtual bool canCompileWithDFG();
1301
#endif
1344
#endif
- Source/JavaScriptCore/bytecode/GetByIdStatus.cpp -5 / +35 lines
Lines 27-46 Source/JavaScriptCore/bytecode/GetByIdStatus.cpp_sec1
27
#include "GetByIdStatus.h"
27
#include "GetByIdStatus.h"
28
28
29
#include "CodeBlock.h"
29
#include "CodeBlock.h"
30
#include "LowLevelInterpreter.h"
30
31
31
namespace JSC {
32
namespace JSC {
32
33
34
GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
35
{
36
    UNUSED_PARAM(profiledBlock);
37
    UNUSED_PARAM(bytecodeIndex);
38
    UNUSED_PARAM(ident);
39
#if ENABLE(LLINT)
40
    Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
41
    
42
    if (instruction[0].u.opcode == llint_op_method_check)
43
        instruction++;
44
45
    Structure* structure = instruction[4].u.structure.get();
46
    if (!structure)
47
        return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
48
    
49
    size_t offset = structure->get(*profiledBlock->globalData(), ident);
50
    if (offset == notFound)
51
        return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
52
    
53
    return GetByIdStatus(SimpleDirect, StructureSet(structure), offset, false);
54
#else
55
    return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
56
#endif
57
}
58
33
GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
59
GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
34
{
60
{
35
    UNUSED_PARAM(profiledBlock);
61
    UNUSED_PARAM(profiledBlock);
36
    UNUSED_PARAM(bytecodeIndex);
62
    UNUSED_PARAM(bytecodeIndex);
37
    UNUSED_PARAM(ident);
63
    UNUSED_PARAM(ident);
38
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
64
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
65
    if (!profiledBlock->numberOfStructureStubInfos())
66
        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
67
    
39
    // First check if it makes either calls, in which case we want to be super careful, or
68
    // First check if it makes either calls, in which case we want to be super careful, or
40
    // if it's not set at all, in which case we punt.
69
    // if it's not set at all, in which case we punt.
41
    StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
70
    StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
42
    if (!stubInfo.seen)
71
    if (!stubInfo.seen)
43
        return GetByIdStatus(NoInformation, StructureSet(), notFound);
72
        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
44
    
73
    
45
    PolymorphicAccessStructureList* list;
74
    PolymorphicAccessStructureList* list;
46
    int listSize;
75
    int listSize;
Lines 60-77 GetByIdStatus GetByIdStatus::computeFor( Source/JavaScriptCore/bytecode/GetByIdStatus.cpp_sec2
60
    }
89
    }
61
    for (int i = 0; i < listSize; ++i) {
90
    for (int i = 0; i < listSize; ++i) {
62
        if (!list->list[i].isDirect)
91
        if (!list->list[i].isDirect)
63
            return GetByIdStatus(MakesCalls, StructureSet(), notFound);
92
            return GetByIdStatus(MakesCalls, StructureSet(), notFound, true);
64
    }
93
    }
65
    
94
    
66
    // Next check if it takes slow case, in which case we want to be kind of careful.
95
    // Next check if it takes slow case, in which case we want to be kind of careful.
67
    if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
96
    if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
68
        return GetByIdStatus(TakesSlowPath, StructureSet(), notFound);
97
        return GetByIdStatus(TakesSlowPath, StructureSet(), notFound, true);
69
    
98
    
70
    // Finally figure out if we can derive an access strategy.
99
    // Finally figure out if we can derive an access strategy.
71
    GetByIdStatus result;
100
    GetByIdStatus result;
101
    result.m_wasSeenInJIT = true;
72
    switch (stubInfo.accessType) {
102
    switch (stubInfo.accessType) {
73
    case access_unset:
103
    case access_unset:
74
        return GetByIdStatus(NoInformation, StructureSet(), notFound);
104
        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
75
        
105
        
76
    case access_get_by_id_self: {
106
    case access_get_by_id_self: {
77
        Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
107
        Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
Lines 130-136 GetByIdStatus GetByIdStatus::computeFor( Source/JavaScriptCore/bytecode/GetByIdStatus.cpp_sec3
130
    
160
    
131
    return result;
161
    return result;
132
#else // ENABLE(JIT)
162
#else // ENABLE(JIT)
133
    return GetByIdStatus(NoInformation, StructureSet(), notFound);
163
    return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
134
#endif // ENABLE(JIT)
164
#endif // ENABLE(JIT)
135
}
165
}
136
166
- Source/JavaScriptCore/bytecode/GetByIdStatus.h -1 / +7 lines
Lines 49-58 public: Source/JavaScriptCore/bytecode/GetByIdStatus.h_sec1
49
    {
49
    {
50
    }
50
    }
51
    
51
    
52
    GetByIdStatus(State state, const StructureSet& structureSet, size_t offset)
52
    GetByIdStatus(State state, const StructureSet& structureSet, size_t offset, bool wasSeenInJIT)
53
        : m_state(state)
53
        : m_state(state)
54
        , m_structureSet(structureSet)
54
        , m_structureSet(structureSet)
55
        , m_offset(offset)
55
        , m_offset(offset)
56
        , m_wasSeenInJIT(wasSeenInJIT)
56
    {
57
    {
57
        ASSERT((state == SimpleDirect) == (offset != notFound));
58
        ASSERT((state == SimpleDirect) == (offset != notFound));
58
    }
59
    }
Lines 70-79 public: Source/JavaScriptCore/bytecode/GetByIdStatus.h_sec2
70
    const StructureSet& structureSet() const { return m_structureSet; }
71
    const StructureSet& structureSet() const { return m_structureSet; }
71
    size_t offset() const { return m_offset; }
72
    size_t offset() const { return m_offset; }
72
    
73
    
74
    bool wasSeenInJIT() const { return m_wasSeenInJIT; }
75
    
73
private:
76
private:
77
    static GetByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&);
78
    
74
    State m_state;
79
    State m_state;
75
    StructureSet m_structureSet;
80
    StructureSet m_structureSet;
76
    size_t m_offset;
81
    size_t m_offset;
82
    bool m_wasSeenInJIT;
77
};
83
};
78
84
79
} // namespace JSC
85
} // namespace JSC
- Source/JavaScriptCore/bytecode/Instruction.h +10 lines
Lines 48-53 namespace JSC { Source/JavaScriptCore/bytecode/Instruction.h_sec1
48
    class JSCell;
48
    class JSCell;
49
    class Structure;
49
    class Structure;
50
    class StructureChain;
50
    class StructureChain;
51
    struct LLIntCallLinkInfo;
51
    struct ValueProfile;
52
    struct ValueProfile;
52
53
53
#if ENABLE(JIT)
54
#if ENABLE(JIT)
Lines 146-151 namespace JSC { Source/JavaScriptCore/bytecode/Instruction.h_sec2
146
#endif
147
#endif
147
148
148
    struct Instruction {
149
    struct Instruction {
150
        Instruction()
151
        {
152
            u.jsCell.clear();
153
        }
154
        
149
        Instruction(Opcode opcode)
155
        Instruction(Opcode opcode)
150
        {
156
        {
151
#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
157
#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
Lines 182-187 namespace JSC { Source/JavaScriptCore/bytecode/Instruction.h_sec3
182
188
183
        Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
189
        Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
184
        
190
        
191
        Instruction(LLIntCallLinkInfo* callLinkInfo) { u.callLinkInfo = callLinkInfo; }
192
        
185
        Instruction(ValueProfile* profile) { u.profile = profile; }
193
        Instruction(ValueProfile* profile) { u.profile = profile; }
186
194
187
        union {
195
        union {
Lines 191-197 namespace JSC { Source/JavaScriptCore/bytecode/Instruction.h_sec4
191
            WriteBarrierBase<StructureChain> structureChain;
199
            WriteBarrierBase<StructureChain> structureChain;
192
            WriteBarrierBase<JSCell> jsCell;
200
            WriteBarrierBase<JSCell> jsCell;
193
            PropertySlot::GetValueFunc getterFunc;
201
            PropertySlot::GetValueFunc getterFunc;
202
            LLIntCallLinkInfo* callLinkInfo;
194
            ValueProfile* profile;
203
            ValueProfile* profile;
204
            void* pointer;
195
        } u;
205
        } u;
196
        
206
        
197
    private:
207
    private:
- Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h +66 lines
Line 0 Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h_sec1
1
/*
2
 * Copyright (C) 2012 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 LLIntCallLinkInfo_h
27
#define LLIntCallLinkInfo_h
28
29
#include "JSFunction.h"
30
#include "MacroAssemblerCodeRef.h"
31
#include <wtf/SentinelLinkedList.h>
32
33
namespace JSC {
34
35
struct Instruction;
36
37
struct LLIntCallLinkInfo : public BasicRawSentinelNode<LLIntCallLinkInfo> {
38
    LLIntCallLinkInfo()
39
    {
40
    }
41
    
42
    ~LLIntCallLinkInfo()
43
    {
44
        if (isOnList())
45
            remove();
46
    }
47
    
48
    bool isLinked() { return callee; }
49
    
50
    void unlink()
51
    {
52
        callee.clear();
53
        machineCodeTarget = MacroAssemblerCodePtr();
54
        if (isOnList())
55
            remove();
56
    }
57
    
58
    WriteBarrier<JSFunction> callee;
59
    WriteBarrier<JSFunction> lastSeenCallee;
60
    MacroAssemblerCodePtr machineCodeTarget;
61
};
62
63
} // namespace JSC
64
65
#endif // LLIntCallLinkInfo_h
66
- Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp +5 lines
Lines 35-40 MethodCallLinkStatus MethodCallLinkStatu Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp_sec1
35
    UNUSED_PARAM(profiledBlock);
35
    UNUSED_PARAM(profiledBlock);
36
    UNUSED_PARAM(bytecodeIndex);
36
    UNUSED_PARAM(bytecodeIndex);
37
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
37
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
38
    // NOTE: This does not have an LLInt fall-back because LLInt does not do any method
39
    // call link caching.
40
    if (!profiledBlock->numberOfMethodCallLinkInfos())
41
        return MethodCallLinkStatus();
42
    
38
    MethodCallLinkInfo& methodCall = profiledBlock->getMethodCallLinkInfo(bytecodeIndex);
43
    MethodCallLinkInfo& methodCall = profiledBlock->getMethodCallLinkInfo(bytecodeIndex);
39
    
44
    
40
    if (!methodCall.seen || !methodCall.cachedStructure)
45
    if (!methodCall.seen || !methodCall.cachedStructure)
- Source/JavaScriptCore/bytecode/Opcode.h -1 / +4 lines
Lines 123-128 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec1
123
        macro(op_get_arguments_length, 4) \
123
        macro(op_get_arguments_length, 4) \
124
        macro(op_put_by_id, 9) \
124
        macro(op_put_by_id, 9) \
125
        macro(op_put_by_id_transition, 9) \
125
        macro(op_put_by_id_transition, 9) \
126
        macro(op_put_by_id_transition_direct, 9) \
127
        macro(op_put_by_id_transition_normal, 9) \
126
        macro(op_put_by_id_replace, 9) \
128
        macro(op_put_by_id_replace, 9) \
127
        macro(op_put_by_id_generic, 9) \
129
        macro(op_put_by_id_generic, 9) \
128
        macro(op_del_by_id, 4) \
130
        macro(op_del_by_id, 4) \
Lines 202-207 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec2
202
        typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
204
        typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
203
    #undef OPCODE_ID_ENUM
205
    #undef OPCODE_ID_ENUM
204
206
207
    const int maxOpcodeLength = 9;
205
    const int numOpcodeIDs = op_end + 1;
208
    const int numOpcodeIDs = op_end + 1;
206
209
207
    #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
210
    #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
Lines 218-224 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec3
218
        FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
221
        FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
219
    #undef VERIFY_OPCODE_ID
222
    #undef VERIFY_OPCODE_ID
220
223
221
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
224
#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
222
#if COMPILER(RVCT) || COMPILER(INTEL)
225
#if COMPILER(RVCT) || COMPILER(INTEL)
223
    typedef void* Opcode;
226
    typedef void* Opcode;
224
#else
227
#else
- Source/JavaScriptCore/bytecode/PutByIdStatus.cpp -2 / +44 lines
Lines 27-53 Source/JavaScriptCore/bytecode/PutByIdStatus.cpp_sec1
27
#include "PutByIdStatus.h"
27
#include "PutByIdStatus.h"
28
28
29
#include "CodeBlock.h"
29
#include "CodeBlock.h"
30
#include "LowLevelInterpreter.h"
30
#include "Structure.h"
31
#include "Structure.h"
31
#include "StructureChain.h"
32
#include "StructureChain.h"
32
33
33
namespace JSC {
34
namespace JSC {
34
35
36
PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
37
{
38
    UNUSED_PARAM(profiledBlock);
39
    UNUSED_PARAM(bytecodeIndex);
40
    UNUSED_PARAM(ident);
41
#if ENABLE(LLINT)
42
    Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
43
44
    Structure* structure = instruction[4].u.structure.get();
45
    if (!structure)
46
        return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
47
    
48
    if (instruction[0].u.opcode == llint_op_put_by_id) {
49
        size_t offset = structure->get(*profiledBlock->globalData(), ident);
50
        if (offset == notFound)
51
            return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
52
        
53
        return PutByIdStatus(SimpleReplace, structure, 0, 0, offset);
54
    }
55
    
56
    ASSERT(instruction[0].u.opcode == llint_op_put_by_id_transition_direct
57
           || instruction[0].u.opcode == llint_op_put_by_id_transition_normal);
58
    
59
    Structure* newStructure = instruction[6].u.structure.get();
60
    StructureChain* chain = instruction[7].u.structureChain.get();
61
    ASSERT(newStructure);
62
    ASSERT(chain);
63
    
64
    size_t offset = newStructure->get(*profiledBlock->globalData(), ident);
65
    if (offset == notFound)
66
        return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
67
    
68
    return PutByIdStatus(SimpleTransition, structure, newStructure, chain, offset);
69
#else
70
    return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
71
#endif
72
}
73
35
PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
74
PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
36
{
75
{
37
    UNUSED_PARAM(profiledBlock);
76
    UNUSED_PARAM(profiledBlock);
38
    UNUSED_PARAM(bytecodeIndex);
77
    UNUSED_PARAM(bytecodeIndex);
39
    UNUSED_PARAM(ident);
78
    UNUSED_PARAM(ident);
40
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
79
#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
80
    if (!profiledBlock->numberOfStructureStubInfos())
81
        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
82
    
41
    if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
83
    if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
42
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
84
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
43
    
85
    
44
    StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
86
    StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
45
    if (!stubInfo.seen)
87
    if (!stubInfo.seen)
46
        return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
88
        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
47
    
89
    
48
    switch (stubInfo.accessType) {
90
    switch (stubInfo.accessType) {
49
    case access_unset:
91
    case access_unset:
50
        return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
92
        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
51
        
93
        
52
    case access_put_by_id_replace: {
94
    case access_put_by_id_replace: {
53
        size_t offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
95
        size_t offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
- Source/JavaScriptCore/bytecode/PutByIdStatus.h +2 lines
Lines 93-98 public: Source/JavaScriptCore/bytecode/PutByIdStatus.h_sec1
93
    size_t offset() const { return m_offset; }
93
    size_t offset() const { return m_offset; }
94
    
94
    
95
private:
95
private:
96
    static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&);
97
    
96
    State m_state;
98
    State m_state;
97
    Structure* m_oldStructure;
99
    Structure* m_oldStructure;
98
    Structure* m_newStructure;
100
    Structure* m_newStructure;
- Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp -24 / +13 lines
Lines 33-38 Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec1
33
#include "BatchedTransitionOptimizer.h"
33
#include "BatchedTransitionOptimizer.h"
34
#include "JSFunction.h"
34
#include "JSFunction.h"
35
#include "Interpreter.h"
35
#include "Interpreter.h"
36
#include "LowLevelInterpreter.h"
36
#include "ScopeChain.h"
37
#include "ScopeChain.h"
37
#include "StrongInlines.h"
38
#include "StrongInlines.h"
38
#include "UString.h"
39
#include "UString.h"
Lines 116-141 namespace JSC { Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec2
116
    expected by the callee.
117
    expected by the callee.
117
*/
118
*/
118
119
119
#ifndef NDEBUG
120
static bool s_dumpsGeneratedCode = false;
120
static bool s_dumpsGeneratedCode = false;
121
#endif
122
121
123
void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
122
void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
124
{
123
{
125
#ifndef NDEBUG
126
    s_dumpsGeneratedCode = dumpsGeneratedCode;
124
    s_dumpsGeneratedCode = dumpsGeneratedCode;
127
#else
128
    UNUSED_PARAM(dumpsGeneratedCode);
129
#endif
130
}
125
}
131
126
132
bool BytecodeGenerator::dumpsGeneratedCode()
127
bool BytecodeGenerator::dumpsGeneratedCode()
133
{
128
{
134
#ifndef NDEBUG
135
    return s_dumpsGeneratedCode;
129
    return s_dumpsGeneratedCode;
136
#else
137
    return false;
138
#endif
139
}
130
}
140
131
141
JSObject* BytecodeGenerator::generate()
132
JSObject* BytecodeGenerator::generate()
Lines 148-157 JSObject* BytecodeGenerator::generate() Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec3
148
139
149
    m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
140
    m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
150
141
151
#ifndef NDEBUG
152
    if (s_dumpsGeneratedCode)
142
    if (s_dumpsGeneratedCode)
153
        m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
143
        m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
154
#endif
155
144
156
    if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
145
    if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
157
        symbolTable().clear();
146
        symbolTable().clear();
Lines 1276-1284 RegisterID* BytecodeGenerator::emitResol Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec4
1276
#if ENABLE(JIT)
1265
#if ENABLE(JIT)
1277
        m_codeBlock->addGlobalResolveInfo(instructions().size());
1266
        m_codeBlock->addGlobalResolveInfo(instructions().size());
1278
#endif
1267
#endif
1279
#if ENABLE(INTERPRETER)
1280
        m_codeBlock->addGlobalResolveInstruction(instructions().size());
1268
        m_codeBlock->addGlobalResolveInstruction(instructions().size());
1281
#endif
1282
        ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1269
        ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1283
        instructions().append(dst->index());
1270
        instructions().append(dst->index());
1284
        instructions().append(addConstant(property));
1271
        instructions().append(addConstant(property));
Lines 1440-1448 RegisterID* BytecodeGenerator::emitResol Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec5
1440
#if ENABLE(JIT)
1427
#if ENABLE(JIT)
1441
    m_codeBlock->addGlobalResolveInfo(instructions().size());
1428
    m_codeBlock->addGlobalResolveInfo(instructions().size());
1442
#endif
1429
#endif
1443
#if ENABLE(INTERPRETER)
1444
    m_codeBlock->addGlobalResolveInstruction(instructions().size());
1430
    m_codeBlock->addGlobalResolveInstruction(instructions().size());
1445
#endif
1446
    ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1431
    ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1447
    instructions().append(propDst->index());
1432
    instructions().append(propDst->index());
1448
    instructions().append(addConstant(property));
1433
    instructions().append(addConstant(property));
Lines 1490-1498 RegisterID* BytecodeGenerator::emitResol Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec6
1490
#if ENABLE(JIT)
1475
#if ENABLE(JIT)
1491
    m_codeBlock->addGlobalResolveInfo(instructions().size());
1476
    m_codeBlock->addGlobalResolveInfo(instructions().size());
1492
#endif
1477
#endif
1493
#if ENABLE(INTERPRETER)
1494
    m_codeBlock->addGlobalResolveInstruction(instructions().size());
1478
    m_codeBlock->addGlobalResolveInstruction(instructions().size());
1495
#endif
1496
    ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1479
    ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1497
    instructions().append(propDst->index());
1480
    instructions().append(propDst->index());
1498
    instructions().append(addConstant(property));
1481
    instructions().append(addConstant(property));
Lines 1511-1519 void BytecodeGenerator::emitMethodCheck( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec7
1511
1494
1512
RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1495
RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1513
{
1496
{
1514
#if ENABLE(INTERPRETER)
1515
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1497
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1516
#endif
1517
1498
1518
    ValueProfile* profile = emitProfiledOpcode(op_get_by_id);
1499
    ValueProfile* profile = emitProfiledOpcode(op_get_by_id);
1519
    instructions().append(dst->index());
1500
    instructions().append(dst->index());
Lines 1539-1547 RegisterID* BytecodeGenerator::emitGetAr Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec8
1539
1520
1540
RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1521
RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1541
{
1522
{
1542
#if ENABLE(INTERPRETER)
1543
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1523
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1544
#endif
1545
1524
1546
    emitOpcode(op_put_by_id);
1525
    emitOpcode(op_put_by_id);
1547
    instructions().append(base->index());
1526
    instructions().append(base->index());
Lines 1557-1565 RegisterID* BytecodeGenerator::emitPutBy Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec9
1557
1536
1558
RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1537
RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1559
{
1538
{
1560
#if ENABLE(INTERPRETER)
1561
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1539
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1562
#endif
1563
    
1540
    
1564
    emitOpcode(op_put_by_id);
1541
    emitOpcode(op_put_by_id);
1565
    instructions().append(base->index());
1542
    instructions().append(base->index());
Lines 1848-1854 RegisterID* BytecodeGenerator::emitCall( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec10
1848
    instructions().append(func->index()); // func
1825
    instructions().append(func->index()); // func
1849
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1826
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1850
    instructions().append(callArguments.registerOffset()); // registerOffset
1827
    instructions().append(callArguments.registerOffset()); // registerOffset
1828
#if ENABLE(LLINT)
1829
    instructions().append(m_codeBlock->addLLIntCallLinkInfo());
1830
#else
1851
    instructions().append(0);
1831
    instructions().append(0);
1832
#endif
1852
    instructions().append(0);
1833
    instructions().append(0);
1853
    if (dst != ignoredResult()) {
1834
    if (dst != ignoredResult()) {
1854
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
1835
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
Lines 1952-1958 RegisterID* BytecodeGenerator::emitConst Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec11
1952
    instructions().append(func->index()); // func
1933
    instructions().append(func->index()); // func
1953
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1934
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1954
    instructions().append(callArguments.registerOffset()); // registerOffset
1935
    instructions().append(callArguments.registerOffset()); // registerOffset
1936
#if ENABLE(LLINT)
1937
    instructions().append(m_codeBlock->addLLIntCallLinkInfo());
1938
#else
1955
    instructions().append(0);
1939
    instructions().append(0);
1940
#endif
1956
    instructions().append(0);
1941
    instructions().append(0);
1957
    if (dst != ignoredResult()) {
1942
    if (dst != ignoredResult()) {
1958
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
1943
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
Lines 2213-2219 RegisterID* BytecodeGenerator::emitCatch Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec12
2213
{
2198
{
2214
    m_usesExceptions = true;
2199
    m_usesExceptions = true;
2215
#if ENABLE(JIT)
2200
#if ENABLE(JIT)
2201
#if ENABLE(LLINT)
2202
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel(bitwise_cast<void*>(&llint_op_catch)) };
2203
#else
2216
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2204
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2205
#endif
2217
#else
2206
#else
2218
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2207
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2219
#endif
2208
#endif
- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -5 / +8 lines
Lines 604-612 private: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
604
    {
604
    {
605
        UNUSED_PARAM(nodeIndex);
605
        UNUSED_PARAM(nodeIndex);
606
        
606
        
607
        ValueProfile* profile = m_inlineStackTop->m_profiledBlock->valueProfileForBytecodeOffset(bytecodeIndex);
607
        PredictedType prediction = m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(bytecodeIndex);
608
        ASSERT(profile);
609
        PredictedType prediction = profile->computeUpdatedPrediction();
610
#if DFG_ENABLE(DEBUG_VERBOSE)
608
#if DFG_ENABLE(DEBUG_VERBOSE)
611
        printf("Dynamic [@%u, bc#%u] prediction: %s\n", nodeIndex, bytecodeIndex, predictionToString(prediction));
609
        printf("Dynamic [@%u, bc#%u] prediction: %s\n", nodeIndex, bytecodeIndex, predictionToString(prediction));
612
#endif
610
#endif
Lines 1041-1046 bool ByteCodeParser::handleInlining(bool Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec2
1041
    
1039
    
1042
    // If we get here then it looks like we should definitely inline this code. Proceed
1040
    // If we get here then it looks like we should definitely inline this code. Proceed
1043
    // with parsing the code to get bytecode, so that we can then parse the bytecode.
1041
    // with parsing the code to get bytecode, so that we can then parse the bytecode.
1042
    // Note that if LLInt is enabled, the bytecode will always be available. Also note
1043
    // that if LLInt is enabled, we may inline a code block that has never been JITted
1044
    // before!
1044
    CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
1045
    CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
1045
    if (!codeBlock)
1046
    if (!codeBlock)
1046
        return false;
1047
        return false;
Lines 1741-1747 bool ByteCodeParser::parseBlock(unsigned Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec3
1741
                m_inlineStackTop->m_profiledBlock, m_currentIndex);
1742
                m_inlineStackTop->m_profiledBlock, m_currentIndex);
1742
            
1743
            
1743
            if (methodCallStatus.isSet()
1744
            if (methodCallStatus.isSet()
1744
                && !getByIdStatus.isSet()
1745
                && !getByIdStatus.wasSeenInJIT()
1745
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
1746
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
1746
                // It's monomorphic as far as we can tell, since the method_check was linked
1747
                // It's monomorphic as far as we can tell, since the method_check was linked
1747
                // but the slow path (i.e. the normal get_by_id) never fired.
1748
                // but the slow path (i.e. the normal get_by_id) never fired.
Lines 1810-1816 bool ByteCodeParser::parseBlock(unsigned Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec4
1810
1811
1811
            NEXT_OPCODE(op_get_by_id);
1812
            NEXT_OPCODE(op_get_by_id);
1812
        }
1813
        }
1813
        case op_put_by_id: {
1814
        case op_put_by_id:
1815
        case op_put_by_id_transition_direct:
1816
        case op_put_by_id_transition_normal: {
1814
            NodeIndex value = get(currentInstruction[3].u.operand);
1817
            NodeIndex value = get(currentInstruction[3].u.operand);
1815
            NodeIndex base = get(currentInstruction[1].u.operand);
1818
            NodeIndex base = get(currentInstruction[1].u.operand);
1816
            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
1819
            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
- Source/JavaScriptCore/dfg/DFGCapabilities.h +2 lines
Lines 111-116 inline bool canCompileOpcode(OpcodeID op Source/JavaScriptCore/dfg/DFGCapabilities.h_sec1
111
    case op_put_scoped_var:
111
    case op_put_scoped_var:
112
    case op_get_by_id:
112
    case op_get_by_id:
113
    case op_put_by_id:
113
    case op_put_by_id:
114
    case op_put_by_id_transition_direct:
115
    case op_put_by_id_transition_normal:
114
    case op_get_global_var:
116
    case op_get_global_var:
115
    case op_put_global_var:
117
    case op_put_global_var:
116
    case op_jmp:
118
    case op_jmp:
- Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp +15 lines
Lines 48-53 void compileOSRExit(ExecState* exec) Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp_sec1
48
    uint32_t exitIndex = globalData->osrExitIndex;
48
    uint32_t exitIndex = globalData->osrExitIndex;
49
    OSRExit& exit = codeBlock->osrExit(exitIndex);
49
    OSRExit& exit = codeBlock->osrExit(exitIndex);
50
    
50
    
51
    // Make sure all code on our inline stack is JIT compiled. This is necessary since
52
    // we may opt to inline a code block even before it had ever been compiled by the
53
    // JIT, but our OSR exit infrastructure currently only works if the target of the
54
    // OSR exit is JIT code. This could be changed since there is nothing particularly
55
    // hard about doing an OSR exit into the interpreter, but for now this seems to make
56
    // sense in that if we're OSR exiting from inlined code of a DFG code block, then
57
    // probably it's a good sign that the thing we're exiting into is hot. Even more
58
    // interestingly, since the code was inlined, it may never otherwise get JIT
59
    // compiled since the act of inlining it may ensure that it otherwise never runs.
60
    for (CodeOrigin codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
61
        static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())
62
            ->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)
63
            ->jitCompile(*globalData);
64
    }
65
    
51
    SpeculationRecovery* recovery = 0;
66
    SpeculationRecovery* recovery = 0;
52
    if (exit.m_recoveryIndex)
67
    if (exit.m_recoveryIndex)
53
        recovery = &codeBlock->speculationRecovery(exit.m_recoveryIndex - 1);
68
        recovery = &codeBlock->speculationRecovery(exit.m_recoveryIndex - 1);
- Source/JavaScriptCore/dfg/DFGOperations.cpp -42 / +1 lines
Lines 31-36 Source/JavaScriptCore/dfg/DFGOperations.cpp_sec1
31
#include "CodeBlock.h"
31
#include "CodeBlock.h"
32
#include "DFGOSRExit.h"
32
#include "DFGOSRExit.h"
33
#include "DFGRepatch.h"
33
#include "DFGRepatch.h"
34
#include "HostCallReturnValue.h"
34
#include "GetterSetter.h"
35
#include "GetterSetter.h"
35
#include "InlineASM.h"
36
#include "InlineASM.h"
36
#include "Interpreter.h"
37
#include "Interpreter.h"
Lines 671-718 size_t DFG_OPERATION operationCompareStr Source/JavaScriptCore/dfg/DFGOperations.cpp_sec2
671
    return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
672
    return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
672
}
673
}
673
674
674
EncodedJSValue DFG_OPERATION getHostCallReturnValue();
675
EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*);
676
677
#if CPU(X86_64)
678
asm (
679
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
680
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
681
    "mov -40(%r13), %r13\n"
682
    "mov %r13, %rdi\n"
683
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
684
);
685
#elif CPU(X86)
686
asm (
687
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
688
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
689
    "mov -40(%edi), %edi\n"
690
    "mov %edi, 4(%esp)\n"
691
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
692
);
693
#elif CPU(ARM_THUMB2)
694
asm (
695
".text" "\n"
696
".align 2" "\n"
697
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
698
HIDE_SYMBOL(getHostCallReturnValue) "\n"
699
".thumb" "\n"
700
".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
701
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
702
    "ldr r5, [r5, #-40]" "\n"
703
    "cpy r0, r5" "\n"
704
    "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
705
);
706
#endif
707
708
EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)
709
{
710
    JSGlobalData* globalData = &exec->globalData();
711
    NativeCallFrameTracer tracer(globalData, exec);
712
    
713
    return JSValue::encode(exec->globalData().hostCallReturnValue);
714
}
715
716
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
675
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
717
{
676
{
718
    ExecState* exec = execCallee->callerFrame();
677
    ExecState* exec = execCallee->callerFrame();
- Source/JavaScriptCore/heap/AllocationSpace.h +3 lines
Lines 34-39 Source/JavaScriptCore/heap/AllocationSpace.h_sec1
34
namespace JSC {
34
namespace JSC {
35
35
36
class Heap;
36
class Heap;
37
class LLIntOffsetsExtractor;
37
class MarkedBlock;
38
class MarkedBlock;
38
39
39
class AllocationSpace {
40
class AllocationSpace {
Lines 67-72 public: Source/JavaScriptCore/heap/AllocationSpace.h_sec2
67
    void shrink();
68
    void shrink();
68
    
69
    
69
private:
70
private:
71
    friend class LLIntOffsetsExtractor;
72
    
70
    enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
73
    enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
71
74
72
    void* allocate(MarkedSpace::SizeClass&);
75
    void* allocate(MarkedSpace::SizeClass&);
- Source/JavaScriptCore/heap/Heap.cpp -1 / +1 lines
Lines 837-843 void Heap::collect(SweepToggle sweepTogg Source/JavaScriptCore/heap/Heap.cpp_sec1
837
        setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
837
        setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
838
    }
838
    }
839
    JAVASCRIPTCORE_GC_END();
839
    JAVASCRIPTCORE_GC_END();
840
840
    
841
    (*m_activityCallback)();
841
    (*m_activityCallback)();
842
}
842
}
843
843
- Source/JavaScriptCore/heap/Heap.h -2 / +4 lines
Lines 50-55 namespace JSC { Source/JavaScriptCore/heap/Heap.h_sec1
50
    class JSGlobalData;
50
    class JSGlobalData;
51
    class JSValue;
51
    class JSValue;
52
    class LiveObjectIterator;
52
    class LiveObjectIterator;
53
    class LLIntOffsetsExtractor;
53
    class MarkedArgumentBuffer;
54
    class MarkedArgumentBuffer;
54
    class RegisterFile;
55
    class RegisterFile;
55
    class UString;
56
    class UString;
Lines 136-146 namespace JSC { Source/JavaScriptCore/heap/Heap.h_sec2
136
        void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
137
        void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
137
138
138
    private:
139
    private:
139
        friend class MarkedBlock;
140
        friend class AllocationSpace;
140
        friend class AllocationSpace;
141
        friend class CodeBlock;
142
        friend class LLIntOffsetsExtractor;
143
        friend class MarkedBlock;
141
        friend class BumpSpace;
144
        friend class BumpSpace;
142
        friend class SlotVisitor;
145
        friend class SlotVisitor;
143
        friend class CodeBlock;
144
146
145
        size_t waterMark();
147
        size_t waterMark();
146
        size_t highWaterMark();
148
        size_t highWaterMark();
- Source/JavaScriptCore/heap/MarkStack.cpp -1 / +1 lines
Lines 304-310 ALWAYS_INLINE static void visitChildren( Source/JavaScriptCore/heap/MarkStack.cpp_sec1
304
#endif
304
#endif
305
305
306
    ASSERT(Heap::isMarked(cell));
306
    ASSERT(Heap::isMarked(cell));
307
307
    
308
    if (isJSString(cell)) {
308
    if (isJSString(cell)) {
309
        JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
309
        JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
310
        return;
310
        return;
- Source/JavaScriptCore/heap/MarkedSpace.h +3 lines
Lines 39-44 namespace JSC { Source/JavaScriptCore/heap/MarkedSpace.h_sec1
39
class Heap;
39
class Heap;
40
class JSCell;
40
class JSCell;
41
class LiveObjectIterator;
41
class LiveObjectIterator;
42
class LLIntOffsetsExtractor;
42
class WeakGCHandle;
43
class WeakGCHandle;
43
class SlotVisitor;
44
class SlotVisitor;
44
45
Lines 77-82 public: Source/JavaScriptCore/heap/MarkedSpace.h_sec2
77
    template<typename Functor> typename Functor::ReturnType forEachBlock();
78
    template<typename Functor> typename Functor::ReturnType forEachBlock();
78
79
79
private:
80
private:
81
    friend class LLIntOffsetsExtractor;
82
    
80
    // [ 32... 256 ]
83
    // [ 32... 256 ]
81
    static const size_t preciseStep = MarkedBlock::atomSize;
84
    static const size_t preciseStep = MarkedBlock::atomSize;
82
    static const size_t preciseCutoff = 256;
85
    static const size_t preciseCutoff = 256;
- Source/JavaScriptCore/interpreter/CallFrame.h +3 lines
Lines 122-127 namespace JSC { Source/JavaScriptCore/interpreter/CallFrame.h_sec1
122
#if ENABLE(INTERPRETER)
122
#if ENABLE(INTERPRETER)
123
        Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
123
        Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
124
#endif
124
#endif
125
#if ENABLE(LLINT)
126
        Instruction* currentVPC() const { return bitwise_cast<Instruction*>(this[RegisterFile::ArgumentCount].tag()); }
127
#endif
125
128
126
        void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
129
        void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
127
        void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
130
        void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
- Source/JavaScriptCore/interpreter/Interpreter.cpp -9 / +36 lines
Lines 69-75 Source/JavaScriptCore/interpreter/Interpreter.cpp_sec1
69
#include "JIT.h"
69
#include "JIT.h"
70
#endif
70
#endif
71
71
72
#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(COMPUTED_GOTO_INTERPRETER) && !defined(__llvm__))
72
#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND ((ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)) && !defined(__llvm__))
73
73
74
using namespace std;
74
using namespace std;
75
75
Lines 547-563 Interpreter::Interpreter() Source/JavaScriptCore/interpreter/Interpreter.cpp_sec2
547
{
547
{
548
}
548
}
549
549
550
void Interpreter::initialize(bool canUseJIT)
550
Interpreter::~Interpreter()
551
{
551
{
552
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
552
#if ENABLE(LLINT)
553
    if (m_enabled)
554
        delete[] m_opcodeTable;
555
#endif
556
}
557
558
void Interpreter::initialize(LLInt::Data* llintData, bool canUseJIT)
559
{
560
    UNUSED_PARAM(llintData);
561
    UNUSED_PARAM(canUseJIT);
562
#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
563
#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
564
    // Having LLInt enabled, but not being able to use the JIT, and not having
565
    // a computed goto interpreter, is not supported. Not because we cannot
566
    // support it, but because I decided to draw the line at the number of
567
    // permutations of execution engines that I wanted this code to grok.
568
    ASSERT(canUseJIT);
569
#endif
553
    if (canUseJIT) {
570
    if (canUseJIT) {
571
#if ENABLE(LLINT)
572
        m_opcodeTable = llintData->opcodeMap();
573
        for (int i = 0; i < numOpcodeIDs; ++i)
574
            m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
575
#else
554
        // If the JIT is present, don't use jump destinations for opcodes.
576
        // If the JIT is present, don't use jump destinations for opcodes.
555
        
577
        
556
        for (int i = 0; i < numOpcodeIDs; ++i) {
578
        for (int i = 0; i < numOpcodeIDs; ++i) {
557
            Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
579
            Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
558
            m_opcodeTable[i] = opcode;
580
            m_opcodeTable[i] = opcode;
559
        }
581
        }
582
#endif
560
    } else {
583
    } else {
584
#if ENABLE(LLINT)
585
        m_opcodeTable = new Opcode[numOpcodeIDs];
586
#endif
561
        privateExecute(InitializeAndReturn, 0, 0);
587
        privateExecute(InitializeAndReturn, 0, 0);
562
        
588
        
563
        for (int i = 0; i < numOpcodeIDs; ++i)
589
        for (int i = 0; i < numOpcodeIDs; ++i)
Lines 566-572 void Interpreter::initialize(bool canUse Source/JavaScriptCore/interpreter/Interpreter.cpp_sec3
566
        m_enabled = true;
592
        m_enabled = true;
567
    }
593
    }
568
#else
594
#else
569
    UNUSED_PARAM(canUseJIT);
570
#if ENABLE(INTERPRETER)
595
#if ENABLE(INTERPRETER)
571
    m_enabled = true;
596
    m_enabled = true;
572
#else
597
#else
Lines 667-675 void Interpreter::dumpRegisters(CallFram Source/JavaScriptCore/interpreter/Interpreter.cpp_sec4
667
692
668
bool Interpreter::isOpcode(Opcode opcode)
693
bool Interpreter::isOpcode(Opcode opcode)
669
{
694
{
670
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
695
#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
696
#if !ENABLE(LLINT)
671
    if (!m_enabled)
697
    if (!m_enabled)
672
        return opcode >= 0 && static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
698
        return opcode >= 0 && static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
699
#endif
673
    return opcode != HashTraits<Opcode>::emptyValue()
700
    return opcode != HashTraits<Opcode>::emptyValue()
674
        && !HashTraits<Opcode>::isDeletedValue(opcode)
701
        && !HashTraits<Opcode>::isDeletedValue(opcode)
675
        && m_opcodeIDTable.contains(opcode);
702
        && m_opcodeIDTable.contains(opcode);
Lines 726-736 NEVER_INLINE bool Interpreter::unwindCal Source/JavaScriptCore/interpreter/Interpreter.cpp_sec5
726
    // have to subtract 1.
753
    // have to subtract 1.
727
#if ENABLE(JIT) && ENABLE(INTERPRETER)
754
#if ENABLE(JIT) && ENABLE(INTERPRETER)
728
    if (callerFrame->globalData().canUseJIT())
755
    if (callerFrame->globalData().canUseJIT())
729
        bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
756
        bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
730
    else
757
    else
731
        bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
758
        bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
732
#elif ENABLE(JIT)
759
#elif ENABLE(JIT)
733
    bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
760
    bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
734
#else
761
#else
735
    bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
762
    bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
736
#endif
763
#endif
Lines 5170-5179 void Interpreter::retrieveLastCaller(Cal Source/JavaScriptCore/interpreter/Interpreter.cpp_sec6
5170
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
5197
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
5171
#if ENABLE(JIT)
5198
#if ENABLE(JIT)
5172
    else
5199
    else
5173
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
5200
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
5174
#endif
5201
#endif
5175
#else
5202
#else
5176
    bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
5203
    bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
5177
#endif
5204
#endif
5178
    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
5205
    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
5179
    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
5206
    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
- Source/JavaScriptCore/interpreter/Interpreter.h -5 / +20 lines
Lines 33-38 Source/JavaScriptCore/interpreter/Interpreter.h_sec1
33
#include "JSCell.h"
33
#include "JSCell.h"
34
#include "JSValue.h"
34
#include "JSValue.h"
35
#include "JSObject.h"
35
#include "JSObject.h"
36
#include "LLIntData.h"
36
#include "Opcode.h"
37
#include "Opcode.h"
37
#include "RegisterFile.h"
38
#include "RegisterFile.h"
38
39
Lines 45-50 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec2
45
    class FunctionExecutable;
46
    class FunctionExecutable;
46
    class JSFunction;
47
    class JSFunction;
47
    class JSGlobalObject;
48
    class JSGlobalObject;
49
    class LLIntOffsetsExtractor;
48
    class ProgramExecutable;
50
    class ProgramExecutable;
49
    class Register;
51
    class Register;
50
    class ScopeChainNode;
52
    class ScopeChainNode;
Lines 100-118 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec3
100
102
101
    class Interpreter {
103
    class Interpreter {
102
        WTF_MAKE_FAST_ALLOCATED;
104
        WTF_MAKE_FAST_ALLOCATED;
103
        friend class JIT;
104
        friend class CachedCall;
105
        friend class CachedCall;
106
        friend class LLIntOffsetsExtractor;
107
        friend class JIT;
105
    public:
108
    public:
106
        Interpreter();
109
        Interpreter();
110
        ~Interpreter();
107
        
111
        
108
        void initialize(bool canUseJIT);
112
        void initialize(LLInt::Data*, bool canUseJIT);
109
113
110
        RegisterFile& registerFile() { return m_registerFile; }
114
        RegisterFile& registerFile() { return m_registerFile; }
111
        
115
        
112
        Opcode getOpcode(OpcodeID id)
116
        Opcode getOpcode(OpcodeID id)
113
        {
117
        {
114
            ASSERT(m_initialized);
118
            ASSERT(m_initialized);
115
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
119
#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
116
            return m_opcodeTable[id];
120
            return m_opcodeTable[id];
117
#else
121
#else
118
            return id;
122
            return id;
Lines 122-128 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec4
122
        OpcodeID getOpcodeID(Opcode opcode)
126
        OpcodeID getOpcodeID(Opcode opcode)
123
        {
127
        {
124
            ASSERT(m_initialized);
128
            ASSERT(m_initialized);
125
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
129
#if ENABLE(LLINT)
130
            ASSERT(isOpcode(opcode));
131
            return m_opcodeIDTable.get(opcode);
132
#elif ENABLE(COMPUTED_GOTO_INTERPRETER)
126
            ASSERT(isOpcode(opcode));
133
            ASSERT(isOpcode(opcode));
127
            if (!m_enabled)
134
            if (!m_enabled)
128
                return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
135
                return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
Lines 132-137 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec5
132
            return opcode;
139
            return opcode;
133
#endif
140
#endif
134
        }
141
        }
142
        
143
        bool enabled()
144
        {
145
            return m_enabled;
146
        }
135
147
136
        bool isOpcode(Opcode);
148
        bool isOpcode(Opcode);
137
149
Lines 199-205 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec6
199
211
200
        RegisterFile m_registerFile;
212
        RegisterFile m_registerFile;
201
        
213
        
202
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
214
#if ENABLE(LLINT)
215
        Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
216
        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
217
#elif ENABLE(COMPUTED_GOTO_INTERPRETER)
203
        Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
218
        Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
204
        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
219
        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
205
#endif
220
#endif
- Source/JavaScriptCore/interpreter/RegisterFile.h +3 lines
Lines 39-44 namespace JSC { Source/JavaScriptCore/interpreter/RegisterFile.h_sec1
39
39
40
    class ConservativeRoots;
40
    class ConservativeRoots;
41
    class DFGCodeBlocks;
41
    class DFGCodeBlocks;
42
    class LLIntOffsetsExtractor;
42
43
43
    class RegisterFile {
44
    class RegisterFile {
44
        WTF_MAKE_NONCOPYABLE(RegisterFile);
45
        WTF_MAKE_NONCOPYABLE(RegisterFile);
Lines 81-86 namespace JSC { Source/JavaScriptCore/interpreter/RegisterFile.h_sec2
81
        }
82
        }
82
83
83
    private:
84
    private:
85
        friend class LLIntOffsetsExtractor;
86
        
84
        bool growSlowCase(Register*);
87
        bool growSlowCase(Register*);
85
        void releaseExcessCapacity();
88
        void releaseExcessCapacity();
86
        void addToCommittedByteCount(long);
89
        void addToCommittedByteCount(long);
- Source/JavaScriptCore/jit/HostCallReturnValue.cpp +75 lines
Line 0 Source/JavaScriptCore/jit/HostCallReturnValue.cpp_sec1
1
/*
2
 * Copyright (C) 2012 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 "HostCallReturnValue.h"
28
29
#include "CallFrame.h"
30
#include "InlineASM.h"
31
#include "JSObject.h"
32
#include "JSValueInlineMethods.h"
33
#include "ScopeChain.h"
34
35
namespace JSC {
36
37
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*);
38
39
#if CPU(X86_64)
40
asm (
41
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
42
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
43
    "mov -40(%r13), %r13\n"
44
    "mov %r13, %rdi\n"
45
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
46
);
47
#elif CPU(X86)
48
asm (
49
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
50
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
51
    "mov -40(%edi), %edi\n"
52
    "mov %edi, 4(%esp)\n"
53
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
54
);
55
#elif CPU(ARM_THUMB2)
56
asm (
57
".text" "\n"
58
".align 2" "\n"
59
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
60
HIDE_SYMBOL(getHostCallReturnValue) "\n"
61
".thumb" "\n"
62
".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
63
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
64
    "ldr r5, [r5, #-40]" "\n"
65
    "cpy r0, r5" "\n"
66
    "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
67
);
68
#endif
69
70
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
71
{
72
    return JSValue::encode(exec->globalData().hostCallReturnValue);
73
}
74
75
} // namespace JSC
- Source/JavaScriptCore/jit/HostCallReturnValue.h +44 lines
Line 0 Source/JavaScriptCore/jit/HostCallReturnValue.h_sec1
1
/*
2
 * Copyright (C) 2012 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 HostCallReturnValue_h
27
#define HostCallReturnValue_h
28
29
#include "JSValue.h"
30
#include "MacroAssemblerCodeRef.h"
31
#include <wtf/Platform.h>
32
33
#if CALLING_CONVENTION_IS_STDCALL
34
#define HOST_CALL_RETURN_VALUE_OPTION CDECL
35
#else
36
#define HOST_CALL_RETURN_VALUE_OPTION
37
#endif
38
39
namespace JSC {
40
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue();
41
}
42
43
#endif // HostCallReturnValue_h
44
- Source/JavaScriptCore/jit/JIT.cpp -2 / +14 lines
Lines 325-330 void JIT::privateCompileMainPass() Source/JavaScriptCore/jit/JIT.cpp_sec1
325
        DEFINE_OP(op_profile_will_call)
325
        DEFINE_OP(op_profile_will_call)
326
        DEFINE_OP(op_push_new_scope)
326
        DEFINE_OP(op_push_new_scope)
327
        DEFINE_OP(op_push_scope)
327
        DEFINE_OP(op_push_scope)
328
        case op_put_by_id_transition_direct:
329
        case op_put_by_id_transition_normal:
328
        DEFINE_OP(op_put_by_id)
330
        DEFINE_OP(op_put_by_id)
329
        DEFINE_OP(op_put_by_index)
331
        DEFINE_OP(op_put_by_index)
330
        DEFINE_OP(op_put_by_val)
332
        DEFINE_OP(op_put_by_val)
Lines 487-492 void JIT::privateCompileSlowCases() Source/JavaScriptCore/jit/JIT.cpp_sec2
487
        DEFINE_SLOWCASE_OP(op_post_inc)
489
        DEFINE_SLOWCASE_OP(op_post_inc)
488
        DEFINE_SLOWCASE_OP(op_pre_dec)
490
        DEFINE_SLOWCASE_OP(op_pre_dec)
489
        DEFINE_SLOWCASE_OP(op_pre_inc)
491
        DEFINE_SLOWCASE_OP(op_pre_inc)
492
        case op_put_by_id_transition_direct:
493
        case op_put_by_id_transition_normal:
490
        DEFINE_SLOWCASE_OP(op_put_by_id)
494
        DEFINE_SLOWCASE_OP(op_put_by_id)
491
        DEFINE_SLOWCASE_OP(op_put_by_val)
495
        DEFINE_SLOWCASE_OP(op_put_by_val)
492
        DEFINE_SLOWCASE_OP(op_resolve_global)
496
        DEFINE_SLOWCASE_OP(op_resolve_global)
Lines 526-531 void JIT::privateCompileSlowCases() Source/JavaScriptCore/jit/JIT.cpp_sec3
526
530
527
JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
531
JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
528
{
532
{
533
#if ENABLE(JIT_VERBOSE_OSR)
534
    printf("Compiling JIT code!\n");
535
#endif
536
    
529
#if ENABLE(VALUE_PROFILER)
537
#if ENABLE(VALUE_PROFILER)
530
    m_canBeOptimized = m_codeBlock->canCompileWithDFG();
538
    m_canBeOptimized = m_codeBlock->canCompileWithDFG();
531
#endif
539
#endif
Lines 690-697 JITCode JIT::privateCompile(CodePtr* fun Source/JavaScriptCore/jit/JIT.cpp_sec4
690
        info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
698
        info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
691
    }
699
    }
692
700
693
#if ENABLE(DFG_JIT)
701
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
694
    if (m_canBeOptimized) {
702
    if (m_canBeOptimized
703
#if ENABLE(LLINT)
704
        || true
705
#endif
706
        ) {
695
        CompactJITCodeMap::Encoder jitCodeMapEncoder;
707
        CompactJITCodeMap::Encoder jitCodeMapEncoder;
696
        for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
708
        for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
697
            if (m_labels[bytecodeOffset].isSet())
709
            if (m_labels[bytecodeOffset].isSet())
- Source/JavaScriptCore/jit/JITCode.h -1 / +13 lines
Lines 48-54 namespace JSC { Source/JavaScriptCore/jit/JITCode.h_sec1
48
        JITCode() { }
48
        JITCode() { }
49
#endif
49
#endif
50
    public:
50
    public:
51
        enum JITType { HostCallThunk, BaselineJIT, DFGJIT };
51
        enum JITType { None, HostCallThunk, InterpreterThunk, BaselineJIT, DFGJIT };
52
        
52
        
53
        static JITType bottomTierJIT()
53
        static JITType bottomTierJIT()
54
        {
54
        {
Lines 66-73 namespace JSC { Source/JavaScriptCore/jit/JITCode.h_sec2
66
            return DFGJIT;
66
            return DFGJIT;
67
        }
67
        }
68
        
68
        
69
        static bool isOptimizingJIT(JITType jitType)
70
        {
71
            return jitType == DFGJIT;
72
        }
73
        
74
        static bool isBaselineCode(JITType jitType)
75
        {
76
            return jitType == InterpreterThunk || jitType == BaselineJIT;
77
        }
78
        
69
#if ENABLE(JIT)
79
#if ENABLE(JIT)
70
        JITCode()
80
        JITCode()
81
            : m_jitType(None)
71
        {
82
        {
72
        }
83
        }
73
84
Lines 75-80 namespace JSC { Source/JavaScriptCore/jit/JITCode.h_sec3
75
            : m_ref(ref)
86
            : m_ref(ref)
76
            , m_jitType(jitType)
87
            , m_jitType(jitType)
77
        {
88
        {
89
            ASSERT(jitType != None);
78
        }
90
        }
79
        
91
        
80
        bool operator !() const
92
        bool operator !() const
- Source/JavaScriptCore/jit/JITDriver.h -9 / +13 lines
Lines 33-47 Source/JavaScriptCore/jit/JITDriver.h_sec1
33
#include "BytecodeGenerator.h"
33
#include "BytecodeGenerator.h"
34
#include "DFGDriver.h"
34
#include "DFGDriver.h"
35
#include "JIT.h"
35
#include "JIT.h"
36
#include "LLIntEntrypoints.h"
36
37
37
namespace JSC {
38
namespace JSC {
38
39
39
template<typename CodeBlockType>
40
template<typename CodeBlockType>
40
inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
41
inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
41
{
42
{
43
    if (jitType == codeBlock->getJITType())
44
        return true;
45
    
42
    if (!globalData.canUseJIT())
46
    if (!globalData.canUseJIT())
43
        return true;
47
        return true;
44
    
48
    
49
    codeBlock->unlinkIncomingCalls();
50
    
45
    bool dfgCompiled = false;
51
    bool dfgCompiled = false;
46
    if (jitType == JITCode::DFGJIT)
52
    if (jitType == JITCode::DFGJIT)
47
        dfgCompiled = DFG::tryCompile(globalData, codeBlock.get(), jitCode);
53
        dfgCompiled = DFG::tryCompile(globalData, codeBlock.get(), jitCode);
Lines 55-64 inline bool jitCompileIfAppropriate(JSGl Source/JavaScriptCore/jit/JITDriver.h_sec2
55
        }
61
        }
56
        jitCode = JIT::compile(&globalData, codeBlock.get());
62
        jitCode = JIT::compile(&globalData, codeBlock.get());
57
    }
63
    }
58
#if !ENABLE(OPCODE_SAMPLING)
64
    codeBlock->handleBytecodeDiscardingOpportunity();
59
    if (!BytecodeGenerator::dumpsGeneratedCode())
60
        codeBlock->handleBytecodeDiscardingOpportunity();
61
#endif
62
    codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
65
    codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
63
    
66
    
64
    return true;
67
    return true;
Lines 66-74 inline bool jitCompileIfAppropriate(JSGl Source/JavaScriptCore/jit/JITDriver.h_sec3
66
69
67
inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
70
inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
68
{
71
{
72
    if (jitType == codeBlock->getJITType())
73
        return true;
74
    
69
    if (!globalData.canUseJIT())
75
    if (!globalData.canUseJIT())
70
        return true;
76
        return true;
71
    
77
    
78
    codeBlock->unlinkIncomingCalls();
79
    
72
    bool dfgCompiled = false;
80
    bool dfgCompiled = false;
73
    if (jitType == JITCode::DFGJIT)
81
    if (jitType == JITCode::DFGJIT)
74
        dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck);
82
        dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck);
Lines 83-93 inline bool jitCompileFunctionIfAppropri Source/JavaScriptCore/jit/JITDriver.h_sec4
83
        }
91
        }
84
        jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck);
92
        jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck);
85
    }
93
    }
86
#if !ENABLE(OPCODE_SAMPLING)
94
    codeBlock->handleBytecodeDiscardingOpportunity();
87
    if (!BytecodeGenerator::dumpsGeneratedCode())
88
        codeBlock->handleBytecodeDiscardingOpportunity();
89
#endif
90
    
91
    codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
95
    codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
92
    
96
    
93
    return true;
97
    return true;
- Source/JavaScriptCore/jit/JITExceptions.cpp -1 / +1 lines
Lines 64-70 ExceptionHandler genericThrow(JSGlobalDa Source/JavaScriptCore/jit/JITExceptions.cpp_sec1
64
64
65
ExceptionHandler jitThrow(JSGlobalData* globalData, ExecState* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation)
65
ExceptionHandler jitThrow(JSGlobalData* globalData, ExecState* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation)
66
{
66
{
67
    return genericThrow(globalData, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(faultLocation));
67
    return genericThrow(globalData, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation));
68
}
68
}
69
69
70
}
70
}
- Source/JavaScriptCore/jit/JITStubs.cpp -35 / +3 lines
Lines 1928-1934 DEFINE_STUB_FUNCTION(void, optimize_from Source/JavaScriptCore/jit/JITStubs.cpp_sec1
1928
    unsigned bytecodeIndex = stackFrame.args[0].int32();
1928
    unsigned bytecodeIndex = stackFrame.args[0].int32();
1929
1929
1930
#if ENABLE(JIT_VERBOSE_OSR)
1930
#if ENABLE(JIT_VERBOSE_OSR)
1931
    printf("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
1931
    printf("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
1932
#endif
1932
#endif
1933
1933
1934
    if (codeBlock->hasOptimizedReplacement()) {
1934
    if (codeBlock->hasOptimizedReplacement()) {
Lines 2183-2227 DEFINE_STUB_FUNCTION(void*, op_construct Source/JavaScriptCore/jit/JITStubs.cpp_sec2
2183
    return result;
2183
    return result;
2184
}
2184
}
2185
2185
2186
inline CallFrame* arityCheckFor(CallFrame* callFrame, RegisterFile* registerFile, CodeSpecializationKind kind)
2187
{
2188
    JSFunction* callee = asFunction(callFrame->callee());
2189
    ASSERT(!callee->isHostFunction());
2190
    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
2191
    int argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
2192
2193
    // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
2194
    if (!registerFile->grow(callFrame->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
2195
        return 0;
2196
2197
    ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
2198
2199
    // Too few arguments -- copy call frame and arguments, then fill in missing arguments with undefined.
2200
    size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
2201
    Register* src = callFrame->registers();
2202
    Register* dst = callFrame->registers() + delta;
2203
2204
    int i;
2205
    int end = -CallFrame::offsetFor(argumentCountIncludingThis);
2206
    for (i = -1; i >= end; --i)
2207
        dst[i] = src[i];
2208
2209
    end -= delta;
2210
    for ( ; i >= end; --i)
2211
        dst[i] = jsUndefined();
2212
2213
    CallFrame* newCallFrame = CallFrame::create(dst);
2214
    ASSERT((void*)newCallFrame <= registerFile->end());
2215
    return newCallFrame;
2216
}
2217
2218
DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
2186
DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
2219
{
2187
{
2220
    STUB_INIT_STACK_FRAME(stackFrame);
2188
    STUB_INIT_STACK_FRAME(stackFrame);
2221
2189
2222
    CallFrame* callFrame = stackFrame.callFrame;
2190
    CallFrame* callFrame = stackFrame.callFrame;
2223
2191
2224
    CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
2192
    CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
2225
    if (!newCallFrame)
2193
    if (!newCallFrame)
2226
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2194
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2227
2195
Lines 2234-2240 DEFINE_STUB_FUNCTION(void*, op_construct Source/JavaScriptCore/jit/JITStubs.cpp_sec3
2234
2202
2235
    CallFrame* callFrame = stackFrame.callFrame;
2203
    CallFrame* callFrame = stackFrame.callFrame;
2236
2204
2237
    CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
2205
    CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
2238
    if (!newCallFrame)
2206
    if (!newCallFrame)
2239
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2207
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2240
2208
- Source/JavaScriptCore/jit/JSInterfaceJIT.h +2 lines
Lines 26-33 Source/JavaScriptCore/jit/JSInterfaceJIT.h_sec1
26
#ifndef JSInterfaceJIT_h
26
#ifndef JSInterfaceJIT_h
27
#define JSInterfaceJIT_h
27
#define JSInterfaceJIT_h
28
28
29
#include "BytecodeConventions.h"
29
#include "JITCode.h"
30
#include "JITCode.h"
30
#include "JITStubs.h"
31
#include "JITStubs.h"
32
#include "JSString.h"
31
#include "JSValue.h"
33
#include "JSValue.h"
32
#include "MacroAssembler.h"
34
#include "MacroAssembler.h"
33
#include "RegisterFile.h"
35
#include "RegisterFile.h"
- Source/JavaScriptCore/llint/LLIntCommon.h +33 lines
Line 0 Source/JavaScriptCore/llint/LLIntCommon.h_sec1
1
/*
2
 * Copyright (C) 2012 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 LLIntCommon_h
27
#define LLIntCommon_h
28
29
#define LLINT_EXECUTION_TRACING 0
30
#define LLINT_HELPER_TRACING 0
31
32
#endif // LLIntCommon_h
33
- Source/JavaScriptCore/llint/LLIntData.cpp +56 lines
Line 0 Source/JavaScriptCore/llint/LLIntData.cpp_sec1
1
/*
2
 * Copyright (C) 2011 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 "LLIntData.h"
28
29
#if ENABLE(LLINT)
30
31
#include "Instruction.h"
32
#include "LowLevelInterpreter.h"
33
#include "Opcode.h"
34
35
namespace JSC { namespace LLInt {
36
37
Data::Data()
38
    : m_exceptionInstructions(new Instruction[maxOpcodeLength + 1])
39
    , m_opcodeMap(new Opcode[numOpcodeIDs])
40
{
41
    for (int i = 0; i < maxOpcodeLength + 1; ++i)
42
        m_exceptionInstructions[i].u.pointer = bitwise_cast<void*>(&llint_throw_from_helper_trampoline);
43
#define OPCODE_ENTRY(opcode, length) m_opcodeMap[opcode] = bitwise_cast<void*>(&llint_##opcode);
44
    FOR_EACH_OPCODE_ID(OPCODE_ENTRY);
45
#undef OPCODE_ENTRY
46
}
47
48
Data::~Data()
49
{
50
    delete[] m_exceptionInstructions;
51
    delete[] m_opcodeMap;
52
}
53
54
} } // namespace JSC::LLInt
55
56
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntData.h +88 lines
Line 0 Source/JavaScriptCore/llint/LLIntData.h_sec1
1
/*
2
 * Copyright (C) 2011 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 LLIntData_h
27
#define LLIntData_h
28
29
#include "Opcode.h"
30
#include <wtf/Platform.h>
31
32
namespace JSC {
33
34
struct Instruction;
35
36
namespace LLInt {
37
38
#if ENABLE(LLINT)
39
class Data {
40
public:
41
    Data();
42
    ~Data();
43
    
44
    Instruction* exceptionInstructions()
45
    {
46
        return m_exceptionInstructions;
47
    }
48
    
49
    Opcode* opcodeMap()
50
    {
51
        return m_opcodeMap;
52
    }
53
private:
54
    Instruction* m_exceptionInstructions;
55
    Opcode* m_opcodeMap;
56
};
57
#else // ENABLE(LLINT)
58
59
#if COMPILER(CLANG)
60
#pragma clang diagnostic push
61
#pragma clang diagnostic ignored "-Wmissing-noreturn"
62
#endif
63
64
class Data {
65
public:
66
    Instruction* exceptionInstructions()
67
    {
68
        ASSERT_NOT_REACHED();
69
        return 0;
70
    }
71
    
72
    Opcode* opcodeMap()
73
    {
74
        ASSERT_NOT_REACHED();
75
        return 0;
76
    }
77
};
78
79
#if COMPILER(CLANG)
80
#pragma clang diagnostic pop
81
#endif
82
83
#endif // ENABLE(LLINT)
84
85
} } // namespace JSC::LLInt
86
87
#endif // LLIntData_h
88
- Source/JavaScriptCore/llint/LLIntEntrypoints.cpp +86 lines
Line 0 Source/JavaScriptCore/llint/LLIntEntrypoints.cpp_sec1
1
/*
2
 * Copyright (C) 2012 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 "LLIntEntrypoints.h"
28
29
#if ENABLE(LLINT)
30
31
#include "JITCode.h"
32
#include "JSGlobalData.h"
33
#include "LLIntThunks.h"
34
#include "LowLevelInterpreter.h"
35
36
namespace JSC { namespace LLInt {
37
38
void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind, JITCode& jitCode, MacroAssemblerCodePtr& arityCheck)
39
{
40
    if (!globalData.canUseJIT()) {
41
        if (kind == CodeForCall) {
42
            jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_prologue))));
43
            arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_arity_check));
44
            return;
45
        }
46
47
        ASSERT(kind == CodeForConstruct);
48
        jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_prologue))));
49
        arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_arity_check));
50
        return;
51
    }
52
    
53
    if (kind == CodeForCall) {
54
        jitCode = JITCode(globalData.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk);
55
        arityCheck = globalData.getCTIStub(functionForCallArityCheckThunkGenerator).code();
56
        return;
57
    }
58
59
    ASSERT(kind == CodeForConstruct);
60
    jitCode = JITCode(globalData.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk);
61
    arityCheck = globalData.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
62
}
63
64
void getEvalEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
65
{
66
    if (!globalData.canUseJIT()) {
67
        jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_eval_prologue))));
68
        return;
69
    }
70
    
71
    jitCode = JITCode(globalData.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk);
72
}
73
74
void getProgramEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
75
{
76
    if (!globalData.canUseJIT()) {
77
        jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_program_prologue))));
78
        return;
79
    }
80
    
81
    jitCode = JITCode(globalData.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk);
82
}
83
84
} } // namespace JSC::LLInt
85
86
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntEntrypoints.h +64 lines
Line 0 Source/JavaScriptCore/llint/LLIntEntrypoints.h_sec1
1
/*
2
 * Copyright (C) 2012 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 LLIntEntrypoints_h
27
#define LLIntEntrypoints_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(LLINT)
32
33
#include "CodeSpecializationKind.h"
34
35
namespace JSC {
36
37
class EvalCodeBlock;
38
class JITCode;
39
class JSGlobalData;
40
class MacroAssemblerCodePtr;
41
class MacroAssemblerCodeRef;
42
class ProgramCodeBlock;
43
44
namespace LLInt {
45
46
void getFunctionEntrypoint(JSGlobalData&, CodeSpecializationKind, JITCode&, MacroAssemblerCodePtr& arityCheck);
47
void getEvalEntrypoint(JSGlobalData&, JITCode&);
48
void getProgramEntrypoint(JSGlobalData&, JITCode&);
49
50
inline void getEntrypoint(JSGlobalData& globalData, EvalCodeBlock*, JITCode& jitCode)
51
{
52
    getEvalEntrypoint(globalData, jitCode);
53
}
54
55
inline void getEntrypoint(JSGlobalData& globalData, ProgramCodeBlock*, JITCode& jitCode)
56
{
57
    getProgramEntrypoint(globalData, jitCode);
58
}
59
60
} } // namespace JSC::LLInt
61
62
#endif // ENABLE(LLINT)
63
64
#endif // LLIntEntrypoints_h
- Source/JavaScriptCore/llint/LLIntExceptions.cpp +80 lines
Line 0 Source/JavaScriptCore/llint/LLIntExceptions.cpp_sec1
1
/*
2
 * Copyright (C) 2011 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 "LLIntExceptions.h"
28
29
#if ENABLE(LLINT)
30
31
#include "CallFrame.h"
32
#include "CodeBlock.h"
33
#include "Instruction.h"
34
#include "JITExceptions.h"
35
#include "LLIntCommon.h"
36
#include "LowLevelInterpreter.h"
37
38
namespace JSC { namespace LLInt {
39
40
void interpreterThrowInCaller(ExecState* exec)
41
{
42
    JSGlobalData* globalData = &exec->globalData();
43
#if LLINT_HELPER_TRACING
44
    printf("Throwing exception %s.\n", globalData->exception.description());
45
#endif
46
    genericThrow(
47
        globalData, exec->callerFrame(), globalData->exception,
48
        exec->callerFrame()->codeBlock()->bytecodeOffset(exec->callerFrame(), exec->returnPC()));
49
}
50
51
Instruction* returnToThrowForThrownException(ExecState* exec)
52
{
53
    return exec->globalData().llintData.exceptionInstructions();
54
}
55
56
Instruction* returnToThrow(ExecState* exec, Instruction* pc)
57
{
58
    JSGlobalData* globalData = &exec->globalData();
59
#if LLINT_HELPER_TRACING
60
    printf("Throwing exception %s (returnToThrow).\n", globalData->exception.description());
61
#endif
62
    genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
63
    
64
    return globalData->llintData.exceptionInstructions();
65
}
66
67
void* callToThrow(ExecState* exec, Instruction* pc)
68
{
69
    JSGlobalData* globalData = &exec->globalData();
70
#if LLINT_HELPER_TRACING
71
    printf("Throwing exception %s (callToThrow).\n", globalData->exception.description());
72
#endif
73
    genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
74
    
75
    return bitwise_cast<void*>(&llint_throw_during_call_trampoline);
76
}
77
78
} } // namespace JSC::LLInt
79
80
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntExceptions.h +64 lines
Line 0 Source/JavaScriptCore/llint/LLIntExceptions.h_sec1
1
/*
2
 * Copyright (C) 2011 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 LLIntExceptions_h
27
#define LLIntExceptions_h
28
29
#include <wtf/Platform.h>
30
#include <wtf/StdLibExtras.h>
31
32
#if ENABLE(LLINT)
33
34
namespace JSC {
35
36
class ExecState;
37
struct Instruction;
38
39
namespace LLInt {
40
41
// Throw the currently active exception in the context of the caller's call frame.
42
void interpreterThrowInCaller(ExecState*);
43
44
// Tells you where to jump to if you want to return-to-throw, after you've already
45
// set up all information needed to throw the exception.
46
Instruction* returnToThrowForThrownException(ExecState*);
47
48
// Saves the current PC in the global data for safe-keeping, and gives you a PC
49
// that you can tell the interpreter to go to, which when advanced between 1
50
// and 9 slots will give you an "instruction" that threads to the interpreter's
51
// exception handler. Note that if you give it the PC for exception handling,
52
// it's smart enough to just return that PC without doing anything else; this
53
// lets you thread exception handling through common helper functions used by
54
// other helpers.
55
Instruction* returnToThrow(ExecState*, Instruction*);
56
57
// Use this when you're throwing to a call thunk.
58
void* callToThrow(ExecState*, Instruction*);
59
60
} } // namespace JSC::LLInt
61
62
#endif // ENABLE(LLINT)
63
64
#endif // LLIntExceptions_h
- Source/JavaScriptCore/llint/LLIntHelpers.cpp +1429 lines
Line 0 Source/JavaScriptCore/llint/LLIntHelpers.cpp_sec1
1
/*
2
 * Copyright (C) 2011, 2012 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 "LLIntHelpers.h"
28
29
#if ENABLE(LLINT)
30
31
#include "Arguments.h"
32
#include "CallFrame.h"
33
#include "CommonSlowPaths.h"
34
#include "HostCallReturnValue.h"
35
#include "Interpreter.h"
36
#include "JIT.h"
37
#include "JITDriver.h"
38
#include "JSActivation.h"
39
#include "JSByteArray.h"
40
#include "JSGlobalObjectFunctions.h"
41
#include "JSPropertyNameIterator.h"
42
#include "JSStaticScopeObject.h"
43
#include "JSString.h"
44
#include "JSValue.h"
45
#include "LLIntCommon.h"
46
#include "LLIntExceptions.h"
47
#include "LowLevelInterpreter.h"
48
#include "Operations.h"
49
50
namespace JSC { namespace LLInt {
51
52
#define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
53
#define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
54
55
#define LLINT_RETURN_TWO(first, second) do {       \
56
        union {                                    \
57
            struct {                               \
58
                void* a;                           \
59
                void* b;                           \
60
            } pair;                                \
61
            int64_t i;                             \
62
        } __rt_u;                                  \
63
        __rt_u.pair.a = first;                     \
64
        __rt_u.pair.b = second;                    \
65
        return __rt_u.i;                           \
66
    } while (false)
67
68
#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
69
70
#define LLINT_THROW(exceptionToThrow) do {                        \
71
        JSGlobalData& __t_globalData = exec->globalData();        \
72
        __t_globalData.exception = (exceptionToThrow);            \
73
        pc = returnToThrow(exec, pc);                             \
74
        LLINT_END_IMPL();                                         \
75
    } while (false)
76
77
#define LLINT_CHECK_EXCEPTION() do {                    \
78
        if (UNLIKELY(exec->globalData().exception)) {   \
79
            pc = returnToThrow(exec, pc);               \
80
            LLINT_END_IMPL();                           \
81
        }                                               \
82
    } while (false)
83
84
#define LLINT_END() do {                        \
85
        LLINT_CHECK_EXCEPTION();                \
86
        LLINT_END_IMPL();                       \
87
    } while (false)
88
89
#define LLINT_BRANCH(opcode, condition) do {                      \
90
        bool __b_condition = (condition);                         \
91
        LLINT_CHECK_EXCEPTION();                                  \
92
        if (__b_condition)                                        \
93
            pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand;        \
94
        else                                                      \
95
            pc += OPCODE_LENGTH(opcode);                          \
96
        LLINT_END_IMPL();                                         \
97
    } while (false)
98
99
#define LLINT_RETURN(value) do {                \
100
        JSValue __r_returnValue = (value);      \
101
        LLINT_CHECK_EXCEPTION();                \
102
        LLINT_OP(1) = __r_returnValue;          \
103
        LLINT_END_IMPL();                       \
104
    } while (false)
105
106
#define LLINT_RETURN_PROFILED(opcode, value) do {               \
107
        JSValue __rp_returnValue = (value);                     \
108
        LLINT_CHECK_EXCEPTION();                                \
109
        LLINT_OP(1) = __rp_returnValue;                         \
110
        pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
111
            JSValue::encode(__rp_returnValue);                  \
112
        LLINT_END_IMPL();                                       \
113
    } while (false)
114
115
#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
116
117
#define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do {               \
118
        ExecState* __ct_exec = (exec);                                  \
119
        Instruction* __ct_pc = (pc);                                    \
120
        JSGlobalData& __ct_globalData = (__ct_exec)->globalData();      \
121
        __ct_globalData.exception = (exceptionToThrow);                 \
122
        LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
123
    } while (false)
124
125
#define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do {                       \
126
        ExecState* __cce_exec = (exec);                                 \
127
        Instruction* __cce_pc = (pc);                                   \
128
        if (UNLIKELY(__cce_exec->globalData().exception))               \
129
            LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
130
    } while (false)
131
132
#define LLINT_CALL_RETURN(exec, pc, callTarget) do {                    \
133
        ExecState* __cr_exec = (exec);                                  \
134
        Instruction* __cr_pc = (pc);                                    \
135
        void* __cr_callTarget = (callTarget);                           \
136
        LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc);  \
137
        LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget);                \
138
    } while (false)
139
140
extern "C" HelperReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
141
{
142
    printf("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
143
           exec->codeBlock(),
144
           exec,
145
           static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
146
           exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
147
           fromWhere,
148
           operand,
149
           pc[operand].u.operand);
150
    LLINT_END();
151
}
152
153
extern "C" HelperReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
154
{
155
    JSValue value = LLINT_OP_C(operand).jsValue();
156
    union {
157
        struct {
158
            uint32_t tag;
159
            uint32_t payload;
160
        } bits;
161
        EncodedJSValue asValue;
162
    } u;
163
    u.asValue = JSValue::encode(value);
164
    printf("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x",
165
           exec->codeBlock(),
166
           exec,
167
           static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
168
           exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
169
           fromWhere,
170
           operand,
171
           pc[operand].u.operand,
172
           u.bits.tag,
173
           u.bits.payload);
174
#ifndef NDEBUG
175
    printf(": %s", value.description());
176
#endif
177
    printf("\n");
178
    LLINT_END();
179
}
180
181
LLINT_HELPER_DECL(trace_prologue)
182
{
183
    printf("%p / %p: in prologue.\n", exec->codeBlock(), exec);
184
    LLINT_END();
185
}
186
187
static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
188
{
189
    JSFunction* callee = asFunction(exec->callee());
190
    FunctionExecutable* executable = callee->jsExecutable();
191
    CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
192
    printf("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u.\n",
193
           codeBlock, exec, comment, callee, executable,
194
           codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters);
195
}
196
197
LLINT_HELPER_DECL(trace_prologue_function_for_call)
198
{
199
    traceFunctionPrologue(exec, "call prologue", CodeForCall);
200
    LLINT_END();
201
}
202
203
LLINT_HELPER_DECL(trace_prologue_function_for_construct)
204
{
205
    traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
206
    LLINT_END();
207
}
208
209
LLINT_HELPER_DECL(trace_arityCheck_for_call)
210
{
211
    traceFunctionPrologue(exec, "call arity check", CodeForCall);
212
    LLINT_END();
213
}
214
215
LLINT_HELPER_DECL(trace_arityCheck_for_construct)
216
{
217
    traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
218
    LLINT_END();
219
}
220
221
LLINT_HELPER_DECL(trace)
222
{
223
    printf("%p / %p: executing bc#%zu, ",
224
           exec->codeBlock(),
225
           exec,
226
           static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()));
227
#ifndef NDEBUG
228
    printf("%s, ", opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)]);
229
#else
230
    printf("op#%u, ", exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode));
231
#endif
232
    printf("scope %p\n", exec->scopeChain());
233
    LLINT_END();
234
}
235
236
LLINT_HELPER_DECL(special_trace)
237
{
238
    printf("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
239
           exec->codeBlock(),
240
           exec,
241
           static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
242
           exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
243
           exec->returnPC().value());
244
    LLINT_END();
245
}
246
247
inline bool shouldJIT(ExecState* exec)
248
{
249
    // You can modify this to turn off JITting without rebuilding the world.
250
    return exec->globalData().canUseJIT();
251
}
252
253
enum EntryKind { Prologue, ArityCheck };
254
static HelperReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
255
{
256
#if ENABLE(JIT_VERBOSE_OSR)
257
    printf("%p: Entered %s with executeCounter = %d\n", codeBlock, name, codeBlock->llintExecuteCounter());
258
#endif
259
    
260
    if (!shouldJIT(exec)) {
261
        codeBlock->dontJITAnytimeSoon();
262
        LLINT_RETURN_TWO(0, exec);
263
    }
264
    if (!codeBlock->jitCompile(exec->globalData())) {
265
#if ENABLE(JIT_VERBOSE_OSR)
266
        printf("    Code was already compiled.\n");
267
#endif
268
    }
269
    codeBlock->jitSoon();
270
    if (kind == Prologue)
271
        LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
272
    ASSERT(kind == ArityCheck);
273
    LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
274
}
275
276
LLINT_HELPER_DECL(entry_osr)
277
{
278
    return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
279
}
280
281
LLINT_HELPER_DECL(entry_osr_function_for_call)
282
{
283
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
284
}
285
286
LLINT_HELPER_DECL(entry_osr_function_for_construct)
287
{
288
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
289
}
290
291
LLINT_HELPER_DECL(entry_osr_function_for_call_arityCheck)
292
{
293
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
294
}
295
296
LLINT_HELPER_DECL(entry_osr_function_for_construct_arityCheck)
297
{
298
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
299
}
300
301
LLINT_HELPER_DECL(loop_osr)
302
{
303
    CodeBlock* codeBlock = exec->codeBlock();
304
    
305
#if ENABLE(JIT_VERBOSE_OSR)
306
    printf("%p: Entered loop_osr with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
307
#endif
308
    
309
    if (!shouldJIT(exec)) {
310
        codeBlock->dontJITAnytimeSoon();
311
        LLINT_RETURN_TWO(0, exec);
312
    }
313
    
314
    if (!codeBlock->jitCompile(exec->globalData())) {
315
#if ENABLE(JIT_VERBOSE_OSR)
316
        printf("    Code was already compiled.\n");
317
#endif
318
    }
319
    codeBlock->jitSoon();
320
    
321
    ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
322
    
323
    Vector<BytecodeAndMachineOffset> map;
324
    codeBlock->jitCodeMap()->decode(map);
325
    BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(map.begin(), map.size(), pc - codeBlock->instructions().begin());
326
    ASSERT(mapping);
327
    ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
328
    
329
    void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
330
    ASSERT(jumpTarget);
331
    
332
    LLINT_RETURN_TWO(jumpTarget, exec);
333
}
334
335
LLINT_HELPER_DECL(replace)
336
{
337
    CodeBlock* codeBlock = exec->codeBlock();
338
    
339
#if ENABLE(JIT_VERBOSE_OSR)
340
    printf("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
341
#endif
342
    
343
    if (shouldJIT(exec)) {
344
        if (!codeBlock->jitCompile(exec->globalData())) {
345
#if ENABLE(JIT_VERBOSE_OSR)
346
            printf("    Code was already compiled.\n");
347
#endif
348
        }
349
        codeBlock->jitSoon();
350
    } else
351
        codeBlock->dontJITAnytimeSoon();
352
    LLINT_END();
353
}
354
355
LLINT_HELPER_DECL(register_file_check)
356
{
357
#if LLINT_HELPER_TRACING
358
    printf("Checking stack height with exec = %p.\n", exec);
359
    printf("CodeBlock = %p.\n", exec->codeBlock());
360
    printf("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
361
    printf("Num vars = %u.\n", exec->codeBlock()->m_numVars);
362
    printf("Current end is at %p.\n", exec->globalData().interpreter->registerFile().end());
363
#endif
364
    ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end());
365
    if (UNLIKELY(!exec->globalData().interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
366
        exec = exec->callerFrame();
367
        exec->globalData().exception = createStackOverflowError(exec);
368
        interpreterThrowInCaller(exec);
369
        pc = returnToThrowForThrownException(exec);
370
    }
371
    LLINT_END_IMPL();
372
}
373
374
LLINT_HELPER_DECL(helper_call_arityCheck)
375
{
376
    ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &exec->globalData().interpreter->registerFile(), CodeForCall);
377
    if (!newExec) {
378
        exec = exec->callerFrame();
379
        exec->globalData().exception = createStackOverflowError(exec);
380
        interpreterThrowInCaller(exec);
381
        LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
382
    }
383
    LLINT_RETURN_TWO(0, newExec);
384
}
385
386
LLINT_HELPER_DECL(helper_construct_arityCheck)
387
{
388
    ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &exec->globalData().interpreter->registerFile(), CodeForConstruct);
389
    if (!newExec) {
390
        exec = exec->callerFrame();
391
        exec->globalData().exception = createStackOverflowError(exec);
392
        interpreterThrowInCaller(exec);
393
        LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
394
    }
395
    LLINT_RETURN_TWO(0, newExec);
396
}
397
398
LLINT_HELPER_DECL(helper_create_activation)
399
{
400
#if LLINT_HELPER_TRACING
401
    printf("Creating an activation, exec = %p!\n", exec);
402
#endif
403
    JSActivation* activation = JSActivation::create(exec->globalData(), exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
404
    exec->setScopeChain(exec->scopeChain()->push(activation));
405
    LLINT_RETURN(JSValue(activation));
406
}
407
408
LLINT_HELPER_DECL(helper_create_arguments)
409
{
410
    JSValue arguments = JSValue(Arguments::create(exec->globalData(), exec));
411
    LLINT_CHECK_EXCEPTION();
412
    exec->uncheckedR(pc[1].u.operand) = arguments;
413
    exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
414
    LLINT_END();
415
}
416
417
LLINT_HELPER_DECL(helper_create_this)
418
{
419
    JSFunction* constructor = asFunction(exec->callee());
420
    
421
#if !ASSERT_DISABLED
422
    ConstructData constructData;
423
    ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
424
#endif
425
    
426
    Structure* structure;
427
    JSValue proto = LLINT_OP(2).jsValue();
428
    if (proto.isObject())
429
        structure = asObject(proto)->inheritorID(exec->globalData());
430
    else
431
        structure = constructor->scope()->globalObject->emptyObjectStructure();
432
    
433
    LLINT_RETURN(constructEmptyObject(exec, structure));
434
}
435
436
LLINT_HELPER_DECL(helper_convert_this)
437
{
438
    JSValue v1 = LLINT_OP(1).jsValue();
439
    ASSERT(v1.isPrimitive());
440
    LLINT_RETURN(v1.toThisObject(exec));
441
}
442
443
LLINT_HELPER_DECL(helper_new_object)
444
{
445
    LLINT_RETURN(constructEmptyObject(exec));
446
}
447
448
LLINT_HELPER_DECL(helper_new_array)
449
{
450
    LLINT_RETURN(constructArray(exec, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
451
}
452
453
LLINT_HELPER_DECL(helper_new_array_buffer)
454
{
455
    LLINT_RETURN(constructArray(exec, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
456
}
457
458
LLINT_HELPER_DECL(helper_new_regexp)
459
{
460
    RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
461
    if (!regExp->isValid())
462
        LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
463
    LLINT_RETURN(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
464
}
465
466
LLINT_HELPER_DECL(helper_not)
467
{
468
    LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
469
}
470
471
LLINT_HELPER_DECL(helper_eq)
472
{
473
    LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
474
}
475
476
LLINT_HELPER_DECL(helper_neq)
477
{
478
    LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
479
}
480
481
LLINT_HELPER_DECL(helper_stricteq)
482
{
483
    LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
484
}
485
486
LLINT_HELPER_DECL(helper_nstricteq)
487
{
488
    LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
489
}
490
491
LLINT_HELPER_DECL(helper_less)
492
{
493
    LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
494
}
495
496
LLINT_HELPER_DECL(helper_lesseq)
497
{
498
    LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
499
}
500
501
LLINT_HELPER_DECL(helper_greater)
502
{
503
    LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
504
}
505
506
LLINT_HELPER_DECL(helper_greatereq)
507
{
508
    LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
509
}
510
511
LLINT_HELPER_DECL(helper_pre_inc)
512
{
513
    LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
514
}
515
516
LLINT_HELPER_DECL(helper_pre_dec)
517
{
518
    LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
519
}
520
521
LLINT_HELPER_DECL(helper_post_inc)
522
{
523
    double result = LLINT_OP(2).jsValue().toNumber(exec);
524
    LLINT_OP(2) = jsNumber(result + 1);
525
    LLINT_RETURN(jsNumber(result));
526
}
527
528
LLINT_HELPER_DECL(helper_post_dec)
529
{
530
    double result = LLINT_OP(2).jsValue().toNumber(exec);
531
    LLINT_OP(2) = jsNumber(result - 1);
532
    LLINT_RETURN(jsNumber(result));
533
}
534
535
LLINT_HELPER_DECL(helper_to_jsnumber)
536
{
537
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
538
}
539
540
LLINT_HELPER_DECL(helper_negate)
541
{
542
    LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
543
}
544
545
LLINT_HELPER_DECL(helper_add)
546
{
547
    JSValue v1 = LLINT_OP_C(2).jsValue();
548
    JSValue v2 = LLINT_OP_C(3).jsValue();
549
    
550
#if LLINT_HELPER_TRACING
551
    printf("Trying to add %s", v1.description());
552
    printf(" to %s.\n", v2.description());
553
#endif
554
    
555
    if (v1.isString() && !v2.isObject())
556
        LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
557
    
558
    if (v1.isNumber() && v2.isNumber())
559
        LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
560
    
561
    LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
562
}
563
564
LLINT_HELPER_DECL(helper_mul)
565
{
566
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) * LLINT_OP_C(3).jsValue().toNumber(exec)));
567
}
568
569
LLINT_HELPER_DECL(helper_sub)
570
{
571
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) - LLINT_OP_C(3).jsValue().toNumber(exec)));
572
}
573
574
LLINT_HELPER_DECL(helper_div)
575
{
576
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) / LLINT_OP_C(3).jsValue().toNumber(exec)));
577
}
578
579
LLINT_HELPER_DECL(helper_mod)
580
{
581
    LLINT_RETURN(jsNumber(fmod(LLINT_OP_C(2).jsValue().toNumber(exec), LLINT_OP_C(3).jsValue().toNumber(exec))));
582
}
583
584
LLINT_HELPER_DECL(helper_lshift)
585
{
586
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) << LLINT_OP_C(3).jsValue().toUInt32(exec)));
587
}
588
589
LLINT_HELPER_DECL(helper_rshift)
590
{
591
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) >> LLINT_OP_C(3).jsValue().toUInt32(exec)));
592
}
593
594
LLINT_HELPER_DECL(helper_urshift)
595
{
596
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toUInt32(exec) >> LLINT_OP_C(3).jsValue().toUInt32(exec)));
597
}
598
599
LLINT_HELPER_DECL(helper_bitand)
600
{
601
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) & LLINT_OP_C(3).jsValue().toInt32(exec)));
602
}
603
604
LLINT_HELPER_DECL(helper_bitor)
605
{
606
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) | LLINT_OP_C(3).jsValue().toInt32(exec)));
607
}
608
609
LLINT_HELPER_DECL(helper_bitxor)
610
{
611
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
612
}
613
614
LLINT_HELPER_DECL(helper_bitnot)
615
{
616
    LLINT_RETURN(jsNumber(~LLINT_OP_C(2).jsValue().toInt32(exec)));
617
}
618
619
LLINT_HELPER_DECL(helper_check_has_instance)
620
{
621
    JSValue baseVal = LLINT_OP_C(1).jsValue();
622
#ifndef NDEBUG
623
    TypeInfo typeInfo(UnspecifiedType);
624
    ASSERT(!baseVal.isObject()
625
           || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
626
#endif
627
    LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
628
}
629
630
LLINT_HELPER_DECL(helper_instanceof)
631
{
632
    LLINT_RETURN(jsBoolean(CommonSlowPaths::opInstanceOfSlow(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue())));
633
}
634
635
LLINT_HELPER_DECL(helper_typeof)
636
{
637
    LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
638
}
639
640
LLINT_HELPER_DECL(helper_is_undefined)
641
{
642
    JSValue v = LLINT_OP_C(2).jsValue();
643
    LLINT_RETURN(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
644
}
645
646
LLINT_HELPER_DECL(helper_is_boolean)
647
{
648
    LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isBoolean()));
649
}
650
651
LLINT_HELPER_DECL(helper_is_number)
652
{
653
    LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isNumber()));
654
}
655
656
LLINT_HELPER_DECL(helper_is_string)
657
{
658
    LLINT_RETURN(jsBoolean(isJSString(LLINT_OP_C(2).jsValue())));
659
}
660
661
LLINT_HELPER_DECL(helper_is_object)
662
{
663
    LLINT_RETURN(jsBoolean(jsIsObjectType(LLINT_OP_C(2).jsValue())));
664
}
665
666
LLINT_HELPER_DECL(helper_is_function)
667
{
668
    LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
669
}
670
671
LLINT_HELPER_DECL(helper_in)
672
{
673
    LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
674
}
675
676
LLINT_HELPER_DECL(helper_resolve)
677
{
678
    LLINT_RETURN_PROFILED(op_resolve, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
679
}
680
681
LLINT_HELPER_DECL(helper_resolve_skip)
682
{
683
    LLINT_RETURN_PROFILED(
684
        op_resolve_skip,
685
        CommonSlowPaths::opResolveSkip(
686
            exec,
687
            exec->codeBlock()->identifier(pc[2].u.operand),
688
            pc[3].u.operand));
689
}
690
691
static JSValue resolveGlobal(ExecState* exec, Instruction* pc)
692
{
693
    CodeBlock* codeBlock = exec->codeBlock();
694
    JSGlobalObject* globalObject = codeBlock->globalObject();
695
    ASSERT(globalObject->isGlobalObject());
696
    int property = pc[2].u.operand;
697
    Structure* structure = pc[3].u.structure.get();
698
    
699
    ASSERT_UNUSED(structure, structure != globalObject->structure());
700
    
701
    Identifier& ident = codeBlock->identifier(property);
702
    PropertySlot slot(globalObject);
703
    
704
    if (globalObject->getPropertySlot(exec, ident, slot)) {
705
        JSValue result = slot.getValue(exec, ident);
706
        if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary()
707
            && slot.slotBase() == globalObject) {
708
            pc[3].u.structure.set(
709
                exec->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
710
            pc[4] = slot.cachedOffset();
711
        }
712
        
713
        return result;
714
    }
715
    
716
    exec->globalData().exception = createUndefinedVariableError(exec, ident);
717
    return JSValue();
718
}
719
720
LLINT_HELPER_DECL(helper_resolve_global)
721
{
722
    LLINT_RETURN_PROFILED(op_resolve_global, resolveGlobal(exec, pc));
723
}
724
725
LLINT_HELPER_DECL(helper_resolve_global_dynamic)
726
{
727
    LLINT_RETURN_PROFILED(op_resolve_global_dynamic, resolveGlobal(exec, pc));
728
}
729
730
LLINT_HELPER_DECL(helper_resolve_for_resolve_global_dynamic)
731
{
732
    LLINT_RETURN_PROFILED(op_resolve_global_dynamic, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
733
}
734
735
LLINT_HELPER_DECL(helper_resolve_base)
736
{
737
    Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
738
    if (pc[3].u.operand) {
739
        JSValue base = JSC::resolveBase(exec, ident, exec->scopeChain(), true);
740
        if (!base)
741
            LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
742
        LLINT_RETURN(base);
743
    }
744
    
745
    LLINT_RETURN_PROFILED(op_resolve_base, JSC::resolveBase(exec, ident, exec->scopeChain(), false));
746
}
747
748
LLINT_HELPER_DECL(helper_ensure_property_exists)
749
{
750
    JSObject* object = asObject(LLINT_OP(1).jsValue());
751
    PropertySlot slot(object);
752
    Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
753
    if (!object->getPropertySlot(exec, ident, slot))
754
        LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
755
    LLINT_END();
756
}
757
758
LLINT_HELPER_DECL(helper_resolve_with_base)
759
{
760
    JSValue result = CommonSlowPaths::opResolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
761
    LLINT_CHECK_EXCEPTION();
762
    LLINT_OP(2) = result;
763
    // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
764
    LLINT_END();
765
}
766
767
LLINT_HELPER_DECL(helper_resolve_with_this)
768
{
769
    JSValue result = CommonSlowPaths::opResolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
770
    LLINT_CHECK_EXCEPTION();
771
    LLINT_OP(2) = result;
772
    // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
773
    LLINT_END();
774
}
775
776
LLINT_HELPER_DECL(helper_get_by_id)
777
{
778
    CodeBlock* codeBlock = exec->codeBlock();
779
    Identifier& ident = codeBlock->identifier(pc[3].u.operand);
780
    JSValue baseValue = LLINT_OP_C(2).jsValue();
781
    PropertySlot slot(baseValue);
782
783
    JSValue result = baseValue.get(exec, ident, slot);
784
    LLINT_CHECK_EXCEPTION();
785
    LLINT_OP(1) = result;
786
787
    if (baseValue.isCell()
788
        && slot.isCacheable()
789
        && slot.slotBase() == baseValue
790
        && slot.cachedPropertyType() == PropertySlot::Value) {
791
        
792
        JSCell* baseCell = baseValue.asCell();
793
        Structure* structure = baseCell->structure();
794
        
795
        if (!structure->isUncacheableDictionary()
796
            && !structure->typeInfo().prohibitsPropertyCaching()) {
797
            pc[4].u.structure.set(
798
                exec->globalData(), codeBlock->ownerExecutable(), structure);
799
            pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
800
        }
801
    }
802
    
803
    pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
804
    LLINT_END();
805
}
806
807
LLINT_HELPER_DECL(helper_get_arguments_length)
808
{
809
    CodeBlock* codeBlock = exec->codeBlock();
810
    Identifier& ident = codeBlock->identifier(pc[3].u.operand);
811
    JSValue baseValue = LLINT_OP(2).jsValue();
812
    PropertySlot slot(baseValue);
813
    LLINT_RETURN(baseValue.get(exec, ident, slot));
814
}
815
816
LLINT_HELPER_DECL(helper_put_by_id)
817
{
818
    CodeBlock* codeBlock = exec->codeBlock();
819
    Identifier& ident = codeBlock->identifier(pc[2].u.operand);
820
    JSValue baseValue = LLINT_OP_C(1).jsValue();
821
    PutPropertySlot slot(codeBlock->isStrictMode());
822
    if (pc[8].u.operand)
823
        asObject(baseValue)->putDirect(exec->globalData(), ident, LLINT_OP_C(3).jsValue(), slot);
824
    else
825
        baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
826
    LLINT_CHECK_EXCEPTION();
827
    
828
    if (baseValue.isCell()
829
        && slot.isCacheable()) {
830
        
831
        JSCell* baseCell = baseValue.asCell();
832
        Structure* structure = baseCell->structure();
833
        
834
        if (!structure->isUncacheableDictionary()
835
            && !structure->typeInfo().prohibitsPropertyCaching()
836
            && baseCell == slot.base()) {
837
            
838
            if (slot.type() == PutPropertySlot::NewProperty) {
839
                if (!structure->isDictionary() && structure->previousID()->propertyStorageCapacity() == structure->propertyStorageCapacity()) {
840
                    // This is needed because some of the methods we call
841
                    // below may GC.
842
                    pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
843
844
                    normalizePrototypeChain(exec, baseCell);
845
                    
846
                    ASSERT(structure->previousID()->isObject());
847
                    pc[4].u.structure.set(
848
                        exec->globalData(), codeBlock->ownerExecutable(), structure->previousID());
849
                    pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
850
                    pc[6].u.structure.set(
851
                        exec->globalData(), codeBlock->ownerExecutable(), structure);
852
                    StructureChain* chain = structure->prototypeChain(exec);
853
                    ASSERT(chain);
854
                    pc[7].u.structureChain.set(
855
                        exec->globalData(), codeBlock->ownerExecutable(), chain);
856
                    
857
                    if (pc[8].u.operand)
858
                        pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct);
859
                    else
860
                        pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal);
861
                }
862
            } else {
863
                pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
864
                pc[4].u.structure.set(
865
                    exec->globalData(), codeBlock->ownerExecutable(), structure);
866
                pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
867
            }
868
        }
869
    }
870
    
871
    LLINT_END();
872
}
873
874
LLINT_HELPER_DECL(helper_del_by_id)
875
{
876
    CodeBlock* codeBlock = exec->codeBlock();
877
    JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
878
    bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
879
    LLINT_CHECK_EXCEPTION();
880
    if (!couldDelete && codeBlock->isStrictMode())
881
        LLINT_THROW(createTypeError(exec, "Unable to delete property."));
882
    LLINT_RETURN(jsBoolean(couldDelete));
883
}
884
885
inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
886
{
887
    if (LIKELY(baseValue.isCell() && subscript.isString())) {
888
        if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
889
            return result;
890
    }
891
    
892
    if (subscript.isUInt32()) {
893
        uint32_t i = subscript.asUInt32();
894
        if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
895
            return asString(baseValue)->getIndex(exec, i);
896
        
897
        if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
898
            return asByteArray(baseValue)->getIndex(exec, i);
899
        
900
        return baseValue.get(exec, i);
901
    }
902
    
903
    Identifier property(exec, subscript.toString(exec)->value(exec));
904
    return baseValue.get(exec, property);
905
}
906
907
LLINT_HELPER_DECL(helper_get_by_val)
908
{
909
    LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
910
}
911
912
LLINT_HELPER_DECL(helper_get_argument_by_val)
913
{
914
    JSValue arguments = LLINT_OP(2).jsValue();
915
    if (!arguments) {
916
        arguments = Arguments::create(exec->globalData(), exec);
917
        LLINT_CHECK_EXCEPTION();
918
        LLINT_OP(2) = arguments;
919
        exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
920
    }
921
    
922
    LLINT_RETURN(getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
923
}
924
925
LLINT_HELPER_DECL(helper_get_by_pname)
926
{
927
    LLINT_RETURN(getByVal(exec, LLINT_OP(2).jsValue(), LLINT_OP(3).jsValue()));
928
}
929
930
LLINT_HELPER_DECL(helper_put_by_val)
931
{
932
    JSGlobalData& globalData = exec->globalData();
933
    
934
    JSValue baseValue = LLINT_OP_C(1).jsValue();
935
    JSValue subscript = LLINT_OP_C(2).jsValue();
936
    JSValue value = LLINT_OP_C(3).jsValue();
937
    
938
    if (LIKELY(subscript.isUInt32())) {
939
        uint32_t i = subscript.asUInt32();
940
        if (isJSArray(baseValue)) {
941
            JSArray* jsArray = asArray(baseValue);
942
            if (jsArray->canSetIndex(i))
943
                jsArray->setIndex(globalData, i, value);
944
            else
945
                JSArray::putByIndex(jsArray, exec, i, value);
946
            LLINT_END();
947
        }
948
        if (isJSByteArray(baseValue)
949
            && asByteArray(baseValue)->canAccessIndex(i)) {
950
            JSByteArray* jsByteArray = asByteArray(baseValue);
951
            if (value.isInt32()) {
952
                jsByteArray->setIndex(i, value.asInt32());
953
                LLINT_END();
954
            }
955
            if (value.isNumber()) {
956
                jsByteArray->setIndex(i, value.asNumber());
957
                LLINT_END();
958
            }
959
        }
960
        baseValue.put(exec, i, value);
961
        LLINT_END();
962
    }
963
    
964
    Identifier property(exec, subscript.toString(exec)->value(exec));
965
    LLINT_CHECK_EXCEPTION();
966
    PutPropertySlot slot(exec->codeBlock()->isStrictMode());
967
    baseValue.put(exec, property, value, slot);
968
    LLINT_END();
969
}
970
971
LLINT_HELPER_DECL(helper_del_by_val)
972
{
973
    JSValue baseValue = LLINT_OP_C(2).jsValue();
974
    JSObject* baseObject = baseValue.toObject(exec);
975
    
976
    JSValue subscript = LLINT_OP_C(3).jsValue();
977
    
978
    bool couldDelete;
979
    
980
    uint32_t i;
981
    if (subscript.getUInt32(i))
982
        couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
983
    else {
984
        LLINT_CHECK_EXCEPTION();
985
        Identifier property(exec, subscript.toString(exec)->value(exec));
986
        LLINT_CHECK_EXCEPTION();
987
        couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
988
    }
989
    
990
    if (!couldDelete && exec->codeBlock()->isStrictMode())
991
        LLINT_THROW(createTypeError(exec, "Unable to delete property."));
992
    
993
    LLINT_RETURN(jsBoolean(couldDelete));
994
}
995
996
LLINT_HELPER_DECL(helper_put_by_index)
997
{
998
    LLINT_OP_C(1).jsValue().put(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
999
    LLINT_END();
1000
}
1001
1002
LLINT_HELPER_DECL(helper_put_getter)
1003
{
1004
    ASSERT(LLINT_OP(1).jsValue().isObject());
1005
    JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1006
    Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
1007
    ASSERT(LLINT_OP(3).jsValue().isObject());
1008
    baseObj->methodTable()->defineGetter(baseObj, exec, ident, asObject(LLINT_OP(3).jsValue()), 0);
1009
    LLINT_END();
1010
}
1011
1012
LLINT_HELPER_DECL(helper_put_setter)
1013
{
1014
    ASSERT(LLINT_OP(1).jsValue().isObject());
1015
    JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1016
    Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
1017
    ASSERT(LLINT_OP(3).jsValue().isObject());
1018
    baseObj->methodTable()->defineSetter(baseObj, exec, ident, asObject(LLINT_OP(3).jsValue()), 0);
1019
    LLINT_END();
1020
}
1021
1022
LLINT_HELPER_DECL(helper_jmp_scopes)
1023
{
1024
    unsigned count = pc[1].u.operand;
1025
    ScopeChainNode* tmp = exec->scopeChain();
1026
    while (count--)
1027
        tmp = tmp->pop();
1028
    exec->setScopeChain(tmp);
1029
    pc += pc[2].u.operand;
1030
    LLINT_END();
1031
}
1032
1033
LLINT_HELPER_DECL(helper_jtrue)
1034
{
1035
    LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
1036
}
1037
1038
LLINT_HELPER_DECL(helper_jfalse)
1039
{
1040
    LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
1041
}
1042
1043
LLINT_HELPER_DECL(helper_jless)
1044
{
1045
    LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1046
}
1047
1048
LLINT_HELPER_DECL(helper_jnless)
1049
{
1050
    LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1051
}
1052
1053
LLINT_HELPER_DECL(helper_jgreater)
1054
{
1055
    LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1056
}
1057
1058
LLINT_HELPER_DECL(helper_jngreater)
1059
{
1060
    LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1061
}
1062
1063
LLINT_HELPER_DECL(helper_jlesseq)
1064
{
1065
    LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1066
}
1067
1068
LLINT_HELPER_DECL(helper_jnlesseq)
1069
{
1070
    LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1071
}
1072
1073
LLINT_HELPER_DECL(helper_jgreatereq)
1074
{
1075
    LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1076
}
1077
1078
LLINT_HELPER_DECL(helper_jngreatereq)
1079
{
1080
    LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1081
}
1082
1083
LLINT_HELPER_DECL(helper_switch_imm)
1084
{
1085
    JSValue scrutinee = LLINT_OP_C(3).jsValue();
1086
    ASSERT(scrutinee.isDouble());
1087
    double value = scrutinee.asDouble();
1088
    int32_t intValue = static_cast<int32_t>(value);
1089
    int defaultOffset = pc[2].u.operand;
1090
    if (value == intValue) {
1091
        CodeBlock* codeBlock = exec->codeBlock();
1092
        pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
1093
    } else
1094
        pc += defaultOffset;
1095
    LLINT_END();
1096
}
1097
1098
LLINT_HELPER_DECL(helper_switch_string)
1099
{
1100
    JSValue scrutinee = LLINT_OP_C(3).jsValue();
1101
    int defaultOffset = pc[2].u.operand;
1102
    if (!scrutinee.isString())
1103
        pc += defaultOffset;
1104
    else {
1105
        CodeBlock* codeBlock = exec->codeBlock();
1106
        pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1107
    }
1108
    LLINT_END();
1109
}
1110
1111
LLINT_HELPER_DECL(helper_new_func)
1112
{
1113
    CodeBlock* codeBlock = exec->codeBlock();
1114
    ASSERT(codeBlock->codeType() != FunctionCode
1115
           || !codeBlock->needsFullScopeChain()
1116
           || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
1117
#if LLINT_HELPER_TRACING
1118
    printf("Creating function!\n");
1119
#endif
1120
    LLINT_RETURN(codeBlock->functionDecl(pc[2].u.operand)->make(exec, exec->scopeChain()));
1121
}
1122
1123
LLINT_HELPER_DECL(helper_new_func_exp)
1124
{
1125
    CodeBlock* codeBlock = exec->codeBlock();
1126
    FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
1127
    JSFunction* func = function->make(exec, exec->scopeChain());
1128
    
1129
    if (!function->name().isNull()) {
1130
        JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(exec, function->name(), func, ReadOnly | DontDelete);
1131
        func->setScope(exec->globalData(), func->scope()->push(functionScopeObject));
1132
    }
1133
    
1134
    LLINT_RETURN(func);
1135
}
1136
1137
static HelperReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1138
{
1139
    ExecState* exec = execCallee->callerFrame();
1140
    JSGlobalData* globalData = &exec->globalData();
1141
1142
    execCallee->setScopeChain(exec->scopeChain());
1143
    execCallee->setCodeBlock(0);
1144
1145
    if (kind == CodeForCall) {
1146
        CallData callData;
1147
        CallType callType = getCallData(callee, callData);
1148
    
1149
        ASSERT(callType != CallTypeJS);
1150
    
1151
        if (callType == CallTypeHost) {
1152
            globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1153
            
1154
            LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
1155
        }
1156
        
1157
#if LLINT_HELPER_TRACING
1158
        printf("Call callee is not a function: %s\n", callee.description());
1159
#endif
1160
1161
        ASSERT(callType == CallTypeNone);
1162
        LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
1163
    }
1164
1165
    ASSERT(kind == CodeForConstruct);
1166
    
1167
    ConstructData constructData;
1168
    ConstructType constructType = getConstructData(callee, constructData);
1169
    
1170
    ASSERT(constructType != ConstructTypeJS);
1171
    
1172
    if (constructType == ConstructTypeHost) {
1173
        globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1174
        LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
1175
    }
1176
    
1177
#if LLINT_HELPER_TRACING
1178
        printf("Constructor callee is not a function: %s\n", callee.description());
1179
#endif
1180
1181
    ASSERT(constructType == ConstructTypeNone);
1182
    LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
1183
}
1184
1185
inline HelperReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1186
{
1187
    JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1188
    if (!calleeAsFunctionCell)
1189
        return handleHostCall(execCallee, pc, calleeAsValue, kind);
1190
    
1191
    JSFunction* callee = asFunction(calleeAsFunctionCell);
1192
    execCallee->setScopeChain(callee->scopeUnchecked());
1193
    ExecutableBase* executable = callee->executable();
1194
    
1195
    MacroAssemblerCodePtr codePtr;
1196
    CodeBlock* codeBlock = 0;
1197
    if (executable->isHostFunction())
1198
        codePtr = executable->generatedJITCodeFor(kind).addressForCall();
1199
    else {
1200
        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1201
        JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1202
        if (error)
1203
            LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1204
        codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1205
        ASSERT(codeBlock);
1206
        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1207
            codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1208
        else
1209
            codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
1210
    }
1211
    
1212
    if (callLinkInfo) {
1213
        if (callLinkInfo->isOnList())
1214
            callLinkInfo->remove();
1215
        ExecState* execCaller = execCallee->callerFrame();
1216
        callLinkInfo->callee.set(execCaller->globalData(), execCaller->codeBlock()->ownerExecutable(), callee);
1217
        callLinkInfo->lastSeenCallee.set(execCaller->globalData(), execCaller->codeBlock()->ownerExecutable(), callee);
1218
        callLinkInfo->machineCodeTarget = codePtr;
1219
        if (codeBlock)
1220
            codeBlock->linkIncomingCall(callLinkInfo);
1221
    }
1222
    
1223
    LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1224
}
1225
1226
inline HelperReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1227
{
1228
    // This needs to:
1229
    // - Set up a call frame.
1230
    // - Figure out what to call and compile it if necessary.
1231
    // - If possible, link the call's inline cache.
1232
    // - Return a tuple of machine code address to call and the new call frame.
1233
    
1234
    JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1235
    
1236
    ExecState* execCallee = exec + pc[3].u.operand;
1237
    
1238
    execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1239
    execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
1240
    execCallee->setCallerFrame(exec);
1241
    
1242
    ASSERT(pc[4].u.callLinkInfo);
1243
    return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
1244
}
1245
1246
LLINT_HELPER_DECL(helper_call)
1247
{
1248
    return genericCall(exec, pc, CodeForCall);
1249
}
1250
1251
LLINT_HELPER_DECL(helper_construct)
1252
{
1253
    return genericCall(exec, pc, CodeForConstruct);
1254
}
1255
1256
LLINT_HELPER_DECL(helper_call_varargs)
1257
{
1258
    // This needs to:
1259
    // - Set up a call frame while respecting the variable arguments.
1260
    // - Figure out what to call and compile it if necessary.
1261
    // - Return a tuple of machine code address to call and the new call frame.
1262
    
1263
    JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1264
    
1265
    ExecState* execCallee = loadVarargs(
1266
        exec, &exec->globalData().interpreter->registerFile(),
1267
        LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
1268
    LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1269
    
1270
    execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
1271
    execCallee->setCallerFrame(exec);
1272
    exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_varargs));
1273
    
1274
    return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1275
}
1276
1277
LLINT_HELPER_DECL(helper_call_eval)
1278
{
1279
    JSValue calleeAsValue = LLINT_OP(1).jsValue();
1280
    
1281
    ExecState* execCallee = exec + pc[3].u.operand;
1282
    JSGlobalData& globalData = exec->globalData();
1283
    
1284
    execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1285
    execCallee->setCallerFrame(exec);
1286
    execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
1287
    execCallee->setScopeChain(exec->scopeChain());
1288
    execCallee->setReturnPC(bitwise_cast<Instruction*>(&llint_generic_return_point));
1289
    execCallee->setCodeBlock(0);
1290
    exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_eval));
1291
    
1292
    if (!isHostFunction(calleeAsValue, globalFuncEval))
1293
        return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1294
    
1295
    globalData.hostCallReturnValue = eval(execCallee);
1296
    LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
1297
}
1298
1299
LLINT_HELPER_DECL(helper_tear_off_activation)
1300
{
1301
    ASSERT(exec->codeBlock()->needsFullScopeChain());
1302
    JSValue activationValue = LLINT_OP(1).jsValue();
1303
    if (!activationValue) {
1304
        if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue()) {
1305
            if (!exec->codeBlock()->isStrictMode())
1306
                asArguments(v)->tearOff(exec);
1307
        }
1308
        LLINT_END();
1309
    }
1310
    JSActivation* activation = asActivation(activationValue);
1311
    activation->tearOff(exec->globalData());
1312
    if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue())
1313
        asArguments(v)->didTearOffActivation(exec->globalData(), activation);
1314
    LLINT_END();
1315
}
1316
1317
LLINT_HELPER_DECL(helper_tear_off_arguments)
1318
{
1319
    ASSERT(exec->codeBlock()->usesArguments() && !exec->codeBlock()->needsFullScopeChain());
1320
    asArguments(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue())->tearOff(exec);
1321
    LLINT_END();
1322
}
1323
1324
LLINT_HELPER_DECL(helper_strcat)
1325
{
1326
    LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1327
}
1328
1329
LLINT_HELPER_DECL(helper_to_primitive)
1330
{
1331
    LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1332
}
1333
1334
LLINT_HELPER_DECL(helper_get_pnames)
1335
{
1336
    JSValue v = LLINT_OP(2).jsValue();
1337
    if (v.isUndefinedOrNull()) {
1338
        pc += pc[5].u.operand;
1339
        LLINT_END();
1340
    }
1341
    
1342
    JSObject* o = v.toObject(exec);
1343
    Structure* structure = o->structure();
1344
    JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1345
    if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1346
        jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1347
    
1348
    LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1349
    LLINT_OP(2) = JSValue(o);
1350
    LLINT_OP(3) = Register::withInt(0);
1351
    LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1352
    
1353
    pc += OPCODE_LENGTH(op_get_pnames);
1354
    LLINT_END();
1355
}
1356
1357
LLINT_HELPER_DECL(helper_next_pname)
1358
{
1359
    JSObject* base = asObject(LLINT_OP(2).jsValue());
1360
    JSString* property = asString(LLINT_OP(1).jsValue());
1361
    if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1362
        // Go to target.
1363
        pc += pc[6].u.operand;
1364
    } // Else, don't change the PC, so the interpreter will reloop.
1365
    LLINT_END();
1366
}
1367
1368
LLINT_HELPER_DECL(helper_push_scope)
1369
{
1370
    JSValue v = LLINT_OP(1).jsValue();
1371
    JSObject* o = v.toObject(exec);
1372
    LLINT_CHECK_EXCEPTION();
1373
    
1374
    LLINT_OP(1) = o;
1375
    exec->setScopeChain(exec->scopeChain()->push(o));
1376
    
1377
    LLINT_END();
1378
}
1379
1380
LLINT_HELPER_DECL(helper_pop_scope)
1381
{
1382
    exec->setScopeChain(exec->scopeChain()->pop());
1383
    LLINT_END();
1384
}
1385
1386
LLINT_HELPER_DECL(helper_push_new_scope)
1387
{
1388
    CodeBlock* codeBlock = exec->codeBlock();
1389
    JSObject* scope = JSStaticScopeObject::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), DontDelete);
1390
    exec->setScopeChain(exec->scopeChain()->push(scope));
1391
    LLINT_RETURN(scope);
1392
}
1393
1394
LLINT_HELPER_DECL(helper_throw)
1395
{
1396
    LLINT_THROW(LLINT_OP_C(1).jsValue());
1397
}
1398
1399
LLINT_HELPER_DECL(helper_throw_reference_error)
1400
{
1401
    LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1402
}
1403
1404
LLINT_HELPER_DECL(helper_debug)
1405
{
1406
    int debugHookID = pc[1].u.operand;
1407
    int firstLine = pc[2].u.operand;
1408
    int lastLine = pc[3].u.operand;
1409
    
1410
    exec->globalData().interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
1411
    
1412
    LLINT_END();
1413
}
1414
1415
LLINT_HELPER_DECL(helper_profile_will_call)
1416
{
1417
    (*Profiler::enabledProfilerReference())->willExecute(exec, LLINT_OP(1).jsValue());
1418
    LLINT_END();
1419
}
1420
1421
LLINT_HELPER_DECL(helper_profile_did_call)
1422
{
1423
    (*Profiler::enabledProfilerReference())->didExecute(exec, LLINT_OP(1).jsValue());
1424
    LLINT_END();
1425
}
1426
1427
} } // namespace JSC::LLInt
1428
1429
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntHelpers.h +172 lines
Line 0 Source/JavaScriptCore/llint/LLIntHelpers.h_sec1
1
/*
2
 * Copyright (C) 2011 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 LLIntHelpers_h
27
#define LLIntHelpers_h
28
29
#include <wtf/Platform.h>
30
#include <wtf/StdLibExtras.h>
31
32
#if ENABLE(LLINT)
33
34
namespace JSC {
35
36
class ExecState;
37
struct Instruction;
38
39
namespace LLInt {
40
41
typedef int64_t HelperReturnType;
42
43
extern "C" HelperReturnType llint_trace_operand(ExecState*, Instruction*, int fromWhere, int operand);
44
extern "C" HelperReturnType llint_trace_value(ExecState*, Instruction*, int fromWhere, int operand);
45
46
#define LLINT_HELPER_DECL(name) \
47
    extern "C" HelperReturnType llint_##name(ExecState* exec, Instruction* pc)
48
49
LLINT_HELPER_DECL(trace_prologue);
50
LLINT_HELPER_DECL(trace_prologue_function_for_call);
51
LLINT_HELPER_DECL(trace_prologue_function_for_construct);
52
LLINT_HELPER_DECL(trace_arityCheck_for_call);
53
LLINT_HELPER_DECL(trace_arityCheck_for_construct);
54
LLINT_HELPER_DECL(trace);
55
LLINT_HELPER_DECL(special_trace);
56
LLINT_HELPER_DECL(entry_osr);
57
LLINT_HELPER_DECL(entry_osr_function_for_call);
58
LLINT_HELPER_DECL(entry_osr_function_for_construct);
59
LLINT_HELPER_DECL(entry_osr_function_for_call_arityCheck);
60
LLINT_HELPER_DECL(entry_osr_function_for_construct_arityCheck);
61
LLINT_HELPER_DECL(loop_osr);
62
LLINT_HELPER_DECL(replace);
63
LLINT_HELPER_DECL(register_file_check);
64
LLINT_HELPER_DECL(helper_call_arityCheck);
65
LLINT_HELPER_DECL(helper_construct_arityCheck);
66
LLINT_HELPER_DECL(helper_create_activation);
67
LLINT_HELPER_DECL(helper_create_arguments);
68
LLINT_HELPER_DECL(helper_create_this);
69
LLINT_HELPER_DECL(helper_convert_this);
70
LLINT_HELPER_DECL(helper_new_object);
71
LLINT_HELPER_DECL(helper_new_array);
72
LLINT_HELPER_DECL(helper_new_array_buffer);
73
LLINT_HELPER_DECL(helper_new_regexp);
74
LLINT_HELPER_DECL(helper_not);
75
LLINT_HELPER_DECL(helper_eq);
76
LLINT_HELPER_DECL(helper_neq);
77
LLINT_HELPER_DECL(helper_stricteq);
78
LLINT_HELPER_DECL(helper_nstricteq);
79
LLINT_HELPER_DECL(helper_less);
80
LLINT_HELPER_DECL(helper_lesseq);
81
LLINT_HELPER_DECL(helper_greater);
82
LLINT_HELPER_DECL(helper_greatereq);
83
LLINT_HELPER_DECL(helper_pre_inc);
84
LLINT_HELPER_DECL(helper_pre_dec);
85
LLINT_HELPER_DECL(helper_post_inc);
86
LLINT_HELPER_DECL(helper_post_dec);
87
LLINT_HELPER_DECL(helper_to_jsnumber);
88
LLINT_HELPER_DECL(helper_negate);
89
LLINT_HELPER_DECL(helper_add);
90
LLINT_HELPER_DECL(helper_mul);
91
LLINT_HELPER_DECL(helper_sub);
92
LLINT_HELPER_DECL(helper_div);
93
LLINT_HELPER_DECL(helper_mod);
94
LLINT_HELPER_DECL(helper_lshift);
95
LLINT_HELPER_DECL(helper_rshift);
96
LLINT_HELPER_DECL(helper_urshift);
97
LLINT_HELPER_DECL(helper_bitand);
98
LLINT_HELPER_DECL(helper_bitor);
99
LLINT_HELPER_DECL(helper_bitxor);
100
LLINT_HELPER_DECL(helper_bitnot);
101
LLINT_HELPER_DECL(helper_check_has_instance);
102
LLINT_HELPER_DECL(helper_instanceof);
103
LLINT_HELPER_DECL(helper_typeof);
104
LLINT_HELPER_DECL(helper_is_undefined);
105
LLINT_HELPER_DECL(helper_is_boolean);
106
LLINT_HELPER_DECL(helper_is_number);
107
LLINT_HELPER_DECL(helper_is_string);
108
LLINT_HELPER_DECL(helper_is_object);
109
LLINT_HELPER_DECL(helper_is_function);
110
LLINT_HELPER_DECL(helper_in);
111
LLINT_HELPER_DECL(helper_resolve);
112
LLINT_HELPER_DECL(helper_resolve_skip);
113
LLINT_HELPER_DECL(helper_resolve_global);
114
LLINT_HELPER_DECL(helper_resolve_global_dynamic);
115
LLINT_HELPER_DECL(helper_resolve_for_resolve_global_dynamic);
116
LLINT_HELPER_DECL(helper_resolve_base);
117
LLINT_HELPER_DECL(helper_ensure_property_exists);
118
LLINT_HELPER_DECL(helper_resolve_with_base);
119
LLINT_HELPER_DECL(helper_resolve_with_this);
120
LLINT_HELPER_DECL(helper_get_by_id);
121
LLINT_HELPER_DECL(helper_get_arguments_length);
122
LLINT_HELPER_DECL(helper_put_by_id);
123
LLINT_HELPER_DECL(helper_del_by_id);
124
LLINT_HELPER_DECL(helper_get_by_val);
125
LLINT_HELPER_DECL(helper_get_argument_by_val);
126
LLINT_HELPER_DECL(helper_get_by_pname);
127
LLINT_HELPER_DECL(helper_put_by_val);
128
LLINT_HELPER_DECL(helper_del_by_val);
129
LLINT_HELPER_DECL(helper_put_by_index);
130
LLINT_HELPER_DECL(helper_put_getter);
131
LLINT_HELPER_DECL(helper_put_setter);
132
LLINT_HELPER_DECL(helper_jmp_scopes);
133
LLINT_HELPER_DECL(helper_jtrue);
134
LLINT_HELPER_DECL(helper_jfalse);
135
LLINT_HELPER_DECL(helper_jless);
136
LLINT_HELPER_DECL(helper_jnless);
137
LLINT_HELPER_DECL(helper_jgreater);
138
LLINT_HELPER_DECL(helper_jngreater);
139
LLINT_HELPER_DECL(helper_jlesseq);
140
LLINT_HELPER_DECL(helper_jnlesseq);
141
LLINT_HELPER_DECL(helper_jgreatereq);
142
LLINT_HELPER_DECL(helper_jngreatereq);
143
LLINT_HELPER_DECL(helper_switch_imm);
144
LLINT_HELPER_DECL(helper_switch_char);
145
LLINT_HELPER_DECL(helper_switch_string);
146
LLINT_HELPER_DECL(helper_new_func);
147
LLINT_HELPER_DECL(helper_new_func_exp);
148
LLINT_HELPER_DECL(helper_call);
149
LLINT_HELPER_DECL(helper_construct);
150
LLINT_HELPER_DECL(helper_call_varargs);
151
LLINT_HELPER_DECL(helper_call_eval);
152
LLINT_HELPER_DECL(helper_tear_off_activation);
153
LLINT_HELPER_DECL(helper_tear_off_arguments);
154
LLINT_HELPER_DECL(helper_strcat);
155
LLINT_HELPER_DECL(helper_to_primitive);
156
LLINT_HELPER_DECL(helper_get_pnames);
157
LLINT_HELPER_DECL(helper_next_pname);
158
LLINT_HELPER_DECL(helper_push_scope);
159
LLINT_HELPER_DECL(helper_pop_scope);
160
LLINT_HELPER_DECL(helper_push_new_scope);
161
LLINT_HELPER_DECL(helper_throw);
162
LLINT_HELPER_DECL(helper_throw_reference_error);
163
LLINT_HELPER_DECL(helper_debug);
164
LLINT_HELPER_DECL(helper_profile_will_call);
165
LLINT_HELPER_DECL(helper_profile_did_call);
166
167
} } // namespace JSC::LLInt
168
169
#endif // ENABLE(LLINT)
170
171
#endif // LLIntHelpers_h
172
- Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h +69 lines
Line 0 Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h_sec1
1
/*
2
 * Copyright (C) 2012 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 LLIntOfflineAsmConfig_h
27
#define LLIntOfflineAsmConfig_h
28
29
#include "LLIntCommon.h"
30
#include <wtf/Assertions.h>
31
#include <wtf/Platform.h>
32
33
#if CPU(X86)
34
#define OFFLINE_ASM_X86 1
35
#else
36
#define OFFLINE_ASM_X86 0
37
#endif
38
39
#if CPU(ARMv7)
40
#define OFFLINE_ASM_ARMv7 1
41
#else
42
#define OFFLINE_ASM_ARMv7 0
43
#endif
44
45
#if !ASSERT_DISABLED
46
#define OFFLINE_ASM_ASSERT_ENABLED 1
47
#else
48
#define OFFLINE_ASM_ASSERT_ENABLED 0
49
#endif
50
51
#if CPU(BIG_ENDIAN)
52
#define OFFLINE_ASM_BIG_ENDIAN 1
53
#else
54
#define OFFLINE_ASM_BIG_ENDIAN 0
55
#endif
56
57
#if ENABLE(LLINT_OSR_TO_JIT)
58
#define OFFLINE_ASM_JIT_ENABLED 1
59
#else
60
#define OFFLINE_ASM_JIT_ENABLED 0
61
#endif
62
63
#if LLINT_EXECUTION_TRACING
64
#define OFFLINE_ASM_EXECUTION_TRACING 1
65
#else
66
#define OFFLINE_ASM_EXECUTION_TRACING 0
67
#endif
68
69
#endif // LLIntOfflineAsmConfig_h
- Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp +77 lines
Line 0 Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp_sec1
1
/*
2
 * Copyright (C) 2012 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
28
#include "AllocationSpace.h"
29
#include "CodeBlock.h"
30
#include "Executable.h"
31
#include "Heap.h"
32
#include "Interpreter.h"
33
#include "JITStubs.h"
34
#include "JSArray.h"
35
#include "JSCell.h"
36
#include "JSFunction.h"
37
#include "JSGlobalData.h"
38
#include "JSGlobalObject.h"
39
#include "JSObject.h"
40
#include "JSPropertyNameIterator.h"
41
#include "JSString.h"
42
#include "JSTypeInfo.h"
43
#include "JSVariableObject.h"
44
#include "JumpTable.h"
45
#include "LLIntOfflineAsmConfig.h"
46
#include "MarkedSpace.h"
47
#include "RegisterFile.h"
48
#include "ScopeChain.h"
49
#include "Structure.h"
50
#include "StructureChain.h"
51
#include "ValueProfile.h"
52
#include <wtf/text/StringImpl.h>
53
54
namespace JSC {
55
56
#define OFFLINE_ASM_OFFSETOF(clazz, field) OBJECT_OFFSETOF(clazz, field)
57
58
class LLIntOffsetsExtractor {
59
public:
60
    static const unsigned* dummy();
61
};
62
63
const unsigned* LLIntOffsetsExtractor::dummy()
64
{
65
#include "LLIntDesiredOffsets.h"
66
    return extractorTable;
67
}
68
69
} // namespace JSC
70
71
int main(int, char**)
72
{
73
    // Out of an abundance of caution, make sure that LLIntOffsetsExtractor::dummy() is live,
74
    // and the extractorTable is live, too.
75
    printf("%p\n", JSC::LLIntOffsetsExtractor::dummy());
76
    return 0;
77
}
- Source/JavaScriptCore/llint/LLIntThunks.cpp +81 lines
Line 0 Source/JavaScriptCore/llint/LLIntThunks.cpp_sec1
1
/*
2
 * Copyright (C) 2012 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 "LLIntThunks.h"
28
29
#if ENABLE(LLINT)
30
31
#include "JSInterfaceJIT.h"
32
#include "LinkBuffer.h"
33
#include "LowLevelInterpreter.h"
34
35
namespace JSC { namespace LLInt {
36
37
static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)())
38
{
39
    JSInterfaceJIT jit;
40
    
41
    // FIXME: there's probably a better way to do it on X86, but I'm not sure I care.
42
    jit.move(JSInterfaceJIT::TrustedImmPtr(bitwise_cast<void*>(target)), JSInterfaceJIT::regT0);
43
    jit.jump(JSInterfaceJIT::regT0);
44
    
45
    LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
46
    return patchBuffer.finalizeCode();
47
}
48
49
MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData* globalData)
50
{
51
    return generateThunkWithJumpTo(globalData, llint_function_for_call_prologue);
52
}
53
54
MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData* globalData)
55
{
56
    return generateThunkWithJumpTo(globalData, llint_function_for_construct_prologue);
57
}
58
59
MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData* globalData)
60
{
61
    return generateThunkWithJumpTo(globalData, llint_function_for_call_arity_check);
62
}
63
64
MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData* globalData)
65
{
66
    return generateThunkWithJumpTo(globalData, llint_function_for_construct_arity_check);
67
}
68
69
MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData* globalData)
70
{
71
    return generateThunkWithJumpTo(globalData, llint_eval_prologue);
72
}
73
74
MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData* globalData)
75
{
76
    return generateThunkWithJumpTo(globalData, llint_program_prologue);
77
}
78
79
} } // namespace JSC::LLInt
80
81
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntThunks.h +52 lines
Line 0 Source/JavaScriptCore/llint/LLIntThunks.h_sec1
1
/*
2
 * Copyright (C) 2012 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 LLIntThunks_h
27
#define LLIntThunks_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(LLINT)
32
33
#include "MacroAssemblerCodeRef.h"
34
35
namespace JSC {
36
37
class JSGlobalData;
38
39
namespace LLInt {
40
41
MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData*);
42
MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData*);
43
MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData*);
44
MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData*);
45
MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData*);
46
MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData*);
47
48
} } // namespace JSC::LLInt
49
50
#endif // ENABLE(LLINT)
51
52
#endif // LLIntThunks_h
- Source/JavaScriptCore/llint/LowLevelInterpreter.asm +2380 lines
Line 0 Source/JavaScriptCore/llint/LowLevelInterpreter.asm_sec1
1
# Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
25
# Crash course on the language that this is written in (which I just call
26
# "assembly" even though it's more than that):
27
#
28
# - Mostly gas-style operand ordering. The last operand tends to be the
29
#   destination. So "a := b" is written as "mov b, a". But unlike gas,
30
#   comparisons are in-order, so "if (a < b)" is written as
31
#   "bilt a, b, ...".
32
#
33
# - "b" = byte, "h" = 16-bit word, "i" = 32-bit word, "p" = pointer.
34
#   Currently this is just 32-bit so "i" and "p" are interchangeable
35
#   except when an op supports one but not the other.
36
#
37
# - In general, valid operands for macro invocations and instructions are
38
#   registers (eg "t0"), addresses (eg "4[t0]"), base-index addresses
39
#   (eg "7[t0, t1, 2]"), absolute addresses (eg "0xa0000000[]"), or labels
40
#   (eg "_foo" or ".foo"). Macro invocations can also take anonymous
41
#   macros as operands. Instructions cannot take anonymous macros.
42
#
43
# - Labels must have names that begin with either "_" or ".".  A "." label
44
#   is local and gets renamed before code gen to minimize namespace
45
#   pollution. A "_" label is an extern symbol (i.e. ".globl"). The "_"
46
#   may or may not be removed during code gen depending on whether the asm
47
#   conventions for C name mangling on the target platform mandate a "_"
48
#   prefix.
49
#
50
# - A "macro" is a lambda expression, which may be either anonymous or
51
#   named. But this has caveats. "macro" can take zero or more arguments,
52
#   which may be macros or any valid operands, but it can only return
53
#   code. But you can do Turing-complete things via continuation passing
54
#   style: "macro foo (a, b) b(a) end foo(foo, foo)". Actually, don't do
55
#   that, since you'll just crash the assembler.
56
#
57
# - An "if" is a conditional on settings. Any identifier supplied in the
58
#   predicate of an "if" is assumed to be a #define that is available
59
#   during code gen. So you can't use "if" for computation in a macro, but
60
#   you can use it to select different pieces of code for different
61
#   platforms.
62
#
63
# - Arguments to macros follow lexical scoping rather than dynamic scoping.
64
#   Const's also follow lexical scoping and may override (hide) arguments
65
#   or other consts. All variables (arguments and constants) can be bound
66
#   to operands. Additionally, arguments (but not constants) can be bound
67
#   to macros.
68
69
70
# These declarations must match interpreter/RegisterFile.h.
71
const CallFrameHeaderSize = 48
72
const ArgumentCount = -48
73
const CallerFrame = -40
74
const Callee = -32
75
const ScopeChain = -24
76
const ReturnPC = -16
77
const CodeBlock = -8
78
79
const ThisArgumentOffset = -CallFrameHeaderSize - 8
80
81
# Declare some aliases for the registers we will use.
82
const PC = t4
83
84
# Offsets needed for reasoning about value representation.
85
if BIG_ENDIAN
86
    const TagOffset = 0
87
    const PayloadOffset = 4
88
else
89
    const TagOffset = 4
90
    const PayloadOffset = 0
91
end
92
93
# Value representation constants.
94
const Int32Tag = -1
95
const BooleanTag = -2
96
const NullTag = -3
97
const UndefinedTag = -4
98
const CellTag = -5
99
const EmptyValueTag = -6
100
const DeletedValueTag = -7
101
const LowestTag = DeletedValueTag
102
103
# Type constants.
104
const StringType = 5
105
const ObjectType = 10
106
107
# Type flags constants.
108
const MasqueradesAsUndefined = 1
109
const ImplementsHasInstance = 2
110
const ImplementsDefaultHasInstance = 8
111
112
# Heap allocation constants.
113
const JSFinalObjectSizeClassIndex = 3
114
115
# Bytecode operand constants.
116
const FirstConstantRegisterIndex = 0x40000000
117
118
# Code type constants.
119
const GlobalCode = 0
120
const EvalCode = 1
121
const FunctionCode = 2
122
123
# The interpreter steals the tag word of the argument count.
124
const LLIntReturnPC = ArgumentCount + TagOffset
125
126
# This must match wtf/Vector.h.
127
const VectorSizeOffset = 0
128
const VectorBufferOffset = 4
129
130
# String flags.
131
const HashFlags8BitBuffer = 64
132
133
# Utilities
134
macro crash()
135
    storei 0, 0xbbadbeef[]
136
    move 0, t0
137
    call t0
138
end
139
140
macro assert(assertion)
141
    if ASSERT_ENABLED
142
        assertion(.ok)
143
        crash()
144
    .ok:
145
    end
146
end
147
148
macro preserveReturnAddressAfterCall(destinationRegister)
149
    if ARMv7
150
        move lr, destinationRegister
151
    elsif X86
152
        pop destinationRegister
153
    else
154
        error
155
    end
156
end
157
158
macro restoreReturnAddressBeforeReturn(sourceRegister)
159
    if ARMv7
160
        move sourceRegister, lr
161
    elsif X86
162
        push sourceRegister
163
    else
164
        error
165
    end
166
end
167
168
macro dispatch(advance)
169
    addp advance * 4, PC
170
    jmp [PC]
171
end
172
173
macro dispatchBranchWithOffset(pcOffset)
174
    lshifti 2, pcOffset
175
    addp pcOffset, PC
176
    jmp [PC]
177
end
178
179
macro dispatchBranch(pcOffset)
180
    loadi pcOffset, t0
181
    dispatchBranchWithOffset(t0)
182
end
183
184
macro dispatchAfterCall()
185
    loadi ArgumentCount + TagOffset[cfr], PC
186
    jmp [PC]
187
end
188
189
macro cCall2(function, arg1, arg2)
190
    if ARMv7
191
        move arg1, t0
192
        move arg2, t1
193
    elsif X86
194
        poke arg1, 0
195
        poke arg2, 1
196
    else
197
        error
198
    end
199
    call function
200
end
201
202
# This barely works. arg3 and arg4 should probably be immediates.
203
macro cCall4(function, arg1, arg2, arg3, arg4)
204
    if ARMv7
205
        move arg1, t0
206
        move arg2, t1
207
        move arg3, t2
208
        move arg4, t3
209
    elsif X86
210
        poke arg1, 0
211
        poke arg2, 1
212
        poke arg3, 2
213
        poke arg4, 3
214
    else
215
        error
216
    end
217
    call function
218
end
219
220
macro callHelper(helper)
221
    cCall2(helper, cfr, PC)
222
    move t0, PC
223
    move t1, cfr
224
end
225
226
# Debugging operation if you'd like to print an operand in the instruction stream. fromWhere
227
# should be an immediate integer - any integer you like; use it to identify the place you're
228
# debugging from. operand should likewise be an immediate, and should identify the operand
229
# in the instruction stream you'd like to print out.
230
macro traceOperand(fromWhere, operand)
231
    cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
232
    move t0, PC
233
    move t1, cfr
234
end
235
236
# Debugging operation if you'd like to print the value of an operand in the instruction
237
# stream. Same as traceOperand(), but assumes that the operand is a register, and prints its
238
# value.
239
macro traceValue(fromWhere, operand)
240
    cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
241
    move t0, PC
242
    move t1, cfr
243
end
244
245
macro traceExecution()
246
    if EXECUTION_TRACING
247
        callHelper(_llint_trace)
248
    end
249
end
250
251
# Call a helper for call opcodes.
252
macro callCallHelper(advance, helper, action)
253
    addp advance * 4, PC, t0
254
    storep t0, ArgumentCount + TagOffset[cfr]
255
    cCall2(helper, cfr, PC)
256
    move t1, cfr
257
    action(t0)
258
end
259
260
macro slowPathForCall(advance, helper)
261
    callCallHelper(
262
        advance,
263
        helper,
264
        macro (callee)
265
            call callee
266
            dispatchAfterCall()
267
        end)
268
end
269
270
macro checkSwitchToJIT(increment, action)
271
    if JIT_ENABLED
272
        loadp CodeBlock[cfr], t0
273
        baddis increment, CodeBlock::m_llintExecuteCounter[t0], .continue
274
        action()
275
    .continue:
276
    end
277
end
278
279
macro checkSwitchToJITForLoop()
280
    checkSwitchToJIT(
281
        1,
282
        macro ()
283
            storei PC, ArgumentCount + TagOffset[cfr]
284
            cCall2(_llint_loop_osr, cfr, PC)
285
            move t1, cfr
286
            btpz t0, .recover
287
            jmp t0
288
        .recover:
289
            loadi ArgumentCount + TagOffset[cfr], PC
290
        end)
291
end
292
293
macro checkSwitchToJITForEpilogue()
294
    checkSwitchToJIT(
295
        10,
296
        macro ()
297
            callHelper(_llint_replace)
298
        end)
299
end
300
301
macro assertNotConstant(index)
302
    assert(macro (ok) bilt index, FirstConstantRegisterIndex, ok end)
303
end
304
305
# Index, tag, and payload must be different registers. Index is not
306
# changed.
307
macro loadConstantOrVariable(index, tag, payload)
308
    bigteq index, FirstConstantRegisterIndex, .constant
309
    loadi TagOffset[cfr, index, 8], tag
310
    loadi PayloadOffset[cfr, index, 8], payload
311
    jmp .done
312
.constant:
313
    loadp CodeBlock[cfr], payload
314
    loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
315
    # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
316
    # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
317
    loadp TagOffset[payload, index, 8], tag
318
    loadp PayloadOffset[payload, index, 8], payload
319
.done:
320
end
321
322
# Index and payload may be the same register. Index may be clobbered.
323
macro loadConstantOrVariable2Reg(index, tag, payload)
324
    bigteq index, FirstConstantRegisterIndex, .constant
325
    loadi TagOffset[cfr, index, 8], tag
326
    loadi PayloadOffset[cfr, index, 8], payload
327
    jmp .done
328
.constant:
329
    loadp CodeBlock[cfr], tag
330
    loadp CodeBlock::m_constantRegisters + VectorBufferOffset[tag], tag
331
    # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
332
    # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
333
    lshifti 3, index
334
    addp index, tag
335
    loadp PayloadOffset[tag], payload
336
    loadp TagOffset[tag], tag
337
.done:
338
end
339
340
macro loadConstantOrVariablePayloadTagCustom(index, tagCheck, payload)
341
    bigteq index, FirstConstantRegisterIndex, .constant
342
    tagCheck(TagOffset[cfr, index, 8])
343
    loadi PayloadOffset[cfr, index, 8], payload
344
    jmp .done
345
.constant:
346
    loadp CodeBlock[cfr], payload
347
    loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
348
    # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
349
    # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
350
    tagCheck(TagOffset[payload, index, 8])
351
    loadp PayloadOffset[payload, index, 8], payload
352
.done:
353
end
354
355
# Index and payload must be different registers. Index is not mutated. Use
356
# this if you know what the tag of the variable should be. Doing the tag
357
# test as part of loading the variable reduces register use, but may not
358
# be faster than doing loadConstantOrVariable followed by a branch on the
359
# tag.
360
macro loadConstantOrVariablePayload(index, expectedTag, payload, slow)
361
    loadConstantOrVariablePayloadTagCustom(
362
        index,
363
        macro (actualTag) bineq actualTag, expectedTag, slow end,
364
        payload)
365
end
366
367
macro loadConstantOrVariablePayloadUnchecked(index, payload)
368
    loadConstantOrVariablePayloadTagCustom(
369
        index,
370
        macro (actualTag) end,
371
        payload)
372
end
373
374
macro writeBarrier(tag, payload)
375
    # Nothing to do, since we don't have a generational or incremental collector.
376
end
377
378
macro valueProfile(tag, payload, profile)
379
    storei tag, ValueProfile::m_buckets + TagOffset[profile]
380
    storei payload, ValueProfile::m_buckets + PayloadOffset[profile]
381
end
382
383
384
# Indicate the beginning of LLInt.
385
_llint_begin:
386
    crash()
387
388
389
# Entrypoints into the interpreter
390
391
macro functionForCallCodeBlockGetter(targetRegister)
392
    loadp Callee[cfr], targetRegister
393
    loadp JSFunction::m_executable[targetRegister], targetRegister
394
    loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
395
end
396
397
macro functionForConstructCodeBlockGetter(targetRegister)
398
    loadp Callee[cfr], targetRegister
399
    loadp JSFunction::m_executable[targetRegister], targetRegister
400
    loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
401
end
402
403
macro notFunctionCodeBlockGetter(targetRegister)
404
    loadp CodeBlock[cfr], targetRegister
405
end
406
407
macro functionCodeBlockSetter(sourceRegister)
408
    storep sourceRegister, CodeBlock[cfr]
409
end
410
411
macro notFunctionCodeBlockSetter(sourceRegister)
412
    # Nothing to do!
413
end
414
415
# Do the bare minimum required to execute code. Sets up the PC, leave the CodeBlock*
416
# in t1. May also trigger prologue entry OSR.
417
macro prologue(codeBlockGetter, codeBlockSetter, osrHelper, traceHelper)
418
    preserveReturnAddressAfterCall(t2)
419
    
420
    # Set up the call frame and check if we should OSR.
421
    storep t2, ReturnPC[cfr]
422
    if EXECUTION_TRACING
423
        callHelper(traceHelper)
424
    end
425
    codeBlockGetter(t1)
426
    if JIT_ENABLED
427
        baddis 5, CodeBlock::m_llintExecuteCounter[t1], .continue
428
        cCall2(osrHelper, cfr, PC)
429
        move t1, cfr
430
        btpz t0, .recover
431
        loadp ReturnPC[cfr], t2
432
        restoreReturnAddressBeforeReturn(t2)
433
        jmp t0
434
    .recover:
435
        codeBlockGetter(t1)
436
    .continue:
437
    end
438
    codeBlockSetter(t1)
439
    
440
    # Set up the PC.
441
    loadp CodeBlock::m_instructions[t1], t0
442
    loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
443
end
444
445
# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
446
# Must call dispatch(0) after calling this.
447
macro functionInitialization(profileArgSkip)
448
    # Profile the arguments. Unfortunately, we have no choice but to do this. This
449
    # code is pretty horrendous because of the difference in ordering between
450
    # arguments and value profiles, the desire to have a simple loop-down-to-zero
451
    # loop, and the desire to use only three registers so as to preserve the PC and
452
    # the code block. It is likely that this code should be rewritten in a more
453
    # optimal way for architectures that have more than five registers available
454
    # for arbitrary use in the interpreter.
455
    loadi CodeBlock::m_numParameters[t1], t0
456
    addi -profileArgSkip, t0 # Use addi because that's what has the peephole
457
    assert(macro (ok) bigteq t0, 0, ok end)
458
    btiz t0, .argumentProfileDone
459
    loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
460
    muli sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
461
    negi t0
462
    lshifti 3, t0
463
    addp t2, t3
464
.argumentProfileLoop:
465
    loadi ThisArgumentOffset + TagOffset + 8 - profileArgSkip * 8[cfr, t0], t2
466
    subp sizeof ValueProfile, t3
467
    storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
468
    loadi ThisArgumentOffset + PayloadOffset + 8 - profileArgSkip * 8[cfr, t0], t2
469
    storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
470
    baddinz 8, t0, .argumentProfileLoop
471
.argumentProfileDone:
472
    
473
    # Check stack height.
474
    loadi CodeBlock::m_numCalleeRegisters[t1], t0
475
    loadp CodeBlock::m_globalData[t1], t2
476
    loadp JSGlobalData::interpreter[t2], t2   # FIXME: Can get to the RegisterFile from the JITStackFrame
477
    lshifti 3, t0
478
    addp t0, cfr, t0
479
    bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK
480
481
    # Stack height check failed - need to call a helper.
482
    callHelper(_llint_register_file_check)
483
.stackHeightOK:
484
end
485
486
# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
487
macro functionArityCheck(doneLabel, helper)
488
    loadi PayloadOffset + ArgumentCount[cfr], t0
489
    biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
490
    cCall2(helper, cfr, PC)   # This helper has a simple protocol: t0 = 0 => no error, t0 != 0 => error
491
    move t1, cfr
492
    btiz t0, .continue
493
    loadp JITStackFrame::globalData[sp], t1
494
    loadp JSGlobalData::callFrameForThrow[t1], t0
495
    jmp JSGlobalData::targetMachinePCForThrow[t1]
496
.continue:
497
    # Reload CodeBlock and PC, since the helper clobbered it.
498
    loadp CodeBlock[cfr], t1
499
    loadp CodeBlock::m_instructions[t1], t0
500
    loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
501
    jmp doneLabel
502
end
503
504
_llint_program_prologue:
505
    prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
506
    dispatch(0)
507
508
509
_llint_eval_prologue:
510
    prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
511
    dispatch(0)
512
513
514
_llint_function_for_call_prologue:
515
    prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call)
516
.functionForCallBegin:
517
    functionInitialization(0)
518
    dispatch(0)
519
    
520
521
_llint_function_for_construct_prologue:
522
    prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct)
523
.functionForConstructBegin:
524
    functionInitialization(1)
525
    dispatch(0)
526
    
527
528
_llint_function_for_call_arity_check:
529
    prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call)
530
    functionArityCheck(.functionForCallBegin, _llint_helper_call_arityCheck)
531
532
533
_llint_function_for_construct_arity_check:
534
    prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct)
535
    functionArityCheck(.functionForConstructBegin, _llint_helper_construct_arityCheck)
536
537
# Instruction implementations
538
539
_llint_op_enter:
540
    traceExecution()
541
    loadp CodeBlock[cfr], t2
542
    loadi CodeBlock::m_numVars[t2], t2
543
    btiz t2, .opEnterDone
544
    move UndefinedTag, t0
545
    move 0, t1
546
.opEnterLoop:
547
    subi 1, t2
548
    storei t0, TagOffset[cfr, t2, 8]
549
    storei t1, PayloadOffset[cfr, t2, 8]
550
    btinz t2, .opEnterLoop
551
.opEnterDone:
552
    dispatch(1)
553
554
555
_llint_op_create_activation:
556
    traceExecution()
557
    loadi 4[PC], t0
558
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateActivationDone
559
    callHelper(_llint_helper_create_activation)
560
.opCreateActivationDone:
561
    dispatch(2)
562
563
564
_llint_op_init_lazy_reg:
565
    traceExecution()
566
    loadi 4[PC], t0
567
    storei EmptyValueTag, TagOffset[cfr, t0, 8]
568
    storei 0, PayloadOffset[cfr, t0, 8]
569
    dispatch(2)
570
571
572
_llint_op_create_arguments:
573
    traceExecution()
574
    loadi 4[PC], t0
575
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
576
    callHelper(_llint_helper_create_arguments)
577
.opCreateArgumentsDone:
578
    dispatch(2)
579
580
581
macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result, scratch1, scratch2, slowCase)
582
    const offsetOfMySizeClass = JSGlobalData::heap + Heap::m_objectSpace + AllocationSpace::m_markedSpace + MarkedSpace::m_preciseSizeClasses + sizeClassIndex * sizeof MarkedSpace::SizeClass
583
    
584
    # FIXME: we can get the global data in one load from the stack.
585
    loadp CodeBlock[cfr], scratch1
586
    loadp CodeBlock::m_globalData[scratch1], scratch1
587
    
588
    # Get the object from the free list.    
589
    loadp offsetOfMySizeClass + MarkedSpace::SizeClass::firstFreeCell[scratch1], result
590
    btpz result, slowCase
591
    
592
    # Remove the object from the free list.
593
    loadp [result], scratch2
594
    storep scratch2, offsetOfMySizeClass + MarkedSpace::SizeClass::firstFreeCell[scratch1]
595
596
    # Initialize the object.
597
    loadp classInfoOffset[scratch1], scratch2
598
    storep scratch2, [result]
599
    storep structure, JSCell::m_structure[result]
600
    storep 0, JSObject::m_inheritorID[result]
601
    addp sizeof JSObject, result, scratch1
602
    storep scratch1, JSObject::m_propertyStorage[result]
603
end
604
605
_llint_op_create_this:
606
    traceExecution()
607
    loadi 8[PC], t0
608
    assertNotConstant(t0)
609
    bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow
610
    loadi PayloadOffset[cfr, t0, 8], t0
611
    loadp JSCell::m_structure[t0], t1
612
    bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
613
    loadp JSObject::m_inheritorID[t0], t2
614
    btpz t2, .opCreateThisSlow
615
    allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
616
    loadi 4[PC], t1
617
    storei CellTag, TagOffset[cfr, t1, 8]
618
    storei t0, PayloadOffset[cfr, t1, 8]
619
    dispatch(3)
620
621
.opCreateThisSlow:
622
    callHelper(_llint_helper_create_this)
623
    dispatch(3)
624
625
626
_llint_op_get_callee:
627
    traceExecution()
628
    loadi 4[PC], t0
629
    loadp PayloadOffset + Callee[cfr], t1
630
    storei CellTag, TagOffset[cfr, t0, 8]
631
    storei t1, PayloadOffset[cfr, t0, 8]
632
    dispatch(2)
633
634
635
_llint_op_convert_this:
636
    traceExecution()
637
    loadi 4[PC], t0
638
    bineq TagOffset[cfr, t0, 8], CellTag, .opConvertThisSlow
639
    loadi PayloadOffset[cfr, t0, 8], t0
640
    loadp JSCell::m_structure[t0], t0
641
    bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
642
    dispatch(2)
643
644
.opConvertThisSlow:
645
    callHelper(_llint_helper_convert_this)
646
    dispatch(2)
647
648
649
_llint_op_new_object:
650
    traceExecution()
651
    loadp CodeBlock[cfr], t0
652
    loadp CodeBlock::m_globalObject[t0], t0
653
    loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
654
    allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
655
    loadi 4[PC], t1
656
    storei CellTag, TagOffset[cfr, t1, 8]
657
    storei t0, PayloadOffset[cfr, t1, 8]
658
    dispatch(2)
659
660
.opNewObjectSlow:
661
    callHelper(_llint_helper_new_object)
662
    dispatch(2)
663
664
665
_llint_op_new_array:
666
    traceExecution()
667
    callHelper(_llint_helper_new_array)
668
    dispatch(4)
669
670
671
_llint_op_new_array_buffer:
672
    traceExecution()
673
    callHelper(_llint_helper_new_array_buffer)
674
    dispatch(4)
675
676
677
_llint_op_new_regexp:
678
    traceExecution()
679
    callHelper(_llint_helper_new_regexp)
680
    dispatch(3)
681
682
683
_llint_op_mov:
684
    traceExecution()
685
    loadi 8[PC], t1
686
    loadi 4[PC], t0
687
    loadConstantOrVariable(t1, t2, t3)
688
    storei t2, TagOffset[cfr, t0, 8]
689
    storei t3, PayloadOffset[cfr, t0, 8]
690
    dispatch(3)
691
692
693
_llint_op_not:
694
    traceExecution()
695
    loadi 8[PC], t0
696
    loadi 4[PC], t1
697
    loadConstantOrVariable(t0, t2, t3)
698
    bineq t2, BooleanTag, .opNotSlow
699
    xori 1, t3
700
    storei t2, TagOffset[cfr, t1, 8]
701
    storei t3, PayloadOffset[cfr, t1, 8]
702
    dispatch(3)
703
704
.opNotSlow:
705
    callHelper(_llint_helper_not)
706
    dispatch(3)
707
708
709
_llint_op_eq:
710
    traceExecution()
711
    loadi 12[PC], t2
712
    loadi 8[PC], t0
713
    loadConstantOrVariable(t2, t3, t1)
714
    loadConstantOrVariable2Reg(t0, t2, t0)
715
    bineq t2, t3, .opEqSlow
716
    bieq t2, CellTag, .opEqSlow
717
    bib t2, LowestTag, .opEqSlow
718
    loadi 4[PC], t2
719
    cieq t0, t1, t0
720
    storei BooleanTag, TagOffset[cfr, t2, 8]
721
    storei t0, PayloadOffset[cfr, t2, 8]
722
    dispatch(4)
723
724
.opEqSlow:
725
    callHelper(_llint_helper_eq)
726
    dispatch(4)
727
728
729
_llint_op_eq_null:
730
    traceExecution()
731
    loadi 8[PC], t0
732
    loadi 4[PC], t3
733
    assertNotConstant(t0)
734
    loadi TagOffset[cfr, t0, 8], t1
735
    loadi PayloadOffset[cfr, t0, 8], t0
736
    bineq t1, CellTag, .opEqNullImmediate
737
    loadp JSCell::m_structure[t0], t1
738
    tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
739
    jmp .opEqNullNotImmediate
740
.opEqNullImmediate:
741
    cieq t1, NullTag, t2
742
    cieq t1, UndefinedTag, t1
743
    ori t2, t1
744
.opEqNullNotImmediate:
745
    storei BooleanTag, TagOffset[cfr, t3, 8]
746
    storei t1, PayloadOffset[cfr, t3, 8]
747
    dispatch(3)
748
749
750
_llint_op_neq:
751
    traceExecution()
752
    loadi 12[PC], t2
753
    loadi 8[PC], t0
754
    loadConstantOrVariable(t2, t3, t1)
755
    loadConstantOrVariable2Reg(t0, t2, t0)
756
    bineq t2, t3, .opNeqSlow
757
    bieq t2, CellTag, .opNeqSlow
758
    bib t2, LowestTag, .opNeqSlow
759
    loadi 4[PC], t2
760
    cineq t0, t1, t0
761
    storei BooleanTag, TagOffset[cfr, t2, 8]
762
    storei t0, PayloadOffset[cfr, t2, 8]
763
    dispatch(4)
764
765
.opNeqSlow:
766
    callHelper(_llint_helper_neq)
767
    dispatch(4)
768
    
769
770
_llint_op_neq_null:
771
    traceExecution()
772
    loadi 8[PC], t0
773
    loadi 4[PC], t3
774
    assertNotConstant(t0)
775
    loadi TagOffset[cfr, t0, 8], t1
776
    loadi PayloadOffset[cfr, t0, 8], t0
777
    bineq t1, CellTag, .opNeqNullImmediate
778
    loadp JSCell::m_structure[t0], t1
779
    tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
780
    jmp .opNeqNullNotImmediate
781
.opNeqNullImmediate:
782
    cineq t1, NullTag, t2
783
    cineq t1, UndefinedTag, t1
784
    andi t2, t1
785
.opNeqNullNotImmediate:
786
    storei BooleanTag, TagOffset[cfr, t3, 8]
787
    storei t1, PayloadOffset[cfr, t3, 8]
788
    dispatch(3)
789
790
791
macro strictEq(equalityOperation, helper)
792
    loadi 12[PC], t2
793
    loadi 8[PC], t0
794
    loadConstantOrVariable(t2, t3, t1)
795
    loadConstantOrVariable2Reg(t0, t2, t0)
796
    bineq t2, t3, .slow
797
    bib t2, LowestTag, .slow
798
    bineq t2, CellTag, .notString
799
    loadp JSCell::m_structure[t0], t2
800
    loadp JSCell::m_structure[t1], t3
801
    bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .notString
802
    bbeq Structure::m_typeInfo + TypeInfo::m_type[t3], StringType, .slow
803
.notString:
804
    loadi 4[PC], t2
805
    equalityOperation(t0, t1, t0)
806
    storei BooleanTag, TagOffset[cfr, t2, 8]
807
    storei t0, PayloadOffset[cfr, t2, 8]
808
    dispatch(4)
809
810
.slow:
811
    callHelper(helper)
812
    dispatch(4)
813
end
814
815
_llint_op_stricteq:
816
    traceExecution()
817
    strictEq(macro (left, right, result) cieq left, right, result end, _llint_helper_stricteq)
818
819
820
_llint_op_nstricteq:
821
    traceExecution()
822
    strictEq(macro (left, right, result) cineq left, right, result end, _llint_helper_nstricteq)
823
824
825
_llint_op_less:
826
    traceExecution()
827
    callHelper(_llint_helper_less)
828
    dispatch(4)
829
830
831
_llint_op_lesseq:
832
    traceExecution()
833
    callHelper(_llint_helper_lesseq)
834
    dispatch(4)
835
836
837
_llint_op_greater:
838
    traceExecution()
839
    callHelper(_llint_helper_greater)
840
    dispatch(4)
841
842
843
_llint_op_greatereq:
844
    traceExecution()
845
    callHelper(_llint_helper_greatereq)
846
    dispatch(4)
847
848
849
_llint_op_pre_inc:
850
    traceExecution()
851
    loadi 4[PC], t0
852
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
853
    loadi PayloadOffset[cfr, t0, 8], t1
854
    baddio 1, t1, .opPreIncSlow
855
    storei t1, PayloadOffset[cfr, t0, 8]
856
    dispatch(2)
857
858
.opPreIncSlow:
859
    callHelper(_llint_helper_pre_inc)
860
    dispatch(2)
861
862
863
_llint_op_pre_dec:
864
    traceExecution()
865
    loadi 4[PC], t0
866
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
867
    loadi PayloadOffset[cfr, t0, 8], t1
868
    bsubio 1, t1, .opPreDecSlow
869
    storei t1, PayloadOffset[cfr, t0, 8]
870
    dispatch(2)
871
872
.opPreDecSlow:
873
    callHelper(_llint_helper_pre_dec)
874
    dispatch(2)
875
876
877
_llint_op_post_inc:
878
    traceExecution()
879
    loadi 8[PC], t0
880
    loadi 4[PC], t1
881
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
882
    bieq t0, t1, .opPostIncDone
883
    loadi PayloadOffset[cfr, t0, 8], t2
884
    move t2, t3
885
    baddio 1, t3, .opPostIncSlow
886
    storei Int32Tag, TagOffset[cfr, t1, 8]
887
    storei t2, PayloadOffset[cfr, t1, 8]
888
    storei t3, PayloadOffset[cfr, t0, 8]
889
.opPostIncDone:
890
    dispatch(3)
891
892
.opPostIncSlow:
893
    callHelper(_llint_helper_post_inc)
894
    dispatch(3)
895
896
897
_llint_op_post_dec:
898
    traceExecution()
899
    loadi 8[PC], t0
900
    loadi 4[PC], t1
901
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
902
    bieq t0, t1, .opPostDecDone
903
    loadi PayloadOffset[cfr, t0, 8], t2
904
    move t2, t3
905
    bsubio 1, t3, .opPostDecSlow
906
    storei Int32Tag, TagOffset[cfr, t1, 8]
907
    storei t2, PayloadOffset[cfr, t1, 8]
908
    storei t3, PayloadOffset[cfr, t0, 8]
909
.opPostDecDone:
910
    dispatch(3)
911
912
.opPostDecSlow:
913
    callHelper(_llint_helper_post_dec)
914
    dispatch(3)
915
916
917
_llint_op_to_jsnumber:
918
    traceExecution()
919
    loadi 8[PC], t0
920
    loadi 4[PC], t1
921
    loadConstantOrVariable(t0, t2, t3)
922
    bieq t2, Int32Tag, .opToJsnumberIsInt
923
    biaeq t2, EmptyValueTag, .opToJsnumberSlow
924
.opToJsnumberIsInt:
925
    storei t2, TagOffset[cfr, t1, 8]
926
    storei t3, PayloadOffset[cfr, t1, 8]
927
    dispatch(3)
928
929
.opToJsnumberSlow:
930
    callHelper(_llint_helper_to_jsnumber)
931
    dispatch(3)
932
933
934
_llint_op_negate:
935
    traceExecution()
936
    loadi 8[PC], t0
937
    loadi 4[PC], t3
938
    loadConstantOrVariable(t0, t1, t2)
939
    bineq t1, Int32Tag, .opNegateSrcNotInt
940
    btiz t2, 0x7fffffff, .opNegateSlow
941
    negi t2
942
    storei Int32Tag, TagOffset[cfr, t3, 8]
943
    storei t2, PayloadOffset[cfr, t3, 8]
944
    dispatch(3)
945
.opNegateSrcNotInt:
946
    bia t1, LowestTag, .opNegateSlow
947
    xori 0x80000000, t1
948
    storei t1, TagOffset[cfr, t3, 8]
949
    storei t2, PayloadOffset[cfr, t3, 8]
950
    dispatch(3)
951
952
.opNegateSlow:
953
    callHelper(_llint_helper_negate)
954
    dispatch(3)
955
956
957
macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, helper)
958
    loadi 12[PC], t2
959
    loadi 8[PC], t0
960
    loadConstantOrVariable(t2, t3, t1)
961
    loadConstantOrVariable2Reg(t0, t2, t0)
962
    bineq t2, Int32Tag, .op1NotInt
963
    bineq t3, Int32Tag, .op2NotInt
964
    loadi 4[PC], t2
965
    integerOperationAndStore(t3, t1, t0, .slow, t2)
966
    dispatch(5)
967
968
.op1NotInt:
969
    # First operand is definitely not an int, the second operand could be anything.
970
    bia t2, LowestTag, .slow
971
    bib t3, LowestTag, .op1NotIntOp2Double
972
    bineq t3, Int32Tag, .slow
973
    ci2d t1, ft1
974
    jmp .op1NotIntReady
975
.op1NotIntOp2Double:
976
    fii2d t1, t3, ft1
977
.op1NotIntReady:
978
    loadi 4[PC], t1
979
    fii2d t0, t2, ft0
980
    doubleOperation(ft1, ft0)
981
    stored ft0, [cfr, t1, 8]
982
    dispatch(5)
983
984
.op2NotInt:
985
    # First operand is definitely an int, the second operand is definitely not.
986
    loadi 4[PC], t2
987
    bia t3, LowestTag, .slow
988
    ci2d t0, ft0
989
    fii2d t1, t3, ft1
990
    doubleOperation(ft1, ft0)
991
    stored ft0, [cfr, t2, 8]
992
    dispatch(5)
993
994
.slow:
995
    callHelper(helper)
996
    dispatch(5)
997
end
998
999
macro binaryOp(integerOperation, doubleOperation, helper)
1000
    binaryOpCustomStore(
1001
        macro (int32Tag, left, right, slow, index)
1002
            integerOperation(left, right, slow)
1003
            storei int32Tag, TagOffset[cfr, index, 8]
1004
            storei right, PayloadOffset[cfr, index, 8]
1005
        end,
1006
        doubleOperation, helper)
1007
end
1008
1009
_llint_op_add:
1010
    traceExecution()
1011
    binaryOp(
1012
        macro (left, right, slow) baddio left, right, slow end,
1013
        macro (left, right) addd left, right end,
1014
        _llint_helper_add)
1015
1016
1017
_llint_op_mul:
1018
    traceExecution()
1019
    binaryOpCustomStore(
1020
        macro (int32Tag, left, right, slow, index)
1021
            const scratch = int32Tag   # We know that we can reuse the int32Tag register since it has a constant.
1022
            move right, scratch
1023
            bmulio left, scratch, slow
1024
            btinz scratch, .done
1025
            bilt left, 0, .slow
1026
            bilt right, 0, .slow
1027
        .done:
1028
            storei Int32Tag, TagOffset[cfr, index, 8]
1029
            storei scratch, PayloadOffset[cfr, index, 8]
1030
        end,
1031
        macro (left, right) muld left, right end,
1032
        _llint_helper_mul)
1033
1034
1035
_llint_op_sub:
1036
    traceExecution()
1037
    binaryOp(
1038
        macro (left, right, slow) bsubio left, right, slow end,
1039
        macro (left, right) subd left, right end,
1040
        _llint_helper_sub)
1041
1042
1043
_llint_op_div:
1044
    traceExecution()
1045
    binaryOpCustomStore(
1046
        macro (int32Tag, left, right, slow, index)
1047
            ci2d left, ft0
1048
            ci2d right, ft1
1049
            divd ft0, ft1
1050
            bcd2i ft1, right, .notInt
1051
            storei int32Tag, TagOffset[cfr, index, 8]
1052
            storei right, PayloadOffset[cfr, index, 8]
1053
            jmp .done
1054
        .notInt:
1055
            stored ft1, [cfr, index, 8]
1056
        .done:
1057
        end,
1058
        macro (left, right) divd left, right end,
1059
        _llint_helper_div)
1060
1061
1062
_llint_op_mod:
1063
    traceExecution()
1064
    callHelper(_llint_helper_mod)
1065
    dispatch(4)
1066
1067
1068
macro bitOp(operation, helper, advance)
1069
    loadi 12[PC], t2
1070
    loadi 8[PC], t0
1071
    loadConstantOrVariable(t2, t3, t1)
1072
    loadConstantOrVariable2Reg(t0, t2, t0)
1073
    bineq t3, Int32Tag, .slow
1074
    bineq t2, Int32Tag, .slow
1075
    loadi 4[PC], t2
1076
    operation(t1, t0, .slow)
1077
    storei t3, TagOffset[cfr, t2, 8]
1078
    storei t0, PayloadOffset[cfr, t2, 8]
1079
    dispatch(advance)
1080
1081
.slow:
1082
    callHelper(helper)
1083
    dispatch(advance)
1084
end
1085
1086
_llint_op_lshift:
1087
    traceExecution()
1088
    bitOp(
1089
        macro (left, right, slow) lshifti left, right end,
1090
        _llint_helper_lshift,
1091
        4)
1092
1093
1094
_llint_op_rshift:
1095
    traceExecution()
1096
    bitOp(
1097
        macro (left, right, slow) rshifti left, right end,
1098
        _llint_helper_rshift,
1099
        4)
1100
1101
1102
_llint_op_urshift:
1103
    traceExecution()
1104
    bitOp(
1105
        macro (left, right, slow)
1106
            urshifti left, right
1107
            bilt right, 0, slow
1108
        end,
1109
        _llint_helper_urshift,
1110
        4)
1111
1112
1113
_llint_op_bitand:
1114
    traceExecution()
1115
    bitOp(
1116
        macro (left, right, slow) andi left, right end,
1117
        _llint_helper_bitand,
1118
        5)
1119
1120
1121
_llint_op_bitxor:
1122
    traceExecution()
1123
    bitOp(
1124
        macro (left, right, slow) xori left, right end,
1125
        _llint_helper_bitxor,
1126
        5)
1127
1128
1129
_llint_op_bitor:
1130
    traceExecution()
1131
    bitOp(
1132
        macro (left, right, slow) ori left, right end,
1133
        _llint_helper_bitor,
1134
        5)
1135
1136
1137
_llint_op_bitnot:
1138
    traceExecution()
1139
    loadi 8[PC], t1
1140
    loadi 4[PC], t0
1141
    loadConstantOrVariable(t1, t2, t3)
1142
    bineq t2, Int32Tag, .opBitnotSlow
1143
    noti t3
1144
    storei t2, TagOffset[cfr, t0, 8]
1145
    storei t3, PayloadOffset[cfr, t0, 8]
1146
    dispatch(3)
1147
1148
.opBitnotSlow:
1149
    callHelper(_llint_helper_bitnot)
1150
    dispatch(3)
1151
1152
1153
_llint_op_check_has_instance:
1154
    traceExecution()
1155
    loadi 4[PC], t1
1156
    loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
1157
    loadp JSCell::m_structure[t0], t0
1158
    btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
1159
    dispatch(2)
1160
1161
.opCheckHasInstanceSlow:
1162
    callHelper(_llint_helper_check_has_instance)
1163
    dispatch(2)
1164
1165
1166
_llint_op_instanceof:
1167
    traceExecution()
1168
    # Check that baseVal implements the default HasInstance behavior.
1169
    # FIXME: This should be deprecated.
1170
    loadi 12[PC], t1
1171
    loadConstantOrVariablePayloadUnchecked(t1, t0)
1172
    loadp JSCell::m_structure[t0], t0
1173
    btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
1174
    
1175
    # Actually do the work.
1176
    loadi 16[PC], t0
1177
    loadi 4[PC], t3
1178
    loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
1179
    loadp JSCell::m_structure[t1], t2
1180
    bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
1181
    loadi 8[PC], t0
1182
    loadConstantOrVariablePayload(t0, CellTag, t2, .opInstanceofSlow)
1183
    
1184
    # Register state: t1 = prototype, t2 = value
1185
    move 1, t0
1186
.opInstanceofLoop:
1187
    loadp JSCell::m_structure[t2], t2
1188
    loadi Structure::m_prototype + PayloadOffset[t2], t2
1189
    bpeq t2, t1, .opInstanceofDone
1190
    btinz t2, .opInstanceofLoop
1191
1192
    move 0, t0
1193
.opInstanceofDone:
1194
    storei BooleanTag, TagOffset[cfr, t3, 8]
1195
    storei t0, PayloadOffset[cfr, t3, 8]
1196
    dispatch(5)
1197
1198
.opInstanceofSlow:
1199
    callHelper(_llint_helper_instanceof)
1200
    dispatch(5)
1201
1202
1203
_llint_op_typeof:
1204
    traceExecution()
1205
    callHelper(_llint_helper_typeof)
1206
    dispatch(3)
1207
1208
1209
_llint_op_is_undefined:
1210
    traceExecution()
1211
    callHelper(_llint_helper_is_undefined)
1212
    dispatch(3)
1213
1214
1215
_llint_op_is_boolean:
1216
    traceExecution()
1217
    callHelper(_llint_helper_is_boolean)
1218
    dispatch(3)
1219
1220
1221
_llint_op_is_number:
1222
    traceExecution()
1223
    callHelper(_llint_helper_is_number)
1224
    dispatch(3)
1225
1226
1227
_llint_op_is_string:
1228
    traceExecution()
1229
    callHelper(_llint_helper_is_string)
1230
    dispatch(3)
1231
1232
1233
_llint_op_is_object:
1234
    traceExecution()
1235
    callHelper(_llint_helper_is_object)
1236
    dispatch(3)
1237
1238
1239
_llint_op_is_function:
1240
    traceExecution()
1241
    callHelper(_llint_helper_is_function)
1242
    dispatch(3)
1243
1244
1245
_llint_op_in:
1246
    traceExecution()
1247
    callHelper(_llint_helper_in)
1248
    dispatch(4)
1249
1250
1251
_llint_op_resolve:
1252
    traceExecution()
1253
    callHelper(_llint_helper_resolve)
1254
    dispatch(4)
1255
1256
1257
_llint_op_resolve_skip:
1258
    traceExecution()
1259
    callHelper(_llint_helper_resolve_skip)
1260
    dispatch(5)
1261
1262
1263
macro resolveGlobal(size, slow)
1264
    # Operands are as follows:
1265
    # 4[PC]   Destination for the load.
1266
    # 8[PC]   Property identifier index in the code block.
1267
    # 12[PC]  Structure pointer, initialized to 0 by bytecode generator.
1268
    # 16[PC]  Offset in global object, initialized to 0 by bytecode generator.
1269
    loadp CodeBlock[cfr], t0
1270
    loadp CodeBlock::m_globalObject[t0], t0
1271
    loadp JSCell::m_structure[t0], t1
1272
    bpneq t1, 12[PC], slow
1273
    loadi 16[PC], t1
1274
    loadp JSObject::m_propertyStorage[t0], t0
1275
    loadi TagOffset[t0, t1, 8], t2
1276
    loadi PayloadOffset[t0, t1, 8], t3
1277
    loadi 4[PC], t0
1278
    storei t2, TagOffset[cfr, t0, 8]
1279
    storei t3, PayloadOffset[cfr, t0, 8]
1280
    loadi (size - 1) * 4[PC], t0
1281
    valueProfile(t2, t3, t0)
1282
end
1283
1284
_llint_op_resolve_global:
1285
    traceExecution()
1286
    resolveGlobal(6, .opResolveGlobalSlow)
1287
    dispatch(6)
1288
1289
.opResolveGlobalSlow:
1290
    callHelper(_llint_helper_resolve_global)
1291
    dispatch(6)
1292
1293
1294
# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
1295
# scopes as they are traversed. scopeCheck() is called with two arguments: the register
1296
# holding the scope, and a register that can be used for scratch. Note that this does not
1297
# use t3, so you can hold stuff in t3 if need be.
1298
macro getScope(deBruijinIndexOperand, scopeCheck)
1299
    loadp ScopeChain + PayloadOffset[cfr], t0
1300
    loadi deBruijinIndexOperand, t2
1301
    
1302
    btiz t2, .done
1303
    
1304
    loadp CodeBlock[cfr], t1
1305
    bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
1306
    btbz CodeBlock::m_needsFullScopeChain[t1], .loop
1307
    
1308
    loadi CodeBlock::m_activationRegister[t1], t1
1309
1310
    # Need to conditionally skip over one scope.
1311
    bieq TagOffset[cfr, t1, 8], EmptyValueTag, .noActivation
1312
    scopeCheck(t0, t1)
1313
    loadp ScopeChainNode::next[t0], t0
1314
.noActivation:
1315
    subi 1, t2
1316
    
1317
    btiz t2, .done
1318
.loop:
1319
    scopeCheck(t0, t1)
1320
    loadp ScopeChainNode::next[t0], t0
1321
    subi 1, t2
1322
    btinz t2, .loop
1323
1324
.done:
1325
end
1326
1327
_llint_op_resolve_global_dynamic:
1328
    traceExecution()
1329
    loadp JITStackFrame::globalData[sp], t3
1330
    loadp JSGlobalData::activationStructure[t3], t3
1331
    getScope(
1332
        20[PC],
1333
        macro (scope, scratch)
1334
            loadp ScopeChainNode::object[scope], scratch
1335
            bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
1336
        end)
1337
    resolveGlobal(7, .opResolveGlobalDynamicSlow)
1338
    dispatch(7)
1339
1340
.opResolveGlobalDynamicSuperSlow:
1341
    callHelper(_llint_helper_resolve_for_resolve_global_dynamic)
1342
    dispatch(7)
1343
1344
.opResolveGlobalDynamicSlow:
1345
    callHelper(_llint_helper_resolve_global_dynamic)
1346
    dispatch(7)
1347
1348
1349
_llint_op_get_scoped_var:
1350
    traceExecution()
1351
    # Operands are as follows:
1352
    # 4[PC]   Destination for the load.
1353
    # 8[PC]   Index of register in the scope.
1354
    # 12[PC]  De Bruijin index.
1355
    getScope(12[PC], macro (scope, scratch) end)
1356
    loadi 4[PC], t1
1357
    loadi 8[PC], t2
1358
    loadp ScopeChainNode::object[t0], t0
1359
    loadp JSVariableObject::m_registers[t0], t0
1360
    loadi TagOffset[t0, t2, 8], t3
1361
    loadi PayloadOffset[t0, t2, 8], t0
1362
    storei t3, TagOffset[cfr, t1, 8]
1363
    storei t0, PayloadOffset[cfr, t1, 8]
1364
    loadi 16[PC], t1
1365
    valueProfile(t3, t0, t1)
1366
    dispatch(5)
1367
1368
1369
_llint_op_put_scoped_var:
1370
    traceExecution()
1371
    getScope(8[PC], macro (scope, scratch) end)
1372
    loadi 12[PC], t1
1373
    loadConstantOrVariable(t1, t3, t2)
1374
    loadi 4[PC], t1
1375
    writeBarrier(t3, t2)
1376
    loadp ScopeChainNode::object[t0], t0
1377
    loadp JSVariableObject::m_registers[t0], t0
1378
    storei t3, TagOffset[t0, t1, 8]
1379
    storei t2, PayloadOffset[t0, t1, 8]
1380
    dispatch(4)
1381
1382
1383
_llint_op_get_global_var:
1384
    traceExecution()
1385
    loadi 8[PC], t1
1386
    loadi 4[PC], t3
1387
    loadp CodeBlock[cfr], t0
1388
    loadp CodeBlock::m_globalObject[t0], t0
1389
    loadp JSGlobalObject::m_registers[t0], t0
1390
    loadi TagOffset[t0, t1, 8], t2
1391
    loadi PayloadOffset[t0, t1, 8], t1
1392
    storei t2, TagOffset[cfr, t3, 8]
1393
    storei t1, PayloadOffset[cfr, t3, 8]
1394
    loadi 12[PC], t3
1395
    valueProfile(t2, t1, t3)
1396
    dispatch(4)
1397
1398
1399
_llint_op_put_global_var:
1400
    traceExecution()
1401
    loadi 8[PC], t1
1402
    loadp CodeBlock[cfr], t0
1403
    loadp CodeBlock::m_globalObject[t0], t0
1404
    loadp JSGlobalObject::m_registers[t0], t0
1405
    loadConstantOrVariable(t1, t2, t3)
1406
    loadi 4[PC], t1
1407
    writeBarrier(t2, t3)
1408
    storei t2, TagOffset[t0, t1, 8]
1409
    storei t3, PayloadOffset[t0, t1, 8]
1410
    dispatch(3)
1411
1412
1413
_llint_op_resolve_base:
1414
    traceExecution()
1415
    callHelper(_llint_helper_resolve_base)
1416
    dispatch(5)
1417
1418
1419
_llint_op_ensure_property_exists:
1420
    traceExecution()
1421
    callHelper(_llint_helper_ensure_property_exists)
1422
    dispatch(3)
1423
1424
1425
_llint_op_resolve_with_base:
1426
    traceExecution()
1427
    callHelper(_llint_helper_resolve_with_base)
1428
    dispatch(5)
1429
1430
1431
_llint_op_resolve_with_this:
1432
    traceExecution()
1433
    callHelper(_llint_helper_resolve_with_this)
1434
    dispatch(5)
1435
1436
1437
_llint_op_get_by_id:
1438
    traceExecution()
1439
    # We only do monomorphic get_by_id caching for now, and we do not modify the
1440
    # opcode. We do, however, allow for the cache to change anytime if fails, since
1441
    # ping-ponging is free. At best we get lucky and the get_by_id will continue
1442
    # to take fast path on the new cache. At worst we take slow path, which is what
1443
    # we would have been doing anyway.
1444
    loadi 8[PC], t0
1445
    loadi 16[PC], t1
1446
    loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
1447
    loadi 20[PC], t2
1448
    loadp JSObject::m_propertyStorage[t3], t0
1449
    bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
1450
    loadi 4[PC], t1
1451
    loadi TagOffset[t0, t2], t3
1452
    loadi PayloadOffset[t0, t2], t2
1453
    storei t3, TagOffset[cfr, t1, 8]
1454
    storei t2, PayloadOffset[cfr, t1, 8]
1455
    loadi 32[PC], t1
1456
    valueProfile(t3, t2, t1)
1457
    dispatch(9)
1458
1459
.opGetByIdSlow:
1460
    callHelper(_llint_helper_get_by_id)
1461
    dispatch(9)
1462
1463
1464
_llint_op_get_arguments_length:
1465
    traceExecution()
1466
    loadi 8[PC], t0
1467
    loadi 4[PC], t1
1468
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
1469
    loadi ArgumentCount + PayloadOffset[cfr], t2
1470
    subi 1, t2
1471
    storei Int32Tag, TagOffset[cfr, t1, 8]
1472
    storei t2, PayloadOffset[cfr, t1, 8]
1473
    dispatch(4)
1474
1475
.opGetArgumentsLengthSlow:
1476
    callHelper(_llint_helper_get_arguments_length)
1477
    dispatch(4)
1478
1479
1480
_llint_op_put_by_id:
1481
    traceExecution()
1482
    loadi 4[PC], t3
1483
    loadi 16[PC], t1
1484
    loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
1485
    loadi 12[PC], t2
1486
    loadp JSObject::m_propertyStorage[t0], t3
1487
    bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
1488
    loadi 20[PC], t1
1489
    loadConstantOrVariable2Reg(t2, t0, t2)
1490
    writeBarrier(t0, t2)
1491
    storei t0, TagOffset[t3, t1]
1492
    storei t2, PayloadOffset[t3, t1]
1493
    dispatch(9)
1494
1495
.opPutByIdSlow:
1496
    callHelper(_llint_helper_put_by_id)
1497
    dispatch(9)
1498
1499
1500
macro putByIdTransition(additionalChecks)
1501
    traceExecution()
1502
    loadi 4[PC], t3
1503
    loadi 16[PC], t1
1504
    loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
1505
    loadi 12[PC], t2
1506
    bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
1507
    additionalChecks(t1, t3, .opPutByIdSlow)
1508
    loadi 20[PC], t1
1509
    loadp JSObject::m_propertyStorage[t0], t3
1510
    addp t1, t3
1511
    loadConstantOrVariable2Reg(t2, t1, t2)
1512
    writeBarrier(t1, t2)
1513
    storei t1, TagOffset[t3]
1514
    loadi 24[PC], t1
1515
    storei t2, PayloadOffset[t3]
1516
    storep t1, JSCell::m_structure[t0]
1517
    dispatch(9)
1518
end
1519
1520
_llint_op_put_by_id_transition_direct:
1521
    putByIdTransition(macro (oldStructure, scratch, slow) end)
1522
1523
1524
_llint_op_put_by_id_transition_normal:
1525
    putByIdTransition(
1526
        macro (oldStructure, scratch, slow)
1527
            const protoCell = oldStructure   # Reusing the oldStructure register for the proto
1528
        
1529
            loadp 28[PC], scratch
1530
            assert(macro (ok) btpnz scratch, ok end)
1531
            loadp StructureChain::m_vector[scratch], scratch
1532
            assert(macro (ok) btpnz scratch, ok end)
1533
            bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
1534
        .loop:
1535
            loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
1536
            loadp JSCell::m_structure[protoCell], oldStructure
1537
            bpneq oldStructure, [scratch], slow
1538
            addp 4, scratch
1539
            bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
1540
        .done:
1541
        end)
1542
1543
1544
_llint_op_del_by_id:
1545
    traceExecution()
1546
    callHelper(_llint_helper_del_by_id)
1547
    dispatch(4)
1548
1549
1550
_llint_op_get_by_val:
1551
    traceExecution()
1552
    loadp CodeBlock[cfr], t1
1553
    loadi 8[PC], t2
1554
    loadi 12[PC], t3
1555
    loadp CodeBlock::m_globalData[t1], t1
1556
    loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
1557
    loadp JSGlobalData::jsArrayClassInfo[t1], t2
1558
    loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
1559
    bpneq [t0], t2, .opGetByValSlow
1560
    loadp JSArray::m_storage[t0], t3
1561
    biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
1562
    loadi 4[PC], t0
1563
    loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
1564
    loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
1565
    bieq t2, EmptyValueTag, .opGetByValSlow
1566
    storei t2, TagOffset[cfr, t0, 8]
1567
    storei t1, PayloadOffset[cfr, t0, 8]
1568
    loadi 16[PC], t0
1569
    valueProfile(t2, t1, t0)
1570
    dispatch(5)
1571
1572
.opGetByValSlow:
1573
    callHelper(_llint_helper_get_by_val)
1574
    dispatch(5)
1575
1576
1577
_llint_op_get_argument_by_val:
1578
    traceExecution()
1579
    loadi 8[PC], t0
1580
    loadi 12[PC], t1
1581
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
1582
    loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
1583
    addi 1, t2
1584
    loadi ArgumentCount + PayloadOffset[cfr], t1
1585
    biaeq t2, t1, .opGetArgumentByValSlow
1586
    negi t2
1587
    loadi 4[PC], t3
1588
    loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
1589
    loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1
1590
    storei t0, TagOffset[cfr, t3, 8]
1591
    storei t1, PayloadOffset[cfr, t3, 8]
1592
    dispatch(4)
1593
1594
.opGetArgumentByValSlow:
1595
    callHelper(_llint_helper_get_argument_by_val)
1596
    dispatch(4)
1597
1598
1599
_llint_op_get_by_pname:
1600
    traceExecution()
1601
    loadi 12[PC], t0
1602
    loadConstantOrVariablePayload(t0, CellTag, t1, .opGetByPnameSlow)
1603
    loadi 16[PC], t0
1604
    bpneq t1, PayloadOffset[cfr, t0, 8], .opGetByPnameSlow
1605
    loadi 8[PC], t0
1606
    loadConstantOrVariablePayload(t0, CellTag, t2, .opGetByPnameSlow)
1607
    loadi 20[PC], t0
1608
    loadi PayloadOffset[cfr, t0, 8], t3
1609
    loadp JSCell::m_structure[t2], t0
1610
    bpneq t0, JSPropertyNameIterator::m_cachedStructure[t3], .opGetByPnameSlow
1611
    loadi 24[PC], t0
1612
    loadi [cfr, t0, 8], t0
1613
    subi 1, t0
1614
    biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
1615
    loadp JSObject::m_propertyStorage[t2], t2
1616
    loadi TagOffset[t2, t0, 8], t1
1617
    loadi PayloadOffset[t2, t0, 8], t3
1618
    loadi 4[PC], t0
1619
    storei t1, TagOffset[cfr, t0, 8]
1620
    storei t3, PayloadOffset[cfr, t0, 8]
1621
    dispatch(7)
1622
1623
.opGetByPnameSlow:
1624
    callHelper(_llint_helper_get_by_pname)
1625
    dispatch(7)
1626
1627
1628
_llint_op_put_by_val:
1629
    traceExecution()
1630
    loadi 4[PC], t0
1631
    loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
1632
    loadi 8[PC], t0
1633
    loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
1634
    loadp CodeBlock[cfr], t0
1635
    loadp CodeBlock::m_globalData[t0], t0
1636
    loadp JSGlobalData::jsArrayClassInfo[t0], t0
1637
    bpneq [t1], t0, .opPutByValSlow
1638
    biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
1639
    loadp JSArray::m_storage[t1], t0
1640
    bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
1641
.opPutByValStoreResult:
1642
    loadi 12[PC], t3
1643
    loadConstantOrVariable2Reg(t3, t1, t3)
1644
    writeBarrier(t1, t3)
1645
    storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
1646
    storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
1647
    dispatch(4)
1648
1649
.opPutByValEmpty:
1650
    addi 1, ArrayStorage::m_numValuesInVector[t0]
1651
    bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
1652
    addi 1, t2, t1
1653
    storei t1, ArrayStorage::m_length[t0]
1654
    jmp .opPutByValStoreResult
1655
1656
.opPutByValSlow:
1657
    callHelper(_llint_helper_put_by_val)
1658
    dispatch(4)
1659
1660
1661
_llint_op_del_by_val:
1662
    traceExecution()
1663
    callHelper(_llint_helper_del_by_val)
1664
    dispatch(4)
1665
1666
1667
_llint_op_put_by_index:
1668
    traceExecution()
1669
    callHelper(_llint_helper_put_by_index)
1670
    dispatch(4)
1671
1672
1673
_llint_op_put_getter:
1674
    traceExecution()
1675
    callHelper(_llint_helper_put_getter)
1676
    dispatch(4)
1677
1678
1679
_llint_op_put_setter:
1680
    traceExecution()
1681
    callHelper(_llint_helper_put_setter)
1682
    dispatch(4)
1683
1684
1685
_llint_op_loop:
1686
    nop
1687
_llint_op_jmp:
1688
    traceExecution()
1689
    dispatchBranch(4[PC])
1690
1691
1692
_llint_op_jmp_scopes:
1693
    traceExecution()
1694
    callHelper(_llint_helper_jmp_scopes)
1695
    dispatch(0)
1696
1697
1698
macro jumpTrueOrFalse(conditionOp, slow)
1699
    loadi 4[PC], t1
1700
    loadConstantOrVariablePayload(t1, BooleanTag, t0, .slow)
1701
    conditionOp(t0, .target)
1702
    dispatch(3)
1703
1704
.target:
1705
    dispatchBranch(8[PC])
1706
1707
.slow:
1708
    callHelper(slow)
1709
    dispatch(0)
1710
end
1711
1712
_llint_op_loop_if_true:
1713
    nop
1714
_llint_op_jtrue:
1715
    traceExecution()
1716
    jumpTrueOrFalse(
1717
        macro (value, target) btinz value, target end,
1718
        _llint_helper_jtrue)
1719
1720
1721
_llint_op_loop_if_false:
1722
    nop
1723
_llint_op_jfalse:
1724
    traceExecution()
1725
    jumpTrueOrFalse(
1726
        macro (value, target) btiz value, target end,
1727
        _llint_helper_jfalse)
1728
1729
1730
macro equalNull(cellHandler, immediateHandler)
1731
    loadi 4[PC], t0
1732
    loadi TagOffset[cfr, t0, 8], t1
1733
    loadi PayloadOffset[cfr, t0, 8], t0
1734
    bineq t1, CellTag, .immediate
1735
    loadp JSCell::m_structure[t0], t2
1736
    cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
1737
    dispatch(3)
1738
1739
.target:
1740
    dispatchBranch(8[PC])
1741
1742
.immediate:
1743
    ori 1, t1
1744
    immediateHandler(t1, .target)
1745
    dispatch(3)
1746
end
1747
1748
_llint_op_jeq_null:
1749
    traceExecution()
1750
    equalNull(
1751
        macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
1752
        macro (value, target) bieq value, NullTag, target end)
1753
    
1754
1755
_llint_op_jneq_null:
1756
    traceExecution()
1757
    equalNull(
1758
        macro (value, target) btbz value, MasqueradesAsUndefined, target end,
1759
        macro (value, target) bineq value, NullTag, target end)
1760
1761
1762
_llint_op_jneq_ptr:
1763
    traceExecution()
1764
    loadi 4[PC], t0
1765
    loadi 8[PC], t1
1766
    bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
1767
    bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
1768
.opJneqPtrBranch:
1769
    dispatchBranch(12[PC])
1770
.opJneqPtrFallThrough:
1771
    dispatch(4)
1772
1773
1774
macro compare(integerCompare, doubleCompare, helper)
1775
    loadi 4[PC], t2
1776
    loadi 8[PC], t3
1777
    loadConstantOrVariable(t2, t0, t1)
1778
    loadConstantOrVariable2Reg(t3, t2, t3)
1779
    bineq t0, Int32Tag, .op1NotInt
1780
    bineq t2, Int32Tag, .op2NotInt
1781
    integerCompare(t1, t3, .jumpTarget)
1782
    dispatch(4)
1783
1784
.op1NotInt:
1785
    bia t0, LowestTag, .slow
1786
    bib t2, LowestTag, .op1NotIntOp2Double
1787
    bineq t2, Int32Tag, .slow
1788
    ci2d t3, ft1
1789
    jmp .op1NotIntReady
1790
.op1NotIntOp2Double:
1791
    fii2d t3, t2, ft1
1792
.op1NotIntReady:
1793
    fii2d t1, t0, ft0
1794
    doubleCompare(ft0, ft1, .jumpTarget)
1795
    dispatch(4)
1796
1797
.op2NotInt:
1798
    ci2d t1, ft0
1799
    bia t2, LowestTag, .slow
1800
    fii2d t3, t2, ft1
1801
    doubleCompare(ft0, ft1, .jumpTarget)
1802
    dispatch(4)
1803
1804
.jumpTarget:
1805
    dispatchBranch(12[PC])
1806
1807
.slow:
1808
    callHelper(helper)
1809
    dispatch(0)
1810
end
1811
1812
_llint_op_loop_if_less:
1813
    nop
1814
_llint_op_jless:
1815
    traceExecution()
1816
    compare(
1817
        macro (left, right, target) bilt left, right, target end,
1818
        macro (left, right, target) bdlt left, right, target end,
1819
        _llint_helper_jless)
1820
1821
1822
_llint_op_jnless:
1823
    traceExecution()
1824
    compare(
1825
        macro (left, right, target) bigteq left, right, target end,
1826
        macro (left, right, target) bdgtequn left, right, target end,
1827
        _llint_helper_jnless)
1828
1829
1830
_llint_op_loop_if_greater:
1831
    nop
1832
_llint_op_jgreater:
1833
    traceExecution()
1834
    compare(
1835
        macro (left, right, target) bigt left, right, target end,
1836
        macro (left, right, target) bdgt left, right, target end,
1837
        _llint_helper_jgreater)
1838
1839
1840
_llint_op_jngreater:
1841
    traceExecution()
1842
    compare(
1843
        macro (left, right, target) bilteq left, right, target end,
1844
        macro (left, right, target) bdltequn left, right, target end,
1845
        _llint_helper_jngreater)
1846
1847
1848
_llint_op_loop_if_lesseq:
1849
    nop
1850
_llint_op_jlesseq:
1851
    traceExecution()
1852
    compare(
1853
        macro (left, right, target) bilteq left, right, target end,
1854
        macro (left, right, target) bdlteq left, right, target end,
1855
        _llint_helper_jlesseq)
1856
1857
1858
_llint_op_jnlesseq:
1859
    traceExecution()
1860
    compare(
1861
        macro (left, right, target) bigt left, right, target end,
1862
        macro (left, right, target) bdgtun left, right, target end,
1863
        _llint_helper_jnlesseq)
1864
1865
1866
_llint_op_loop_if_greatereq:
1867
    nop
1868
_llint_op_jgreatereq:
1869
    traceExecution()
1870
    compare(
1871
        macro (left, right, target) bigteq left, right, target end,
1872
        macro (left, right, target) bdgteq left, right, target end,
1873
        _llint_helper_jgreatereq)
1874
1875
1876
_llint_op_jngreatereq:
1877
    traceExecution()
1878
    compare(
1879
        macro (left, right, target) bilt left, right, target end,
1880
        macro (left, right, target) bdltun left, right, target end,
1881
        _llint_helper_jngreatereq)
1882
1883
1884
_llint_op_loop_hint:
1885
    traceExecution()
1886
    checkSwitchToJITForLoop()
1887
    dispatch(1)
1888
1889
1890
_llint_op_switch_imm:
1891
    traceExecution()
1892
    loadi 12[PC], t2
1893
    loadi 4[PC], t3
1894
    loadConstantOrVariable(t2, t1, t0)
1895
    loadp CodeBlock[cfr], t2
1896
    loadp CodeBlock::m_rareData[t2], t2
1897
    muli sizeof SimpleJumpTable, t3   # FIXME: would be nice to peephole this!
1898
    loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
1899
    addp t3, t2
1900
    bineq t1, Int32Tag, .opSwitchImmNotInt
1901
    subi SimpleJumpTable::min[t2], t0
1902
    biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
1903
    loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
1904
    loadi [t3, t0, 4], t1
1905
    btiz t1, .opSwitchImmFallThrough
1906
    dispatchBranchWithOffset(t1)
1907
1908
.opSwitchImmNotInt:
1909
    bib t1, LowestTag, .opSwitchImmSlow  # Go to slow path if it's a double.
1910
.opSwitchImmFallThrough:
1911
    dispatchBranch(8[PC])
1912
1913
.opSwitchImmSlow:
1914
    callHelper(_llint_helper_switch_imm)
1915
    dispatch(0)
1916
1917
1918
_llint_op_switch_char:
1919
    traceExecution()
1920
    loadi 12[PC], t2
1921
    loadi 4[PC], t3
1922
    loadConstantOrVariable(t2, t1, t0)
1923
    loadp CodeBlock[cfr], t2
1924
    loadp CodeBlock::m_rareData[t2], t2
1925
    muli sizeof SimpleJumpTable, t3
1926
    loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
1927
    addp t3, t2
1928
    bineq t1, CellTag, .opSwitchCharFallThrough
1929
    loadp JSCell::m_structure[t0], t1
1930
    bbneq Structure::m_typeInfo + TypeInfo::m_type[t1], StringType, .opSwitchCharFallThrough
1931
    loadp JSString::m_value[t0], t0
1932
    bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
1933
    loadp StringImpl::m_data8[t0], t1
1934
    btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
1935
    loadh [t1], t0
1936
    jmp .opSwitchCharReady
1937
.opSwitchChar8Bit:
1938
    loadb [t1], t0
1939
.opSwitchCharReady:
1940
    subi SimpleJumpTable::min[t2], t0
1941
    biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
1942
    loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
1943
    loadi [t2, t0, 4], t1
1944
    btiz t1, .opSwitchImmFallThrough
1945
    dispatchBranchWithOffset(t1)
1946
1947
.opSwitchCharFallThrough:
1948
    dispatchBranch(8[PC])
1949
1950
1951
_llint_op_switch_string:
1952
    traceExecution()
1953
    callHelper(_llint_helper_switch_string)
1954
    dispatch(0)
1955
1956
1957
_llint_op_new_func:
1958
    traceExecution()
1959
    btiz 12[PC], .opNewFuncUnchecked
1960
    loadi 4[PC], t1
1961
    bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
1962
.opNewFuncUnchecked:
1963
    callHelper(_llint_helper_new_func)
1964
.opNewFuncDone:
1965
    dispatch(4)
1966
1967
1968
_llint_op_new_func_exp:
1969
    traceExecution()
1970
    callHelper(_llint_helper_new_func_exp)
1971
    dispatch(3)
1972
1973
1974
macro doCall(helper)
1975
    loadi 4[PC], t0
1976
    loadi 16[PC], t1
1977
    loadp LLIntCallLinkInfo::callee[t1], t2
1978
    loadConstantOrVariablePayload(t0, CellTag, t3, .opCallSlow)
1979
    bineq t3, t2, .opCallSlow
1980
    loadi 12[PC], t3
1981
    addp 24, PC
1982
    lshifti 3, t3
1983
    addp cfr, t3  # t3 contains the new value of cfr
1984
    loadp JSFunction::m_scopeChain[t2], t0
1985
    storei t2, Callee + PayloadOffset[t3]
1986
    storei t0, ScopeChain + PayloadOffset[t3]
1987
    loadi 8 - 24[PC], t2
1988
    storei PC, ArgumentCount + TagOffset[cfr]
1989
    storep cfr, CallerFrame[t3]
1990
    storei t2, ArgumentCount + PayloadOffset[t3]
1991
    storei CellTag, Callee + TagOffset[t3]
1992
    storei CellTag, ScopeChain + TagOffset[t3]
1993
    move t3, cfr
1994
    call LLIntCallLinkInfo::machineCodeTarget[t1]
1995
    dispatchAfterCall()
1996
1997
.opCallSlow:
1998
    slowPathForCall(6, helper)
1999
end
2000
2001
_llint_op_call:
2002
    traceExecution()
2003
    doCall(_llint_helper_call)
2004
2005
2006
_llint_op_construct:
2007
    traceExecution()
2008
    doCall(_llint_helper_construct)
2009
2010
2011
_llint_op_call_varargs:
2012
    traceExecution()
2013
    slowPathForCall(6, _llint_helper_call_varargs)
2014
2015
2016
_llint_op_call_eval:
2017
    traceExecution()
2018
    
2019
    # Eval is executed in one of two modes:
2020
    #
2021
    # 1) We find that we're really invoking eval() in which case the
2022
    #    execution is perfomed entirely inside the helper, and it
2023
    #    returns the PC of a function that just returns the return value
2024
    #    that the eval returned.
2025
    #
2026
    # 2) We find that we're invoking something called eval() that is not
2027
    #    the real eval. Then the helper returns the PC of the thing to
2028
    #    call, and we call it.
2029
    #
2030
    # This allows us to handle two cases, which would require a total of
2031
    # up to four pieces of state that cannot be easily packed into two
2032
    # registers (C functions can return up to two registers, easily):
2033
    #
2034
    # - The call frame register. This may or may not have been modified
2035
    #   by the helper, but the convention is that it returns it. It's not
2036
    #   totally clear if that's necessary, since the cfr is callee save.
2037
    #   But that's our style in this here interpreter so we stick with it.
2038
    #
2039
    # - A bit to say if the helper successfully executed the eval and has
2040
    #   the return value, or did not execute the eval but has a PC for us
2041
    #   to call.
2042
    #
2043
    # - Either:
2044
    #   - The JS return value (two registers), or
2045
    #
2046
    #   - The PC to call.
2047
    #
2048
    # It turns out to be easier to just always have this return the cfr
2049
    # and a PC to call, and that PC may be a dummy thunk that just
2050
    # returns the JS value that the eval returned.
2051
    
2052
    slowPathForCall(4, _llint_helper_call_eval)
2053
2054
2055
_llint_generic_return_point:
2056
    dispatchAfterCall()
2057
2058
2059
_llint_op_tear_off_activation:
2060
    traceExecution()
2061
    loadi 4[PC], t0
2062
    loadi 8[PC], t1
2063
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationCreated
2064
    bieq TagOffset[cfr, t1, 8], EmptyValueTag, .opTearOffActivationNotCreated
2065
.opTearOffActivationCreated:
2066
    callHelper(_llint_helper_tear_off_activation)
2067
.opTearOffActivationNotCreated:
2068
    dispatch(3)
2069
2070
2071
_llint_op_tear_off_arguments:
2072
    traceExecution()
2073
    loadi 4[PC], t0
2074
    subi 1, t0   # Get the unmodifiedArgumentsRegister
2075
    bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
2076
    callHelper(_llint_helper_tear_off_arguments)
2077
.opTearOffArgumentsNotCreated:
2078
    dispatch(2)
2079
2080
2081
macro doReturn()
2082
    loadp ReturnPC[cfr], t2
2083
    loadp CallerFrame[cfr], cfr
2084
    restoreReturnAddressBeforeReturn(t2)
2085
    ret
2086
end
2087
2088
_llint_op_ret:
2089
    traceExecution()
2090
    checkSwitchToJITForEpilogue()
2091
    loadi 4[PC], t2
2092
    loadConstantOrVariable(t2, t1, t0)
2093
    doReturn()
2094
2095
2096
_llint_op_call_put_result:
2097
    loadi 4[PC], t2
2098
    loadi 8[PC], t3
2099
    storei t1, TagOffset[cfr, t2, 8]
2100
    storei t0, PayloadOffset[cfr, t2, 8]
2101
    valueProfile(t1, t0, t3)
2102
    traceExecution() # Needs to be here because it would clobber t1, t0
2103
    dispatch(3)
2104
2105
2106
_llint_op_ret_object_or_this:
2107
    traceExecution()
2108
    checkSwitchToJITForEpilogue()
2109
    loadi 4[PC], t2
2110
    loadConstantOrVariable(t2, t1, t0)
2111
    bineq t1, CellTag, .opRetObjectOrThisNotObject
2112
    loadp JSCell::m_structure[t0], t2
2113
    bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
2114
    doReturn()
2115
2116
.opRetObjectOrThisNotObject:
2117
    loadi 8[PC], t2
2118
    loadConstantOrVariable(t2, t1, t0)
2119
    doReturn()
2120
2121
2122
_llint_op_method_check:
2123
    traceExecution()
2124
    # We ignore method checks and use normal get_by_id optimizations.
2125
    dispatch(1)
2126
2127
2128
_llint_op_strcat:
2129
    traceExecution()
2130
    callHelper(_llint_helper_strcat)
2131
    dispatch(4)
2132
2133
2134
_llint_op_to_primitive:
2135
    traceExecution()
2136
    loadi 8[PC], t2
2137
    loadi 4[PC], t3
2138
    loadConstantOrVariable(t2, t1, t0)
2139
    bineq t1, CellTag, .opToPrimitiveIsImm
2140
    loadp JSCell::m_structure[t0], t2
2141
    bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
2142
.opToPrimitiveIsImm:
2143
    storei t1, TagOffset[cfr, t3, 8]
2144
    storei t0, PayloadOffset[cfr, t3, 8]
2145
    dispatch(3)
2146
2147
.opToPrimitiveSlowCase:
2148
    callHelper(_llint_helper_to_primitive)
2149
    dispatch(3)
2150
2151
2152
_llint_op_get_pnames:
2153
    traceExecution()
2154
    callHelper(_llint_helper_get_pnames)
2155
    dispatch(0) # The helper either advances the PC or jumps us to somewhere else.
2156
2157
2158
_llint_op_next_pname:
2159
    traceExecution()
2160
    loadi 12[PC], t1
2161
    loadi 16[PC], t2
2162
    loadi PayloadOffset[cfr, t1, 8], t0
2163
    bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
2164
    loadi 20[PC], t2
2165
    loadi PayloadOffset[cfr, t2, 8], t2
2166
    loadp JSPropertyNameIterator::m_jsStrings[t2], t3
2167
    loadi [t3, t0, 8], t3
2168
    addi 1, t0
2169
    storei t0, PayloadOffset[cfr, t1, 8]
2170
    loadi 4[PC], t1
2171
    storei CellTag, TagOffset[cfr, t1, 8]
2172
    storei t3, PayloadOffset[cfr, t1, 8]
2173
    loadi 8[PC], t3
2174
    loadi PayloadOffset[cfr, t3, 8], t3
2175
    loadp JSCell::m_structure[t3], t1
2176
    bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
2177
    loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
2178
    loadp StructureChain::m_vector[t0], t0
2179
    btpz [t0], .opNextPnameTarget
2180
.opNextPnameCheckPrototypeLoop:
2181
    bieq Structure::m_prototype + TagOffset[t1], NullTag, .opNextPnameSlow
2182
    loadp Structure::m_prototype + PayloadOffset[t1], t2
2183
    loadp JSCell::m_structure[t2], t1
2184
    bpneq t1, [t0], .opNextPnameSlow
2185
    addp 4, t0
2186
    btpnz [t0], .opNextPnameCheckPrototypeLoop
2187
.opNextPnameTarget:
2188
    dispatchBranch(24[PC])
2189
2190
.opNextPnameEnd:
2191
    dispatch(7)
2192
2193
.opNextPnameSlow:
2194
    callHelper(_llint_helper_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
2195
    dispatch(0)
2196
2197
2198
_llint_op_push_scope:
2199
    traceExecution()
2200
    callHelper(_llint_helper_push_scope)
2201
    dispatch(2)
2202
2203
2204
_llint_op_pop_scope:
2205
    traceExecution()
2206
    callHelper(_llint_helper_pop_scope)
2207
    dispatch(1)
2208
2209
2210
_llint_op_push_new_scope:
2211
    traceExecution()
2212
    callHelper(_llint_helper_push_new_scope)
2213
    dispatch(4)
2214
2215
2216
_llint_op_catch:
2217
    # This is where we end up from the JIT's throw trampoline (because the
2218
    # machine code return address will be set to _llint_op_catch), and from
2219
    # the interpreter's throw trampoline (see _llint_throw_trampoline).
2220
    # The JIT throwing protocol calls for the cfr to be in t0. The throwing
2221
    # code must have known that we were throwing to the interpreter, and have
2222
    # set JSGlobalData::targetInterpreterPCForThrow.
2223
    move t0, cfr
2224
    loadp JITStackFrame::globalData[sp], t3
2225
    loadi JSGlobalData::targetInterpreterPCForThrow[t3], PC
2226
    loadi JSGlobalData::exception + PayloadOffset[t3], t0
2227
    loadi JSGlobalData::exception + TagOffset[t3], t1
2228
    storei 0, JSGlobalData::exception + PayloadOffset[t3]
2229
    storei EmptyValueTag, JSGlobalData::exception + TagOffset[t3]       
2230
    loadi 4[PC], t2
2231
    storei t0, PayloadOffset[cfr, t2, 8]
2232
    storei t1, TagOffset[cfr, t2, 8]
2233
    traceExecution()  # This needs to be here because we don't want to clobber t0, t1, t2, t3 above.
2234
    dispatch(2)
2235
2236
2237
_llint_op_throw:
2238
    traceExecution()
2239
    callHelper(_llint_helper_throw)
2240
    dispatch(2)
2241
2242
2243
_llint_op_throw_reference_error:
2244
    traceExecution()
2245
    callHelper(_llint_helper_throw_reference_error)
2246
    dispatch(2)
2247
2248
2249
_llint_op_jsr:
2250
    traceExecution()
2251
    loadi 4[PC], t0
2252
    addi 3 * 4, PC, t1
2253
    storei t1, [cfr, t0, 8]
2254
    dispatchBranch(8[PC])
2255
2256
2257
_llint_op_sret:
2258
    traceExecution()
2259
    loadi 4[PC], t0
2260
    loadp [cfr, t0, 8], PC
2261
    dispatch(0)
2262
2263
2264
_llint_op_debug:
2265
    traceExecution()
2266
    callHelper(_llint_helper_debug)
2267
    dispatch(4)
2268
2269
2270
_llint_op_profile_will_call:
2271
    traceExecution()
2272
    loadp JITStackFrame::enabledProfilerReference[sp], t0
2273
    btpz [t0], .opProfileWillCallDone
2274
    callHelper(_llint_helper_profile_will_call)
2275
.opProfileWillCallDone:
2276
    dispatch(2)
2277
2278
2279
_llint_op_profile_did_call:
2280
    traceExecution()
2281
    loadp JITStackFrame::enabledProfilerReference[sp], t0
2282
    btpz [t0], .opProfileWillCallDone
2283
    callHelper(_llint_helper_profile_did_call)
2284
.opProfileDidCallDone:
2285
    dispatch(2)
2286
2287
2288
_llint_op_end:
2289
    traceExecution()
2290
    checkSwitchToJITForEpilogue()
2291
    loadi 4[PC], t0
2292
    loadi TagOffset[cfr, t0, 8], t1
2293
    loadi PayloadOffset[cfr, t0, 8], t0
2294
    doReturn()
2295
2296
2297
_llint_throw_from_helper_trampoline:
2298
    # When throwing from the interpreter (i.e. throwing from LLIntHelpers), so
2299
    # the throw target is not necessarily interpreted code, we come to here.
2300
    # This essentially emulates the JIT's throwing protocol.
2301
    loadp JITStackFrame::globalData[sp], t1
2302
    loadp JSGlobalData::callFrameForThrow[t1], t0
2303
    jmp JSGlobalData::targetMachinePCForThrow[t1]
2304
2305
2306
_llint_throw_during_call_trampoline:
2307
    preserveReturnAddressAfterCall(t2)
2308
    loadp JITStackFrame::globalData[sp], t1
2309
    loadp JSGlobalData::callFrameForThrow[t1], t0
2310
    jmp JSGlobalData::targetMachinePCForThrow[t1]
2311
2312
2313
# Lastly, make sure that we can link even though we don't support all opcodes.
2314
# These opcodes should never arise when using LLInt or either JIT. We assert
2315
# as much.
2316
2317
macro notSupported()
2318
    if ASSERT_ENABLED
2319
        crash()
2320
    else
2321
        # We should use whatever the smallest possible instruction is, just to
2322
        # ensure that there is a gap between instruction labels. If multiple
2323
        # smallest instructions exist, we should pick the one that is most
2324
        # likely result in execution being halted. Currently that is the break
2325
        # instruction on all architectures we're interested in. (Break is int3
2326
        # on Intel, which is 1 byte, and bkpt on ARMv7, which is 2 bytes.)
2327
        break
2328
    end
2329
end
2330
2331
_llint_op_get_array_length:
2332
    notSupported()
2333
2334
_llint_op_get_by_id_chain:
2335
    notSupported()
2336
2337
_llint_op_get_by_id_custom_chain:
2338
    notSupported()
2339
2340
_llint_op_get_by_id_custom_proto:
2341
    notSupported()
2342
2343
_llint_op_get_by_id_custom_self:
2344
    notSupported()
2345
2346
_llint_op_get_by_id_generic:
2347
    notSupported()
2348
2349
_llint_op_get_by_id_getter_chain:
2350
    notSupported()
2351
2352
_llint_op_get_by_id_getter_proto:
2353
    notSupported()
2354
2355
_llint_op_get_by_id_getter_self:
2356
    notSupported()
2357
2358
_llint_op_get_by_id_proto:
2359
    notSupported()
2360
2361
_llint_op_get_by_id_self:
2362
    notSupported()
2363
2364
_llint_op_get_string_length:
2365
    notSupported()
2366
2367
_llint_op_put_by_id_generic:
2368
    notSupported()
2369
2370
_llint_op_put_by_id_replace:
2371
    notSupported()
2372
2373
_llint_op_put_by_id_transition:
2374
    notSupported()
2375
2376
2377
# Indicate the end of LLInt.
2378
_llint_end:
2379
    crash()
2380
- Source/JavaScriptCore/llint/LowLevelInterpreter.cpp +35 lines
Line 0 Source/JavaScriptCore/llint/LowLevelInterpreter.cpp_sec1
1
/*
2
 * Copyright (C) 2012 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 "LowLevelInterpreter.h"
28
29
#if ENABLE(LLINT)
30
31
#include "LLIntOfflineAsmConfig.h"
32
33
#include "LLIntAssembly.h"
34
35
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LowLevelInterpreter.h +53 lines
Line 0 Source/JavaScriptCore/llint/LowLevelInterpreter.h_sec1
1
/*
2
 * Copyright (C) 2012 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 LowLevelInterpreter_h
27
#define LowLevelInterpreter_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(LLINT)
32
33
#include "Opcode.h"
34
35
#define LLINT_INSTRUCTION_DECL(opcode, length) extern "C" void llint_##opcode();
36
    FOR_EACH_OPCODE_ID(LLINT_INSTRUCTION_DECL);
37
#undef LLINT_INSTRUCTION_DECL
38
39
extern "C" void llint_begin();
40
extern "C" void llint_end();
41
extern "C" void llint_program_prologue();
42
extern "C" void llint_eval_prologue();
43
extern "C" void llint_function_for_call_prologue();
44
extern "C" void llint_function_for_construct_prologue();
45
extern "C" void llint_function_for_call_arity_check();
46
extern "C" void llint_function_for_construct_arity_check();
47
extern "C" void llint_generic_return_point();
48
extern "C" void llint_throw_from_helper_trampoline();
49
extern "C" void llint_throw_during_call_trampoline();
50
51
#endif // ENABLE(LLINT)
52
53
#endif // LowLevelInterpreter_h
- Source/JavaScriptCore/offlineasm/armv7.rb +193 lines
Line 0 Source/JavaScriptCore/offlineasm/armv7.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
class SpecialRegister
25
  def initialize(name)
26
    @name = name
27
  end
28
  
29
  def armV7Operand
30
    @name
31
  end
32
end
33
34
ARMv7_DATA_REG = SpecialRegister.new("ip")
35
ARMv7_ADDR_REG = SpecialRegister.new("r3")
36
37
def moveImmediate(value, register)
38
  # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
39
  if value >= 0 && value < 256
40
    $asm.puts "movw \##{value}, #{register.armV7Operand}"
41
  elsif (~value) >= 0 && (~value) < 256
42
    $asm.puts "mvnw \##{~value}, #{register.armV7Operand}"
43
  else
44
    $asm.puts "movw \##{value & 0xffff}, #{register.armV7Operand}"
45
    if (value & 0xffff0000) != 0
46
      $asm.puts "movt \##{value >> 16}, #{register.armV7Operand}"
47
    end
48
  end
49
end
50
51
class RegisterID
52
  def armV7Operand
53
    case name
54
    when "t0", "a0", "r0"
55
      "r0"
56
    when "t1", "a1", "r1"
57
      "r1"
58
    when "t2", "a2"
59
      "r2"
60
    when "a3"
61
      "r3"
62
    when "t3"
63
      "r4"
64
    when "t4"
65
      "r7"
66
    when "cfr"
67
      "r5"
68
    else
69
      raise
70
    end
71
  end
72
  
73
  def armV7PreparePossibleMemoryOperand
74
  end
75
  
76
  def armV7PossibleMemoryOperand
77
    armV7Operand
78
  end
79
  
80
  def armV7LoadStoreWrap
81
    yield
82
  end
83
end
84
85
class FPRegisterID
86
  def armV7Operand
87
    case name
88
    when "ft0", "fr"
89
      "d0"
90
    when "fr1",
91
      "d1"
92
    when "fr2"
93
      "d2"
94
    when "fr3"
95
      "d3"
96
    when "fr4"
97
      "d4"
98
    when "fr5"
99
      "d5"
100
    else
101
      raise
102
    end
103
  end
104
  
105
  def armV7PreparePossibleMemoryOperand
106
  end
107
  
108
  def armV7PossibleMemoryOperand
109
    armV7Operand
110
  end
111
  
112
  def armV7LoadStoreWrap
113
    yield self
114
  end
115
end
116
117
class Immediate
118
  def armV7Operand
119
    raise "Invalid immediate #{value}" if value < 0 or value > 255
120
    "#${value}"
121
  end
122
  
123
  def armV7PreparePossibleMemoryOperand
124
  end
125
  
126
  def armV7PossibleMemoryOperand
127
    armV7Operand
128
  end
129
  
130
  def armV7LoadStoreWrap
131
    yield self
132
  end
133
end
134
135
module ARMv7AddressUtilities
136
  def armV7LoadStoreWrap
137
    self.armV7PreparePossibleMemoryOperand
138
    $asm.puts "\tldr #{self.armV7PossiblyMemoryOperand}, #{ARMv7_DATA_REG.armV7Operand}"
139
    yield ARMv7_DATA_REG
140
    $asm.puts "\tstr #{ARMv7_DATA_REG.armV7Operand}, #{self.armV7PossiblyMemoryOperand}"
141
  end
142
end
143
144
class Address
145
  include ARMv7AddressUtilities
146
147
  def armV7PreparePossibleMemoryOperand
148
    if offset.value < -0xff || offset.value > 0xfff
149
      moveImmediate(offset.value, ARMv7_ADDR_REG)
150
    end
151
  end
152
  
153
  def armV7PossibleMemoryOperand
154
    if offset.value < -0xff || offset.value > 0xfff
155
      "[#{base.armV7Operand}, #{ARMv7_ADDR_REG.armV7Operand}]"
156
    else
157
      "[#{base.armV7Operand}, #{offset.armV7Operand}]"
158
    end
159
  end
160
end
161
162
class BaseIndex
163
  include ARMv7AddressUtilities
164
165
  def armV7PreparePossibleMemoryOperand
166
    if offset.value != 0
167
      moveImmediate(offset.value, ARMv7_ADDR_REG)
168
      $asm.puts "addw #{ARMv7_ADDR_REG.armV7Operand}, #{base.armV7Operand}"
169
    end
170
  end
171
  
172
  def armV7PossibleMemoryOperand
173
    if offset.value != 0
174
      "[#{ARMv7_ADDR_REG.armV7Operand}, #{index.armV7Operand}, lsl \##{scale}]"
175
    else
176
      "[#{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scale}]"
177
    end
178
  end
179
end
180
181
class AbsoluteAddress
182
  include ARMv7AddressUtilities
183
  
184
  def armV7PreparePossibleMemoryOperand
185
    moveImmediate(address.value, ARMv7_ADDR_REG)
186
  end
187
  
188
  def armV7PossibleMemoryOperand
189
    "[#{ARMv7_ADDR_REG.armV7Operand}]"
190
  end
191
end
192
193
- Source/JavaScriptCore/offlineasm/asm.rb +108 lines
Line 0 Source/JavaScriptCore/offlineasm/asm.rb_sec1
1
#!/usr/bin/env ruby
2
3
# Copyright (C) 2011 Apple Inc. All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
# 1. Redistributions of source code must retain the above copyright
9
#    notice, this list of conditions and the following disclaimer.
10
# 2. Redistributions in binary form must reproduce the above copyright
11
#    notice, this list of conditions and the following disclaimer in the
12
#    documentation and/or other materials provided with the distribution.
13
#
14
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24
# THE POSSIBILITY OF SUCH DAMAGE.
25
26
$: << File.dirname(__FILE__)
27
28
require "backends"
29
require "digest/sha1"
30
require "offsets"
31
require "parser"
32
require "settings"
33
require "transform"
34
35
class Assembler
36
  def initialize(outp)
37
    @outp = outp
38
    @state = :cpp
39
  end
40
  
41
  def enterAsm
42
    @outp.puts "asm ("
43
    @state = :asm
44
  end
45
  
46
  def leaveAsm
47
    @outp.puts ");"
48
    @state = :cpp
49
  end
50
  
51
  def inAsm
52
    enterAsm
53
    yield
54
    leaveAsm
55
  end
56
  
57
  def puts(line)
58
    raise unless @state == :asm
59
    @outp.puts((line + "\n").inspect)
60
  end
61
  
62
  def comment(text)
63
    @outp.puts "// #{text}"
64
  end
65
end
66
67
asmFile = ARGV.shift
68
offsetsFile = ARGV.shift
69
outputFlnm = ARGV.shift
70
71
offsetsList, configIndex = offsetsAndConfigurationIndex(offsetsFile)
72
inputData = IO::read(asmFile)
73
74
inputHash =
75
  "// offlineasm input hash: " + Digest::SHA1.hexdigest(inputData) +
76
  " " + Digest::SHA1.hexdigest((offsetsList + [configIndex]).join(' '))
77
78
if FileTest.exist? outputFlnm
79
  File.open(outputFlnm, "r") {
80
    | inp |
81
    firstLine = inp.gets
82
    if firstLine and firstLine.chomp == inputHash
83
      $stderr.puts "Nothing changed."
84
      exit 0
85
    end
86
  }
87
end
88
89
File.open(outputFlnm, "w") {
90
  | outp |
91
  $output = outp
92
  $output.puts inputHash
93
  
94
  $asm = Assembler.new($output)
95
  
96
  ast = parse(lex(inputData))
97
  
98
  forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
99
    | concreteSettings, lowLevelAST, backend |
100
    assertConfiguration(concreteSettings)
101
    lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
102
    emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
103
      $asm.inAsm {
104
        lowLevelAST.lower(backend)
105
      }
106
    }
107
  }
108
}
- Source/JavaScriptCore/offlineasm/ast.rb +813 lines
Line 0 Source/JavaScriptCore/offlineasm/ast.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
#
25
# Base utility types for the AST.
26
#
27
28
# Valid methods for Node:
29
#
30
# node.children -> Returns an array of immediate children.
31
#
32
# node.descendents -> Returns an array of all strict descendants (children
33
#     and children of children, transitively).
34
#
35
# node.flatten -> Returns an array containing the strict descendants and
36
#     the node itself.
37
#
38
# node.filter(type) -> Returns an array containing those elements in
39
#     node.flatten that are of the given type (is_a? type returns true).
40
#
41
# node.mapChildren{|v| ...} -> Returns a new node with all children
42
#     replaced according to the given block.
43
#
44
# Examples:
45
#
46
# node.filter(Setting).uniq -> Returns all of the settings that the AST's
47
#     IfThenElse blocks depend on.
48
#
49
# node.filter(StructOffset).uniq -> Returns all of the structure offsets
50
#     that the AST depends on.
51
52
class Node
53
  attr_reader :codeOrigin
54
  
55
  def initialize(codeOrigin)
56
    @codeOrigin = codeOrigin
57
  end
58
  
59
  def codeOriginString
60
    "line number #{@codeOrigin}"
61
  end
62
  
63
  def descendants
64
    children.collect{|v| v.flatten}.flatten
65
  end
66
  
67
  def flatten
68
    [self] + descendants
69
  end
70
  
71
  def filter(type)
72
    flatten.select{|v| v.is_a? type}
73
  end
74
end
75
76
class NoChildren < Node
77
  def initialize(codeOrigin)
78
    super(codeOrigin)
79
  end
80
  
81
  def children
82
    []
83
  end
84
  
85
  def mapChildren
86
    self
87
  end
88
end
89
90
class StructOffsetKey
91
  attr_reader :struct, :field
92
  
93
  def initialize(struct, field)
94
    @struct = struct
95
    @field = field
96
  end
97
  
98
  def hash
99
    @struct.hash + @field.hash * 3
100
  end
101
  
102
  def eql?(other)
103
    @struct == other.struct and @field == other.field
104
  end
105
end
106
    
107
#
108
# AST nodes.
109
#
110
111
class StructOffset < NoChildren
112
  attr_reader :struct, :field
113
  
114
  def initialize(codeOrigin, struct, field)
115
    super(codeOrigin)
116
    @struct = struct
117
    @field = field
118
  end
119
  
120
  @@mapping = {}
121
  
122
  def self.forField(codeOrigin, struct, field)
123
    key = StructOffsetKey.new(struct, field)
124
    
125
    unless @@mapping[key]
126
      @@mapping[key] = StructOffset.new(codeOrigin, struct, field)
127
    end
128
    @@mapping[key]
129
  end
130
  
131
  def dump
132
    "#{struct}::#{field}"
133
  end
134
  
135
  def <=>(other)
136
    if @struct != other.struct
137
      return @struct <=> other.struct
138
    end
139
    @field <=> other.field
140
  end
141
end
142
143
class Sizeof < NoChildren
144
  attr_reader :struct
145
  
146
  def initialize(codeOrigin, struct)
147
    super(codeOrigin)
148
    @struct = struct
149
  end
150
  
151
  @@mapping = {}
152
  
153
  def self.forName(codeOrigin, struct)
154
    unless @@mapping[struct]
155
      @@mapping[struct] = Sizeof.new(codeOrigin, struct)
156
    end
157
    @@mapping[struct]
158
  end
159
  
160
  def dump
161
    "sizeof #{@struct}"
162
  end
163
  
164
  def <=>(other)
165
    @struct <=> other.struct
166
  end
167
end
168
169
class Immediate < NoChildren
170
  attr_reader :value
171
  
172
  def initialize(codeOrigin, value)
173
    super(codeOrigin)
174
    @value = value
175
  end
176
  
177
  def dump
178
    "#{value}"
179
  end
180
  
181
  def ==(other)
182
    other.is_a? Immediate and other.value == @value
183
  end
184
end
185
186
class AddImmediates < Node
187
  attr_reader :left, :right
188
  
189
  def initialize(codeOrigin, left, right)
190
    super(codeOrigin)
191
    @left = left
192
    @right = right
193
  end
194
  
195
  def children
196
    [@left, @right]
197
  end
198
  
199
  def mapChildren
200
    AddImmediates.new(codeOrigin, (yield @left), (yield @right))
201
  end
202
  
203
  def dump
204
    "(#{left.dump} + #{right.dump})"
205
  end
206
end
207
208
class SubImmediates < Node
209
  attr_reader :left, :right
210
  
211
  def initialize(codeOrigin, left, right)
212
    super(codeOrigin)
213
    @left = left
214
    @right = right
215
  end
216
  
217
  def children
218
    [@left, @right]
219
  end
220
  
221
  def mapChildren
222
    SubImmediates.new(codeOrigin, (yield @left), (yield @right))
223
  end
224
  
225
  def dump
226
    "(#{left.dump} - #{right.dump})"
227
  end
228
end
229
230
class MulImmediates < Node
231
  attr_reader :left, :right
232
  
233
  def initialize(codeOrigin, left, right)
234
    super(codeOrigin)
235
    @left = left
236
    @right = right
237
  end
238
  
239
  def children
240
    [@left, @right]
241
  end
242
  
243
  def mapChildren
244
    MulImmediates.new(codeOrigin, (yield @left), (yield @right))
245
  end
246
  
247
  def dump
248
    "(#{left.dump} * #{right.dump})"
249
  end
250
end
251
252
class NegImmediate < Node
253
  attr_reader :child
254
  
255
  def initialize(codeOrigin, child)
256
    super(codeOrigin)
257
    @child = child
258
  end
259
  
260
  def children
261
    [@child]
262
  end
263
  
264
  def mapChildren
265
    NegImmediate.new(codeOrigin, (yield @child))
266
  end
267
  
268
  def dump
269
    "(-#{@child.dump})"
270
  end
271
end
272
273
class RegisterID < NoChildren
274
  attr_reader :name
275
  
276
  def initialize(codeOrigin, name)
277
    super(codeOrigin)
278
    @name = name
279
  end
280
  
281
  @@mapping = {}
282
  
283
  def self.forName(codeOrigin, name)
284
    unless @@mapping[name]
285
      @@mapping[name] = RegisterID.new(codeOrigin, name)
286
    end
287
    @@mapping[name]
288
  end
289
  
290
  def dump
291
    name
292
  end
293
end
294
295
class FPRegisterID < NoChildren
296
  attr_reader :name
297
  
298
  def initialize(codeOrigin, name)
299
    super(codeOrigin)
300
    @name = name
301
  end
302
  
303
  @@mapping = {}
304
  
305
  def self.forName(codeOrigin, name)
306
    unless @@mapping[name]
307
      @@mapping[name] = FPRegisterID.new(codeOrigin, name)
308
    end
309
    @@mapping[name]
310
  end
311
  
312
  def dump
313
    name
314
  end
315
end
316
317
class Variable < NoChildren
318
  attr_reader :name
319
  
320
  def initialize(codeOrigin, name)
321
    super(codeOrigin)
322
    @name = name
323
  end
324
  
325
  @@mapping = {}
326
  
327
  def self.forName(codeOrigin, name)
328
    unless @@mapping[name]
329
      @@mapping[name] = Variable.new(codeOrigin, name)
330
    end
331
    @@mapping[name]
332
  end
333
  
334
  def dump
335
    name
336
  end
337
end
338
339
class Address < Node
340
  attr_reader :base, :offset
341
  
342
  def initialize(codeOrigin, base, offset)
343
    super(codeOrigin)
344
    @base = base
345
    @offset = offset
346
  end
347
  
348
  def children
349
    [@base, @offset]
350
  end
351
  
352
  def mapChildren
353
    Address.new(codeOrigin, (yield @base), (yield @offset))
354
  end
355
  
356
  def dump
357
    "#{offset.dump}[#{base.dump}]"
358
  end
359
end
360
361
class BaseIndex < Node
362
  attr_reader :base, :index, :scale, :offset
363
  
364
  def initialize(codeOrigin, base, index, scale, offset)
365
    super(codeOrigin)
366
    @base = base
367
    @index = index
368
    @scale = scale
369
    raise unless [1, 2, 4, 8].member? @scale
370
    @offset = offset
371
  end
372
  
373
  def children
374
    [@base, @index, @offset]
375
  end
376
  
377
  def mapChildren
378
    BaseIndex.new(codeOrigin, (yield @base), (yield @index), @scale, (yield @offset))
379
  end
380
  
381
  def dump
382
    "#{offset.dump}[#{base.dump}, #{index.dump}, #{scale}]"
383
  end
384
end
385
386
class AbsoluteAddress < NoChildren
387
  attr_reader :address
388
  
389
  def initialize(codeOrigin, address)
390
    super(codeOrigin)
391
    @address = address
392
  end
393
  
394
  def dump
395
    "#{address.dump}[]"
396
  end
397
end
398
399
class Instruction < Node
400
  attr_reader :opcode, :operands
401
  
402
  def initialize(codeOrigin, opcode, operands)
403
    super(codeOrigin)
404
    @opcode = opcode
405
    @operands = operands
406
  end
407
  
408
  def children
409
    operands
410
  end
411
  
412
  def mapChildren(&proc)
413
    Instruction.new(codeOrigin, @opcode, @operands.map(&proc))
414
  end
415
  
416
  def dump
417
    "\t" + opcode.to_s + " " + operands.collect{|v| v.dump}.join(", ")
418
  end
419
end
420
421
class Error < NoChildren
422
  def initialize(codeOrigin)
423
    super(codeOrigin)
424
  end
425
  
426
  def dump
427
    "\terror"
428
  end
429
end
430
431
class ConstDecl < Node
432
  attr_reader :variable, :value
433
  
434
  def initialize(codeOrigin, variable, value)
435
    super(codeOrigin)
436
    @variable = variable
437
    @value = value
438
  end
439
  
440
  def children
441
    [@variable, @value]
442
  end
443
  
444
  def mapChildren
445
    ConstDecl.new(codeOrigin, (yield @variable), (yield @value))
446
  end
447
  
448
  def dump
449
    "const #{@variable.dump} = #{@value.dump}"
450
  end
451
end
452
453
$labelMapping = {}
454
455
class Label < NoChildren
456
  attr_reader :name
457
  
458
  def initialize(codeOrigin, name)
459
    super(codeOrigin)
460
    @name = name
461
  end
462
  
463
  def self.forName(codeOrigin, name)
464
    if $labelMapping[name]
465
      raise "Label name collision: #{name}" unless $labelMapping[name].is_a? Label
466
    else
467
      $labelMapping[name] = Label.new(codeOrigin, name)
468
    end
469
    $labelMapping[name]
470
  end
471
  
472
  def dump
473
    "#{name}:"
474
  end
475
end
476
477
class LocalLabel < NoChildren
478
  attr_reader :name
479
  
480
  def initialize(codeOrigin, name)
481
    super(codeOrigin)
482
    @name = name
483
  end
484
485
  @@uniqueNameCounter = 0
486
  
487
  def self.forName(codeOrigin, name)
488
    if $labelMapping[name]
489
      raise "Label name collision: #{name}" unless $labelMapping[name].is_a? LocalLabel
490
    else
491
      $labelMapping[name] = LocalLabel.new(codeOrigin, name)
492
    end
493
    $labelMapping[name]
494
  end
495
  
496
  def self.unique(comment)
497
    newName = "_#{comment}"
498
    if $labelMapping[newName]
499
      while $labelMapping[newName = "_#{@@uniqueNameCounter}_#{comment}"]
500
        @@uniqueNameCounter += 1
501
      end
502
    end
503
    forName(nil, newName)
504
  end
505
  
506
  def cleanName
507
    if name =~ /^\./
508
      "_" + name[1..-1]
509
    else
510
      name
511
    end
512
  end
513
  
514
  def dump
515
    "#{name}:"
516
  end
517
end
518
519
class LabelReference < Node
520
  attr_reader :label
521
  
522
  def initialize(codeOrigin, label)
523
    super(codeOrigin)
524
    @label = label
525
  end
526
  
527
  def children
528
    [@label]
529
  end
530
  
531
  def mapChildren
532
    LabelReference.new(codeOrigin, (yield @label))
533
  end
534
  
535
  def name
536
    label.name
537
  end
538
  
539
  def dump
540
    label.name
541
  end
542
end
543
544
class LocalLabelReference < NoChildren
545
  attr_reader :label
546
  
547
  def initialize(codeOrigin, label)
548
    super(codeOrigin)
549
    @label = label
550
  end
551
  
552
  def children
553
    [@label]
554
  end
555
  
556
  def mapChildren
557
    LocalLabelReference.new(codeOrigin, (yield @label))
558
  end
559
  
560
  def name
561
    label.name
562
  end
563
  
564
  def dump
565
    label.name
566
  end
567
end
568
569
class Sequence < Node
570
  attr_reader :list
571
  
572
  def initialize(codeOrigin, list)
573
    super(codeOrigin)
574
    @list = list
575
  end
576
  
577
  def children
578
    list
579
  end
580
  
581
  def mapChildren(&proc)
582
    Sequence.new(codeOrigin, @list.map(&proc))
583
  end
584
  
585
  def dump
586
    list.collect{|v| v.dump}.join("\n")
587
  end
588
end
589
590
class True < NoChildren
591
  def initialize
592
    super(nil)
593
  end
594
  
595
  @@instance = True.new
596
  
597
  def self.instance
598
    @@instance
599
  end
600
  
601
  def value
602
    true
603
  end
604
  
605
  def dump
606
    "true"
607
  end
608
end
609
610
class False < NoChildren
611
  def initialize
612
    super(nil)
613
  end
614
  
615
  @@instance = False.new
616
  
617
  def self.instance
618
    @@instance
619
  end
620
  
621
  def value
622
    false
623
  end
624
  
625
  def dump
626
    "false"
627
  end
628
end
629
630
class TrueClass
631
  def asNode
632
    True.instance
633
  end
634
end
635
636
class FalseClass
637
  def asNode
638
    False.instance
639
  end
640
end
641
642
class Setting < NoChildren
643
  attr_reader :name
644
  
645
  def initialize(codeOrigin, name)
646
    super(codeOrigin)
647
    @name = name
648
  end
649
  
650
  @@mapping = {}
651
  
652
  def self.forName(codeOrigin, name)
653
    unless @@mapping[name]
654
      @@mapping[name] = Setting.new(codeOrigin, name)
655
    end
656
    @@mapping[name]
657
  end
658
  
659
  def dump
660
    name
661
  end
662
end
663
664
class And < Node
665
  attr_reader :left, :right
666
  
667
  def initialize(codeOrigin, left, right)
668
    super(codeOrigin)
669
    @left = left
670
    @right = right
671
  end
672
  
673
  def children
674
    [@left, @right]
675
  end
676
  
677
  def mapChildren
678
    And.new(codeOrigin, (yield @left), (yield @right))
679
  end
680
  
681
  def dump
682
    "(#{left.dump} and #{right.dump})"
683
  end
684
end
685
686
class Or < Node
687
  attr_reader :left, :right
688
  
689
  def initialize(codeOrigin, left, right)
690
    super(codeOrigin)
691
    @left = left
692
    @right = right
693
  end
694
  
695
  def children
696
    [@left, @right]
697
  end
698
  
699
  def mapChildren
700
    Or.new(codeOrigin, (yield @left), (yield @right))
701
  end
702
  
703
  def dump
704
    "(#{left.dump} or #{right.dump})"
705
  end
706
end
707
708
class Not < Node
709
  attr_reader :child
710
  
711
  def initialize(codeOrigin, child)
712
    super(codeOrigin)
713
    @child = child
714
  end
715
  
716
  def children
717
    [@left, @right]
718
  end
719
  
720
  def mapChildren
721
    Not.new(codeOrigin, (yield @child))
722
  end
723
  
724
  def dump
725
    "(not #{child.dump})"
726
  end
727
end
728
729
class Skip < NoChildren
730
  def initialize(codeOrigin)
731
    super(codeOrigin)
732
  end
733
  
734
  def dump
735
    "\tskip"
736
  end
737
end
738
739
class IfThenElse < Node
740
  attr_reader :predicate, :thenCase
741
  attr_accessor :elseCase
742
  
743
  def initialize(codeOrigin, predicate, thenCase)
744
    super(codeOrigin)
745
    @predicate = predicate
746
    @thenCase = thenCase
747
    @elseCase = Skip.new(codeOrigin)
748
  end
749
  
750
  def children
751
    if @elseCase
752
      [@predicate, @thenCase, @elseCase]
753
    else
754
      [@predicate, @thenCase]
755
    end
756
  end
757
  
758
  def mapChildren
759
    IfThenElse.new(codeOrigin, (yield @predicate), (yield @thenCase), (yield @elseCase))
760
  end
761
  
762
  def dump
763
    "if #{predicate.dump}\n" + thenCase.dump + "\nelse\n" + elseCase.dump + "\nend"
764
  end
765
end
766
767
class Macro < Node
768
  attr_reader :name, :variables, :body
769
  
770
  def initialize(codeOrigin, name, variables, body)
771
    super(codeOrigin)
772
    @name = name
773
    @variables = variables
774
    @body = body
775
  end
776
  
777
  def children
778
    @variables + [@body]
779
  end
780
  
781
  def mapChildren
782
    Macro.new(codeOrigin, @name, @variables.map{|v| yield v}, (yield @body))
783
  end
784
  
785
  def dump
786
    "macro #{name}(" + variables.collect{|v| v.dump}.join(", ") + ")\n" + body.dump + "\nend"
787
  end
788
end
789
790
class MacroCall < Node
791
  attr_reader :name, :operands
792
  
793
  def initialize(codeOrigin, name, operands)
794
    super(codeOrigin)
795
    @name = name
796
    @operands = operands
797
    raise unless @operands
798
    @operands.each{|v| raise unless v}
799
  end
800
  
801
  def children
802
    @operands
803
  end
804
  
805
  def mapChildren(&proc)
806
    MacroCall.new(codeOrigin, @name, @operands.map(&proc))
807
  end
808
  
809
  def dump
810
    "\t#{name}(" + operands.collect{|v| v.dump}.join(", ") + ")"
811
  end
812
end
813
- Source/JavaScriptCore/offlineasm/backends.rb +80 lines
Line 0 Source/JavaScriptCore/offlineasm/backends.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
require "ast"
25
require "x86"
26
27
BACKENDS =
28
  [
29
   "X86",
30
   "ARMv7"
31
  ]
32
33
WORKING_BACKENDS =
34
  [
35
   "X86"
36
  ]
37
38
BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
39
40
class Node
41
  def lower(name)
42
    send("lower" + name)
43
  end
44
end
45
46
# Overrides for lower() for those nodes that are backend-agnostic
47
48
def sanitizeLabelName(name)
49
  # Some platforms don't want the leading "_". If we ever want to do something
50
  # about that, it would be here.
51
  name
52
end
53
54
class Label
55
  def lower(name)
56
    $asm.puts ".globl #{sanitizeLabelName(self.name)}"
57
    $asm.puts "#{sanitizeLabelName(self.name)}:"
58
  end
59
end
60
61
class LocalLabel
62
  def lower(name)
63
    $asm.puts "L_offlineasm_#{self.name[1..-1]}:"
64
  end
65
end
66
67
class Skip
68
  def lower(name)
69
  end
70
end
71
72
class Sequence
73
  def lower(name)
74
    @list.each {
75
      | node |
76
      node.lower(name)
77
    }
78
  end
79
end
80
- Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb +87 lines
Line 0 Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb_sec1
1
#!/usr/bin/env ruby
2
3
# Copyright (C) 2011 Apple Inc. All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
# 1. Redistributions of source code must retain the above copyright
9
#    notice, this list of conditions and the following disclaimer.
10
# 2. Redistributions in binary form must reproduce the above copyright
11
#    notice, this list of conditions and the following disclaimer in the
12
#    documentation and/or other materials provided with the distribution.
13
#
14
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24
# THE POSSIBILITY OF SUCH DAMAGE.
25
26
$: << File.dirname(__FILE__)
27
28
require "backends"
29
require "digest/sha1"
30
require "offsets"
31
require "parser"
32
require "settings"
33
require "transform"
34
35
inputFlnm = ARGV.shift
36
outputFlnm = ARGV.shift
37
38
def emitMagicNumber
39
  OFFSET_MAGIC_NUMBERS.each {
40
    | number |
41
    $output.puts "#{number},"
42
  }
43
end
44
45
inputData = IO::read(inputFlnm)
46
inputHash = Digest::SHA1.hexdigest(inputData)
47
48
if FileTest.exist? outputFlnm
49
  File.open(outputFlnm, "r") {
50
    | inp |
51
    firstLine = inp.gets
52
    if firstLine and firstLine.chomp == "// offlineasm input hash: #{inputHash}"
53
      $stderr.puts "Nothing changed."
54
      exit 0
55
    end
56
  }
57
end
58
59
originalAST = parse(lex(inputData))
60
61
File.open(outputFlnm, "w") {
62
  | outp |
63
  $output = outp
64
  outp.puts "// offlineasm input hash: #{inputHash}"
65
  emitCodeInAllConfigurations(originalAST) {
66
    | settings, ast, backend, index |
67
    offsetsList = ast.filter(StructOffset).uniq.sort
68
    sizesList = ast.filter(Sizeof).uniq.sort
69
    
70
    length = (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size)
71
    
72
    outp.puts "static const unsigned extractorTable[#{length}] = {"
73
    emitMagicNumber
74
    outp.puts "#{index},"
75
    offsetsList.each {
76
      | offset |
77
      emitMagicNumber
78
      outp.puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
79
    }
80
    sizesList.each {
81
      | offset |
82
      emitMagicNumber
83
      outp.puts "sizeof(#{offset.struct}),"
84
    }
85
    outp.puts "};"
86
  }
87
}
- Source/JavaScriptCore/offlineasm/instructions.rb +188 lines
Line 0 Source/JavaScriptCore/offlineasm/instructions.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
MACRO_INSTRUCTIONS =
25
  [
26
   "addi",
27
   "andi",
28
   "lshifti",
29
   "muli",
30
   "negi",
31
   "noti",
32
   "ori",
33
   "rshifti",
34
   "urshifti",
35
   "subi",
36
   "xori",
37
   "loadi",
38
   "loadb",
39
   "loadh",
40
   "storei",
41
   "storeb",
42
   "loadd",
43
   "moved",
44
   "stored",
45
   "addd",
46
   "divd",
47
   "subd",
48
   "muld",
49
   "sqrtd",
50
   "ci2d",
51
   "fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr>
52
   "fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
53
   "bdeq",
54
   "bdneq",
55
   "bdgt",
56
   "bdgteq",
57
   "bdlt",
58
   "bdlteq",
59
   "bdequn",
60
   "bdnequn",
61
   "bdgtun",
62
   "bdgtequn",
63
   "bdltun",
64
   "bdltequn",
65
   "btd2i",
66
   "td2i",
67
   "bcd2i",
68
   "movdz",
69
   "pop",
70
   "push",
71
   "move",
72
   "sxi2p",
73
   "zxi2p",
74
   "nop",
75
   "bieq",
76
   "bineq",
77
   "bia",
78
   "biaeq",
79
   "bib",
80
   "bibeq",
81
   "bigt",
82
   "bigteq",
83
   "bilt",
84
   "bilteq",
85
   "bbeq",
86
   "bbneq",
87
   "bba",
88
   "bbaeq",
89
   "bbb",
90
   "bbbeq",
91
   "bbgt",
92
   "bbgteq",
93
   "bblt",
94
   "bblteq",
95
   "btio",
96
   "btis",
97
   "btiz",
98
   "btinz",
99
   "btbo",
100
   "btbs",
101
   "btbz",
102
   "btbnz",
103
   "jmp",
104
   "baddio",
105
   "baddis",
106
   "baddiz",
107
   "baddinz",
108
   "bsubio",
109
   "bsubis",
110
   "bsubiz",
111
   "bsubinz",
112
   "bmulio",
113
   "bmulis",
114
   "bmuliz",
115
   "bmulinz",
116
   "borio",
117
   "boris",
118
   "boriz",
119
   "borinz",
120
   "break",
121
   "call",
122
   "ret",
123
   "cieq",
124
   "cineq",
125
   "cia",
126
   "ciaeq",
127
   "cib",
128
   "cibeq",
129
   "cigt",
130
   "cigteq",
131
   "cilt",
132
   "cilteq",
133
   "tio",
134
   "tis",
135
   "tiz",
136
   "tinz",
137
   "tbo",
138
   "tbs",
139
   "tbz",
140
   "tbnz",
141
   "peek",
142
   "poke",
143
   "bpeq",
144
   "bpneq",
145
   "bpa",
146
   "bpaeq",
147
   "bpb",
148
   "bpbeq",
149
   "bpgt",
150
   "bpgteq",
151
   "bplt",
152
   "bplteq",
153
   "addp",
154
   "andp",
155
   "orp",
156
   "subp",
157
   "xorp",
158
   "loadp",
159
   "cpeq",
160
   "cpneq",
161
   "cpa",
162
   "cpaeq",
163
   "cpb",
164
   "cpbeq",
165
   "cpgt",
166
   "cpgteq",
167
   "cplt",
168
   "cplteq",
169
   "storep",
170
   "btpo",
171
   "btps",
172
   "btpz",
173
   "btpnz",
174
   "baddpo",
175
   "baddps",
176
   "baddpz",
177
   "baddpnz"
178
  ]
179
180
X86_INSTRUCTIONS =
181
  [
182
   "cdqi",
183
   "idivi"
184
  ]
185
186
INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS
187
188
INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
- Source/JavaScriptCore/offlineasm/offset_extractor_constants.rb +26 lines
Line 0 Source/JavaScriptCore/offlineasm/offset_extractor_constants.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
25
26
- Source/JavaScriptCore/offlineasm/offsets.rb +150 lines
Line 0 Source/JavaScriptCore/offlineasm/offsets.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
require "ast"
25
require "offset_extractor_constants"
26
27
OFFSET_MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
28
29
#
30
# offsetsList(ast)
31
# sizesList(ast)
32
#
33
# Returns a list of offsets and sizes used by the AST.
34
#
35
36
def offsetsList(ast)
37
  ast.filter(StructOffset).uniq.sort
38
end
39
40
def sizesList(ast)
41
  ast.filter(Sizeof).uniq.sort
42
end
43
44
#
45
# offsetsAndConfigurationIndex(ast, file) ->
46
#     [offsets, index]
47
#
48
# Parses the offsets from a file and returns a list of offsets and the
49
# index of the configuration that is valid in this build target.
50
#
51
52
def offsetsAndConfigurationIndex(file)
53
  index = nil
54
  offsets = []
55
  endiannessMarkerBytes = nil
56
  
57
  def readInt(endianness, inp)
58
    bytes = []
59
    4.times {
60
      bytes << inp.getbyte
61
    }
62
    
63
    if endianness == :little
64
      # Little endian
65
      (bytes[0] << 0 |
66
       bytes[1] << 8 |
67
       bytes[2] << 16 |
68
       bytes[3] << 24)
69
    else
70
      # Big endian
71
      (bytes[0] << 24 |
72
       bytes[1] << 16 |
73
       bytes[2] << 8 |
74
       bytes[3] << 0)
75
    end
76
  end
77
  
78
  [:little, :big].each {
79
    | endianness |
80
    magicBytes = []
81
    MAGIC_NUMBERS.each {
82
      | number |
83
      currentBytes = []
84
      4.times {
85
        currentBytes << (number & 0xff)
86
        number >>= 8
87
      }
88
      if endianness == :big
89
        currentBytes.reverse!
90
      end
91
      magicBytes += currentBytes
92
    }
93
    
94
    File.open(file, "r") {
95
      | inp |
96
      whereInMarker = 0
97
      loop {
98
        byte = inp.getbyte
99
        break unless byte
100
        if byte == magicBytes[whereInMarker]
101
          whereInMarker += 1
102
          if whereInMarker == magicBytes.size
103
            # We have a match! If we have not yet read the endianness marker and index,
104
            # then read those now; otherwise read an offset.
105
            
106
            if not index
107
              index = readInt(endianness, inp)
108
            else
109
              offsets << readInt(endianness, inp)
110
            end
111
            
112
            whereInMarker = 0
113
          end
114
        else
115
          whereInMarker = 0
116
        end
117
      }
118
    }
119
    
120
    break if index
121
  }
122
  
123
  raise unless index
124
  
125
  [offsets, index]
126
end
127
128
#
129
# buildOffsetsMap(ast, offsetsList) -> [offsets, sizes]
130
#
131
# Builds a mapping between StructOffset nodes and their values.
132
#
133
134
def buildOffsetsMap(ast, offsetsList)
135
  offsetsMap = {}
136
  sizesMap = {}
137
  astOffsetsList = offsetsList(ast)
138
  astSizesList = sizesList(ast)
139
  raise unless astOffsetsList.size + astSizesList.size == offsetsList.size
140
  offsetsList(ast).each_with_index {
141
    | structOffset, index |
142
    offsetsMap[structOffset] = offsetsList.shift
143
  }
144
  sizesList(ast).each_with_index {
145
    | sizeof, index |
146
    sizesMap[sizeof] = offsetsList.shift
147
  }
148
  [offsetsMap, sizesMap]
149
end
150
- Source/JavaScriptCore/offlineasm/parser.rb +585 lines
Line 0 Source/JavaScriptCore/offlineasm/parser.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
require "ast"
25
require "instructions"
26
require "registers"
27
28
class Token
29
  attr_reader :codeOrigin, :string
30
  
31
  def initialize(codeOrigin, string)
32
    @codeOrigin = codeOrigin
33
    @string = string
34
  end
35
  
36
  def ==(other)
37
    if other.is_a? Token
38
      @string == other.string
39
    else
40
      @string == other
41
    end
42
  end
43
  
44
  def =~(other)
45
    @string =~ other
46
  end
47
  
48
  def to_s
49
    "#{@string.inspect} at line #{codeOrigin}"
50
  end
51
  
52
  def parseError(*comment)
53
    if comment.empty?
54
      raise "Parse error: #{to_s}"
55
    else
56
      raise "Parse error: #{to_s}: #{comment[0]}"
57
    end
58
  end
59
end
60
61
#
62
# The lexer. Takes a string and returns an array of tokens.
63
#
64
65
def lex(str)
66
  result = []
67
  lineNumber = 1
68
  while not str.empty?
69
    case str
70
    when /\A\#([^\n]*)/
71
      # comment, ignore
72
    when /\A\n/
73
      result << Token.new(lineNumber, $&)
74
      lineNumber += 1
75
    when /\A[a-zA-Z]([a-zA-Z0-9_]*)/
76
      result << Token.new(lineNumber, $&)
77
    when /\A\.([a-zA-Z0-9_]*)/
78
      result << Token.new(lineNumber, $&)
79
    when /\A_([a-zA-Z0-9_]*)/
80
      result << Token.new(lineNumber, $&)
81
    when /\A([ \t]+)/
82
      # whitespace, ignore
83
    when /\A0x([0-9a-fA-F]+)/
84
      result << Token.new(lineNumber, $&.hex.to_s)
85
    when /\A0([0-7]+)/
86
      result << Token.new(lineNumber, $&.oct.to_s)
87
    when /\A([0-9]+)/
88
      result << Token.new(lineNumber, $&)
89
    when /\A::/
90
      result << Token.new(lineNumber, $&)
91
    when /\A[:,\(\)\[\]=\+\-*]/
92
      result << Token.new(lineNumber, $&)
93
    else
94
      raise "Lexer error at line number #{lineNumber}, unexpected sequence #{str[0..20].inspect}"
95
    end
96
    str = $~.post_match
97
  end
98
  result
99
end
100
101
#
102
# Token identification.
103
#
104
105
def isRegister(token)
106
  token =~ REGISTER_PATTERN
107
end
108
109
def isInstruction(token)
110
  token =~ INSTRUCTION_PATTERN
111
end
112
113
def isKeyword(token)
114
  token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(macro)|(const)|(sizeof)|(error))\Z/ or
115
    token =~ REGISTER_PATTERN or
116
    token =~ INSTRUCTION_PATTERN
117
end
118
119
def isIdentifier(token)
120
  token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
121
end
122
123
def isLabel(token)
124
  token =~ /\A_([a-zA-Z0-9_]*)\Z/
125
end
126
127
def isLocalLabel(token)
128
  token =~ /\A\.([a-zA-Z0-9_]*)\Z/
129
end
130
131
def isVariable(token)
132
  isIdentifier(token) or isRegister(token)
133
end
134
135
def isInteger(token)
136
  token =~ /\A[0-9]/
137
end
138
139
#
140
# The parser. Takes an array of tokens and returns an AST. Methods
141
# other than parse(tokens) are not for public consumption.
142
#
143
144
class Parser
145
  def initialize(tokens)
146
    @tokens = tokens
147
    @idx = 0
148
  end
149
  
150
  def parseError(*comment)
151
    if @tokens[@idx]
152
      @tokens[@idx].parseError(*comment)
153
    else
154
      if comment.empty?
155
        raise "Parse error at end of file"
156
      else
157
        raise "Parse error at end of file: #{comment[0]}"
158
      end
159
    end
160
  end
161
  
162
  def consume(regexp)
163
    if regexp
164
      parseError unless @tokens[@idx] =~ regexp
165
    else
166
      parseError unless @idx == @tokens.length
167
    end
168
    @idx += 1
169
  end
170
  
171
  def skipNewLine
172
    while @tokens[@idx] == "\n"
173
      @idx += 1
174
    end
175
  end
176
  
177
  def parsePredicateAtom
178
    if @tokens[@idx] == "not"
179
      @idx += 1
180
      parsePredicateAtom
181
    elsif @tokens[@idx] == "("
182
      @idx += 1
183
      skipNewLine
184
      result = parsePredicate
185
      parseError unless @tokens[@idx] == ")"
186
      @idx += 1
187
      result
188
    elsif @tokens[@idx] == "true"
189
      result = True.instance
190
      @idx += 1
191
      result
192
    elsif @tokens[@idx] == "false"
193
      result = False.instance
194
      @idx += 1
195
      result
196
    elsif isIdentifier @tokens[@idx]
197
      result = Setting.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
198
      @idx += 1
199
      result
200
    else
201
      parseError
202
    end
203
  end
204
  
205
  def parsePredicateAnd
206
    result = parsePredicateAtom
207
    while @tokens[@idx] == "and"
208
      codeOrigin = @tokens[@idx].codeOrigin
209
      @idx += 1
210
      skipNewLine
211
      right = parsePredicateAtom
212
      result = And.new(codeOrigin, result, right)
213
    end
214
    result
215
  end
216
  
217
  def parsePredicate
218
    # some examples of precedence:
219
    # not a and b -> (not a) and b
220
    # a and b or c -> (a and b) or c
221
    # a or b and c -> a or (b and c)
222
    
223
    result = parsePredicateAnd
224
    while @tokens[@idx] == "or"
225
      codeOrigin = @tokens[@idx].codeOrigin
226
      @idx += 1
227
      skipNewLine
228
      right = parsePredicateAnd
229
      result = Or.new(codeOrigin, result, right)
230
    end
231
    result
232
  end
233
  
234
  def parseVariable
235
    if isRegister(@tokens[@idx])
236
      if @tokens[@idx] =~ FPR_PATTERN
237
        result = FPRegisterID.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
238
      else
239
        result = RegisterID.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
240
      end
241
    elsif isIdentifier(@tokens[@idx])
242
      result = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
243
    else
244
      parseError
245
    end
246
    @idx += 1
247
    result
248
  end
249
  
250
  def parseAddress(offset)
251
    parseError unless @tokens[@idx] == "["
252
    codeOrigin = @tokens[@idx].codeOrigin
253
    
254
    # Three possibilities:
255
    # []       -> AbsoluteAddress
256
    # [a]      -> Address
257
    # [a,b]    -> BaseIndex with scale = 1
258
    # [a,b,c]  -> BaseIndex
259
    
260
    @idx += 1
261
    if @tokens[@idx] == "]"
262
      @idx += 1
263
      return AbsoluteAddress.new(codeOrigin, offset)
264
    end
265
    a = parseVariable
266
    if @tokens[@idx] == "]"
267
      result = Address.new(codeOrigin, a, offset)
268
    else
269
      parseError unless @tokens[@idx] == ","
270
      @idx += 1
271
      b = parseVariable
272
      if @tokens[@idx] == "]"
273
        result = BaseIndex.new(codeOrigin, a, b, 1, offset)
274
      else
275
        parseError unless @tokens[@idx] == ","
276
        @idx += 1
277
        parseError unless ["1", "2", "4", "8"].member? @tokens[@idx].string
278
        c = @tokens[@idx].string.to_i
279
        @idx += 1
280
        parseError unless @tokens[@idx] == "]"
281
        result = BaseIndex.new(codeOrigin, a, b, c, offset)
282
      end
283
    end
284
    @idx += 1
285
    result
286
  end
287
  
288
  def parseColonColon
289
    skipNewLine
290
    codeOrigin = @tokens[@idx].codeOrigin
291
    parseError unless isIdentifier @tokens[@idx]
292
    names = [@tokens[@idx].string]
293
    @idx += 1
294
    while @tokens[@idx] == "::"
295
      @idx += 1
296
      parseError unless isIdentifier @tokens[@idx]
297
      names << @tokens[@idx].string
298
      @idx += 1
299
    end
300
    raise if names.empty?
301
    [codeOrigin, names]
302
  end
303
  
304
  def parseExpressionAtom
305
    skipNewLine
306
    if @tokens[@idx] == "-"
307
      @idx += 1
308
      NegImmediate.new(@tokens[@idx - 1].codeOrigin, parseExpressionAtom)
309
    elsif @tokens[@idx] == "("
310
      @idx += 1
311
      result = parseExpression
312
      parseError unless @tokens[@idx] == ")"
313
      @idx += 1
314
      result
315
    elsif isInteger @tokens[@idx]
316
      result = Immediate.new(@tokens[@idx].codeOrigin, @tokens[@idx].string.to_i)
317
      @idx += 1
318
      result
319
    elsif isIdentifier @tokens[@idx]
320
      codeOrigin, names = parseColonColon
321
      if names.size > 1
322
        StructOffset.forField(codeOrigin, names[0..-2].join('::'), names[-1])
323
      else
324
        Variable.forName(codeOrigin, names[0])
325
      end
326
    elsif isRegister @tokens[@idx]
327
      parseVariable
328
    elsif @tokens[@idx] == "sizeof"
329
      @idx += 1
330
      codeOrigin, names = parseColonColon
331
      Sizeof.forName(codeOrigin, names.join('::'))
332
    else
333
      parseError
334
    end
335
  end
336
  
337
  def parseExpressionMul
338
    skipNewLine
339
    result = parseExpressionAtom
340
    while @tokens[@idx] == "*"
341
      if @tokens[@idx] == "*"
342
        @idx += 1
343
        result = MulImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionAtom)
344
      else
345
        raise
346
      end
347
    end
348
    result
349
  end
350
  
351
  def couldBeExpression
352
    @tokens[@idx] == "-" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
353
  end
354
  
355
  def parseExpression
356
    skipNewLine
357
    result = parseExpressionMul
358
    while @tokens[@idx] == "+" or @tokens[@idx] == "-"
359
      if @tokens[@idx] == "+"
360
        @idx += 1
361
        result = AddImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionMul)
362
      elsif @tokens[@idx] == "-"
363
        @idx += 1
364
        result = SubImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionMul)
365
      else
366
        raise
367
      end
368
    end
369
    result
370
  end
371
  
372
  def parseOperand(comment)
373
    if couldBeExpression
374
      expr = parseExpression
375
      if @tokens[@idx] == "["
376
        parseAddress(expr)
377
      else
378
        expr
379
      end
380
    elsif @tokens[@idx] == "["
381
      parseAddress(Immediate.new(@tokens[@idx].codeOrigin, 0))
382
    elsif isLabel @tokens[@idx]
383
      result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
384
      @idx += 1
385
      result
386
    elsif isLocalLabel @tokens[@idx]
387
      result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
388
      @idx += 1
389
      result
390
    else
391
      parseError(comment)
392
    end
393
  end
394
  
395
  def parseMacroVariables
396
    skipNewLine
397
    consume(/\A\(\Z/)
398
    variables = []
399
    loop {
400
      skipNewLine
401
      if @tokens[@idx] == ")"
402
        @idx += 1
403
        break
404
      elsif isIdentifier(@tokens[@idx])
405
        variables << Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
406
        @idx += 1
407
        skipNewLine
408
        if @tokens[@idx] == ")"
409
          @idx += 1
410
          break
411
        elsif @tokens[@idx] == ","
412
          @idx += 1
413
        else
414
          parseError
415
        end
416
      else
417
        parseError
418
      end
419
    }
420
    variables
421
  end
422
  
423
  def parseSequence(final, comment)
424
    firstCodeOrigin = @tokens[@idx].codeOrigin
425
    list = []
426
    loop {
427
      if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
428
        break
429
      elsif @tokens[@idx] == "\n"
430
        # ignore
431
        @idx += 1
432
      elsif @tokens[@idx] == "const"
433
        @idx += 1
434
        parseError unless isVariable @tokens[@idx]
435
        variable = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
436
        @idx += 1
437
        parseError unless @tokens[@idx] == "="
438
        @idx += 1
439
        value = parseOperand("while inside of const #{variable.name}")
440
        list << ConstDecl.new(@tokens[@idx].codeOrigin, variable, value)
441
      elsif @tokens[@idx] == "error"
442
        list << Error.new(@tokens[@idx].codeOrigin)
443
        @idx += 1
444
      elsif @tokens[@idx] == "if"
445
        codeOrigin = @tokens[@idx].codeOrigin
446
        @idx += 1
447
        skipNewLine
448
        predicate = parsePredicate
449
        consume(/\A((then)|(\n))\Z/)
450
        skipNewLine
451
        ifThenElse = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
452
        list << ifThenElse
453
        while @tokens[@idx] == "elsif"
454
          codeOrigin = @tokens[@idx].codeOrigin
455
          @idx += 1
456
          skipNewLine
457
          predicate = parsePredicate
458
          consume(/\A((then)|(\n))\Z/)
459
          skipNewLine
460
          elseCase = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
461
          ifThenElse.elseCase = elseCase
462
          ifThenElse = elseCase
463
        end
464
        if @tokens[@idx] == "else"
465
          @idx += 1
466
          ifThenElse.elseCase = parseSequence(/\Aend\Z/, "while inside of else case for \"if #{predicate.dump}\"")
467
          @idx += 1
468
        else
469
          parseError unless @tokens[@idx] == "end"
470
          @idx += 1
471
        end
472
      elsif @tokens[@idx] == "macro"
473
        codeOrigin = @tokens[@idx].codeOrigin
474
        @idx += 1
475
        skipNewLine
476
        parseError unless isIdentifier(@tokens[@idx])
477
        name = @tokens[@idx].string
478
        @idx += 1
479
        variables = parseMacroVariables
480
        body = parseSequence(/\Aend\Z/, "while inside of macro #{name}")
481
        @idx += 1
482
        list << Macro.new(codeOrigin, name, variables, body)
483
      elsif isInstruction @tokens[@idx]
484
        codeOrigin = @tokens[@idx].codeOrigin
485
        name = @tokens[@idx].string
486
        @idx += 1
487
        if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
488
          # Zero operand instruction, and it's the last one.
489
          list << Instruction.new(codeOrigin, name, [])
490
          break
491
        elsif @tokens[@idx] == "\n"
492
          # Zero operand instruction.
493
          list << Instruction.new(codeOrigin, name, [])
494
          @idx += 1
495
        else
496
          # It's definitely an instruction, and it has at least one operand.
497
          operands = []
498
          endOfSequence = false
499
          loop {
500
            operands << parseOperand("while inside of instruction #{name}")
501
            if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
502
              # The end of the instruction and of the sequence.
503
              endOfSequence = true
504
              break
505
            elsif @tokens[@idx] == ","
506
              # Has another operand.
507
              @idx += 1
508
            elsif @tokens[@idx] == "\n"
509
              # The end of the instruction.
510
              @idx += 1
511
              break
512
            else
513
              parseError("Expected a comma, newline, or #{final} after #{operands.last.dump}")
514
            end
515
          }
516
          list << Instruction.new(codeOrigin, name, operands)
517
          if endOfSequence
518
            break
519
          end
520
        end
521
      elsif isIdentifier @tokens[@idx]
522
        codeOrigin = @tokens[@idx].codeOrigin
523
        name = @tokens[@idx].string
524
        @idx += 1
525
        if @tokens[@idx] == "("
526
          # Macro invocation.
527
          @idx += 1
528
          operands = []
529
          skipNewLine
530
          if @tokens[@idx] == ")"
531
            @idx += 1
532
          else
533
            loop {
534
              skipNewLine
535
              if @tokens[@idx] == "macro"
536
                # It's a macro lambda!
537
                codeOriginInner = @tokens[@idx].codeOrigin
538
                @idx += 1
539
                variables = parseMacroVariables
540
                body = parseSequence(/\Aend\Z/, "while inside of anonymous macro passed as argument to #{name}")
541
                @idx += 1
542
                operands << Macro.new(codeOriginInner, nil, variables, body)
543
              else
544
                operands << parseOperand("while inside of macro call to #{name}")
545
              end
546
              skipNewLine
547
              if @tokens[@idx] == ")"
548
                @idx += 1
549
                break
550
              elsif @tokens[@idx] == ","
551
                @idx += 1
552
              else
553
                parseError "Unexpected #{@tokens[@idx].string.inspect} while parsing invocation of macro #{name}"
554
              end
555
            }
556
          end
557
          list << MacroCall.new(codeOrigin, name, operands)
558
        else
559
          parseError "Expected \"(\" after #{name}"
560
        end
561
      elsif isLabel @tokens[@idx] or isLocalLabel @tokens[@idx]
562
        codeOrigin = @tokens[@idx].codeOrigin
563
        name = @tokens[@idx].string
564
        @idx += 1
565
        parseError unless @tokens[@idx] == ":"
566
        # It's a label.
567
        if isLabel name
568
          list << Label.forName(codeOrigin, name)
569
        else
570
          list << LocalLabel.forName(codeOrigin, name)
571
        end
572
        @idx += 1
573
      else
574
        parseError "Expecting terminal #{final} #{comment}"
575
      end
576
    }
577
    Sequence.new(firstCodeOrigin, list)
578
  end
579
end
580
581
def parse(tokens)
582
  parser = Parser.new(tokens)
583
  parser.parseSequence(nil, "")
584
end
585
- Source/JavaScriptCore/offlineasm/registers.rb +59 lines
Line 0 Source/JavaScriptCore/offlineasm/registers.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
GPRS =
25
  [
26
   "t0",
27
   "t1",
28
   "t2",
29
   "t3",
30
   "t4",
31
   "cfr",
32
   "a0",
33
   "a1",
34
   "r0",
35
   "r1",
36
   "sp"
37
  ]
38
39
FPRS =
40
  [
41
   "ft0",
42
   "ft1",
43
   "ft2",
44
   "ft3",
45
   "ft4",
46
   "ft5",
47
   "fa0",
48
   "fa1",
49
   "fa2",
50
   "fa3",
51
   "fr"
52
  ]
53
54
REGISTERS = GPRS + FPRS
55
56
GPR_PATTERN = Regexp.new('\\A((' + GPRS.join(')|(') + '))\\Z')
57
FPR_PATTERN = Regexp.new('\\A((' + FPRS.join(')|(') + '))\\Z')
58
59
REGISTER_PATTERN = Regexp.new('\\A((' + REGISTERS.join(')|(') + '))\\Z')
- Source/JavaScriptCore/offlineasm/settings.rb +205 lines
Line 0 Source/JavaScriptCore/offlineasm/settings.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
require "ast"
25
require "backends"
26
require "parser"
27
require "transform"
28
29
#
30
# computeSettingsCombinations(ast) -> settingsCombiations
31
#
32
# Computes an array of settings maps, where a settings map constitutes
33
# a configuration for the assembly code being generated. The map
34
# contains key value pairs where keys are settings names (strings) and
35
# the values are booleans (true for enabled, false for disabled).
36
#
37
38
def computeSettingsCombinations(ast)
39
  settingsCombinations = []
40
  
41
  def settingsCombinator(settingsCombinations, mapSoFar, remaining)
42
    if remaining.empty?
43
      settingsCombinations << mapSoFar
44
      return
45
    end
46
    
47
    newMap = mapSoFar.dup
48
    newMap[remaining[0]] = true
49
    settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
50
    
51
    newMap = mapSoFar.dup
52
    newMap[remaining[0]] = false
53
    settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
54
  end
55
  
56
  settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + ["X86", "ARMv7"]).uniq)
57
  
58
  settingsCombinations
59
end
60
61
#
62
# forSettings(concreteSettings, ast) {
63
#     | concreteSettings, lowLevelAST, backend | ... }
64
#
65
# Determines if the settings combination is valid, and if so, calls
66
# the block with the information you need to generate code.
67
#
68
69
def forSettings(concreteSettings, ast)
70
  # Check which architectures this combinator claims to support.
71
  numClaimedBackends = 0
72
  selectedBackend = nil
73
  BACKENDS.each {
74
    | backend |
75
    isSupported = concreteSettings[backend]
76
    raise unless isSupported != nil
77
    numClaimedBackends += if isSupported then 1 else 0 end
78
    if isSupported
79
      selectedBackend = backend
80
    end
81
  }
82
  
83
  return if numClaimedBackends > 1
84
  
85
  # Resolve the AST down to a low-level form (no macros or conditionals).
86
  lowLevelAST = ast.resolveSettings(concreteSettings)
87
  
88
  yield concreteSettings, lowLevelAST, selectedBackend
89
end
90
91
#
92
# forEachValidSettingsCombination(ast) {
93
#     | concreteSettings, ast, backend, index | ... }
94
#
95
# forEachValidSettingsCombination(ast, settingsCombinations) {
96
#     | concreteSettings, ast, backend, index | ... }
97
#
98
# Executes the given block for each valid settings combination in the
99
# settings map. The ast passed into the block is resolved
100
# (ast.resolve) against the settings.
101
#
102
# The first form will call computeSettingsCombinations(ast) for you.
103
#
104
105
def forEachValidSettingsCombination(ast, *optionalSettingsCombinations)
106
  raise if optionalSettingsCombinations.size > 1
107
  
108
  if optionalSettingsCombinations.empty?
109
    settingsCombinations = computeSettingsCombinations(ast)
110
  else
111
    settingsCombinations = optionalSettingsCombiations[0]
112
  end
113
  
114
  settingsCombinations.each_with_index {
115
    | concreteSettings, index |
116
    forSettings(concreteSettings, ast) {
117
      | concreteSettings_, lowLevelAST, backend |
118
      yield concreteSettings, lowLevelAST, backend, index
119
    }
120
  }
121
end
122
123
#
124
# cppSettingsTest(concreteSettings)
125
#
126
# Returns the C++ code used to test if we are in a configuration that
127
# corresponds to the given concrete settings.
128
#
129
130
def cppSettingsTest(concreteSettings)
131
  "#if " + concreteSettings.to_a.collect{
132
    | pair |
133
    (if pair[1]
134
       ""
135
     else
136
       "!"
137
     end) + "OFFLINE_ASM_" + pair[0]
138
  }.join(" && ")
139
end
140
141
#
142
# isASTErroneous(ast)
143
#
144
# Tests to see if the AST claims that there is an error - i.e. if the
145
# user's code, after settings resolution, has Error nodes.
146
#
147
148
def isASTErroneous(ast)
149
  not ast.filter(Error).empty?
150
end
151
152
#
153
# assertConfiguration(concreteSettings)
154
#
155
# Emits a check that asserts that we're using the given configuration.
156
#
157
158
def assertConfiguration(concreteSettings)
159
  $output.puts cppSettingsTest(concreteSettings)
160
  $output.puts "#else"
161
  $output.puts "#error \"Configuration mismatch.\""
162
  $output.puts "#endif"
163
end
164
165
#
166
# emitCodeInConfiguration(concreteSettings, ast, backend) {
167
#     | concreteSettings, ast, backend | ... }
168
#
169
# Emits all relevant guards to see if the configuration holds and
170
# calls the block if the configuration is not erroneous.
171
#
172
173
def emitCodeInConfiguration(concreteSettings, ast, backend)
174
  $output.puts cppSettingsTest(concreteSettings)
175
  
176
  if isASTErroneous(ast)
177
    $output.puts "#error \"Invalid configuration.\""
178
  elsif not WORKING_BACKENDS.include? backend
179
    $output.puts "#error \"This backend is not supported yet.\""
180
  else
181
    yield concreteSettings, ast, backend
182
  end
183
  
184
  $output.puts "#endif"
185
end
186
187
#
188
# emitCodeInAllConfigurations(ast) {
189
#     | concreteSettings, ast, backend, index | ... }
190
#
191
# Emits guard codes for all valid configurations, and calls the block
192
# for those configurations that are valid and not erroneous.
193
#
194
195
def emitCodeInAllConfigurations(ast)
196
  forEachValidSettingsCombination(ast) {
197
    | concreteSettings, lowLevelAST, backend, index |
198
    $output.puts cppSettingsTest(concreteSettings)
199
    yield concreteSettings, lowLevelAST, backend, index
200
    $output.puts "#endif"
201
  }
202
end
203
204
205
- Source/JavaScriptCore/offlineasm/transform.rb +342 lines
Line 0 Source/JavaScriptCore/offlineasm/transform.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
require "ast"
25
26
#
27
# node.resolveSettings(settings)
28
#
29
# Construct a new AST that does not have any IfThenElse nodes by
30
# substituting concrete boolean values for each Setting.
31
#
32
33
class Node
34
  def resolveSettings(settings)
35
    mapChildren {
36
      | child |
37
      child.resolveSettings(settings)
38
    }
39
  end
40
end
41
42
class True
43
  def resolveSettings(settings)
44
    self
45
  end
46
end
47
48
class False
49
  def resolveSettings(settings)
50
    self
51
  end
52
end
53
54
class Setting
55
  def resolveSettings(settings)
56
    settings[@name].asNode
57
  end
58
end
59
60
class And
61
  def resolveSettings(settings)
62
    (@left.resolveSettings(settings).value and @right.resolveSettings(settings).value).asNode
63
  end
64
end
65
66
class Or
67
  def resolveSettings(settings)
68
    (@left.resolveSettings(settings).value or @right.resolveSettings(settings).value).asNode
69
  end
70
end
71
72
class Not
73
  def resolveSettings(settings)
74
    (not @child.resolveSettings(settings).value).asNode
75
  end
76
end
77
78
class IfThenElse
79
  def resolveSettings(settings)
80
    if @predicate.resolveSettings(settings).value
81
      @thenCase.resolveSettings(settings)
82
    else
83
      @elseCase.resolveSettings(settings)
84
    end
85
  end
86
end
87
88
class Sequence
89
  def resolveSettings(settings)
90
    newList = []
91
    @list.each {
92
      | item |
93
      item = item.resolveSettings(settings)
94
      if item.is_a? Sequence
95
        newList += item.list
96
      else
97
        newList << item
98
      end
99
    }
100
    Sequence.new(codeOrigin, newList)
101
  end
102
end
103
104
#
105
# node.demacroify(macros)
106
# node.substitute(mapping)
107
#
108
# demacroify() constructs a new AST that does not have any Macro
109
# nodes, while substitute() replaces Variable nodes with the given
110
# nodes in the mapping.
111
#
112
113
class Node
114
  def demacroify(macros)
115
    mapChildren {
116
      | child |
117
      child.demacroify(macros)
118
    }
119
  end
120
  
121
  def substitute(mapping)
122
    mapChildren {
123
      | child |
124
      child.substitute(mapping)
125
    }
126
  end
127
  
128
  def substituteLabels(mapping)
129
    mapChildren {
130
      | child |
131
      child.substituteLabels(mapping)
132
    }
133
  end
134
end
135
136
class Macro
137
  def substitute(mapping)
138
    myMapping = {}
139
    mapping.each_pair {
140
      | key, value |
141
      unless @variables.include? key
142
        myMapping[key] = value
143
      end
144
    }
145
    mapChildren {
146
      | child |
147
      child.substitute(myMapping)
148
    }
149
  end
150
end
151
152
class Variable
153
  def substitute(mapping)
154
    if mapping[self]
155
      mapping[self]
156
    else
157
      self
158
    end
159
  end
160
end
161
162
class LocalLabel
163
  def substituteLabels(mapping)
164
    if mapping[self]
165
      mapping[self]
166
    else
167
      self
168
    end
169
  end
170
end
171
172
class Sequence
173
  def substitute(constants)
174
    newList = []
175
    myConstants = constants.dup
176
    @list.each {
177
      | item |
178
      if item.is_a? ConstDecl
179
        myConstants[item.variable] = item.value.substitute(myConstants)
180
      else
181
        newList << item.substitute(myConstants)
182
      end
183
    }
184
    Sequence.new(codeOrigin, newList)
185
  end
186
  
187
  def renameLabels(comment)
188
    mapping = {}
189
    
190
    @list.each {
191
      | item |
192
      if item.is_a? LocalLabel
193
        mapping[item] = LocalLabel.unique(if comment then comment + "_" else "" end + item.cleanName)
194
      end
195
    }
196
    
197
    substituteLabels(mapping)
198
  end
199
  
200
  def demacroify(macros)
201
    myMacros = macros.dup
202
    @list.each {
203
      | item |
204
      if item.is_a? Macro
205
        myMacros[item.name] = item
206
      end
207
    }
208
    newList = []
209
    @list.each {
210
      | item |
211
      if item.is_a? Macro
212
        # Ignore.
213
      elsif item.is_a? MacroCall
214
        mapping = {}
215
        myMyMacros = myMacros.dup
216
        raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros[item.name]
217
        raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item.operands.size == myMacros[item.name].variables.size
218
        item.operands.size.times {
219
          | idx |
220
          if item.operands[idx].is_a? Variable and myMacros[item.operands[idx].name]
221
            myMyMacros[myMacros[item.name].variables[idx].name] = myMacros[item.operands[idx].name]
222
            mapping[myMacros[item.name].variables[idx].name] = nil
223
          elsif item.operands[idx].is_a? Macro
224
            myMyMacros[myMacros[item.name].variables[idx].name] = item.operands[idx]
225
            mapping[myMacros[item.name].variables[idx].name] = nil
226
          else
227
            myMyMacros[myMacros[item.name].variables[idx]] = nil
228
            mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
229
          end
230
        }
231
        newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
232
      else
233
        newList << item.demacroify(myMacros)
234
      end
235
    }
236
    Sequence.new(codeOrigin, newList).substitute({})
237
  end
238
end
239
240
#
241
# node.resolveOffsets(offsets, sizes)
242
#
243
# Construct a new AST that has offset values instead of symbolic
244
# offsets.
245
#
246
247
class Node
248
  def resolveOffsets(offsets, sizes)
249
    mapChildren {
250
      | child |
251
      child.resolveOffsets(offsets, sizes)
252
    }
253
  end
254
end
255
256
class StructOffset
257
  def resolveOffsets(offsets, sizes)
258
    if offsets[self]
259
      Immediate.new(codeOrigin, offsets[self])
260
    else
261
      self
262
    end
263
  end
264
end
265
266
class Sizeof
267
  def resolveOffsets(offsets, sizes)
268
    if sizes[self]
269
      Immediate.new(codeOrigin, sizes[self])
270
    else
271
      puts "Could not find #{self.inspect} in #{sizes.keys.inspect}"
272
      puts "sizes = #{sizes.inspect}"
273
      self
274
    end
275
  end
276
end
277
278
#
279
# node.fold
280
#
281
# Resolve constant references and compute arithmetic expressions.
282
#
283
284
class Node
285
  def fold
286
    mapChildren {
287
      | child |
288
      child.fold
289
    }
290
  end
291
end
292
293
class AddImmediates
294
  def fold
295
    @left = @left.fold
296
    @right = @right.fold
297
    return self unless @left.is_a? Immediate
298
    return self unless @right.is_a? Immediate
299
    Immediate.new(codeOrigin, @left.value + @right.value)
300
  end
301
end
302
303
class SubImmediates
304
  def fold
305
    @left = @left.fold
306
    @right = @right.fold
307
    return self unless @left.is_a? Immediate
308
    return self unless @right.is_a? Immediate
309
    Immediate.new(codeOrigin, @left.value - @right.value)
310
  end
311
end
312
313
class MulImmediates
314
  def fold
315
    @left = @left.fold
316
    @right = @right.fold
317
    return self unless @left.is_a? Immediate
318
    return self unless @right.is_a? Immediate
319
    Immediate.new(codeOrigin, @left.value * @right.value)
320
  end
321
end
322
323
class NegImmediate
324
  def fold
325
    @child = @child.fold
326
    return self unless @child.is_a? Immediate
327
    Immediate.new(codeOrigin, -@child.value)
328
  end
329
end
330
331
#
332
# node.resolveAfterSettings(offsets, sizes)
333
#
334
# Compile assembly against a set of offsets.
335
#
336
337
class Node
338
  def resolve(offsets, sizes)
339
    demacroify({}).resolveOffsets(offsets, sizes).fold
340
  end
341
end
342
- Source/JavaScriptCore/offlineasm/x86.rb +673 lines
Line 0 Source/JavaScriptCore/offlineasm/x86.rb_sec1
1
# Copyright (C) 2011 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
23
24
class RegisterID
25
  def supports8BitOnX86
26
    case name
27
    when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3"
28
      true
29
    when "t4", "cfr"
30
      false
31
    else
32
      raise
33
    end
34
  end
35
  
36
  def x86Operand(kind)
37
    case name
38
    when "t0", "a0", "r0"
39
      case kind
40
      when :byte
41
        "%al"
42
      when :half
43
        "%ax"
44
      when :int
45
        "%eax"
46
      else
47
        raise
48
      end
49
    when "t1", "a1", "r1"
50
      case kind
51
      when :byte
52
        "%dl"
53
      when :half
54
        "%dx"
55
      when :int
56
        "%edx"
57
      else
58
        raise
59
      end
60
    when "t2"
61
      case kind
62
      when :byte
63
        "%cl"
64
      when :half
65
        "%cx"
66
      when :int
67
        "%ecx"
68
      else
69
        raise
70
      end
71
    when "t3"
72
      case kind
73
      when :byte
74
        "%bl"
75
      when :half
76
        "%bx"
77
      when :int
78
        "%ebx"
79
      else
80
        raise
81
      end
82
    when "t4"
83
      case kind
84
      when :byte
85
        "%sil"
86
      when :half
87
        "%si"
88
      when :int
89
        "%esi"
90
      else
91
        raise
92
      end
93
    when "cfr"
94
      case kind
95
      when :byte
96
        "%dil"
97
      when :half
98
        "%di"
99
      when :int
100
        "%edi"
101
      else
102
        raise
103
      end
104
    when "sp"
105
      case kind
106
      when :byte
107
        "%spl"
108
      when :half
109
        "%sp"
110
      when :int
111
        "%esp"
112
      else
113
        raise
114
      end
115
    else
116
      raise
117
    end
118
  end
119
  def x86CallOperand(kind)
120
    "*#{x86Operand(kind)}"
121
  end
122
end
123
124
class FPRegisterID
125
  def x86Operand(kind)
126
    raise unless kind == :double
127
    case name
128
    when "ft0", "fa0", "fr"
129
      "%xmm0"
130
    when "ft1", "fa1"
131
      "%xmm1"
132
    when "ft2", "fa2"
133
      "%xmm2"
134
    when "ft3", "fa3"
135
      "%xmm3"
136
    when "ft4"
137
      "%xmm4"
138
    when "ft5"
139
      "%xmm5"
140
    else
141
      raise
142
    end
143
  end
144
  def x86CallOperand(kind)
145
    "*#{x86Operand(kind)}"
146
  end
147
end
148
149
class Immediate
150
  def x86Operand(kind)
151
    "$#{value}"
152
  end
153
  def x86CallOperand(kind)
154
    "#{value}"
155
  end
156
end
157
158
class Address
159
  def supports8BitOnX86
160
    true
161
  end
162
    
163
  def x86Operand(kind)
164
    "#{offset.value}(#{base.x86Operand(:int)})"
165
  end
166
  def x86CallOperand(kind)
167
    "*#{x86Operand(kind)}"
168
  end
169
end
170
171
class BaseIndex
172
  def supports8BitOnX86
173
    true
174
  end
175
    
176
  def x86Operand(kind)
177
    "#{offset.value}(#{base.x86Operand(:int)}, #{index.x86Operand(:int)}, #{scale})"
178
  end
179
180
  def x86CallOperand(kind)
181
    "*#{x86operand(kind)}"
182
  end
183
end
184
185
class AbsoluteAddress
186
  def supports8BitOnX86
187
    true
188
  end
189
    
190
  def x86Operand(kind)
191
    "#{address.value}"
192
  end
193
194
  def x86CallOperand(kind)
195
    "*#{address.value}"
196
  end
197
end
198
199
class LabelReference
200
  def x86Label
201
    sanitizeLabelName(name)
202
  end
203
  def x86CallOperand(kind)
204
    x86Label
205
  end
206
end
207
208
class LocalLabelReference
209
  def x86Label
210
    "L_offlineasm_"+name[1..-1]
211
  end
212
  def x86CallOperand(kind)
213
    x86Label
214
  end
215
end
216
217
class Instruction
218
  def x86Operands(*kinds)
219
    raise unless kinds.size == operands.size
220
    result = []
221
    kinds.size.times {
222
      | idx |
223
      result << operands[idx].x86Operand(kinds[idx])
224
    }
225
    result.join(", ")
226
  end
227
228
  def x86Suffix(kind)
229
    case kind
230
    when :byte
231
      "b"
232
    when :half
233
      "w"
234
    when :int
235
      "l"
236
    when :double
237
      "sd"
238
    else
239
      raise
240
    end
241
  end
242
  
243
  def handleX86OpWithNumOperands(opcode, kind, numOperands)
244
    if numOperands == 3
245
      if operands[0] == operands[2]
246
        $asm.puts "\t#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
247
      elsif operands[1] == operands[2]
248
        $asm.puts "\t#{opcode} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
249
      else
250
        $asm.puts "\tmov#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
251
        $asm.puts "\t#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
252
      end
253
    else
254
      $asm.puts "\t#{opcode} #{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
255
    end
256
  end
257
  
258
  def handleX86Op(opcode, kind)
259
    handleX86OpWithNumOperands(opcode, kind, operands.size)
260
  end
261
  
262
  def handleX86Shift(opcode, kind)
263
    if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
264
      $asm.puts "\t#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
265
    else
266
      $asm.puts "\txchgl #{operands[0].x86Operand(:int)}, %ecx"
267
      $asm.puts "\t#{opcode} %cl, #{operands[1].x86Operand(kind)}"
268
      $asm.puts "\txchgl #{operands[0].x86Operand(:int)}, %ecx"
269
    end
270
  end
271
  
272
  def handleX86DoubleBranch(branchOpcode, mode)
273
    case mode
274
    when :normal
275
      $asm.puts "\tucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
276
    when :reverse
277
      $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
278
    else
279
      raise mode.inspect
280
    end
281
    $asm.puts "\t#{branchOpcode} #{operands[2].x86Label}"
282
  end
283
  
284
  def handleX86IntCompare(opcodeSuffix, kind)
285
    if operands[0].is_a? Immediate and operands[0].value == 0 and operands[1].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
286
      $asm.puts "\ttest#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}"
287
    elsif operands[1].is_a? Immediate and operands[1].value == 0 and operands[0].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
288
      $asm.puts "\ttest#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}"
289
    else
290
      $asm.puts "\tcmp#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
291
    end
292
  end
293
  
294
  def handleX86IntBranch(branchOpcode, kind)
295
    handleX86IntCompare(branchOpcode[1..-1], kind)
296
    $asm.puts "\t#{branchOpcode} #{operands[2].x86Label}"
297
  end
298
  
299
  def handleX86Set(setOpcode, operand)
300
    if operand.supports8BitOnX86
301
      $asm.puts "\t#{setOpcode} #{operand.x86Operand(:byte)}"
302
      $asm.puts "\tmovzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
303
    else
304
      $asm.puts "\txchgl #{operand.x86Operand(:int)}, %eax"
305
      $asm.puts "\t#{setOpcode} %al"
306
      $asm.puts "\tmovzbl %al, %eax"
307
      $asm.puts "\txchgl #{operand.x86Operand(:int)}, %eax"
308
    end
309
  end
310
  
311
  def handleX86IntCompareSet(setOpcode, kind)
312
    handleX86IntCompare(setOpcode[3..-1], kind)
313
    handleX86Set(setOpcode, operands[2])
314
  end
315
  
316
  def handleX86Test(kind)
317
    value = operands[0]
318
    case operands.size
319
    when 2
320
      mask = Immediate.new(codeOrigin, -1)
321
    when 3
322
      mask = operands[1]
323
    else
324
      raise "Expected 2 or 3 operands, but got #{operands.size} at #{codeOriginString}"
325
    end
326
    
327
    if mask.is_a? Immediate and mask.value == -1
328
      if value.is_a? RegisterID
329
        $asm.puts "\ttest#{x86Suffix(kind)} #{value.x86Operand(kind)}, #{value.x86Operand(kind)}"
330
      else
331
        $asm.puts "\tcmp#{x86Suffix(kind)} $0, #{value.x86Operand(kind)}"
332
      end
333
    else
334
      $asm.puts "\ttest#{x86Suffix(kind)} #{mask.x86Operand(kind)}, #{value.x86Operand(kind)}"
335
    end
336
  end
337
  
338
  def handleX86BranchTest(branchOpcode, kind)
339
    handleX86Test(kind)
340
    $asm.puts "\t#{branchOpcode} #{operands.last.x86Label}"
341
  end
342
  
343
  def handleX86SetTest(setOpcode, kind)
344
    handleX86Test(kind)
345
    handleX86Set(setOpcode, operands.last)
346
  end
347
  
348
  def handleX86OpBranch(opcode, branchOpcode, kind)
349
    handleX86OpWithNumOperands(opcode, kind, operands.size - 1)
350
    case operands.size
351
    when 4
352
      jumpTarget = operands[3]
353
    when 3
354
      jumpTarget = operands[2]
355
    else
356
      raise self.inspect
357
    end
358
    $asm.puts "\t#{branchOpcode} #{jumpTarget.x86Label}"
359
  end
360
  
361
  def handleX86SubBranch(branchOpcode, kind)
362
    if operands.size == 4 and operands[1] == operands[2]
363
      $asm.puts "\tnegl #{operands[2].x86Operand(:int)}"
364
      $asm.puts "\taddl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
365
    else
366
      handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind, operands.size - 1)
367
    end
368
    case operands.size
369
    when 4
370
      jumpTarget = operands[3]
371
    when 3
372
      jumpTarget = operands[2]
373
    else
374
      raise self.inspect
375
    end
376
    $asm.puts "\t#{branchOpcode} #{jumpTarget.x86Label}"
377
  end
378
  
379
  def lowerX86
380
    $asm.comment codeOriginString
381
    case opcode
382
    when "addi", "addp"
383
      if operands.size == 3 and operands[0].is_a? Immediate
384
        raise unless operands[1].is_a? RegisterID
385
        raise unless operands[2].is_a? RegisterID
386
        if operands[0].value == 0
387
          unless operands[1] == operands[2]
388
            $asm.puts "\tmovl #{operands[1].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
389
          end
390
        else
391
          $asm.puts "\tleal #{operands[0].value}(#{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
392
        end
393
      elsif operands.size == 3 and operands[0].is_a? RegisterID
394
        raise unless operands[1].is_a? RegisterID
395
        raise unless operands[2].is_a? RegisterID
396
        $asm.puts "\tleal (#{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
397
      else
398
        unless Immediate.new(nil, 0) == operands[0]
399
          $asm.puts "\taddl #{x86Operands(:int, :int)}"
400
        end
401
      end
402
    when "andi", "andp"
403
      handleX86Op("andl", :int)
404
    when "lshifti"
405
      handleX86Shift("sall", :int)
406
    when "muli"
407
      if operands.size == 3 and operands[0].is_a? Immediate
408
        $asm.puts "\timull #{x86Operands(:int, :int, :int)}"
409
      else
410
        # FIXME: could do some peephole in case the left operand is immediate and it's
411
        # a power of two.
412
        handleX86Op("imull", :int)
413
      end
414
    when "negi"
415
      $asm.puts "\tnegl #{x86Operands(:int)}"
416
    when "noti"
417
      $asm.puts "\tnotl #{x86Operands(:int)}"
418
    when "ori", "orp"
419
      handleX86Op("orl", :int)
420
    when "rshifti"
421
      handleX86Shift("sarl", :int)
422
    when "urshifti"
423
      handleX86Shift("shrl", :int)
424
    when "subi", "subp"
425
      if operands.size == 3 and operands[1] == operands[2]
426
        $asm.puts "\tnegl #{operands[2].x86Operand(:int)}"
427
        $asm.puts "\taddl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
428
      else
429
        handleX86Op("subl", :int)
430
      end
431
    when "xori", "xorp"
432
      handleX86Op("xorl", :int)
433
    when "loadi", "storei", "loadp", "storep"
434
      $asm.puts "\tmovl #{x86Operands(:int, :int)}"
435
    when "loadb"
436
      $asm.puts "\tmovzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
437
    when "loadh"
438
      $asm.puts "\tmovzwl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
439
    when "storeb"
440
      $asm.puts "\tmovb #{x86Operands(:byte, :byte)}"
441
    when "loadd", "moved", "stored"
442
      $asm.puts "\tmovsd #{x86Operands(:double, :double)}"
443
    when "addd"
444
      $asm.puts "\taddsd #{x86Operands(:double, :double)}"
445
    when "divd"
446
      $asm.puts "\tdivsd #{x86Operands(:double, :double)}"
447
    when "subd"
448
      $asm.puts "\tsubsd #{x86Operands(:double, :double)}"
449
    when "muld"
450
      $asm.puts "\tmulsd #{x86Operands(:double, :double)}"
451
    when "sqrtd"
452
      $asm.puts "\tsqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
453
    when "ci2d"
454
      $asm.puts "\tcvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
455
    when "bdeq"
456
      isUnordered = LocalLabel.unique("bdeq")
457
      $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
458
      $asm.puts "\tjp #{LabelReference.new(codeOrigin, isUnordered).x86Label}"
459
      $asm.puts "\tje #{LabelReference.new(codeOrigin, operands[2]).x86Label}"
460
      isUnordered.lower("X86")
461
    when "bdneq"
462
      handleX86DoubleBranch("jne", :normal)
463
    when "bdgt"
464
      handleX86DoubleBranch("ja", :normal)
465
    when "bdgteq"
466
      handleX86DoubleBranch("jae", :normal)
467
    when "bdlt"
468
      handleX86DoubleBranch("ja", :reverse)
469
    when "bdlteq"
470
      handleX86DoubleBranch("jae", :reverse)
471
    when "bdequn"
472
      handleX86DoubleBranch("je", :normal)
473
    when "bdnequn"
474
      isUnordered = LocalLabel.unique("bdnequn")
475
      isEqual = LocalLabel.unique("bdnequn")
476
      $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
477
      $asm.puts "\tjp #{LabelReference.new(codeOrigin, isUnordered).x86Label}"
478
      $asm.puts "\tje #{LabelReference.new(codeOrigin, isEqual).x86Label}"
479
      isUnordered.lower("X86")
480
      $asm.puts "\tjmp #{operands[2].x86Label}"
481
      isEqual.lower("X86")
482
    when "bdgtun"
483
      handleX86DoubleBranch("jb", :reverse)
484
    when "bdgtequn"
485
      handleX86DoubleBranch("jbe", :reverse)
486
    when "bdltun"
487
      handleX86DoubleBranch("jb", :normal)
488
    when "bdltequn"
489
      handleX86DoubleBranch("jbe", :normal)
490
    when "btd2i"
491
      $asm.puts "\tcvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
492
      $asm.puts "\tcmpl $0x80000000 #{operands[1].x86Operand(:int)}"
493
      $asm.puts "\tje #{operands[2].x86Label}"
494
    when "td2i"
495
      $asm.puts "\tcvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
496
    when "bcd2i"
497
      $asm.puts "\tcvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
498
      $asm.puts "\ttestl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
499
      $asm.puts "\tje #{operands[2].x86Label}"
500
      $asm.puts "\tcvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
501
      $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, %xmm7"
502
      $asm.puts "\tjp #{operands[2].x86Label}"
503
      $asm.puts "\tjne #{operands[2].x86Label}"
504
    when "movdz"
505
      $asm.puts "\txorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
506
    when "pop"
507
      $asm.puts "\tpop #{operands[0].x86Operand(:int)}"
508
    when "push"
509
      $asm.puts "\tpush #{operands[0].x86Operand(:int)}"
510
    when "move", "sxi2p", "zxi2p"
511
      if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
512
        $asm.puts "\txorl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
513
      elsif operands[0] != operands[1]
514
        $asm.puts "\tmovl #{x86Operands(:int, :int)}"
515
      end
516
    when "nop"
517
      $asm.puts "\tnop"
518
    when "bieq", "bpeq"
519
      handleX86IntBranch("je", :int)
520
    when "bineq", "bpneq"
521
      handleX86IntBranch("jne", :int)
522
    when "bia", "bpa"
523
      handleX86IntBranch("ja", :int)
524
    when "biaeq", "bpaeq"
525
      handleX86IntBranch("jae", :int)
526
    when "bib", "bpb"
527
      handleX86IntBranch("jb", :int)
528
    when "bibeq", "bpbeq"
529
      handleX86IntBranch("jbe", :int)
530
    when "bigt", "bpgt"
531
      handleX86IntBranch("jg", :int)
532
    when "bigteq", "bpgteq"
533
      handleX86IntBranch("jge", :int)
534
    when "bilt", "bplt"
535
      handleX86IntBranch("jl", :int)
536
    when "bilteq", "bplteq"
537
      handleX86IntBranch("jle", :int)
538
    when "bbeq"
539
      handleX86IntBranch("je", :byte)
540
    when "bbneq"
541
      handleX86IntBranch("jne", :byte)
542
    when "bba"
543
      handleX86IntBranch("ja", :byte)
544
    when "bbaeq"
545
      handleX86IntBranch("jae", :byte)
546
    when "bbb"
547
      handleX86IntBranch("jb", :byte)
548
    when "bbbeq"
549
      handleX86IntBranch("jbe", :byte)
550
    when "bbgt"
551
      handleX86IntBranch("jg", :byte)
552
    when "bbgteq"
553
      handleX86IntBranch("jge", :byte)
554
    when "bblt"
555
      handleX86IntBranch("jl", :byte)
556
    when "bblteq"
557
      handleX86IntBranch("jlteq", :byte)
558
    when "btio", "btpo"
559
      handleX86BranchTest("jo", :int)
560
    when "btis", "btps"
561
      handleX86BranchTest("js", :int)
562
    when "btiz", "btpz"
563
      handleX86BranchTest("jz", :int)
564
    when "btinz", "btpnz"
565
      handleX86BranchTest("jnz", :int)
566
    when "btbo"
567
      handleX86BranchTest("jo", :byte)
568
    when "btbs"
569
      handleX86BranchTest("js", :byte)
570
    when "btbz"
571
      handleX86BranchTest("jz", :byte)
572
    when "btbnz"
573
      handleX86BranchTest("jnz", :byte)
574
    when "jmp"
575
      $asm.puts "\tjmp #{operands[0].x86CallOperand(:int)}"
576
    when "baddio", "baddpo"
577
      handleX86OpBranch("addl", "jo", :int)
578
    when "baddis", "baddps"
579
      handleX86OpBranch("addl", "js", :int)
580
    when "baddiz", "baddpz"
581
      handleX86OpBranch("addl", "jz", :int)
582
    when "baddinz", "baddpnz"
583
      handleX86OpBranch("addl", "jnz", :int)
584
    when "bsubio"
585
      handleX86SubBranch("jo", :int)
586
    when "bsubis"
587
      handleX86SubBranch("js", :int)
588
    when "bsubiz"
589
      handleX86SubBranch("jz", :int)
590
    when "bsubinz"
591
      handleX86SubBranch("jnz", :int)
592
    when "bmulio"
593
      handleX86OpBranch("imull", "jo", :int)
594
    when "bmulis"
595
      handleX86OpBranch("imull", "js", :int)
596
    when "bmuliz"
597
      handleX86OpBranch("imull", "jz", :int)
598
    when "bmulinz"
599
      handleX86OpBranch("imull", "jnz", :int)
600
    when "borio"
601
      handleX86OpBranch("orl", "jo", :int)
602
    when "boris"
603
      handleX86OpBranch("orl", "js", :int)
604
    when "boriz"
605
      handleX86OpBranch("orl", "jz", :int)
606
    when "borinz"
607
      handleX86OpBranch("orl", "jnz", :int)
608
    when "break"
609
      $asm.puts "\tint $3"
610
    when "call"
611
      $asm.puts "\tcall #{operands[0].x86CallOperand(:int)}"
612
    when "ret"
613
      $asm.puts "\tret"
614
    when "cieq", "cpeq"
615
      handleX86IntCompareSet("sete", :int)
616
    when "cineq", "cpneq"
617
      handleX86IntCompareSet("setne", :int)
618
    when "cia", "cpa"
619
      handleX86IntCompareSet("seta", :int)
620
    when "ciaeq", "cpaeq"
621
      handleX86IntCompareSet("setae", :int)
622
    when "cib", "cpb"
623
      handleX86IntCompareSet("setb", :int)
624
    when "cibeq", "cpbeq"
625
      handleX86IntCompareSet("setbe", :int)
626
    when "cigt", "cpgt"
627
      handleX86IntCompareSet("setg", :int)
628
    when "cigteq", "cpgteq"
629
      handleX86IntCompareSet("setge", :int)
630
    when "cilt", "cplt"
631
      handleX86IntCompareSet("setl", :int)
632
    when "cilteq", "cplteq"
633
      handleX86IntCompareSet("setle", :int)
634
    when "tio"
635
      handleX86SetTest("seto", :int)
636
    when "tis"
637
      handleX86SetTest("sets", :int)
638
    when "tiz"
639
      handleX86SetTest("setz", :int)
640
    when "tinz"
641
      handleX86SetTest("setnz", :int)
642
    when "tbo"
643
      handleX86SetTest("seto", :byte)
644
    when "tbs"
645
      handleX86SetTest("sets", :byte)
646
    when "tbz"
647
      handleX86SetTest("setz", :byte)
648
    when "tbnz"
649
      handleX86SetTest("setnz", :byte)
650
    when "peek"
651
      $asm.puts "\tmovl #{operands[0].value * 4}(%esp), #{operands[1].x86Operand(:int)}"
652
    when "poke"
653
      $asm.puts "\tmovl #{operands[0].x86Operand(:int)}, #{operands[1].value * 4}(%esp)"
654
    when "cdqi"
655
      $asm.puts "\tcdq"
656
    when "idivi"
657
      $asm.puts "\tidivl #{operands[0].x86Operand(:int)}"
658
    when "fii2d"
659
      $asm.puts "\tmovd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
660
      $asm.puts "\tmovd #{operands[1].x86Operand(:int)}, %xmm7"
661
      $asm.puts "\tpsllq $32, %xmm7"
662
      $asm.puts "\tpor %xmm7, #{operands[2].x86Operand(:double)}"
663
    when "fd2ii"
664
      $asm.puts "\tmovd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
665
      $asm.puts "\tmovsd #{operands[0].x86Operand(:double)}, %xmm7"
666
      $asm.puts "\tpsrlq $32, %xmm7"
667
      $asm.puts "\tmovsd %xmm7, #{operands[2].x86Operand(:int)}"
668
    else
669
      raise "Bad opcode: #{opcode}"
670
    end
671
  end
672
end
673
- Source/JavaScriptCore/runtime/CodeSpecializationKind.h +36 lines
Line 0 Source/JavaScriptCore/runtime/CodeSpecializationKind.h_sec1
1
/*
2
 * Copyright (C) 2012 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 CodeSpecializationKind_h
27
#define CodeSpecializationKind_h
28
29
namespace JSC {
30
31
enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
32
33
} // namespace JSC
34
35
#endif // CodeSpecializationKind_h
36
- Source/JavaScriptCore/runtime/CommonSlowPaths.h +33 lines
Lines 27-32 Source/JavaScriptCore/runtime/CommonSlowPaths.h_sec1
27
#define CommonSlowPaths_h
27
#define CommonSlowPaths_h
28
28
29
#include "CodeBlock.h"
29
#include "CodeBlock.h"
30
#include "CodeSpecializationKind.h"
30
#include "ExceptionHelpers.h"
31
#include "ExceptionHelpers.h"
31
#include "JSArray.h"
32
#include "JSArray.h"
32
33
Lines 41-46 namespace JSC { Source/JavaScriptCore/runtime/CommonSlowPaths.h_sec2
41
42
42
namespace CommonSlowPaths {
43
namespace CommonSlowPaths {
43
44
45
ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFile, CodeSpecializationKind kind)
46
{
47
    JSFunction* callee = asFunction(exec->callee());
48
    ASSERT(!callee->isHostFunction());
49
    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
50
    int argumentCountIncludingThis = exec->argumentCountIncludingThis();
51
52
    // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
53
    if (!registerFile->grow(exec->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
54
        return 0;
55
56
    ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
57
58
    // Too few arguments -- copy call frame and arguments, then fill in missing arguments with undefined.
59
    size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
60
    Register* src = exec->registers();
61
    Register* dst = exec->registers() + delta;
62
63
    int i;
64
    int end = -ExecState::offsetFor(argumentCountIncludingThis);
65
    for (i = -1; i >= end; --i)
66
        dst[i] = src[i];
67
68
    end -= delta;
69
    for ( ; i >= end; --i)
70
        dst[i] = jsUndefined();
71
72
    ExecState* newExec = ExecState::create(dst);
73
    ASSERT((void*)newExec <= registerFile->end());
74
    return newExec;
75
}
76
44
ALWAYS_INLINE bool opInstanceOfSlow(ExecState* exec, JSValue value, JSValue baseVal, JSValue proto)
77
ALWAYS_INLINE bool opInstanceOfSlow(ExecState* exec, JSValue value, JSValue baseVal, JSValue proto)
45
{
78
{
46
    ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
79
    ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
- Source/JavaScriptCore/runtime/Executable.cpp -10 / +50 lines
Lines 29-34 Source/JavaScriptCore/runtime/Executable.cpp_sec1
29
#include "BytecodeGenerator.h"
29
#include "BytecodeGenerator.h"
30
#include "CodeBlock.h"
30
#include "CodeBlock.h"
31
#include "DFGDriver.h"
31
#include "DFGDriver.h"
32
#include "ExecutionHarness.h"
32
#include "JIT.h"
33
#include "JIT.h"
33
#include "JITDriver.h"
34
#include "JITDriver.h"
34
#include "Parser.h"
35
#include "Parser.h"
Lines 84-90 Intrinsic NativeExecutable::intrinsic() Source/JavaScriptCore/runtime/Executable.cpp_sec2
84
template<typename T>
85
template<typename T>
85
static void jettisonCodeBlock(JSGlobalData& globalData, OwnPtr<T>& codeBlock)
86
static void jettisonCodeBlock(JSGlobalData& globalData, OwnPtr<T>& codeBlock)
86
{
87
{
87
    ASSERT(codeBlock->getJITType() != JITCode::BaselineJIT);
88
    ASSERT(JITCode::isOptimizingJIT(codeBlock->getJITType()));
88
    ASSERT(codeBlock->alternative());
89
    ASSERT(codeBlock->alternative());
89
    OwnPtr<T> codeBlockToJettison = codeBlock.release();
90
    OwnPtr<T> codeBlockToJettison = codeBlock.release();
90
    codeBlock = static_pointer_cast<T>(codeBlockToJettison->releaseAlternative());
91
    codeBlock = static_pointer_cast<T>(codeBlockToJettison->releaseAlternative());
Lines 167-175 JSObject* EvalExecutable::compileOptimiz Source/JavaScriptCore/runtime/Executable.cpp_sec3
167
    return error;
168
    return error;
168
}
169
}
169
170
171
void EvalExecutable::jitCompile(JSGlobalData& globalData)
172
{
173
    bool result = jitCompileIfAppropriate(globalData, m_evalCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
174
    ASSERT_UNUSED(result, result);
175
}
176
177
inline const char* samplingDescription(JITCode::JITType jitType)
178
{
179
    switch (jitType) {
180
    case JITCode::InterpreterThunk:
181
        return "Interpreter Compilation (TOTAL)";
182
    case JITCode::BaselineJIT:
183
        return "Baseline Compilation (TOTAL)";
184
    case JITCode::DFGJIT:
185
        return "DFG Compilation (TOTAL)";
186
    default:
187
        ASSERT_NOT_REACHED();
188
        return 0;
189
    }
190
}
191
170
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
192
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
171
{
193
{
172
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
194
    SamplingRegion samplingRegion(samplingDescription(jitType));
173
    
195
    
174
#if !ENABLE(JIT)
196
#if !ENABLE(JIT)
175
    UNUSED_PARAM(jitType);
197
    UNUSED_PARAM(jitType);
Lines 210-216 JSObject* EvalExecutable::compileInterna Source/JavaScriptCore/runtime/Executable.cpp_sec4
210
    }
232
    }
211
233
212
#if ENABLE(JIT)
234
#if ENABLE(JIT)
213
    if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
235
    if (!prepareForExecution(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
214
        return 0;
236
        return 0;
215
#endif
237
#endif
216
238
Lines 295-303 JSObject* ProgramExecutable::compileOpti Source/JavaScriptCore/runtime/Executable.cpp_sec5
295
    return error;
317
    return error;
296
}
318
}
297
319
320
void ProgramExecutable::jitCompile(JSGlobalData& globalData)
321
{
322
    bool result = jitCompileIfAppropriate(globalData, m_programCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
323
    ASSERT_UNUSED(result, result);
324
}
325
298
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
326
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
299
{
327
{
300
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
328
    SamplingRegion samplingRegion(samplingDescription(jitType));
301
    
329
    
302
#if !ENABLE(JIT)
330
#if !ENABLE(JIT)
303
    UNUSED_PARAM(jitType);
331
    UNUSED_PARAM(jitType);
Lines 336-342 JSObject* ProgramExecutable::compileInte Source/JavaScriptCore/runtime/Executable.cpp_sec6
336
    }
364
    }
337
365
338
#if ENABLE(JIT)
366
#if ENABLE(JIT)
339
    if (!jitCompileIfAppropriate(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
367
    if (!prepareForExecution(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
340
        return 0;
368
        return 0;
341
#endif
369
#endif
342
370
Lines 412-418 FunctionCodeBlock* FunctionExecutable::b Source/JavaScriptCore/runtime/Executable.cpp_sec7
412
    while (result->alternative())
440
    while (result->alternative())
413
        result = static_cast<FunctionCodeBlock*>(result->alternative());
441
        result = static_cast<FunctionCodeBlock*>(result->alternative());
414
    ASSERT(result);
442
    ASSERT(result);
415
    ASSERT(result->getJITType() == JITCode::BaselineJIT);
443
    ASSERT(JITCode::isBaselineCode(result->getJITType()));
416
    return result;
444
    return result;
417
}
445
}
418
446
Lines 438-443 JSObject* FunctionExecutable::compileOpt Source/JavaScriptCore/runtime/Executable.cpp_sec8
438
    return error;
466
    return error;
439
}
467
}
440
468
469
void FunctionExecutable::jitCompileForCall(JSGlobalData& globalData)
470
{
471
    bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
472
    ASSERT_UNUSED(result, result);
473
}
474
475
void FunctionExecutable::jitCompileForConstruct(JSGlobalData& globalData)
476
{
477
    bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
478
    ASSERT_UNUSED(result, result);
479
}
480
441
FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
481
FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
442
{
482
{
443
    FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);
483
    FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);
Lines 482-488 PassOwnPtr<FunctionCodeBlock> FunctionEx Source/JavaScriptCore/runtime/Executable.cpp_sec9
482
522
483
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
523
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
484
{
524
{
485
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
525
    SamplingRegion samplingRegion(samplingDescription(jitType));
486
    
526
    
487
#if !ENABLE(JIT)
527
#if !ENABLE(JIT)
488
    UNUSED_PARAM(exec);
528
    UNUSED_PARAM(exec);
Lines 504-510 JSObject* FunctionExecutable::compileFor Source/JavaScriptCore/runtime/Executable.cpp_sec10
504
    m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
544
    m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
505
545
506
#if ENABLE(JIT)
546
#if ENABLE(JIT)
507
    if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType))
547
    if (!prepareFunctionForExecution(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, CodeForCall))
508
        return 0;
548
        return 0;
509
#endif
549
#endif
510
550
Lines 524-530 JSObject* FunctionExecutable::compileFor Source/JavaScriptCore/runtime/Executable.cpp_sec11
524
564
525
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
565
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
526
{
566
{
527
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
567
    SamplingRegion samplingRegion(samplingDescription(jitType));
528
    
568
    
529
#if !ENABLE(JIT)
569
#if !ENABLE(JIT)
530
    UNUSED_PARAM(jitType);
570
    UNUSED_PARAM(jitType);
Lines 546-552 JSObject* FunctionExecutable::compileFor Source/JavaScriptCore/runtime/Executable.cpp_sec12
546
    m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
586
    m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
547
587
548
#if ENABLE(JIT)
588
#if ENABLE(JIT)
549
    if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType))
589
    if (!prepareFunctionForExecution(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, CodeForConstruct))
550
        return 0;
590
        return 0;
551
#endif
591
#endif
552
592
- Source/JavaScriptCore/runtime/Executable.h -1 / +19 lines
Lines 27-32 Source/JavaScriptCore/runtime/Executable.h_sec1
27
#define Executable_h
27
#define Executable_h
28
28
29
#include "CallData.h"
29
#include "CallData.h"
30
#include "CodeSpecializationKind.h"
30
#include "JSFunction.h"
31
#include "JSFunction.h"
31
#include "Interpreter.h"
32
#include "Interpreter.h"
32
#include "Nodes.h"
33
#include "Nodes.h"
Lines 39-50 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec2
39
    class Debugger;
40
    class Debugger;
40
    class EvalCodeBlock;
41
    class EvalCodeBlock;
41
    class FunctionCodeBlock;
42
    class FunctionCodeBlock;
43
    class LLIntOffsetsExtractor;
42
    class ProgramCodeBlock;
44
    class ProgramCodeBlock;
43
    class ScopeChainNode;
45
    class ScopeChainNode;
44
46
45
    struct ExceptionInfo;
47
    struct ExceptionInfo;
46
    
48
    
47
    enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
48
    enum CompilationKind { FirstCompilation, OptimizingCompilation };
49
    enum CompilationKind { FirstCompilation, OptimizingCompilation };
49
50
50
    inline bool isCall(CodeSpecializationKind kind)
51
    inline bool isCall(CodeSpecializationKind kind)
Lines 319-324 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec3
319
    };
320
    };
320
321
321
    class EvalExecutable : public ScriptExecutable {
322
    class EvalExecutable : public ScriptExecutable {
323
        friend class LLIntOffsetsExtractor;
322
    public:
324
    public:
323
        typedef ScriptExecutable Base;
325
        typedef ScriptExecutable Base;
324
326
Lines 338-343 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec4
338
        
340
        
339
#if ENABLE(JIT)
341
#if ENABLE(JIT)
340
        void jettisonOptimizedCode(JSGlobalData&);
342
        void jettisonOptimizedCode(JSGlobalData&);
343
        void jitCompile(JSGlobalData&);
341
#endif
344
#endif
342
345
343
        EvalCodeBlock& generatedBytecode()
346
        EvalCodeBlock& generatedBytecode()
Lines 384-389 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec5
384
    };
387
    };
385
388
386
    class ProgramExecutable : public ScriptExecutable {
389
    class ProgramExecutable : public ScriptExecutable {
390
        friend class LLIntOffsetsExtractor;
387
    public:
391
    public:
388
        typedef ScriptExecutable Base;
392
        typedef ScriptExecutable Base;
389
393
Lines 411-416 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec6
411
        
415
        
412
#if ENABLE(JIT)
416
#if ENABLE(JIT)
413
        void jettisonOptimizedCode(JSGlobalData&);
417
        void jettisonOptimizedCode(JSGlobalData&);
418
        void jitCompile(JSGlobalData&);
414
#endif
419
#endif
415
420
416
        ProgramCodeBlock& generatedBytecode()
421
        ProgramCodeBlock& generatedBytecode()
Lines 453-458 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec7
453
458
454
    class FunctionExecutable : public ScriptExecutable {
459
    class FunctionExecutable : public ScriptExecutable {
455
        friend class JIT;
460
        friend class JIT;
461
        friend class LLIntOffsetsExtractor;
456
    public:
462
    public:
457
        typedef ScriptExecutable Base;
463
        typedef ScriptExecutable Base;
458
464
Lines 508-513 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec8
508
        
514
        
509
#if ENABLE(JIT)
515
#if ENABLE(JIT)
510
        void jettisonOptimizedCodeForCall(JSGlobalData&);
516
        void jettisonOptimizedCodeForCall(JSGlobalData&);
517
        void jitCompileForCall(JSGlobalData&);
511
#endif
518
#endif
512
519
513
        bool isGeneratedForCall() const
520
        bool isGeneratedForCall() const
Lines 535-540 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec9
535
        
542
        
536
#if ENABLE(JIT)
543
#if ENABLE(JIT)
537
        void jettisonOptimizedCodeForConstruct(JSGlobalData&);
544
        void jettisonOptimizedCodeForConstruct(JSGlobalData&);
545
        void jitCompileForConstruct(JSGlobalData&);
538
#endif
546
#endif
539
547
540
        bool isGeneratedForConstruct() const
548
        bool isGeneratedForConstruct() const
Lines 582-587 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec10
582
                jettisonOptimizedCodeForConstruct(globalData);
590
                jettisonOptimizedCodeForConstruct(globalData);
583
            }
591
            }
584
        }
592
        }
593
        
594
        void jitCompileFor(JSGlobalData& globalData, CodeSpecializationKind kind)
595
        {
596
            if (kind == CodeForCall) {
597
                jitCompileForCall(globalData);
598
                return;
599
            }
600
            ASSERT(kind == CodeForConstruct);
601
            jitCompileForConstruct(globalData);
602
        }
585
#endif
603
#endif
586
        
604
        
587
        bool isGeneratedFor(CodeSpecializationKind kind)
605
        bool isGeneratedFor(CodeSpecializationKind kind)
- Source/JavaScriptCore/runtime/ExecutionHarness.h +72 lines
Line 0 Source/JavaScriptCore/runtime/ExecutionHarness.h_sec1
1
/*
2
 * Copyright (C) 2012 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 ExecutionHarness_h
27
#define ExecutionHarness_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(JIT)
32
33
#include "JITDriver.h"
34
#include "LLIntEntrypoints.h"
35
36
namespace JSC {
37
38
template<typename CodeBlockType>
39
inline bool prepareForExecution(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
40
{
41
#if ENABLE(LLINT)
42
    if (JITCode::isBaselineCode(jitType)) {
43
        // Start off in the low level interpreter.
44
        LLInt::getEntrypoint(globalData, codeBlock.get(), jitCode);
45
        codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
46
        return true;
47
    }
48
#endif // ENABLE(LLINT)
49
    return jitCompileIfAppropriate(globalData, codeBlock, jitCode, jitType);
50
}
51
52
inline bool prepareFunctionForExecution(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, CodeSpecializationKind kind)
53
{
54
#if ENABLE(LLINT)
55
    if (JITCode::isBaselineCode(jitType)) {
56
        // Start off in the low level interpreter.
57
        LLInt::getFunctionEntrypoint(globalData, kind, jitCode, jitCodeWithArityCheck);
58
        codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
59
        return true;
60
    }
61
#else
62
    UNUSED_PARAM(kind);
63
#endif // ENABLE(LLINT)
64
    return jitCompileFunctionIfAppropriate(globalData, codeBlock, jitCode, jitCodeWithArityCheck, symbolTable, jitType);
65
}
66
67
} // namespace JSC
68
69
#endif // ENABLE(JIT)
70
71
#endif // ExecutionHarness_h
72
- Source/JavaScriptCore/runtime/JSActivation.h -1 / +1 lines
Lines 124-130 namespace JSC { Source/JavaScriptCore/runtime/JSActivation.h_sec1
124
124
125
        OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]);
125
        OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]);
126
        WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset;
126
        WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset;
127
127
        
128
        // Copy all arguments that can be captured by name or by the arguments object.
128
        // Copy all arguments that can be captured by name or by the arguments object.
129
        for (int i = 0; i < m_numCapturedArgs; ++i) {
129
        for (int i = 0; i < m_numCapturedArgs; ++i) {
130
            int index = CallFrame::argumentOffset(i);
130
            int index = CallFrame::argumentOffset(i);
- Source/JavaScriptCore/runtime/JSArray.h +2 lines
Lines 28-33 Source/JavaScriptCore/runtime/JSArray.h_sec1
28
namespace JSC {
28
namespace JSC {
29
29
30
    class JSArray;
30
    class JSArray;
31
    class LLIntOffsetsExtractor;
31
32
32
    struct SparseArrayEntry : public WriteBarrier<Unknown> {
33
    struct SparseArrayEntry : public WriteBarrier<Unknown> {
33
        typedef WriteBarrier<Unknown> Base;
34
        typedef WriteBarrier<Unknown> Base;
Lines 122-127 namespace JSC { Source/JavaScriptCore/runtime/JSArray.h_sec2
122
    };
123
    };
123
124
124
    class JSArray : public JSNonFinalObject {
125
    class JSArray : public JSNonFinalObject {
126
        friend class LLIntOffsetsExtractor;
125
        friend class Walker;
127
        friend class Walker;
126
128
127
    protected:
129
    protected:
- Source/JavaScriptCore/runtime/JSCell.h -1 / +4 lines
Lines 36-44 Source/JavaScriptCore/runtime/JSCell.h_sec1
36
namespace JSC {
36
namespace JSC {
37
37
38
    class JSGlobalObject;
38
    class JSGlobalObject;
39
    class Structure;
39
    class LLIntOffsetsExtractor;
40
    class PropertyDescriptor;
40
    class PropertyDescriptor;
41
    class PropertyNameArray;
41
    class PropertyNameArray;
42
    class Structure;
42
43
43
    enum EnumerationMode {
44
    enum EnumerationMode {
44
        ExcludeDontEnumProperties,
45
        ExcludeDontEnumProperties,
Lines 164-169 namespace JSC { Source/JavaScriptCore/runtime/JSCell.h_sec2
164
        static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
165
        static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
165
166
166
    private:
167
    private:
168
        friend class LLIntOffsetsExtractor;
169
        
167
        const ClassInfo* m_classInfo;
170
        const ClassInfo* m_classInfo;
168
        WriteBarrier<Structure> m_structure;
171
        WriteBarrier<Structure> m_structure;
169
    };
172
    };
- Source/JavaScriptCore/runtime/JSFunction.h +3 lines
Lines 33-38 namespace JSC { Source/JavaScriptCore/runtime/JSFunction.h_sec1
33
    class FunctionPrototype;
33
    class FunctionPrototype;
34
    class JSActivation;
34
    class JSActivation;
35
    class JSGlobalObject;
35
    class JSGlobalObject;
36
    class LLIntOffsetsExtractor;
36
    class NativeExecutable;
37
    class NativeExecutable;
37
    class SourceCode;
38
    class SourceCode;
38
    namespace DFG {
39
    namespace DFG {
Lines 140-145 namespace JSC { Source/JavaScriptCore/runtime/JSFunction.h_sec2
140
        static void visitChildren(JSCell*, SlotVisitor&);
141
        static void visitChildren(JSCell*, SlotVisitor&);
141
142
142
    private:
143
    private:
144
        friend class LLIntOffsetsExtractor;
145
        
143
        JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
146
        JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
144
147
145
        static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
148
        static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
- Source/JavaScriptCore/runtime/JSGlobalData.cpp -1 / +3 lines
Lines 141-146 JSGlobalData::JSGlobalData(GlobalDataTyp Source/JavaScriptCore/runtime/JSGlobalData.cpp_sec1
141
    , keywords(adoptPtr(new Keywords(this)))
141
    , keywords(adoptPtr(new Keywords(this)))
142
    , interpreter(0)
142
    , interpreter(0)
143
    , heap(this, heapSize)
143
    , heap(this, heapSize)
144
    , jsArrayClassInfo(&JSArray::s_info)
145
    , jsFinalObjectClassInfo(&JSFinalObject::s_info)
144
#if ENABLE(DFG_JIT)
146
#if ENABLE(DFG_JIT)
145
    , sizeOfLastScratchBuffer(0)
147
    , sizeOfLastScratchBuffer(0)
146
#endif
148
#endif
Lines 216-222 JSGlobalData::JSGlobalData(GlobalDataTyp Source/JavaScriptCore/runtime/JSGlobalData.cpp_sec2
216
    jitStubs = adoptPtr(new JITThunks(this));
218
    jitStubs = adoptPtr(new JITThunks(this));
217
#endif
219
#endif
218
220
219
    interpreter->initialize(this->canUseJIT());
221
    interpreter->initialize(&llintData, this->canUseJIT());
220
222
221
    heap.notifyIsSafeToCollect();
223
    heap.notifyIsSafeToCollect();
222
}
224
}
- Source/JavaScriptCore/runtime/JSGlobalData.h -2 / +12 lines
Lines 30-44 Source/JavaScriptCore/runtime/JSGlobalData.h_sec1
30
#define JSGlobalData_h
30
#define JSGlobalData_h
31
31
32
#include "CachedTranscendentalFunction.h"
32
#include "CachedTranscendentalFunction.h"
33
#include "Intrinsic.h"
34
#include "DateInstanceCache.h"
33
#include "DateInstanceCache.h"
35
#include "ExecutableAllocator.h"
34
#include "ExecutableAllocator.h"
36
#include "Heap.h"
35
#include "Heap.h"
37
#include "Strong.h"
36
#include "Intrinsic.h"
38
#include "JITStubs.h"
37
#include "JITStubs.h"
39
#include "JSValue.h"
38
#include "JSValue.h"
39
#include "LLIntData.h"
40
#include "NumericStrings.h"
40
#include "NumericStrings.h"
41
#include "SmallStrings.h"
41
#include "SmallStrings.h"
42
#include "Strong.h"
42
#include "Terminator.h"
43
#include "Terminator.h"
43
#include "TimeoutChecker.h"
44
#include "TimeoutChecker.h"
44
#include "WeakRandom.h"
45
#include "WeakRandom.h"
Lines 65-70 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalData.h_sec2
65
    class JSGlobalObject;
66
    class JSGlobalObject;
66
    class JSObject;
67
    class JSObject;
67
    class Keywords;
68
    class Keywords;
69
    class LLIntOffsetsExtractor;
68
    class NativeExecutable;
70
    class NativeExecutable;
69
    class ParserArena;
71
    class ParserArena;
70
    class RegExpCache;
72
    class RegExpCache;
Lines 241-246 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalData.h_sec3
241
        Heap heap;
243
        Heap heap;
242
244
243
        JSValue exception;
245
        JSValue exception;
246
247
        const ClassInfo* const jsArrayClassInfo;
248
        const ClassInfo* const jsFinalObjectClassInfo;
249
250
        LLInt::Data llintData;
251
244
#if ENABLE(JIT)
252
#if ENABLE(JIT)
245
        ReturnAddressPtr exceptionLocation;
253
        ReturnAddressPtr exceptionLocation;
246
        JSValue hostCallReturnValue;
254
        JSValue hostCallReturnValue;
Lines 346-351 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalData.h_sec4
346
#undef registerTypedArrayFunction
354
#undef registerTypedArrayFunction
347
355
348
    private:
356
    private:
357
        friend class LLIntOffsetsExtractor;
358
        
349
        JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
359
        JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
350
        static JSGlobalData*& sharedInstanceInternal();
360
        static JSGlobalData*& sharedInstanceInternal();
351
        void createNativeThunk();
361
        void createNativeThunk();
- Source/JavaScriptCore/runtime/JSGlobalObject.h +3 lines
Lines 44-49 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalObject.h_sec1
44
    class FunctionPrototype;
44
    class FunctionPrototype;
45
    class GetterSetter;
45
    class GetterSetter;
46
    class GlobalCodeBlock;
46
    class GlobalCodeBlock;
47
    class LLIntOffsetsExtractor;
47
    class NativeErrorConstructor;
48
    class NativeErrorConstructor;
48
    class ProgramCodeBlock;
49
    class ProgramCodeBlock;
49
    class RegExpConstructor;
50
    class RegExpConstructor;
Lines 335-340 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalObject.h_sec2
335
        JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
336
        JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
336
337
337
    private:
338
    private:
339
        friend class LLIntOffsetsExtractor;
340
        
338
        // FIXME: Fold reset into init.
341
        // FIXME: Fold reset into init.
339
        JS_EXPORT_PRIVATE void init(JSObject* thisValue);
342
        JS_EXPORT_PRIVATE void init(JSObject* thisValue);
340
        void reset(JSValue prototype);
343
        void reset(JSValue prototype);
- Source/JavaScriptCore/runtime/JSObject.h +5 lines
Lines 49-54 namespace JSC { Source/JavaScriptCore/runtime/JSObject.h_sec1
49
    class GetterSetter;
49
    class GetterSetter;
50
    class HashEntry;
50
    class HashEntry;
51
    class InternalFunction;
51
    class InternalFunction;
52
    class LLIntOffsetsExtractor;
52
    class MarkedBlock;
53
    class MarkedBlock;
53
    class PropertyDescriptor;
54
    class PropertyDescriptor;
54
    class PropertyNameArray;
55
    class PropertyNameArray;
Lines 269-274 namespace JSC { Source/JavaScriptCore/runtime/JSObject.h_sec2
269
        JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
270
        JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
270
271
271
    private:
272
    private:
273
        friend class LLIntOffsetsExtractor;
274
        
272
        // Nobody should ever ask any of these questions on something already known to be a JSObject.
275
        // Nobody should ever ask any of these questions on something already known to be a JSObject.
273
        using JSCell::isAPIValueWrapper;
276
        using JSCell::isAPIValueWrapper;
274
        using JSCell::isGetterSetter;
277
        using JSCell::isGetterSetter;
Lines 381-386 COMPILE_ASSERT((JSFinalObject_inlineStor Source/JavaScriptCore/runtime/JSObject.h_sec3
381
        static void destroy(JSCell*);
384
        static void destroy(JSCell*);
382
385
383
    private:
386
    private:
387
        friend class LLIntOffsetsExtractor;
388
        
384
        explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
389
        explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
385
            : JSObject(globalData, structure, m_inlineStorage)
390
            : JSObject(globalData, structure, m_inlineStorage)
386
        {
391
        {
- Source/JavaScriptCore/runtime/JSPropertyNameIterator.h +3 lines
Lines 38-43 namespace JSC { Source/JavaScriptCore/runtime/JSPropertyNameIterator.h_sec1
38
38
39
    class Identifier;
39
    class Identifier;
40
    class JSObject;
40
    class JSObject;
41
    class LLIntOffsetsExtractor;
41
42
42
    class JSPropertyNameIterator : public JSCell {
43
    class JSPropertyNameIterator : public JSCell {
43
        friend class JIT;
44
        friend class JIT;
Lines 96-101 namespace JSC { Source/JavaScriptCore/runtime/JSPropertyNameIterator.h_sec2
96
        }
97
        }
97
98
98
    private:
99
    private:
100
        friend class LLIntOffsetsExtractor;
101
        
99
        JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
102
        JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
100
103
101
        WriteBarrier<Structure> m_cachedStructure;
104
        WriteBarrier<Structure> m_cachedStructure;
- Source/JavaScriptCore/runtime/JSString.h +3 lines
Lines 32-37 Source/JavaScriptCore/runtime/JSString.h_sec1
32
namespace JSC {
32
namespace JSC {
33
33
34
    class JSString;
34
    class JSString;
35
    class LLIntOffsetsExtractor;
35
36
36
    JSString* jsEmptyString(JSGlobalData*);
37
    JSString* jsEmptyString(JSGlobalData*);
37
    JSString* jsEmptyString(ExecState*);
38
    JSString* jsEmptyString(ExecState*);
Lines 240-245 namespace JSC { Source/JavaScriptCore/runtime/JSString.h_sec2
240
        static void visitChildren(JSCell*, SlotVisitor&);
241
        static void visitChildren(JSCell*, SlotVisitor&);
241
242
242
    private:
243
    private:
244
        friend class LLIntOffsetsExtractor;
245
        
243
        JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
246
        JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
244
        void resolveRopeSlowCase8(LChar*) const;
247
        void resolveRopeSlowCase8(LChar*) const;
245
        void resolveRopeSlowCase(UChar*) const;
248
        void resolveRopeSlowCase(UChar*) const;
- Source/JavaScriptCore/runtime/JSTypeInfo.h +4 lines
Lines 34-39 Source/JavaScriptCore/runtime/JSTypeInfo.h_sec1
34
34
35
namespace JSC {
35
namespace JSC {
36
36
37
    class LLIntOffsetsExtractor;
38
37
    static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
39
    static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
38
    static const unsigned ImplementsHasInstance = 1 << 1;
40
    static const unsigned ImplementsHasInstance = 1 << 1;
39
    static const unsigned OverridesHasInstance = 1 << 2;
41
    static const unsigned OverridesHasInstance = 1 << 2;
Lines 87-92 namespace JSC { Source/JavaScriptCore/runtime/JSTypeInfo.h_sec2
87
        }
89
        }
88
90
89
    private:
91
    private:
92
        friend class LLIntOffsetsExtractor;
93
        
90
        bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
94
        bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
91
        bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
95
        bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
92
96
- Source/JavaScriptCore/runtime/JSValue.cpp -5 / +3 lines
Lines 116-125 JSObject* JSValue::synthesizePrototype(E Source/JavaScriptCore/runtime/JSValue.cpp_sec1
116
    return JSNotAnObject::create(exec);
116
    return JSNotAnObject::create(exec);
117
}
117
}
118
118
119
#ifndef NDEBUG
120
char* JSValue::description()
119
char* JSValue::description()
121
{
120
{
122
    static const size_t size = 64;
121
    static const size_t size = 128;
123
    static char description[size];
122
    static char description[size];
124
123
125
    if (!*this)
124
    if (!*this)
Lines 128-141 char* JSValue::description() Source/JavaScriptCore/runtime/JSValue.cpp_sec2
128
        snprintf(description, size, "Int32: %d", asInt32());
127
        snprintf(description, size, "Int32: %d", asInt32());
129
    else if (isDouble()) {
128
    else if (isDouble()) {
130
#if USE(JSVALUE64)
129
#if USE(JSVALUE64)
131
        snprintf(description, size, "Double: %lf, %lx", asDouble(), reinterpretDoubleToIntptr(asDouble()));
130
        snprintf(description, size, "Double: %lx, %lf", reinterpretDoubleToIntptr(asDouble()), asDouble());
132
#else
131
#else
133
        union {
132
        union {
134
            double asDouble;
133
            double asDouble;
135
            uint32_t asTwoInt32s[2];
134
            uint32_t asTwoInt32s[2];
136
        } u;
135
        } u;
137
        u.asDouble = asDouble();
136
        u.asDouble = asDouble();
138
        snprintf(description, size, "Double: %lf, %08x:%08x", asDouble(), u.asTwoInt32s[1], u.asTwoInt32s[0]);
137
        snprintf(description, size, "Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
139
#endif
138
#endif
140
    } else if (isCell())
139
    } else if (isCell())
141
        snprintf(description, size, "Cell: %p", asCell());
140
        snprintf(description, size, "Cell: %p", asCell());
Lines 152-158 char* JSValue::description() Source/JavaScriptCore/runtime/JSValue.cpp_sec3
152
151
153
    return description;
152
    return description;
154
}
153
}
155
#endif
156
154
157
// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
155
// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
158
// Note that this operation is identical to ToUInt32 other than to interpretation
156
// Note that this operation is identical to ToUInt32 other than to interpretation
- Source/JavaScriptCore/runtime/JSValue.h -2 lines
Lines 232-240 namespace JSC { Source/JavaScriptCore/runtime/JSValue.h_sec1
232
        JSCell* asCell() const;
232
        JSCell* asCell() const;
233
        JS_EXPORT_PRIVATE bool isValidCallee();
233
        JS_EXPORT_PRIVATE bool isValidCallee();
234
234
235
#ifndef NDEBUG
236
        char* description();
235
        char* description();
237
#endif
238
236
239
    private:
237
    private:
240
        template <class T> JSValue(WriteBarrierBase<T>);
238
        template <class T> JSValue(WriteBarrierBase<T>);
- Source/JavaScriptCore/runtime/JSVariableObject.h +2 lines
Lines 38-47 Source/JavaScriptCore/runtime/JSVariableObject.h_sec1
38
38
39
namespace JSC {
39
namespace JSC {
40
40
41
    class LLIntOffsetsExtractor;
41
    class Register;
42
    class Register;
42
43
43
    class JSVariableObject : public JSNonFinalObject {
44
    class JSVariableObject : public JSNonFinalObject {
44
        friend class JIT;
45
        friend class JIT;
46
        friend class LLIntOffsetsExtractor;
45
47
46
    public:
48
    public:
47
        typedef JSNonFinalObject Base;
49
        typedef JSNonFinalObject Base;
- Source/JavaScriptCore/runtime/Options.cpp +10 lines
Lines 52-57 unsigned maximumFunctionForConstructInli Source/JavaScriptCore/runtime/Options.cpp_sec1
52
52
53
unsigned maximumInliningDepth;
53
unsigned maximumInliningDepth;
54
54
55
int32_t executionCounterValueForJITAfterWarmUp;
56
int32_t executionCounterValueForDontJITAnytimeSoon;
57
int32_t executionCounterValueForJITSoon;
58
55
int32_t executionCounterValueForOptimizeAfterWarmUp;
59
int32_t executionCounterValueForOptimizeAfterWarmUp;
56
int32_t executionCounterValueForOptimizeAfterLongWarmUp;
60
int32_t executionCounterValueForOptimizeAfterLongWarmUp;
57
int32_t executionCounterValueForDontOptimizeAnytimeSoon;
61
int32_t executionCounterValueForDontOptimizeAnytimeSoon;
Lines 137-142 void initializeOptions() Source/JavaScriptCore/runtime/Options.cpp_sec2
137
    
141
    
138
    SET(maximumInliningDepth, 5);
142
    SET(maximumInliningDepth, 5);
139
143
144
    SET(executionCounterValueForJITAfterWarmUp,     -100);
145
    SET(executionCounterValueForDontJITAnytimeSoon, std::numeric_limits<int32_t>::min());
146
    SET(executionCounterValueForJITSoon,            -100);
147
140
    SET(executionCounterValueForOptimizeAfterWarmUp,     -1000);
148
    SET(executionCounterValueForOptimizeAfterWarmUp,     -1000);
141
    SET(executionCounterValueForOptimizeAfterLongWarmUp, -5000);
149
    SET(executionCounterValueForOptimizeAfterLongWarmUp, -5000);
142
    SET(executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min());
150
    SET(executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min());
Lines 185-190 void initializeOptions() Source/JavaScriptCore/runtime/Options.cpp_sec3
185
    if (cpusToUse < 1)
193
    if (cpusToUse < 1)
186
        cpusToUse = 1;
194
        cpusToUse = 1;
187
    
195
    
196
    cpusToUse = 1;
197
    
188
    SET(numberOfGCMarkers, cpusToUse);
198
    SET(numberOfGCMarkers, cpusToUse);
189
199
190
    ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp);
200
    ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp);
- Source/JavaScriptCore/runtime/Options.h +4 lines
Lines 37-42 extern unsigned maximumFunctionForConstr Source/JavaScriptCore/runtime/Options.h_sec1
37
37
38
extern unsigned maximumInliningDepth; // Depth of inline stack, so 1 = no inlining, 2 = one level, etc.
38
extern unsigned maximumInliningDepth; // Depth of inline stack, so 1 = no inlining, 2 = one level, etc.
39
39
40
extern int32_t executionCounterValueForJITAfterWarmUp;
41
extern int32_t executionCounterValueForDontJITAnytimeSoon;
42
extern int32_t executionCounterValueForJITSoon;
43
40
extern int32_t executionCounterValueForOptimizeAfterWarmUp;
44
extern int32_t executionCounterValueForOptimizeAfterWarmUp;
41
extern int32_t executionCounterValueForOptimizeAfterLongWarmUp;
45
extern int32_t executionCounterValueForOptimizeAfterLongWarmUp;
42
extern int32_t executionCounterValueForDontOptimizeAnytimeSoon;
46
extern int32_t executionCounterValueForDontOptimizeAnytimeSoon;
- Source/JavaScriptCore/runtime/ScopeChain.h +3 lines
Lines 30-35 namespace JSC { Source/JavaScriptCore/runtime/ScopeChain.h_sec1
30
    class JSGlobalData;
30
    class JSGlobalData;
31
    class JSGlobalObject;
31
    class JSGlobalObject;
32
    class JSObject;
32
    class JSObject;
33
    class LLIntOffsetsExtractor;
33
    class ScopeChainIterator;
34
    class ScopeChainIterator;
34
    class SlotVisitor;
35
    class SlotVisitor;
35
    
36
    
Lines 91-96 namespace JSC { Source/JavaScriptCore/runtime/ScopeChain.h_sec2
91
        static JS_EXPORTDATA const ClassInfo s_info;
92
        static JS_EXPORTDATA const ClassInfo s_info;
92
93
93
    private:
94
    private:
95
        friend class LLIntOffsetsExtractor;
96
        
94
        static const unsigned StructureFlags = OverridesVisitChildren;
97
        static const unsigned StructureFlags = OverridesVisitChildren;
95
    };
98
    };
96
99
- Source/JavaScriptCore/runtime/Structure.h +3 lines
Lines 45-50 Source/JavaScriptCore/runtime/Structure.h_sec1
45
45
46
namespace JSC {
46
namespace JSC {
47
47
48
    class LLIntOffsetsExtractor;
48
    class PropertyNameArray;
49
    class PropertyNameArray;
49
    class PropertyNameArrayData;
50
    class PropertyNameArrayData;
50
    class StructureChain;
51
    class StructureChain;
Lines 196-201 namespace JSC { Source/JavaScriptCore/runtime/Structure.h_sec2
196
        static JS_EXPORTDATA const ClassInfo s_info;
197
        static JS_EXPORTDATA const ClassInfo s_info;
197
198
198
    private:
199
    private:
200
        friend class LLIntOffsetsExtractor;
201
        
199
        JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
202
        JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
200
        Structure(JSGlobalData&);
203
        Structure(JSGlobalData&);
201
        Structure(JSGlobalData&, const Structure*);
204
        Structure(JSGlobalData&, const Structure*);
- Source/JavaScriptCore/runtime/StructureChain.h +3 lines
Lines 37-42 Source/JavaScriptCore/runtime/StructureChain.h_sec1
37
37
38
namespace JSC {
38
namespace JSC {
39
39
40
    class LLIntOffsetsExtractor;
40
    class Structure;
41
    class Structure;
41
42
42
    class StructureChain : public JSCell {
43
    class StructureChain : public JSCell {
Lines 74-79 namespace JSC { Source/JavaScriptCore/runtime/StructureChain.h_sec2
74
        }
75
        }
75
76
76
    private:
77
    private:
78
        friend class LLIntOffsetsExtractor;
79
        
77
        StructureChain(JSGlobalData&, Structure*);
80
        StructureChain(JSGlobalData&, Structure*);
78
        static void destroy(JSCell*);
81
        static void destroy(JSCell*);
79
        OwnArrayPtr<WriteBarrier<Structure> > m_vector;
82
        OwnArrayPtr<WriteBarrier<Structure> > m_vector;
- Source/JavaScriptCore/wtf/Platform.h +12 lines
Lines 920-925 Source/JavaScriptCore/wtf/Platform.h_sec1
920
#define ENABLE_JIT 1
920
#define ENABLE_JIT 1
921
#endif
921
#endif
922
922
923
/* On some of the platforms where we have a JIT, we want to also have the 
924
   low-level interpreter. */
925
#if !defined(ENABLE_LLINT) && ENABLE(JIT) && PLATFORM(MAC) && USE(JSVALUE32_64)
926
#define ENABLE_LLINT 1
927
#endif
928
929
/* If we have LLInt enabled and the JIT enabled, we also enable OSRing from
930
   LLInt to the JIT. */
931
#if !defined(ENABLE_LLINT_OSR_TO_JIT) && ENABLE(JIT) && ENABLE(LLINT)
932
#define ENABLE_LLINT_OSR_TO_JIT 1
933
#endif
934
923
#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
935
#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
924
/* Enable the DFG JIT on X86 and X86_64.  Only tested on Mac and GNU/Linux. */
936
/* Enable the DFG JIT on X86 and X86_64.  Only tested on Mac and GNU/Linux. */
925
#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
937
#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
- Source/JavaScriptCore/wtf/SentinelLinkedList.h +2 lines
Lines 86-91 public: Source/JavaScriptCore/wtf/SentinelLinkedList.h_sec1
86
86
87
    iterator begin();
87
    iterator begin();
88
    iterator end();
88
    iterator end();
89
    
90
    bool isEmpty() { return begin() == end(); }
89
91
90
private:
92
private:
91
    RawNode m_headSentinel;
93
    RawNode m_headSentinel;
- Source/JavaScriptCore/wtf/text/StringImpl.h -1 / +3 lines
Lines 43-48 typedef const struct __CFString * CFStri Source/JavaScriptCore/wtf/text/StringImpl.h_sec1
43
// Landing the file moves in one patch, will follow on with patches to change the namespaces.
43
// Landing the file moves in one patch, will follow on with patches to change the namespaces.
44
namespace JSC {
44
namespace JSC {
45
struct IdentifierCStringTranslator;
45
struct IdentifierCStringTranslator;
46
class LLIntOffsetsExtractor;
46
template <typename T> struct IdentifierCharBufferTranslator;
47
template <typename T> struct IdentifierCharBufferTranslator;
47
struct IdentifierLCharFromUCharTranslator;
48
struct IdentifierLCharFromUCharTranslator;
48
}
49
}
Lines 72-78 class StringImpl { Source/JavaScriptCore/wtf/text/StringImpl.h_sec2
72
    friend struct WTF::SubstringTranslator;
73
    friend struct WTF::SubstringTranslator;
73
    friend struct WTF::UCharBufferTranslator;
74
    friend struct WTF::UCharBufferTranslator;
74
    friend class AtomicStringImpl;
75
    friend class AtomicStringImpl;
75
76
    friend class JSC::LLIntOffsetsExtractor;
77
    
76
private:
78
private:
77
    enum BufferOwnership {
79
    enum BufferOwnership {
78
        BufferInternal,
80
        BufferInternal,
- Source/WebCore/ChangeLog +14 lines
Lines 1-3 Source/WebCore/ChangeLog_sec1
1
2012-01-26  Filip Pizlo  <fpizlo@apple.com>
2
3
        JSC should be a triple-tier VM
4
        https://bugs.webkit.org/show_bug.cgi?id=75812
5
        <rdar://problem/10079694>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        Changed EFL's build system to include a new directory in JavaScriptCore.
10
        
11
        No new tests because no behavior changed.
12
13
        * CMakeLists.txt:
14
1
2012-01-26  Cris Neckar  <cdn@chromium.org>
15
2012-01-26  Cris Neckar  <cdn@chromium.org>
2
16
3
        The registration of schemes is currently racey as they are not registered from the main thread. 
17
        The registration of schemes is currently racey as they are not registered from the main thread. 
- Source/WebCore/CMakeLists.txt +1 lines
Lines 74-79 SET(WebCore_INCLUDE_DIRECTORIES Source/WebCore/CMakeLists.txt_sec1
74
    "${JAVASCRIPTCORE_DIR}/debugger"
74
    "${JAVASCRIPTCORE_DIR}/debugger"
75
    "${JAVASCRIPTCORE_DIR}/interpreter"
75
    "${JAVASCRIPTCORE_DIR}/interpreter"
76
    "${JAVASCRIPTCORE_DIR}/jit"
76
    "${JAVASCRIPTCORE_DIR}/jit"
77
    "${JAVASCRIPTCORE_DIR}/llint"
77
    "${JAVASCRIPTCORE_DIR}/parser"
78
    "${JAVASCRIPTCORE_DIR}/parser"
78
    "${JAVASCRIPTCORE_DIR}/profiler"
79
    "${JAVASCRIPTCORE_DIR}/profiler"
79
    "${JAVASCRIPTCORE_DIR}/runtime"
80
    "${JAVASCRIPTCORE_DIR}/runtime"
- Source/WebKit/ChangeLog +12 lines
Lines 1-3 Source/WebKit/ChangeLog_sec1
1
2012-01-26  Filip Pizlo  <fpizlo@apple.com>
2
3
        JSC should be a triple-tier VM
4
        https://bugs.webkit.org/show_bug.cgi?id=75812
5
        <rdar://problem/10079694>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        Changed EFL's build system to include a new directory in JavaScriptCore.
10
        
11
        * CMakeLists.txt:
12
1
2012-01-11  Jacky Jiang  <zhajiang@rim.com>
13
2012-01-11  Jacky Jiang  <zhajiang@rim.com>
2
14
3
        [BlackBerry] ASSERT failure in BackingStorePrivate::blitVisibleContents()
15
        [BlackBerry] ASSERT failure in BackingStorePrivate::blitVisibleContents()
- Source/WebKit/CMakeLists.txt +1 lines
Lines 44-49 SET(WebKit_INCLUDE_DIRECTORIES Source/WebKit/CMakeLists.txt_sec1
44
    "${JAVASCRIPTCORE_DIR}/debugger"
44
    "${JAVASCRIPTCORE_DIR}/debugger"
45
    "${JAVASCRIPTCORE_DIR}/interpreter"
45
    "${JAVASCRIPTCORE_DIR}/interpreter"
46
    "${JAVASCRIPTCORE_DIR}/jit"
46
    "${JAVASCRIPTCORE_DIR}/jit"
47
    "${JAVASCRIPTCORE_DIR}/llint"
47
    "${JAVASCRIPTCORE_DIR}/parser"
48
    "${JAVASCRIPTCORE_DIR}/parser"
48
    "${JAVASCRIPTCORE_DIR}/profiler"
49
    "${JAVASCRIPTCORE_DIR}/profiler"
49
    "${JAVASCRIPTCORE_DIR}/runtime"
50
    "${JAVASCRIPTCORE_DIR}/runtime"

Return to Bug 75812