| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog -118 lines
Lines 1-121 Source/JavaScriptCore/ChangeLog_sec1
1
2012-02-21  Adam Roben  <aroben@apple.com>
2
3
        Roll out r108309, r108323, and r108326
4
5
        They broke the 32-bit Lion build.
6
7
        Original bugs is <http://webkit.org/b/75812> <rdar://problem/10079694>.
8
9
        * CMakeLists.txt:
10
        * GNUmakefile.am:
11
        * GNUmakefile.list.am:
12
        * JavaScriptCore.pri:
13
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
14
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
15
        * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
16
        * JavaScriptCore.xcodeproj/project.pbxproj:
17
        * Target.pri:
18
        * assembler/LinkBuffer.h:
19
        * assembler/MacroAssemblerCodeRef.h:
20
        * bytecode/BytecodeConventions.h: Removed.
21
        * bytecode/CallLinkStatus.cpp:
22
        * bytecode/CallLinkStatus.h:
23
        * bytecode/CodeBlock.cpp:
24
        * bytecode/CodeBlock.h:
25
        * bytecode/GetByIdStatus.cpp:
26
        * bytecode/GetByIdStatus.h:
27
        * bytecode/Instruction.h:
28
        * bytecode/LLIntCallLinkInfo.h: Removed.
29
        * bytecode/MethodCallLinkStatus.cpp:
30
        * bytecode/Opcode.cpp:
31
        * bytecode/Opcode.h:
32
        * bytecode/PutByIdStatus.cpp:
33
        * bytecode/PutByIdStatus.h:
34
        * bytecompiler/BytecodeGenerator.cpp:
35
        * dfg/DFGByteCodeParser.cpp:
36
        * dfg/DFGCapabilities.h:
37
        * dfg/DFGOSRExitCompiler.cpp:
38
        * dfg/DFGOperations.cpp:
39
        * heap/Heap.h:
40
        * heap/MarkStack.cpp:
41
        * heap/MarkedAllocator.h:
42
        * heap/MarkedSpace.h:
43
        * interpreter/CallFrame.cpp:
44
        * interpreter/CallFrame.h:
45
        * interpreter/Interpreter.cpp:
46
        * interpreter/Interpreter.h:
47
        * interpreter/RegisterFile.h:
48
        * jit/ExecutableAllocator.h:
49
        * jit/HostCallReturnValue.cpp: Removed.
50
        * jit/HostCallReturnValue.h: Removed.
51
        * jit/JIT.cpp:
52
        * jit/JITCode.h:
53
        * jit/JITDriver.h:
54
        * jit/JITExceptions.cpp:
55
        * jit/JITInlineMethods.h:
56
        * jit/JITStubs.cpp:
57
        * jit/JITStubs.h:
58
        * jit/JSInterfaceJIT.h:
59
        * llint/LLIntCommon.h: Removed.
60
        * llint/LLIntData.cpp: Removed.
61
        * llint/LLIntData.h: Removed.
62
        * llint/LLIntEntrypoints.cpp: Removed.
63
        * llint/LLIntEntrypoints.h: Removed.
64
        * llint/LLIntExceptions.cpp: Removed.
65
        * llint/LLIntExceptions.h: Removed.
66
        * llint/LLIntOfflineAsmConfig.h: Removed.
67
        * llint/LLIntOffsetsExtractor.cpp: Removed.
68
        * llint/LLIntSlowPaths.cpp: Removed.
69
        * llint/LLIntSlowPaths.h: Removed.
70
        * llint/LLIntThunks.cpp: Removed.
71
        * llint/LLIntThunks.h: Removed.
72
        * llint/LowLevelInterpreter.asm: Removed.
73
        * llint/LowLevelInterpreter.cpp: Removed.
74
        * llint/LowLevelInterpreter.h: Removed.
75
        * offlineasm/armv7.rb: Removed.
76
        * offlineasm/asm.rb: Removed.
77
        * offlineasm/ast.rb: Removed.
78
        * offlineasm/backends.rb: Removed.
79
        * offlineasm/generate_offset_extractor.rb: Removed.
80
        * offlineasm/instructions.rb: Removed.
81
        * offlineasm/offset_extractor_constants.rb: Removed.
82
        * offlineasm/offsets.rb: Removed.
83
        * offlineasm/opt.rb: Removed.
84
        * offlineasm/parser.rb: Removed.
85
        * offlineasm/registers.rb: Removed.
86
        * offlineasm/self_hash.rb: Removed.
87
        * offlineasm/settings.rb: Removed.
88
        * offlineasm/transform.rb: Removed.
89
        * offlineasm/x86.rb: Removed.
90
        * runtime/CodeSpecializationKind.h: Removed.
91
        * runtime/CommonSlowPaths.h:
92
        * runtime/Executable.cpp:
93
        * runtime/Executable.h:
94
        * runtime/ExecutionHarness.h: Removed.
95
        * runtime/JSArray.h:
96
        * runtime/JSCell.h:
97
        * runtime/JSFunction.h:
98
        * runtime/JSGlobalData.cpp:
99
        * runtime/JSGlobalData.h:
100
        * runtime/JSGlobalObject.h:
101
        * runtime/JSObject.h:
102
        * runtime/JSPropertyNameIterator.h:
103
        * runtime/JSString.h:
104
        * runtime/JSTypeInfo.h:
105
        * runtime/JSValue.cpp:
106
        * runtime/JSValue.h:
107
        * runtime/JSVariableObject.h:
108
        * runtime/Options.cpp:
109
        * runtime/Options.h:
110
        * runtime/ScopeChain.h:
111
        * runtime/Structure.cpp:
112
        * runtime/Structure.h:
113
        * runtime/StructureChain.h:
114
        * wtf/InlineASM.h:
115
        * wtf/Platform.h:
116
        * wtf/SentinelLinkedList.h:
117
        * wtf/text/StringImpl.h:
118
119
2012-02-21  Gustavo Noronha Silva  <kov@debian.org> and Bob Tracy  <rct@frus.com>
1
2012-02-21  Gustavo Noronha Silva  <kov@debian.org> and Bob Tracy  <rct@frus.com>
120
2
121
        Does not build on IA64, SPARC and Alpha
3
        Does not build on IA64, SPARC and Alpha
- 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 102-107 SET(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec2
102
    interpreter/RegisterFile.cpp
103
    interpreter/RegisterFile.cpp
103
104
104
    jit/ExecutableAllocator.cpp
105
    jit/ExecutableAllocator.cpp
106
    jit/HostCallReturnValue.cpp
105
    jit/JITArithmetic32_64.cpp
107
    jit/JITArithmetic32_64.cpp
106
    jit/JITArithmetic.cpp
108
    jit/JITArithmetic.cpp
107
    jit/JITCall32_64.cpp
109
    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 297-302 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec3
297
	Source/JavaScriptCore/jit/CompactJITCodeMap.h \
299
	Source/JavaScriptCore/jit/CompactJITCodeMap.h \
298
	Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
300
	Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
299
	Source/JavaScriptCore/jit/ExecutableAllocator.h \
301
	Source/JavaScriptCore/jit/ExecutableAllocator.h \
302
	Source/JavaScriptCore/jit/HostCallReturnValue.cpp \
303
	Source/JavaScriptCore/jit/HostCallReturnValue.h \
300
	Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \
304
	Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \
301
	Source/JavaScriptCore/jit/JITArithmetic.cpp \
305
	Source/JavaScriptCore/jit/JITArithmetic.cpp \
302
	Source/JavaScriptCore/jit/JITCall32_64.cpp \
306
	Source/JavaScriptCore/jit/JITCall32_64.cpp \
Lines 320-325 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec4
320
	Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
324
	Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
321
	Source/JavaScriptCore/jit/ThunkGenerators.cpp \
325
	Source/JavaScriptCore/jit/ThunkGenerators.cpp \
322
	Source/JavaScriptCore/jit/ThunkGenerators.h \
326
	Source/JavaScriptCore/jit/ThunkGenerators.h \
327
	Source/JavaScriptCore/llint/LLIntData.h \
323
	Source/JavaScriptCore/os-win32/stdbool.h \
328
	Source/JavaScriptCore/os-win32/stdbool.h \
324
	Source/JavaScriptCore/os-win32/stdint.h \
329
	Source/JavaScriptCore/os-win32/stdint.h \
325
	Source/JavaScriptCore/parser/ASTBuilder.h \
330
	Source/JavaScriptCore/parser/ASTBuilder.h \
Lines 370-375 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec5
370
	Source/JavaScriptCore/runtime/CallData.cpp \
375
	Source/JavaScriptCore/runtime/CallData.cpp \
371
	Source/JavaScriptCore/runtime/CallData.h \
376
	Source/JavaScriptCore/runtime/CallData.h \
372
	Source/JavaScriptCore/runtime/ClassInfo.h \
377
	Source/JavaScriptCore/runtime/ClassInfo.h \
378
	Source/JavaScriptCore/runtime/CodeSpecializationKind.h \
373
	Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
379
	Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
374
	Source/JavaScriptCore/runtime/CommonIdentifiers.h \
380
	Source/JavaScriptCore/runtime/CommonIdentifiers.h \
375
	Source/JavaScriptCore/runtime/CommonSlowPaths.h \
381
	Source/JavaScriptCore/runtime/CommonSlowPaths.h \
Lines 398-403 javascriptcore_sources += \ Source/JavaScriptCore/GNUmakefile.list.am_sec6
398
	Source/JavaScriptCore/runtime/ExceptionHelpers.h \
404
	Source/JavaScriptCore/runtime/ExceptionHelpers.h \
399
	Source/JavaScriptCore/runtime/Executable.cpp \
405
	Source/JavaScriptCore/runtime/Executable.cpp \
400
	Source/JavaScriptCore/runtime/Executable.h \
406
	Source/JavaScriptCore/runtime/Executable.h \
407
	Source/JavaScriptCore/runtime/ExecutionHarness.h \
401
	Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
408
	Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
402
	Source/JavaScriptCore/runtime/FunctionConstructor.h \
409
	Source/JavaScriptCore/runtime/FunctionConstructor.h \
403
	Source/JavaScriptCore/runtime/FunctionPrototype.cpp \
410
	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 113-118 SOURCES += \ Source/JavaScriptCore/Target.pri_sec1
113
    interpreter/RegisterFile.cpp \
113
    interpreter/RegisterFile.cpp \
114
    jit/ExecutableAllocatorFixedVMPool.cpp \
114
    jit/ExecutableAllocatorFixedVMPool.cpp \
115
    jit/ExecutableAllocator.cpp \
115
    jit/ExecutableAllocator.cpp \
116
    jit/HostCallReturnValue.cpp \
116
    jit/JITArithmetic.cpp \
117
    jit/JITArithmetic.cpp \
117
    jit/JITArithmetic32_64.cpp \
118
    jit/JITArithmetic32_64.cpp \
118
    jit/JITCall.cpp \
119
    jit/JITCall.cpp \
- Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +12 lines
Lines 1762-1767 Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj_sec1
1762
				>
1762
				>
1763
			</File>
1763
			</File>
1764
			<File
1764
			<File
1765
				RelativePath="..\..\jit\HostCallReturnValue.cpp"
1766
				>
1767
			</File>
1768
			<File
1765
				RelativePath="..\..\jit\JIT.cpp"
1769
				RelativePath="..\..\jit\JIT.cpp"
1766
				>
1770
				>
1767
			</File>
1771
			</File>
Lines 1847-1852 Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj_sec2
1847
			</File>
1851
			</File>
1848
		</Filter>
1852
		</Filter>
1849
		<Filter
1853
		<Filter
1854
			Name="llint"
1855
			>
1856
			<File
1857
				RelativePath="..\..\llint\LLIntData.h"
1858
				>
1859
			</File>
1860
		</Filter>
1861
		<Filter
1850
			Name="interpreter"
1862
			Name="interpreter"
1851
			>
1863
			>
1852
			<File
1864
			<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/;../../tools/;../../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/;../../tools/;../../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.vcproj/JavaScriptCore/copy-files.cmd +1 lines
Lines 43-48 for %%d in ( Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd_sec1
43
    debugger
43
    debugger
44
    interpreter
44
    interpreter
45
    jit
45
    jit
46
    llint
46
    parser
47
    parser
47
    profiler
48
    profiler
48
    runtime
49
    runtime
- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj -2 / +357 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 /* LLIntSlowPaths.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46809F14BA7F8200BFE272 /* LLIntSlowPaths.cpp */; settings = {COMPILER_FLAGS = "-Wno-unused-parameter"; }; };
96
		0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.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 419-425 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
419
		86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
452
		86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
420
		86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
453
		86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
421
		86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
454
		86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
422
		86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
455
		86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
423
		86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
456
		86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
424
		86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; };
457
		86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; };
425
		86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; };
458
		86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; };
Lines 790-795 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
790
/* End PBXBuildFile section */
823
/* End PBXBuildFile section */
791
824
792
/* Begin PBXContainerItemProxy section */
825
/* Begin PBXContainerItemProxy section */
826
		0F4680B114BA811500BFE272 /* PBXContainerItemProxy */ = {
827
			isa = PBXContainerItemProxy;
828
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
829
			proxyType = 1;
830
			remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
831
			remoteInfo = "LLInt Offsets";
832
		};
833
		0F4680B314BA821400BFE272 /* PBXContainerItemProxy */ = {
834
			isa = PBXContainerItemProxy;
835
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
836
			proxyType = 1;
837
			remoteGlobalIDString = 0F46808E14BA7E5E00BFE272;
838
			remoteInfo = JSCLLIntOffsetsExtractor;
839
		};
793
		141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
840
		141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
794
			isa = PBXContainerItemProxy;
841
			isa = PBXContainerItemProxy;
795
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
842
			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
Lines 835-840 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
835
/* End PBXContainerItemProxy section */
882
/* End PBXContainerItemProxy section */
836
883
837
/* Begin PBXCopyFilesBuildPhase section */
884
/* Begin PBXCopyFilesBuildPhase section */
885
		0F46808D14BA7E5E00BFE272 /* CopyFiles */ = {
886
			isa = PBXCopyFilesBuildPhase;
887
			buildActionMask = 2147483647;
888
			dstPath = /usr/share/man/man1/;
889
			dstSubfolderSpec = 0;
890
			files = (
891
			);
892
			runOnlyForDeploymentPostprocessing = 1;
893
		};
838
		5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
894
		5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
839
			isa = PBXCopyFilesBuildPhase;
895
			isa = PBXCopyFilesBuildPhase;
840
			buildActionMask = 12;
896
			buildActionMask = 12;
Lines 875-880 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
875
		0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
931
		0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
876
		0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
932
		0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
877
		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
933
		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
934
		0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
935
		0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
936
		0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
937
		0F0B839814BCF45A00885B4F /* LLIntThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntThunks.h; path = llint/LLIntThunks.h; sourceTree = "<group>"; };
878
		0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
938
		0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
879
		0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
939
		0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
880
		0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };
940
		0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };
Lines 885-893 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec10
885
		0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
945
		0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
886
		0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
946
		0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
887
		0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
947
		0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
948
		0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
888
		0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
949
		0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
889
		0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
950
		0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
890
		0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
951
		0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
952
		0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
953
		0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
954
		0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
891
		0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
955
		0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
892
		0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
956
		0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
893
		0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };
957
		0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };
Lines 898-903 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec11
898
		0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
962
		0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
899
		0F46807F14BA572700BFE272 /* JITExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITExceptions.cpp; sourceTree = "<group>"; };
963
		0F46807F14BA572700BFE272 /* JITExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITExceptions.cpp; sourceTree = "<group>"; };
900
		0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
964
		0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
965
		0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
966
		0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntExceptions.cpp; path = llint/LLIntExceptions.cpp; sourceTree = "<group>"; };
967
		0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntExceptions.h; path = llint/LLIntExceptions.h; sourceTree = "<group>"; };
968
		0F46809F14BA7F8200BFE272 /* LLIntSlowPaths.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntSlowPaths.cpp; path = llint/LLIntSlowPaths.cpp; sourceTree = "<group>"; };
969
		0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntSlowPaths.h; path = llint/LLIntSlowPaths.h; sourceTree = "<group>"; };
970
		0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntOffsetsExtractor.cpp; path = llint/LLIntOffsetsExtractor.cpp; sourceTree = "<group>"; };
971
		0F4680C514BBB16900BFE272 /* LLIntCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCommon.h; path = llint/LLIntCommon.h; sourceTree = "<group>"; };
972
		0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOfflineAsmConfig.h; path = llint/LLIntOfflineAsmConfig.h; sourceTree = "<group>"; };
973
		0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LowLevelInterpreter.cpp; path = llint/LowLevelInterpreter.cpp; sourceTree = "<group>"; };
974
		0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LowLevelInterpreter.h; path = llint/LowLevelInterpreter.h; sourceTree = "<group>"; };
975
		0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntData.cpp; path = llint/LLIntData.cpp; sourceTree = "<group>"; };
976
		0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; };
977
		0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; };
978
		0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
901
		0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; };
979
		0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; };
902
		0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; };
980
		0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; };
903
		0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
981
		0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
Lines 1656-1661 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec12
1656
/* End PBXFileReference section */
1734
/* End PBXFileReference section */
1657
1735
1658
/* Begin PBXFrameworksBuildPhase section */
1736
/* Begin PBXFrameworksBuildPhase section */
1737
		0F46808C14BA7E5E00BFE272 /* Frameworks */ = {
1738
			isa = PBXFrameworksBuildPhase;
1739
			buildActionMask = 2147483647;
1740
			files = (
1741
			);
1742
			runOnlyForDeploymentPostprocessing = 0;
1743
		};
1659
		1412111E0A48793C00480255 /* Frameworks */ = {
1744
		1412111E0A48793C00480255 /* Frameworks */ = {
1660
			isa = PBXFrameworksBuildPhase;
1745
			isa = PBXFrameworksBuildPhase;
1661
			buildActionMask = 2147483647;
1746
			buildActionMask = 2147483647;
Lines 1714-1719 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec13
1714
				141211200A48793C00480255 /* minidom */,
1799
				141211200A48793C00480255 /* minidom */,
1715
				14BD59BF0A3E8F9000BAF59C /* testapi */,
1800
				14BD59BF0A3E8F9000BAF59C /* testapi */,
1716
				6511230514046A4C002B101D /* testRegExp */,
1801
				6511230514046A4C002B101D /* testRegExp */,
1802
				0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
1717
			);
1803
			);
1718
			name = Products;
1804
			name = Products;
1719
			sourceTree = "<group>";
1805
			sourceTree = "<group>";
Lines 1739-1744 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec14
1739
				F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
1825
				F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
1740
				45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
1826
				45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
1741
				F68EBB8C0255D4C601FF60F7 /* config.h */,
1827
				F68EBB8C0255D4C601FF60F7 /* config.h */,
1828
				0F46809C14BA7F4D00BFE272 /* llint */,
1742
				1432EBD70A34CAD400717B9F /* API */,
1829
				1432EBD70A34CAD400717B9F /* API */,
1743
				9688CB120ED12B4E001D649F /* assembler */,
1830
				9688CB120ED12B4E001D649F /* assembler */,
1744
				969A078F0ED1D3AE00F1F681 /* bytecode */,
1831
				969A078F0ED1D3AE00F1F681 /* bytecode */,
Lines 1778-1783 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec15
1778
			tabWidth = 4;
1865
			tabWidth = 4;
1779
			usesTabs = 0;
1866
			usesTabs = 0;
1780
		};
1867
		};
1868
		0F46809C14BA7F4D00BFE272 /* llint */ = {
1869
			isa = PBXGroup;
1870
			children = (
1871
				0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
1872
				0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
1873
				0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
1874
				0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
1875
				0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
1876
				0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
1877
				0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
1878
				0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
1879
				0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
1880
				0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
1881
				0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
1882
				0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
1883
				0F46809F14BA7F8200BFE272 /* LLIntSlowPaths.cpp */,
1884
				0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.h */,
1885
				0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
1886
			);
1887
			name = llint;
1888
			sourceTree = "<group>";
1889
		};
1781
		141211000A48772600480255 /* tests */ = {
1890
		141211000A48772600480255 /* tests */ = {
1782
			isa = PBXGroup;
1891
			isa = PBXGroup;
1783
			children = (
1892
			children = (
Lines 1812-1817 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec16
1812
		1429D92C0ED22D7000B89619 /* jit */ = {
1921
		1429D92C0ED22D7000B89619 /* jit */ = {
1813
			isa = PBXGroup;
1922
			isa = PBXGroup;
1814
			children = (
1923
			children = (
1924
				0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
1925
				0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
1815
				0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
1926
				0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
1816
				0F46808014BA572700BFE272 /* JITExceptions.h */,
1927
				0F46808014BA572700BFE272 /* JITExceptions.h */,
1817
				0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
1928
				0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
Lines 2286-2291 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec17
2286
		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
2397
		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
2287
			isa = PBXGroup;
2398
			isa = PBXGroup;
2288
			children = (
2399
			children = (
2400
				0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
2401
				0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
2289
				0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
2402
				0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
2290
				BCF605110E203EF800B9A64D /* ArgList.cpp */,
2403
				BCF605110E203EF800B9A64D /* ArgList.cpp */,
2291
				BCF605120E203EF800B9A64D /* ArgList.h */,
2404
				BCF605120E203EF800B9A64D /* ArgList.h */,
Lines 2670-2675 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec18
2670
		969A078F0ED1D3AE00F1F681 /* bytecode */ = {
2783
		969A078F0ED1D3AE00F1F681 /* bytecode */ = {
2671
			isa = PBXGroup;
2784
			isa = PBXGroup;
2672
			children = (
2785
			children = (
2786
				0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
2787
				0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
2673
				0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */,
2788
				0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */,
2674
				0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
2789
				0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
2675
				0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */,
2790
				0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */,
Lines 3234-3240 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec19
3234
				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
3349
				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
3235
				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
3350
				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
3236
				0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
3351
				0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
3352
				0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
3353
				0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
3237
				0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
3354
				0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
3355
				0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
3356
				0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
3357
				0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
3358
				0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
3359
				0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
3360
				0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
3361
				0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
3238
				0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
3362
				0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
3239
				0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
3363
				0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
3240
				0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
3364
				0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
Lines 3243-3249 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec20
3243
				0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
3367
				0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
3244
				0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
3368
				0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
3245
				0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
3369
				0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
3370
				0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
3246
				0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
3371
				0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
3372
				0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
3373
				0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
3374
				0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
3247
				0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
3375
				0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
3248
				0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
3376
				0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
3249
				0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,
3377
				0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,
Lines 3275-3280 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec21
3275
/* End PBXHeadersBuildPhase section */
3403
/* End PBXHeadersBuildPhase section */
3276
3404
3277
/* Begin PBXNativeTarget section */
3405
/* Begin PBXNativeTarget section */
3406
		0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {
3407
			isa = PBXNativeTarget;
3408
			buildConfigurationList = 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */;
3409
			buildPhases = (
3410
				0F46808B14BA7E5E00BFE272 /* Sources */,
3411
				0F46808C14BA7E5E00BFE272 /* Frameworks */,
3412
				0F46808D14BA7E5E00BFE272 /* CopyFiles */,
3413
			);
3414
			buildRules = (
3415
			);
3416
			dependencies = (
3417
				0F4680B214BA811500BFE272 /* PBXTargetDependency */,
3418
			);
3419
			name = JSCLLIntOffsetsExtractor;
3420
			productName = JSCLLIntOffsetsExtractor;
3421
			productReference = 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
3422
			productType = "com.apple.product-type.tool";
3423
		};
3278
		1412111F0A48793C00480255 /* minidom */ = {
3424
		1412111F0A48793C00480255 /* minidom */ = {
3279
			isa = PBXNativeTarget;
3425
			isa = PBXNativeTarget;
3280
			buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;
3426
			buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;
Lines 3401-3411 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec22
3401
				14BD59BE0A3E8F9000BAF59C /* testapi */,
3547
				14BD59BE0A3E8F9000BAF59C /* testapi */,
3402
				932F5BDA0822A1C700736975 /* jsc */,
3548
				932F5BDA0822A1C700736975 /* jsc */,
3403
				651122F714046A4C002B101D /* testRegExp */,
3549
				651122F714046A4C002B101D /* testRegExp */,
3550
				0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
3551
				0F4680A914BA7FD900BFE272 /* LLInt Offsets */,
3404
			);
3552
			);
3405
		};
3553
		};
3406
/* End PBXProject section */
3554
/* End PBXProject section */
3407
3555
3408
/* Begin PBXShellScriptBuildPhase section */
3556
/* Begin PBXShellScriptBuildPhase section */
3557
		0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */ = {
3558
			isa = PBXShellScriptBuildPhase;
3559
			buildActionMask = 2147483647;
3560
			files = (
3561
			);
3562
			inputPaths = (
3563
				"$(SRCROOT)/llint/LowLevelAssembler.asm",
3564
			);
3565
			name = "Generate Derived Sources";
3566
			outputPaths = (
3567
				"$(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h",
3568
			);
3569
			runOnlyForDeploymentPostprocessing = 0;
3570
			shellPath = /bin/sh;
3571
			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";
3572
		};
3409
		3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
3573
		3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
3410
			isa = PBXShellScriptBuildPhase;
3574
			isa = PBXShellScriptBuildPhase;
3411
			buildActionMask = 2147483647;
3575
			buildActionMask = 2147483647;
Lines 3511-3517 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec23
3511
			);
3675
			);
3512
			runOnlyForDeploymentPostprocessing = 0;
3676
			runOnlyForDeploymentPostprocessing = 0;
3513
			shellPath = /bin/sh;
3677
			shellPath = /bin/sh;
3514
			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";
3678
			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";
3515
		};
3679
		};
3516
		9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
3680
		9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
3517
			isa = PBXShellScriptBuildPhase;
3681
			isa = PBXShellScriptBuildPhase;
Lines 3546-3551 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec24
3546
/* End PBXShellScriptBuildPhase section */
3710
/* End PBXShellScriptBuildPhase section */
3547
3711
3548
/* Begin PBXSourcesBuildPhase section */
3712
/* Begin PBXSourcesBuildPhase section */
3713
		0F46808B14BA7E5E00BFE272 /* Sources */ = {
3714
			isa = PBXSourcesBuildPhase;
3715
			buildActionMask = 2147483647;
3716
			files = (
3717
				0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */,
3718
			);
3719
			runOnlyForDeploymentPostprocessing = 0;
3720
		};
3549
		1412111D0A48793C00480255 /* Sources */ = {
3721
		1412111D0A48793C00480255 /* Sources */ = {
3550
			isa = PBXSourcesBuildPhase;
3722
			isa = PBXSourcesBuildPhase;
3551
			buildActionMask = 2147483647;
3723
			buildActionMask = 2147483647;
Lines 3806-3812 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec25
3806
				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
3978
				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
3807
				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
3979
				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
3808
				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
3980
				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
3981
				0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
3982
				0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
3809
				0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
3983
				0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
3984
				0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
3985
				0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
3986
				0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
3987
				0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
3988
				0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
3810
				0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
3989
				0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
3811
				0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
3990
				0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
3812
				F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,
3991
				F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,
Lines 3840-3845 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec26
3840
/* End PBXSourcesBuildPhase section */
4019
/* End PBXSourcesBuildPhase section */
3841
4020
3842
/* Begin PBXTargetDependency section */
4021
/* Begin PBXTargetDependency section */
4022
		0F4680B214BA811500BFE272 /* PBXTargetDependency */ = {
4023
			isa = PBXTargetDependency;
4024
			target = 0F4680A914BA7FD900BFE272 /* LLInt Offsets */;
4025
			targetProxy = 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */;
4026
		};
4027
		0F4680B414BA821400BFE272 /* PBXTargetDependency */ = {
4028
			isa = PBXTargetDependency;
4029
			target = 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
4030
			targetProxy = 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */;
4031
		};
3843
		141214BF0A49190E00480255 /* PBXTargetDependency */ = {
4032
		141214BF0A49190E00480255 /* PBXTargetDependency */ = {
3844
			isa = PBXTargetDependency;
4033
			isa = PBXTargetDependency;
3845
			target = 1412111F0A48793C00480255 /* minidom */;
4034
			target = 1412111F0A48793C00480255 /* minidom */;
Lines 3873-3878 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec27
3873
/* End PBXTargetDependency section */
4062
/* End PBXTargetDependency section */
3874
4063
3875
/* Begin XCBuildConfiguration section */
4064
/* Begin XCBuildConfiguration section */
4065
		0F46809614BA7E5E00BFE272 /* Debug */ = {
4066
			isa = XCBuildConfiguration;
4067
			buildSettings = {
4068
				ALWAYS_SEARCH_USER_PATHS = NO;
4069
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
4070
				COPY_PHASE_STRIP = NO;
4071
				GCC_C_LANGUAGE_STANDARD = gnu99;
4072
				GCC_DYNAMIC_NO_PIC = NO;
4073
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
4074
				GCC_OPTIMIZATION_LEVEL = 0;
4075
				GCC_PREPROCESSOR_DEFINITIONS = (
4076
					"DEBUG=1",
4077
					"$(inherited)",
4078
				);
4079
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
4080
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
4081
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
4082
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
4083
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
4084
				GCC_WARN_UNUSED_VARIABLE = YES;
4085
				"HEADER_SEARCH_PATHS[arch=*]" = (
4086
					.,
4087
					icu,
4088
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
4089
					"$(HEADER_SEARCH_PATHS)",
4090
				);
4091
				MACOSX_DEPLOYMENT_TARGET = 10.7;
4092
				ONLY_ACTIVE_ARCH = NO;
4093
				PRODUCT_NAME = "$(TARGET_NAME)";
4094
				SDKROOT = macosx;
4095
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
4096
			};
4097
			name = Debug;
4098
		};
4099
		0F46809714BA7E5E00BFE272 /* Release */ = {
4100
			isa = XCBuildConfiguration;
4101
			buildSettings = {
4102
				ALWAYS_SEARCH_USER_PATHS = NO;
4103
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
4104
				COPY_PHASE_STRIP = YES;
4105
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
4106
				GCC_C_LANGUAGE_STANDARD = gnu99;
4107
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
4108
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
4109
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
4110
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
4111
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
4112
				GCC_WARN_UNUSED_VARIABLE = YES;
4113
				"HEADER_SEARCH_PATHS[arch=*]" = (
4114
					.,
4115
					icu,
4116
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets$(HEADER_SEARCH_PATHS)",
4117
				);
4118
				MACOSX_DEPLOYMENT_TARGET = 10.7;
4119
				ONLY_ACTIVE_ARCH = NO;
4120
				PRODUCT_NAME = "$(TARGET_NAME)";
4121
				SDKROOT = macosx;
4122
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
4123
			};
4124
			name = Release;
4125
		};
4126
		0F46809814BA7E5E00BFE272 /* Profiling */ = {
4127
			isa = XCBuildConfiguration;
4128
			buildSettings = {
4129
				ALWAYS_SEARCH_USER_PATHS = NO;
4130
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
4131
				COPY_PHASE_STRIP = YES;
4132
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
4133
				GCC_C_LANGUAGE_STANDARD = gnu99;
4134
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
4135
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
4136
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
4137
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
4138
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
4139
				GCC_WARN_UNUSED_VARIABLE = YES;
4140
				"HEADER_SEARCH_PATHS[arch=*]" = (
4141
					.,
4142
					icu,
4143
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
4144
					"$(HEADER_SEARCH_PATHS)",
4145
				);
4146
				MACOSX_DEPLOYMENT_TARGET = 10.7;
4147
				ONLY_ACTIVE_ARCH = NO;
4148
				PRODUCT_NAME = "$(TARGET_NAME)";
4149
				SDKROOT = macosx;
4150
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
4151
			};
4152
			name = Profiling;
4153
		};
4154
		0F46809914BA7E5E00BFE272 /* Production */ = {
4155
			isa = XCBuildConfiguration;
4156
			buildSettings = {
4157
				ALWAYS_SEARCH_USER_PATHS = NO;
4158
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
4159
				COPY_PHASE_STRIP = YES;
4160
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
4161
				GCC_C_LANGUAGE_STANDARD = gnu99;
4162
				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
4163
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
4164
				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
4165
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
4166
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
4167
				GCC_WARN_UNUSED_VARIABLE = YES;
4168
				"HEADER_SEARCH_PATHS[arch=*]" = (
4169
					.,
4170
					icu,
4171
					"$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
4172
					"$(HEADER_SEARCH_PATHS)",
4173
				);
4174
				MACOSX_DEPLOYMENT_TARGET = 10.7;
4175
				PRODUCT_NAME = "$(TARGET_NAME)";
4176
				SDKROOT = macosx;
4177
				USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
4178
			};
4179
			name = Production;
4180
		};
4181
		0F4680AD14BA7FD900BFE272 /* Debug */ = {
4182
			isa = XCBuildConfiguration;
4183
			buildSettings = {
4184
				PRODUCT_NAME = "Derived Sources copy";
4185
			};
4186
			name = Debug;
4187
		};
4188
		0F4680AE14BA7FD900BFE272 /* Release */ = {
4189
			isa = XCBuildConfiguration;
4190
			buildSettings = {
4191
				PRODUCT_NAME = "Derived Sources copy";
4192
			};
4193
			name = Release;
4194
		};
4195
		0F4680AF14BA7FD900BFE272 /* Profiling */ = {
4196
			isa = XCBuildConfiguration;
4197
			buildSettings = {
4198
				PRODUCT_NAME = "Derived Sources copy";
4199
			};
4200
			name = Profiling;
4201
		};
4202
		0F4680B014BA7FD900BFE272 /* Production */ = {
4203
			isa = XCBuildConfiguration;
4204
			buildSettings = {
4205
				PRODUCT_NAME = "Derived Sources copy";
4206
			};
4207
			name = Production;
4208
		};
3876
		1412113A0A48798400480255 /* Debug */ = {
4209
		1412113A0A48798400480255 /* Debug */ = {
3877
			isa = XCBuildConfiguration;
4210
			isa = XCBuildConfiguration;
3878
			buildSettings = {
4211
			buildSettings = {
Lines 4114-4119 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec28
4114
/* End XCBuildConfiguration section */
4447
/* End XCBuildConfiguration section */
4115
4448
4116
/* Begin XCConfigurationList section */
4449
/* Begin XCConfigurationList section */
4450
		0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */ = {
4451
			isa = XCConfigurationList;
4452
			buildConfigurations = (
4453
				0F46809614BA7E5E00BFE272 /* Debug */,
4454
				0F46809714BA7E5E00BFE272 /* Release */,
4455
				0F46809814BA7E5E00BFE272 /* Profiling */,
4456
				0F46809914BA7E5E00BFE272 /* Production */,
4457
			);
4458
			defaultConfigurationIsVisible = 0;
4459
			defaultConfigurationName = Production;
4460
		};
4461
		0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */ = {
4462
			isa = XCConfigurationList;
4463
			buildConfigurations = (
4464
				0F4680AD14BA7FD900BFE272 /* Debug */,
4465
				0F4680AE14BA7FD900BFE272 /* Release */,
4466
				0F4680AF14BA7FD900BFE272 /* Profiling */,
4467
				0F4680B014BA7FD900BFE272 /* Production */,
4468
			);
4469
			defaultConfigurationIsVisible = 0;
4470
			defaultConfigurationName = Production;
4471
		};
4117
		141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
4472
		141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
4118
			isa = XCConfigurationList;
4473
			isa = XCConfigurationList;
4119
			buildConfigurations = (
4474
			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/DataLog.h>
38
#include <wtf/DataLog.h>
39
#include <wtf/Noncopyable.h>
39
#include <wtf/Noncopyable.h>
40
40
- Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h -4 / +8 lines
Lines 31-38 Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h_sec1
31
#include "RefPtr.h"
31
#include "RefPtr.h"
32
#include "UnusedParam.h"
32
#include "UnusedParam.h"
33
33
34
#if ENABLE(ASSEMBLER)
35
36
// ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
34
// ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
37
// instruction address on the platform (for example, check any alignment requirements).
35
// instruction address on the platform (for example, check any alignment requirements).
38
#if CPU(ARM_THUMB2)
36
#if CPU(ARM_THUMB2)
Lines 273-278 public: Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h_sec2
273
    {
271
    {
274
        ASSERT_VALID_CODE_POINTER(m_value);
272
        ASSERT_VALID_CODE_POINTER(m_value);
275
    }
273
    }
274
    
275
    static MacroAssemblerCodePtr createFromExecutableAddress(void* value)
276
    {
277
        ASSERT_VALID_CODE_POINTER(value);
278
        MacroAssemblerCodePtr result;
279
        result.m_value = value;
280
        return result;
281
    }
276
282
277
    explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
283
    explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
278
        : m_value(ra.value())
284
        : m_value(ra.value())
Lines 360-365 private: Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h_sec3
360
366
361
} // namespace JSC
367
} // namespace JSC
362
368
363
#endif // ENABLE(ASSEMBLER)
364
365
#endif // MacroAssemblerCodeRef_h
369
#endif // MacroAssemblerCodeRef_h
- 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 / +173 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 356-365 void CodeBlock::dump(ExecState* exec) co Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec2
356
    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)])
357
        ++instructionCount;
358
        ++instructionCount;
358
359
359
    dataLog("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
360
    dataLog("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s); %d variable(s)\n\n",
360
        static_cast<unsigned long>(instructionCount),
361
        static_cast<unsigned long>(instructionCount),
361
        static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
362
        static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
362
        this, m_numParameters, m_numCalleeRegisters);
363
        this, m_numParameters, m_numCalleeRegisters, m_numVars);
363
364
364
    Vector<Instruction>::const_iterator begin = instructions().begin();
365
    Vector<Instruction>::const_iterator begin = instructions().begin();
365
    Vector<Instruction>::const_iterator end = instructions().end();
366
    Vector<Instruction>::const_iterator end = instructions().end();
Lines 896-901 void CodeBlock::dump(ExecState* exec, co Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec3
896
            printPutByIdOp(exec, location, it, "put_by_id_transition");
897
            printPutByIdOp(exec, location, it, "put_by_id_transition");
897
            break;
898
            break;
898
        }
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
        }
899
        case op_put_by_id_generic: {
908
        case op_put_by_id_generic: {
900
            printPutByIdOp(exec, location, it, "put_by_id_generic");
909
            printPutByIdOp(exec, location, it, "put_by_id_generic");
901
            break;
910
            break;
Lines 1453-1458 CodeBlock::CodeBlock(CopyParsedBlockTag, Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec4
1453
{
1462
{
1454
    setNumParameters(other.numParameters());
1463
    setNumParameters(other.numParameters());
1455
    optimizeAfterWarmUp();
1464
    optimizeAfterWarmUp();
1465
    jitAfterWarmUp();
1456
    
1466
    
1457
    if (other.m_rareData) {
1467
    if (other.m_rareData) {
1458
        createRareDataIfNecessary();
1468
        createRareDataIfNecessary();
Lines 1501-1506 CodeBlock::CodeBlock(ScriptExecutable* o Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec5
1501
    ASSERT(m_source);
1511
    ASSERT(m_source);
1502
    
1512
    
1503
    optimizeAfterWarmUp();
1513
    optimizeAfterWarmUp();
1514
    jitAfterWarmUp();
1504
1515
1505
#if DUMP_CODE_BLOCK_STATISTICS
1516
#if DUMP_CODE_BLOCK_STATISTICS
1506
    liveCodeBlockSet.add(this);
1517
    liveCodeBlockSet.add(this);
Lines 1518-1524 CodeBlock::~CodeBlock() Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec6
1518
#if ENABLE(VERBOSE_VALUE_PROFILE)
1529
#if ENABLE(VERBOSE_VALUE_PROFILE)
1519
    dumpValueProfiles();
1530
    dumpValueProfiles();
1520
#endif
1531
#endif
1521
    
1532
1533
#if ENABLE(LLINT)    
1534
    while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
1535
        m_incomingLLIntCalls.begin()->remove();
1536
#endif // ENABLE(LLINT)
1522
#if ENABLE(JIT)
1537
#if ENABLE(JIT)
1523
    // We may be destroyed before any CodeBlocks that refer to us are destroyed.
1538
    // We may be destroyed before any CodeBlocks that refer to us are destroyed.
1524
    // Consider that two CodeBlocks become unreachable at the same time. There
1539
    // Consider that two CodeBlocks become unreachable at the same time. There
Lines 1730-1737 void CodeBlock::finalizeUnconditionally( Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec7
1730
#else
1745
#else
1731
    static const bool verboseUnlinking = false;
1746
    static const bool verboseUnlinking = false;
1732
#endif
1747
#endif
1733
#endif
1748
#endif // ENABLE(JIT)
1734
    
1749
    
1750
#if ENABLE(LLINT)
1751
    Interpreter* interpreter = m_globalData->interpreter;
1752
    // interpreter->classicEnabled() returns true if the old C++ interpreter is enabled. If that's enabled
1753
    // then we're not using LLInt.
1754
    if (!interpreter->classicEnabled()) {
1755
        for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
1756
            Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
1757
            switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
1758
            case op_get_by_id:
1759
            case op_put_by_id:
1760
                if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
1761
                    break;
1762
                if (verboseUnlinking)
1763
                    dataLog("Clearing LLInt property access with structure %p.\n", curInstruction[4].u.structure.get());
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
                if (verboseUnlinking) {
1774
                    dataLog("Clearing LLInt put transition with structures %p -> %p, chain %p.\n",
1775
                            curInstruction[4].u.structure.get(),
1776
                            curInstruction[6].u.structure.get(),
1777
                            curInstruction[7].u.structureChain.get());
1778
                }
1779
                curInstruction[4].u.structure.clear();
1780
                curInstruction[6].u.structure.clear();
1781
                curInstruction[7].u.structureChain.clear();
1782
                curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
1783
                break;
1784
            default:
1785
                ASSERT_NOT_REACHED();
1786
            }
1787
        }
1788
        for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) {
1789
            Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]];
1790
            ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global
1791
                   || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic);
1792
            if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get()))
1793
                continue;
1794
            if (verboseUnlinking)
1795
                dataLog("Clearing LLInt global resolve cache with structure %p.\n", curInstruction[3].u.structure.get());
1796
            curInstruction[3].u.structure.clear();
1797
            curInstruction[4].u.operand = 0;
1798
        }
1799
        for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
1800
            if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
1801
                if (verboseUnlinking)
1802
                    dataLog("Clearing LLInt call from %p.\n", this);
1803
                m_llintCallLinkInfos[i].unlink();
1804
            }
1805
            if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
1806
                m_llintCallLinkInfos[i].lastSeenCallee.clear();
1807
        }
1808
    }
1809
#endif // ENABLE(LLINT)
1810
1735
#if ENABLE(DFG_JIT)
1811
#if ENABLE(DFG_JIT)
1736
    // Check if we're not live. If we are, then jettison.
1812
    // Check if we're not live. If we are, then jettison.
1737
    if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {
1813
    if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {
Lines 1754-1760 void CodeBlock::finalizeUnconditionally( Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec8
1754
        for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) {
1830
        for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) {
1755
            if (callLinkInfo(i).isLinked() && !Heap::isMarked(callLinkInfo(i).callee.get())) {
1831
            if (callLinkInfo(i).isLinked() && !Heap::isMarked(callLinkInfo(i).callee.get())) {
1756
                if (verboseUnlinking)
1832
                if (verboseUnlinking)
1757
                    dataLog("Clearing call from %p.\n", this);
1833
                    dataLog("Clearing call from %p to %p.\n", this, callLinkInfo(i).callee.get());
1758
                callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
1834
                callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
1759
            }
1835
            }
1760
            if (!!callLinkInfo(i).lastSeenCallee
1836
            if (!!callLinkInfo(i).lastSeenCallee
Lines 1852-1861 void CodeBlock::stronglyVisitStrongRefer Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec9
1852
    for (size_t i = 0; i < m_functionDecls.size(); ++i)
1928
    for (size_t i = 0; i < m_functionDecls.size(); ++i)
1853
        visitor.append(&m_functionDecls[i]);
1929
        visitor.append(&m_functionDecls[i]);
1854
#if ENABLE(CLASSIC_INTERPRETER)
1930
#if ENABLE(CLASSIC_INTERPRETER)
1855
    for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1931
    if (m_globalData->interpreter->classicEnabled()) {
1856
        visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1932
        for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1857
    for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1933
            visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1858
        visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
1934
        for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1935
            visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
1936
    }
1859
#endif
1937
#endif
1860
1938
1861
#if ENABLE(DFG_JIT)
1939
#if ENABLE(DFG_JIT)
Lines 1863-1870 void CodeBlock::stronglyVisitStrongRefer Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec10
1863
        // Make sure that executables that we have inlined don't die.
1941
        // Make sure that executables that we have inlined don't die.
1864
        // FIXME: If they would have otherwise died, we should probably trigger recompilation.
1942
        // FIXME: If they would have otherwise died, we should probably trigger recompilation.
1865
        for (size_t i = 0; i < inlineCallFrames().size(); ++i) {
1943
        for (size_t i = 0; i < inlineCallFrames().size(); ++i) {
1866
            visitor.append(&inlineCallFrames()[i].executable);
1944
            InlineCallFrame& inlineCallFrame = inlineCallFrames()[i];
1867
            visitor.append(&inlineCallFrames()[i].callee);
1945
            visitor.append(&inlineCallFrame.executable);
1946
            visitor.append(&inlineCallFrame.callee);
1868
        }
1947
        }
1869
    }
1948
    }
1870
#endif
1949
#endif
Lines 2068-2079 unsigned CodeBlock::addOrFindConstant(JS Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec11
2068
    }
2147
    }
2069
    return addConstant(v);
2148
    return addConstant(v);
2070
}
2149
}
2071
    
2150
2072
#if ENABLE(JIT)
2151
#if ENABLE(JIT)
2073
void CodeBlock::unlinkCalls()
2152
void CodeBlock::unlinkCalls()
2074
{
2153
{
2075
    if (!!m_alternative)
2154
    if (!!m_alternative)
2076
        m_alternative->unlinkCalls();
2155
        m_alternative->unlinkCalls();
2156
#if ENABLE(LLINT)
2157
    for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2158
        if (m_llintCallLinkInfos[i].isLinked())
2159
            m_llintCallLinkInfos[i].unlink();
2160
    }
2161
#endif
2077
    if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
2162
    if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
2078
        return;
2163
        return;
2079
    if (!m_globalData->canUseJIT())
2164
    if (!m_globalData->canUseJIT())
Lines 2088-2097 void CodeBlock::unlinkCalls() Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec12
2088
2173
2089
void CodeBlock::unlinkIncomingCalls()
2174
void CodeBlock::unlinkIncomingCalls()
2090
{
2175
{
2176
#if ENABLE(LLINT)
2177
    while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
2178
        m_incomingLLIntCalls.begin()->unlink();
2179
#endif
2180
    if (m_incomingCalls.isEmpty())
2181
        return;
2091
    RepatchBuffer repatchBuffer(this);
2182
    RepatchBuffer repatchBuffer(this);
2092
    while (m_incomingCalls.begin() != m_incomingCalls.end())
2183
    while (m_incomingCalls.begin() != m_incomingCalls.end())
2093
        m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
2184
        m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
2094
}
2185
}
2186
2187
unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
2188
{
2189
#if ENABLE(LLINT)
2190
    if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin)
2191
        && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) {
2192
        ASSERT(exec->codeBlock());
2193
        ASSERT(exec->codeBlock() == this);
2194
        ASSERT(JITCode::isBaselineCode(getJITType()));
2195
        Instruction* instruction = exec->currentVPC();
2196
        ASSERT(instruction);
2197
        
2198
        // The LLInt stores the PC after the call instruction rather than the PC of
2199
        // the call instruction. This requires some correcting. We rely on the fact
2200
        // that the preceding instruction must be one of the call instructions, so
2201
        // either it's a call_varargs or it's a call, construct, or eval.
2202
        ASSERT(OPCODE_LENGTH(op_call_varargs) <= OPCODE_LENGTH(op_call));
2203
        ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
2204
        ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval));
2205
        if (instruction[-OPCODE_LENGTH(op_call_varargs)].u.pointer == bitwise_cast<void*>(llint_op_call_varargs)) {
2206
            // We know that the preceding instruction must be op_call_varargs because there is no way that
2207
            // the pointer to the call_varargs could be an operand to the call.
2208
            instruction -= OPCODE_LENGTH(op_call_varargs);
2209
            ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_call)
2210
                   && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_construct)
2211
                   && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_call_eval));
2212
        } else {
2213
            // Must be that the last instruction was some op_call.
2214
            ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_call)
2215
                   || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_construct)
2216
                   || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_call_eval));
2217
            instruction -= OPCODE_LENGTH(op_call);
2218
        }
2219
        
2220
        return bytecodeOffset(instruction);
2221
    }
2222
#else
2223
    UNUSED_PARAM(exec);
2224
#endif
2225
    if (!m_rareData)
2226
        return 1;
2227
    Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
2228
    if (!callIndices.size())
2229
        return 1;
2230
    return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
2231
}
2095
#endif
2232
#endif
2096
2233
2097
void CodeBlock::clearEvalCache()
2234
void CodeBlock::clearEvalCache()
Lines 2187-2210 bool FunctionCodeBlock::canCompileWithDF Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec13
2187
2324
2188
void ProgramCodeBlock::jettison()
2325
void ProgramCodeBlock::jettison()
2189
{
2326
{
2190
    ASSERT(getJITType() != JITCode::BaselineJIT);
2327
    ASSERT(JITCode::isOptimizingJIT(getJITType()));
2191
    ASSERT(this == replacement());
2328
    ASSERT(this == replacement());
2192
    static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2329
    static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2193
}
2330
}
2194
2331
2195
void EvalCodeBlock::jettison()
2332
void EvalCodeBlock::jettison()
2196
{
2333
{
2197
    ASSERT(getJITType() != JITCode::BaselineJIT);
2334
    ASSERT(JITCode::isOptimizingJIT(getJITType()));
2198
    ASSERT(this == replacement());
2335
    ASSERT(this == replacement());
2199
    static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2336
    static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2200
}
2337
}
2201
2338
2202
void FunctionCodeBlock::jettison()
2339
void FunctionCodeBlock::jettison()
2203
{
2340
{
2204
    ASSERT(getJITType() != JITCode::BaselineJIT);
2341
    ASSERT(JITCode::isOptimizingJIT(getJITType()));
2205
    ASSERT(this == replacement());
2342
    ASSERT(this == replacement());
2206
    static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
2343
    static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
2207
}
2344
}
2345
2346
void ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData)
2347
{
2348
    ASSERT(getJITType() == JITCode::InterpreterThunk);
2349
    ASSERT(this == replacement());
2350
    return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(globalData);
2351
}
2352
2353
void EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData)
2354
{
2355
    ASSERT(getJITType() == JITCode::InterpreterThunk);
2356
    ASSERT(this == replacement());
2357
    return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(globalData);
2358
}
2359
2360
void FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData)
2361
{
2362
    ASSERT(getJITType() == JITCode::InterpreterThunk);
2363
    ASSERT(this == replacement());
2364
    return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(globalData, m_isConstructor ? CodeForConstruct : CodeForCall);
2365
}
2208
#endif
2366
#endif
2209
2367
2210
#if ENABLE(VALUE_PROFILER)
2368
#if ENABLE(VALUE_PROFILER)
- Source/JavaScriptCore/bytecode/CodeBlock.h -35 / +97 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 192-206 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec6
192
            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));
193
        }
191
        }
194
192
195
        unsigned bytecodeOffset(ReturnAddressPtr returnAddress)
193
        unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
196
        {
197
            if (!m_rareData)
198
                return 1;
199
            Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
200
            if (!callIndices.size())
201
                return 1;
202
            return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
203
        }
204
194
205
        unsigned bytecodeOffsetForCallAtIndex(unsigned index)
195
        unsigned bytecodeOffsetForCallAtIndex(unsigned index)
206
        {
196
        {
Lines 221-231 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec7
221
        {
211
        {
222
            m_incomingCalls.push(incoming);
212
            m_incomingCalls.push(incoming);
223
        }
213
        }
214
#if ENABLE(LLINT)
215
        void linkIncomingCall(LLIntCallLinkInfo* incoming)
216
        {
217
            m_incomingLLIntCalls.push(incoming);
218
        }
219
#endif // ENABLE(LLINT)
224
        
220
        
225
        void unlinkIncomingCalls();
221
        void unlinkIncomingCalls();
226
#endif
222
#endif // ENABLE(JIT)
227
223
228
#if ENABLE(DFG_JIT)
224
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
229
        void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
225
        void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
230
        {
226
        {
231
            m_jitCodeMap = jitCodeMap;
227
            m_jitCodeMap = jitCodeMap;
Lines 234-240 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec8
234
        {
230
        {
235
            return m_jitCodeMap.get();
231
            return m_jitCodeMap.get();
236
        }
232
        }
233
#endif
237
        
234
        
235
#if ENABLE(DFG_JIT)
238
        void createDFGDataIfNecessary()
236
        void createDFGDataIfNecessary()
239
        {
237
        {
240
            if (!!m_dfgData)
238
            if (!!m_dfgData)
Lines 333-344 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec9
333
        }
331
        }
334
#endif
332
#endif
335
333
336
#if ENABLE(CLASSIC_INTERPRETER)
337
        unsigned bytecodeOffset(Instruction* returnAddress)
334
        unsigned bytecodeOffset(Instruction* returnAddress)
338
        {
335
        {
336
            ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end());
339
            return static_cast<Instruction*>(returnAddress) - instructions().begin();
337
            return static_cast<Instruction*>(returnAddress) - instructions().begin();
340
        }
338
        }
341
#endif
342
339
343
        void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
340
        void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
344
        bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
341
        bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
Lines 376-381 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec10
376
        ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
373
        ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
377
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
374
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
378
        virtual void jettison() = 0;
375
        virtual void jettison() = 0;
376
        bool jitCompile(JSGlobalData& globalData)
377
        {
378
            if (getJITType() != JITCode::InterpreterThunk) {
379
                ASSERT(getJITType() == JITCode::BaselineJIT);
380
                return false;
381
            }
382
#if ENABLE(JIT)
383
            jitCompileImpl(globalData);
384
            return true;
385
#else
386
            UNUSED_PARAM(globalData);
387
            return false;
388
#endif
389
        }
379
        virtual CodeBlock* replacement() = 0;
390
        virtual CodeBlock* replacement() = 0;
380
391
381
        enum CompileWithDFGState {
392
        enum CompileWithDFGState {
Lines 395-407 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec11
395
406
396
        bool hasOptimizedReplacement()
407
        bool hasOptimizedReplacement()
397
        {
408
        {
398
            ASSERT(getJITType() == JITCode::BaselineJIT);
409
            ASSERT(JITCode::isBaselineCode(getJITType()));
399
            bool result = replacement()->getJITType() > getJITType();
410
            bool result = replacement()->getJITType() > getJITType();
400
#if !ASSERT_DISABLED
411
#if !ASSERT_DISABLED
401
            if (result)
412
            if (result)
402
                ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
413
                ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
403
            else {
414
            else {
404
                ASSERT(replacement()->getJITType() == JITCode::BaselineJIT);
415
                ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
405
                ASSERT(replacement() == this);
416
                ASSERT(replacement() == this);
406
            }
417
            }
407
#endif
418
#endif
Lines 460-477 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec12
460
471
461
        void clearEvalCache();
472
        void clearEvalCache();
462
473
463
#if ENABLE(CLASSIC_INTERPRETER)
464
        void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
474
        void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
465
        {
475
        {
466
            if (!m_globalData->canUseJIT())
476
            m_propertyAccessInstructions.append(propertyAccessInstruction);
467
                m_propertyAccessInstructions.append(propertyAccessInstruction);
468
        }
477
        }
469
        void addGlobalResolveInstruction(unsigned globalResolveInstruction)
478
        void addGlobalResolveInstruction(unsigned globalResolveInstruction)
470
        {
479
        {
471
            if (!m_globalData->canUseJIT())
480
            m_globalResolveInstructions.append(globalResolveInstruction);
472
                m_globalResolveInstructions.append(globalResolveInstruction);
473
        }
481
        }
474
        bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
482
        bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
483
#if ENABLE(LLINT)
484
        LLIntCallLinkInfo* addLLIntCallLinkInfo()
485
        {
486
            m_llintCallLinkInfos.append(LLIntCallLinkInfo());
487
            return &m_llintCallLinkInfos.last();
488
        }
475
#endif
489
#endif
476
#if ENABLE(JIT)
490
#if ENABLE(JIT)
477
        void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
491
        void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
Lines 480-487 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec13
480
494
481
        void addGlobalResolveInfo(unsigned globalResolveInstruction)
495
        void addGlobalResolveInfo(unsigned globalResolveInstruction)
482
        {
496
        {
483
            if (m_globalData->canUseJIT())
497
            m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
484
                m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
485
        }
498
        }
486
        GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
499
        GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
487
        bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
500
        bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
Lines 492-497 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec14
492
505
493
        void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); }
506
        void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); }
494
        MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
507
        MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
508
        size_t numberOfMethodCallLinkInfos() { return m_methodCallLinkInfos.size(); }
495
#endif
509
#endif
496
        
510
        
497
#if ENABLE(VALUE_PROFILER)
511
#if ENABLE(VALUE_PROFILER)
Lines 533-538 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec15
533
                                   bytecodeOffset].u.opcode)) - 1].u.profile == result);
547
                                   bytecodeOffset].u.opcode)) - 1].u.profile == result);
534
            return result;
548
            return result;
535
        }
549
        }
550
        PredictedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
551
        {
552
            return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction();
553
        }
536
        
554
        
537
        unsigned totalNumberOfValueProfiles()
555
        unsigned totalNumberOfValueProfiles()
538
        {
556
        {
Lines 559-570 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec16
559
        
577
        
560
        bool likelyToTakeSlowCase(int bytecodeOffset)
578
        bool likelyToTakeSlowCase(int bytecodeOffset)
561
        {
579
        {
580
            if (!numberOfRareCaseProfiles())
581
                return false;
562
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
582
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
563
            return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
583
            return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
564
        }
584
        }
565
        
585
        
566
        bool couldTakeSlowCase(int bytecodeOffset)
586
        bool couldTakeSlowCase(int bytecodeOffset)
567
        {
587
        {
588
            if (!numberOfRareCaseProfiles())
589
                return false;
568
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
590
            unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
569
            return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
591
            return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
570
        }
592
        }
Lines 583-594 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec17
583
        
605
        
584
        bool likelyToTakeSpecialFastCase(int bytecodeOffset)
606
        bool likelyToTakeSpecialFastCase(int bytecodeOffset)
585
        {
607
        {
608
            if (!numberOfRareCaseProfiles())
609
                return false;
586
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
610
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
587
            return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
611
            return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
588
        }
612
        }
589
        
613
        
590
        bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
614
        bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
591
        {
615
        {
616
            if (!numberOfRareCaseProfiles())
617
                return false;
592
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
618
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
593
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
619
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
594
            unsigned value = slowCaseCount - specialFastCaseCount;
620
            unsigned value = slowCaseCount - specialFastCaseCount;
Lines 597-602 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec18
597
        
623
        
598
        bool likelyToTakeAnySlowCase(int bytecodeOffset)
624
        bool likelyToTakeAnySlowCase(int bytecodeOffset)
599
        {
625
        {
626
            if (!numberOfRareCaseProfiles())
627
                return false;
600
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
628
            unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
601
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
629
            unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
602
            unsigned value = slowCaseCount + specialFastCaseCount;
630
            unsigned value = slowCaseCount + specialFastCaseCount;
Lines 694-700 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec19
694
        
722
        
695
        bool addFrequentExitSite(const DFG::FrequentExitSite& site)
723
        bool addFrequentExitSite(const DFG::FrequentExitSite& site)
696
        {
724
        {
697
            ASSERT(getJITType() == JITCode::BaselineJIT);
725
            ASSERT(JITCode::isBaselineCode(getJITType()));
698
            return m_exitProfile.add(site);
726
            return m_exitProfile.add(site);
699
        }
727
        }
700
728
Lines 802-807 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec20
802
        void copyPostParseDataFrom(CodeBlock* alternative);
830
        void copyPostParseDataFrom(CodeBlock* alternative);
803
        void copyPostParseDataFromAlternative();
831
        void copyPostParseDataFromAlternative();
804
        
832
        
833
        // Functions for controlling when JITting kicks in, in a mixed mode
834
        // execution world.
835
        
836
        void dontJITAnytimeSoon()
837
        {
838
            m_llintExecuteCounter = Options::executionCounterValueForDontJITAnytimeSoon;
839
        }
840
        
841
        void jitAfterWarmUp()
842
        {
843
            m_llintExecuteCounter = Options::executionCounterValueForJITAfterWarmUp;
844
        }
845
        
846
        void jitSoon()
847
        {
848
            m_llintExecuteCounter = Options::executionCounterValueForJITSoon;
849
        }
850
        
851
        int32_t llintExecuteCounter() const
852
        {
853
            return m_llintExecuteCounter;
854
        }
855
        
805
        // Functions for controlling when tiered compilation kicks in. This
856
        // Functions for controlling when tiered compilation kicks in. This
806
        // controls both when the optimizing compiler is invoked and when OSR
857
        // controls both when the optimizing compiler is invoked and when OSR
807
        // entry happens. Two triggers exist: the loop trigger and the return
858
        // entry happens. Two triggers exist: the loop trigger and the return
Lines 994-999 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec21
994
        bool m_shouldDiscardBytecode;
1045
        bool m_shouldDiscardBytecode;
995
1046
996
    protected:
1047
    protected:
1048
#if ENABLE(JIT)
1049
        virtual void jitCompileImpl(JSGlobalData&) = 0;
1050
#endif
997
        virtual void visitWeakReferences(SlotVisitor&);
1051
        virtual void visitWeakReferences(SlotVisitor&);
998
        virtual void finalizeUnconditionally();
1052
        virtual void finalizeUnconditionally();
999
        
1053
        
Lines 1075-1083 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec22
1075
        RefPtr<SourceProvider> m_source;
1129
        RefPtr<SourceProvider> m_source;
1076
        unsigned m_sourceOffset;
1130
        unsigned m_sourceOffset;
1077
1131
1078
#if ENABLE(CLASSIC_INTERPRETER)
1079
        Vector<unsigned> m_propertyAccessInstructions;
1132
        Vector<unsigned> m_propertyAccessInstructions;
1080
        Vector<unsigned> m_globalResolveInstructions;
1133
        Vector<unsigned> m_globalResolveInstructions;
1134
#if ENABLE(LLINT)
1135
        SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
1136
        SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
1081
#endif
1137
#endif
1082
#if ENABLE(JIT)
1138
#if ENABLE(JIT)
1083
        Vector<StructureStubInfo> m_structureStubInfos;
1139
        Vector<StructureStubInfo> m_structureStubInfos;
Lines 1088-1096 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec23
1088
        MacroAssemblerCodePtr m_jitCodeWithArityCheck;
1144
        MacroAssemblerCodePtr m_jitCodeWithArityCheck;
1089
        SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
1145
        SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
1090
#endif
1146
#endif
1091
#if ENABLE(DFG_JIT)
1147
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
1092
        OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1148
        OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1093
        
1149
#endif
1150
#if ENABLE(DFG_JIT)
1094
        struct WeakReferenceTransition {
1151
        struct WeakReferenceTransition {
1095
            WeakReferenceTransition() { }
1152
            WeakReferenceTransition() { }
1096
            
1153
            
Lines 1153-1164 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec24
1153
1210
1154
        OwnPtr<CodeBlock> m_alternative;
1211
        OwnPtr<CodeBlock> m_alternative;
1155
        
1212
        
1213
        int32_t m_llintExecuteCounter;
1214
        
1156
        int32_t m_jitExecuteCounter;
1215
        int32_t m_jitExecuteCounter;
1157
        uint32_t m_speculativeSuccessCounter;
1216
        uint32_t m_speculativeSuccessCounter;
1158
        uint32_t m_speculativeFailCounter;
1217
        uint32_t m_speculativeFailCounter;
1159
        uint8_t m_optimizationDelayCounter;
1218
        uint8_t m_optimizationDelayCounter;
1160
        uint8_t m_reoptimizationRetryCounter;
1219
        uint8_t m_reoptimizationRetryCounter;
1161
1220
        
1162
        struct RareData {
1221
        struct RareData {
1163
           WTF_MAKE_FAST_ALLOCATED;
1222
           WTF_MAKE_FAST_ALLOCATED;
1164
        public:
1223
        public:
Lines 1234-1239 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec25
1234
    protected:
1293
    protected:
1235
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1294
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1236
        virtual void jettison();
1295
        virtual void jettison();
1296
        virtual void jitCompileImpl(JSGlobalData&);
1237
        virtual CodeBlock* replacement();
1297
        virtual CodeBlock* replacement();
1238
        virtual bool canCompileWithDFGInternal();
1298
        virtual bool canCompileWithDFGInternal();
1239
#endif
1299
#endif
Lines 1268-1273 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec26
1268
    protected:
1328
    protected:
1269
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1329
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1270
        virtual void jettison();
1330
        virtual void jettison();
1331
        virtual void jitCompileImpl(JSGlobalData&);
1271
        virtual CodeBlock* replacement();
1332
        virtual CodeBlock* replacement();
1272
        virtual bool canCompileWithDFGInternal();
1333
        virtual bool canCompileWithDFGInternal();
1273
#endif
1334
#endif
Lines 1305-1310 namespace JSC { Source/JavaScriptCore/bytecode/CodeBlock.h_sec27
1305
    protected:
1366
    protected:
1306
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1367
        virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
1307
        virtual void jettison();
1368
        virtual void jettison();
1369
        virtual void jitCompileImpl(JSGlobalData&);
1308
        virtual CodeBlock* replacement();
1370
        virtual CodeBlock* replacement();
1309
        virtual bool canCompileWithDFGInternal();
1371
        virtual bool canCompileWithDFGInternal();
1310
#endif
1372
#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_CLASSIC_INTERPRETER)
157
#if !ENABLE(COMPUTED_GOTO_CLASSIC_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.cpp -4 lines
Lines 39-54 using namespace std; Source/JavaScriptCore/bytecode/Opcode.cpp_sec1
39
39
40
namespace JSC {
40
namespace JSC {
41
41
42
#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
43
44
const char* const opcodeNames[] = {
42
const char* const opcodeNames[] = {
45
#define OPCODE_NAME_ENTRY(opcode, size) #opcode,
43
#define OPCODE_NAME_ENTRY(opcode, size) #opcode,
46
    FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY)
44
    FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY)
47
#undef OPCODE_NAME_ENTRY
45
#undef OPCODE_NAME_ENTRY
48
};
46
};
49
47
50
#endif
51
52
#if ENABLE(OPCODE_STATS)
48
#if ENABLE(OPCODE_STATS)
53
49
54
long long OpcodeStats::opcodeCounts[numOpcodeIDs];
50
long long OpcodeStats::opcodeCounts[numOpcodeIDs];
- Source/JavaScriptCore/bytecode/Opcode.h -5 / +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 201-206 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec2
201
        typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
203
        typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
202
    #undef OPCODE_ID_ENUM
204
    #undef OPCODE_ID_ENUM
203
205
206
    const int maxOpcodeLength = 9;
204
    const int numOpcodeIDs = op_end + 1;
207
    const int numOpcodeIDs = op_end + 1;
205
208
206
    #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
209
    #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
Lines 217-223 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec3
217
        FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
220
        FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
218
    #undef VERIFY_OPCODE_ID
221
    #undef VERIFY_OPCODE_ID
219
222
220
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
223
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
221
#if COMPILER(RVCT) || COMPILER(INTEL)
224
#if COMPILER(RVCT) || COMPILER(INTEL)
222
    typedef void* Opcode;
225
    typedef void* Opcode;
223
#else
226
#else
Lines 227-234 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec4
227
    typedef OpcodeID Opcode;
230
    typedef OpcodeID Opcode;
228
#endif
231
#endif
229
232
230
#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
231
232
#define PADDING_STRING "                                "
233
#define PADDING_STRING "                                "
233
#define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
234
#define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
234
235
Lines 244-251 namespace JSC { Source/JavaScriptCore/bytecode/Opcode.h_sec5
244
#undef PADDING_STRING_LENGTH
245
#undef PADDING_STRING_LENGTH
245
#undef PADDING_STRING
246
#undef PADDING_STRING
246
247
247
#endif
248
249
#if ENABLE(OPCODE_STATS)
248
#if ENABLE(OPCODE_STATS)
250
249
251
    struct OpcodeStats {
250
    struct OpcodeStats {
- 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 -11 / +13 lines
Lines 35-40 Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec1
35
#include "JSActivation.h"
35
#include "JSActivation.h"
36
#include "JSFunction.h"
36
#include "JSFunction.h"
37
#include "Interpreter.h"
37
#include "Interpreter.h"
38
#include "LowLevelInterpreter.h"
38
#include "ScopeChain.h"
39
#include "ScopeChain.h"
39
#include "StrongInlines.h"
40
#include "StrongInlines.h"
40
#include "UString.h"
41
#include "UString.h"
Lines 1278-1286 RegisterID* BytecodeGenerator::emitResol Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec2
1278
#if ENABLE(JIT)
1279
#if ENABLE(JIT)
1279
        m_codeBlock->addGlobalResolveInfo(instructions().size());
1280
        m_codeBlock->addGlobalResolveInfo(instructions().size());
1280
#endif
1281
#endif
1281
#if ENABLE(CLASSIC_INTERPRETER)
1282
        m_codeBlock->addGlobalResolveInstruction(instructions().size());
1282
        m_codeBlock->addGlobalResolveInstruction(instructions().size());
1283
#endif
1284
        bool dynamic = resolveResult.isDynamic() && resolveResult.depth();
1283
        bool dynamic = resolveResult.isDynamic() && resolveResult.depth();
1285
        ValueProfile* profile = emitProfiledOpcode(dynamic ? op_resolve_global_dynamic : op_resolve_global);
1284
        ValueProfile* profile = emitProfiledOpcode(dynamic ? op_resolve_global_dynamic : op_resolve_global);
1286
        instructions().append(dst->index());
1285
        instructions().append(dst->index());
Lines 1384-1392 RegisterID* BytecodeGenerator::emitResol Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec3
1384
        return baseDst;
1383
        return baseDst;
1385
    }
1384
    }
1386
1385
1387
1388
1389
1390
    ValueProfile* profile = emitProfiledOpcode(op_resolve_with_base);
1386
    ValueProfile* profile = emitProfiledOpcode(op_resolve_with_base);
1391
    instructions().append(baseDst->index());
1387
    instructions().append(baseDst->index());
1392
    instructions().append(propDst->index());
1388
    instructions().append(propDst->index());
Lines 1494-1502 void BytecodeGenerator::emitMethodCheck( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec4
1494
1490
1495
RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1491
RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1496
{
1492
{
1497
#if ENABLE(CLASSIC_INTERPRETER)
1498
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1493
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1499
#endif
1500
1494
1501
    ValueProfile* profile = emitProfiledOpcode(op_get_by_id);
1495
    ValueProfile* profile = emitProfiledOpcode(op_get_by_id);
1502
    instructions().append(dst->index());
1496
    instructions().append(dst->index());
Lines 1522-1530 RegisterID* BytecodeGenerator::emitGetAr Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec5
1522
1516
1523
RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1517
RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1524
{
1518
{
1525
#if ENABLE(CLASSIC_INTERPRETER)
1526
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1519
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1527
#endif
1528
1520
1529
    emitOpcode(op_put_by_id);
1521
    emitOpcode(op_put_by_id);
1530
    instructions().append(base->index());
1522
    instructions().append(base->index());
Lines 1540-1548 RegisterID* BytecodeGenerator::emitPutBy Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec6
1540
1532
1541
RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1533
RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1542
{
1534
{
1543
#if ENABLE(CLASSIC_INTERPRETER)
1544
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1535
    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1545
#endif
1546
    
1536
    
1547
    emitOpcode(op_put_by_id);
1537
    emitOpcode(op_put_by_id);
1548
    instructions().append(base->index());
1538
    instructions().append(base->index());
Lines 1823-1829 RegisterID* BytecodeGenerator::emitCall( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec7
1823
    instructions().append(func->index()); // func
1813
    instructions().append(func->index()); // func
1824
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1814
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1825
    instructions().append(callArguments.registerOffset()); // registerOffset
1815
    instructions().append(callArguments.registerOffset()); // registerOffset
1816
#if ENABLE(LLINT)
1817
    instructions().append(m_codeBlock->addLLIntCallLinkInfo());
1818
#else
1826
    instructions().append(0);
1819
    instructions().append(0);
1820
#endif
1827
    instructions().append(0);
1821
    instructions().append(0);
1828
    if (dst != ignoredResult()) {
1822
    if (dst != ignoredResult()) {
1829
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
1823
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
Lines 1927-1933 RegisterID* BytecodeGenerator::emitConst Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec8
1927
    instructions().append(func->index()); // func
1921
    instructions().append(func->index()); // func
1928
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1922
    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1929
    instructions().append(callArguments.registerOffset()); // registerOffset
1923
    instructions().append(callArguments.registerOffset()); // registerOffset
1924
#if ENABLE(LLINT)
1925
    instructions().append(m_codeBlock->addLLIntCallLinkInfo());
1926
#else
1930
    instructions().append(0);
1927
    instructions().append(0);
1928
#endif
1931
    instructions().append(0);
1929
    instructions().append(0);
1932
    if (dst != ignoredResult()) {
1930
    if (dst != ignoredResult()) {
1933
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
1931
        ValueProfile* profile = emitProfiledOpcode(op_call_put_result);
Lines 2188-2194 RegisterID* BytecodeGenerator::emitCatch Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec9
2188
{
2186
{
2189
    m_usesExceptions = true;
2187
    m_usesExceptions = true;
2190
#if ENABLE(JIT)
2188
#if ENABLE(JIT)
2189
#if ENABLE(LLINT)
2190
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(bitwise_cast<void*>(&llint_op_catch))) };
2191
#else
2191
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2192
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2193
#endif
2192
#else
2194
#else
2193
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2195
    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2194
#endif
2196
#endif
- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -5 / +8 lines
Lines 585-593 private: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
585
    {
585
    {
586
        UNUSED_PARAM(nodeIndex);
586
        UNUSED_PARAM(nodeIndex);
587
        
587
        
588
        ValueProfile* profile = m_inlineStackTop->m_profiledBlock->valueProfileForBytecodeOffset(bytecodeIndex);
588
        PredictedType prediction = m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(bytecodeIndex);
589
        ASSERT(profile);
590
        PredictedType prediction = profile->computeUpdatedPrediction();
591
#if DFG_ENABLE(DEBUG_VERBOSE)
589
#if DFG_ENABLE(DEBUG_VERBOSE)
592
        dataLog("Dynamic [@%u, bc#%u] prediction: %s\n", nodeIndex, bytecodeIndex, predictionToString(prediction));
590
        dataLog("Dynamic [@%u, bc#%u] prediction: %s\n", nodeIndex, bytecodeIndex, predictionToString(prediction));
593
#endif
591
#endif
Lines 1022-1027 bool ByteCodeParser::handleInlining(bool Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec2
1022
    
1020
    
1023
    // If we get here then it looks like we should definitely inline this code. Proceed
1021
    // If we get here then it looks like we should definitely inline this code. Proceed
1024
    // with parsing the code to get bytecode, so that we can then parse the bytecode.
1022
    // with parsing the code to get bytecode, so that we can then parse the bytecode.
1023
    // Note that if LLInt is enabled, the bytecode will always be available. Also note
1024
    // that if LLInt is enabled, we may inline a code block that has never been JITted
1025
    // before!
1025
    CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
1026
    CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
1026
    if (!codeBlock)
1027
    if (!codeBlock)
1027
        return false;
1028
        return false;
Lines 1722-1728 bool ByteCodeParser::parseBlock(unsigned Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec3
1722
                m_inlineStackTop->m_profiledBlock, m_currentIndex);
1723
                m_inlineStackTop->m_profiledBlock, m_currentIndex);
1723
            
1724
            
1724
            if (methodCallStatus.isSet()
1725
            if (methodCallStatus.isSet()
1725
                && !getByIdStatus.isSet()
1726
                && !getByIdStatus.wasSeenInJIT()
1726
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
1727
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
1727
                // It's monomorphic as far as we can tell, since the method_check was linked
1728
                // It's monomorphic as far as we can tell, since the method_check was linked
1728
                // but the slow path (i.e. the normal get_by_id) never fired.
1729
                // but the slow path (i.e. the normal get_by_id) never fired.
Lines 1791-1797 bool ByteCodeParser::parseBlock(unsigned Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec4
1791
1792
1792
            NEXT_OPCODE(op_get_by_id);
1793
            NEXT_OPCODE(op_get_by_id);
1793
        }
1794
        }
1794
        case op_put_by_id: {
1795
        case op_put_by_id:
1796
        case op_put_by_id_transition_direct:
1797
        case op_put_by_id_transition_normal: {
1795
            NodeIndex value = get(currentInstruction[3].u.operand);
1798
            NodeIndex value = get(currentInstruction[3].u.operand);
1796
            NodeIndex base = get(currentInstruction[1].u.operand);
1799
            NodeIndex base = get(currentInstruction[1].u.operand);
1797
            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
1800
            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 -46 / +53 lines
Lines 26-36 Source/JavaScriptCore/dfg/DFGOperations.cpp_sec1
26
#include "config.h"
26
#include "config.h"
27
#include "DFGOperations.h"
27
#include "DFGOperations.h"
28
28
29
#if ENABLE(DFG_JIT)
30
31
#include "CodeBlock.h"
29
#include "CodeBlock.h"
32
#include "DFGOSRExit.h"
30
#include "DFGOSRExit.h"
33
#include "DFGRepatch.h"
31
#include "DFGRepatch.h"
32
#include "HostCallReturnValue.h"
34
#include "GetterSetter.h"
33
#include "GetterSetter.h"
35
#include "InlineASM.h"
34
#include "InlineASM.h"
36
#include "Interpreter.h"
35
#include "Interpreter.h"
Lines 38-43 Source/JavaScriptCore/dfg/DFGOperations.cpp_sec2
38
#include "JSGlobalData.h"
37
#include "JSGlobalData.h"
39
#include "Operations.h"
38
#include "Operations.h"
40
39
40
#if ENABLE(DFG_JIT)
41
41
#if CPU(X86_64)
42
#if CPU(X86_64)
42
43
43
#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
44
#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
Lines 737-786 size_t DFG_OPERATION operationCompareStr Source/JavaScriptCore/dfg/DFGOperations.cpp_sec3
737
    return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
738
    return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
738
}
739
}
739
740
740
EncodedJSValue DFG_OPERATION getHostCallReturnValue();
741
EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*);
742
743
#if CPU(X86_64)
744
asm (
745
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
746
HIDE_SYMBOL(getHostCallReturnValue) "\n"
747
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
748
    "mov -40(%r13), %r13\n"
749
    "mov %r13, %rdi\n"
750
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
751
);
752
#elif CPU(X86)
753
asm (
754
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
755
HIDE_SYMBOL(getHostCallReturnValue) "\n"
756
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
757
    "mov -40(%edi), %edi\n"
758
    "mov %edi, 4(%esp)\n"
759
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
760
);
761
#elif CPU(ARM_THUMB2)
762
asm (
763
".text" "\n"
764
".align 2" "\n"
765
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
766
HIDE_SYMBOL(getHostCallReturnValue) "\n"
767
".thumb" "\n"
768
".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
769
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
770
    "ldr r5, [r5, #-40]" "\n"
771
    "cpy r0, r5" "\n"
772
    "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
773
);
774
#endif
775
776
EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)
777
{
778
    JSGlobalData* globalData = &exec->globalData();
779
    NativeCallFrameTracer tracer(globalData, exec);
780
    
781
    return JSValue::encode(exec->globalData().hostCallReturnValue);
782
}
783
784
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
741
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
785
{
742
{
786
    ExecState* exec = execCallee->callerFrame();
743
    ExecState* exec = execCallee->callerFrame();
Lines 788-793 static void* handleHostCall(ExecState* e Source/JavaScriptCore/dfg/DFGOperations.cpp_sec4
788
745
789
    execCallee->setScopeChain(exec->scopeChain());
746
    execCallee->setScopeChain(exec->scopeChain());
790
    execCallee->setCodeBlock(0);
747
    execCallee->setCodeBlock(0);
748
    execCallee->clearReturnPC();
791
749
792
    if (kind == CodeForCall) {
750
    if (kind == CodeForCall) {
793
        CallData callData;
751
        CallData callData;
Lines 1093-1095 void DFG_OPERATION debugOperationPrintSp Source/JavaScriptCore/dfg/DFGOperations.cpp_sec5
1093
} } // namespace JSC::DFG
1051
} } // namespace JSC::DFG
1094
1052
1095
#endif
1053
#endif
1054
1055
#if COMPILER(GCC)
1056
1057
namespace JSC {
1058
1059
#if CPU(X86_64)
1060
asm (
1061
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1062
HIDE_SYMBOL(getHostCallReturnValue) "\n"
1063
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1064
    "mov -40(%r13), %r13\n"
1065
    "mov %r13, %rdi\n"
1066
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1067
);
1068
#elif CPU(X86)
1069
asm (
1070
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1071
HIDE_SYMBOL(getHostCallReturnValue) "\n"
1072
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1073
    "mov -40(%edi), %edi\n"
1074
    "mov %edi, 4(%esp)\n"
1075
    "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1076
);
1077
#elif CPU(ARM_THUMB2)
1078
asm (
1079
".text" "\n"
1080
".align 2" "\n"
1081
".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1082
HIDE_SYMBOL(getHostCallReturnValue) "\n"
1083
".thumb" "\n"
1084
".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
1085
SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1086
    "ldr r5, [r5, #-40]" "\n"
1087
    "cpy r0, r5" "\n"
1088
    "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1089
);
1090
#endif
1091
1092
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1093
{
1094
    if (!exec)
1095
        return JSValue::encode(JSValue());
1096
    return JSValue::encode(exec->globalData().hostCallReturnValue);
1097
}
1098
1099
} // namespace JSC
1100
1101
#endif // COMPILER(GCC)
1102
- Source/JavaScriptCore/heap/Heap.h -1 / +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 95-100 namespace JSC { Source/JavaScriptCore/heap/Heap.h_sec2
95
        // true if an allocation or collection is in progress
96
        // true if an allocation or collection is in progress
96
        inline bool isBusy();
97
        inline bool isBusy();
97
        
98
        
99
        MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); }
98
        MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
100
        MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
99
        MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
101
        MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
100
        CheckedBoolean tryAllocateStorage(size_t, void**);
102
        CheckedBoolean tryAllocateStorage(size_t, void**);
Lines 136-147 namespace JSC { Source/JavaScriptCore/heap/Heap.h_sec3
136
        void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
138
        void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
137
139
138
    private:
140
    private:
141
        friend class CodeBlock;
142
        friend class LLIntOffsetsExtractor;
139
        friend class MarkedSpace;
143
        friend class MarkedSpace;
140
        friend class MarkedAllocator;
144
        friend class MarkedAllocator;
141
        friend class MarkedBlock;
145
        friend class MarkedBlock;
142
        friend class CopiedSpace;
146
        friend class CopiedSpace;
143
        friend class SlotVisitor;
147
        friend class SlotVisitor;
144
        friend class CodeBlock;
145
        template<typename T> friend void* allocateCell(Heap&);
148
        template<typename T> friend void* allocateCell(Heap&);
146
149
147
        void* allocateWithDestructor(size_t);
150
        void* allocateWithDestructor(size_t);
- Source/JavaScriptCore/heap/MarkStack.cpp -1 / +1 lines
Lines 303-309 ALWAYS_INLINE static void visitChildren( Source/JavaScriptCore/heap/MarkStack.cpp_sec1
303
#endif
303
#endif
304
304
305
    ASSERT(Heap::isMarked(cell));
305
    ASSERT(Heap::isMarked(cell));
306
306
    
307
    if (isJSString(cell)) {
307
    if (isJSString(cell)) {
308
        JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
308
        JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
309
        return;
309
        return;
- Source/JavaScriptCore/heap/MarkedAllocator.h +3 lines
Lines 8-13 namespace JSC { Source/JavaScriptCore/heap/MarkedAllocator.h_sec1
8
8
9
class Heap;
9
class Heap;
10
class MarkedSpace;
10
class MarkedSpace;
11
class LLIntOffsetsExtractor;
11
12
12
namespace DFG {
13
namespace DFG {
13
class SpeculativeJIT;
14
class SpeculativeJIT;
Lines 33-38 public: Source/JavaScriptCore/heap/MarkedAllocator.h_sec2
33
    void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction);
34
    void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction);
34
    
35
    
35
private:
36
private:
37
    friend class LLIntOffsetsExtractor;
38
    
36
    JS_EXPORT_PRIVATE void* allocateSlowCase();
39
    JS_EXPORT_PRIVATE void* allocateSlowCase();
37
    void* tryAllocate();
40
    void* tryAllocate();
38
    void* tryAllocateHelper();
41
    void* tryAllocateHelper();
- Source/JavaScriptCore/heap/MarkedSpace.h +9 lines
Lines 41-46 namespace JSC { Source/JavaScriptCore/heap/MarkedSpace.h_sec1
41
class Heap;
41
class Heap;
42
class JSCell;
42
class JSCell;
43
class LiveObjectIterator;
43
class LiveObjectIterator;
44
class LLIntOffsetsExtractor;
44
class WeakGCHandle;
45
class WeakGCHandle;
45
class SlotVisitor;
46
class SlotVisitor;
46
47
Lines 51-56 public: Source/JavaScriptCore/heap/MarkedSpace.h_sec2
51
52
52
    MarkedSpace(Heap*);
53
    MarkedSpace(Heap*);
53
54
55
    MarkedAllocator& firstAllocator();
54
    MarkedAllocator& allocatorFor(size_t);
56
    MarkedAllocator& allocatorFor(size_t);
55
    MarkedAllocator& allocatorFor(MarkedBlock*);
57
    MarkedAllocator& allocatorFor(MarkedBlock*);
56
    MarkedAllocator& destructorAllocatorFor(size_t);
58
    MarkedAllocator& destructorAllocatorFor(size_t);
Lines 79-84 public: Source/JavaScriptCore/heap/MarkedSpace.h_sec3
79
    void didConsumeFreeList(MarkedBlock*);
81
    void didConsumeFreeList(MarkedBlock*);
80
82
81
private:
83
private:
84
    friend class LLIntOffsetsExtractor;
85
    
82
    // [ 32... 256 ]
86
    // [ 32... 256 ]
83
    static const size_t preciseStep = MarkedBlock::atomSize;
87
    static const size_t preciseStep = MarkedBlock::atomSize;
84
    static const size_t preciseCutoff = 256;
88
    static const size_t preciseCutoff = 256;
Lines 129-134 template<typename Functor> inline typena Source/JavaScriptCore/heap/MarkedSpace.h_sec4
129
    return forEachCell(functor);
133
    return forEachCell(functor);
130
}
134
}
131
135
136
inline MarkedAllocator& MarkedSpace::firstAllocator()
137
{
138
    return m_normalSpace.preciseAllocators[0];
139
}
140
132
inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes)
141
inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes)
133
{
142
{
134
    ASSERT(bytes && bytes <= maxCellSize);
143
    ASSERT(bytes && bytes <= maxCellSize);
- Source/JavaScriptCore/interpreter/CallFrame.cpp -2 / +25 lines
Lines 50-55 RegisterFile* CallFrame::registerFile() Source/JavaScriptCore/interpreter/CallFrame.cpp_sec1
50
50
51
#endif
51
#endif
52
52
53
#if USE(JSVALUE32_64)
54
unsigned CallFrame::bytecodeOffsetForNonDFGCode() const
55
{
56
    ASSERT(codeBlock());
57
    return currentVPC() - codeBlock()->instructions().begin();
58
}
59
60
void CallFrame::setBytecodeOffsetForNonDFGCode(unsigned offset)
61
{
62
    ASSERT(codeBlock());
63
    setCurrentVPC(codeBlock()->instructions().begin() + offset);
64
}
65
#else
66
Instruction* CallFrame::currentVPC() const
67
{
68
    return codeBlock()->instructions().begin() + bytecodeOffsetForNonDFGCode();
69
}
70
void CallFrame::setCurrentVPC(Instruction* vpc)
71
{
72
    setBytecodeOffsetForNonDFGCode(vpc - codeBlock()->instructions().begin());
73
}
74
#endif
75
    
53
#if ENABLE(DFG_JIT)
76
#if ENABLE(DFG_JIT)
54
bool CallFrame::isInlineCallFrameSlow()
77
bool CallFrame::isInlineCallFrameSlow()
55
{
78
{
Lines 142-148 CallFrame* CallFrame::trueCallerFrame() Source/JavaScriptCore/interpreter/CallFrame.cpp_sec2
142
    //    more frames above the true caller due to inlining.
165
    //    more frames above the true caller due to inlining.
143
166
144
    // Am I an inline call frame? If so, we're done.
167
    // Am I an inline call frame? If so, we're done.
145
    if (isInlineCallFrame() || !hasReturnPC())
168
    if (isInlineCallFrame())
146
        return callerFrame()->removeHostCallFrameFlag();
169
        return callerFrame()->removeHostCallFrameFlag();
147
    
170
    
148
    // I am a machine call frame, so the question is: is my caller a machine call frame
171
    // I am a machine call frame, so the question is: is my caller a machine call frame
Lines 153-159 CallFrame* CallFrame::trueCallerFrame() Source/JavaScriptCore/interpreter/CallFrame.cpp_sec3
153
    ASSERT(!machineCaller->isInlineCallFrame());
176
    ASSERT(!machineCaller->isInlineCallFrame());
154
    
177
    
155
    // Figure out how we want to get the current code location.
178
    // Figure out how we want to get the current code location.
156
    if (hasHostCallFrameFlag() || returnAddressIsInCtiTrampoline(returnPC()))
179
    if (!hasReturnPC() || returnAddressIsInCtiTrampoline(returnPC()))
157
        return machineCaller->trueCallFrameFromVMCode()->removeHostCallFrameFlag();
180
        return machineCaller->trueCallFrameFromVMCode()->removeHostCallFrameFlag();
158
    
181
    
159
    return machineCaller->trueCallFrame(returnPC())->removeHostCallFrameFlag();
182
    return machineCaller->trueCallFrame(returnPC())->removeHostCallFrameFlag();
- Source/JavaScriptCore/interpreter/CallFrame.h -2 / +21 lines
Lines 103-113 namespace JSC { Source/JavaScriptCore/interpreter/CallFrame.h_sec1
103
103
104
        CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
104
        CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
105
#if ENABLE(JIT)
105
#if ENABLE(JIT)
106
        bool hasReturnPC() const { return this[RegisterFile::ReturnPC].vPC(); }
107
        ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
106
        ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
107
        bool hasReturnPC() const { return !!this[RegisterFile::ReturnPC].vPC(); }
108
        void clearReturnPC() { registers()[RegisterFile::ReturnPC] = static_cast<Instruction*>(0); }
108
#endif
109
#endif
109
        AbstractPC abstractReturnPC(JSGlobalData& globalData) { return AbstractPC(globalData, this); }
110
        AbstractPC abstractReturnPC(JSGlobalData& globalData) { return AbstractPC(globalData, this); }
110
        unsigned bytecodeOffsetForNonDFGCode()
111
#if USE(JSVALUE32_64)
112
        unsigned bytecodeOffsetForNonDFGCode() const;
113
        void setBytecodeOffsetForNonDFGCode(unsigned offset);
114
#else
115
        unsigned bytecodeOffsetForNonDFGCode() const
111
        {
116
        {
112
            ASSERT(codeBlock());
117
            ASSERT(codeBlock());
113
            return this[RegisterFile::ArgumentCount].tag();
118
            return this[RegisterFile::ArgumentCount].tag();
Lines 118-123 namespace JSC { Source/JavaScriptCore/interpreter/CallFrame.h_sec2
118
            ASSERT(codeBlock());
123
            ASSERT(codeBlock());
119
            this[RegisterFile::ArgumentCount].tag() = static_cast<int32_t>(offset);
124
            this[RegisterFile::ArgumentCount].tag() = static_cast<int32_t>(offset);
120
        }
125
        }
126
#endif
121
127
122
#if ENABLE(DFG_JIT)
128
#if ENABLE(DFG_JIT)
123
        InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); }
129
        InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); }
Lines 135-140 namespace JSC { Source/JavaScriptCore/interpreter/CallFrame.h_sec3
135
#if ENABLE(CLASSIC_INTERPRETER)
141
#if ENABLE(CLASSIC_INTERPRETER)
136
        Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
142
        Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
137
#endif
143
#endif
144
#if USE(JSVALUE32_64)
145
        Instruction* currentVPC() const
146
        {
147
            return bitwise_cast<Instruction*>(this[RegisterFile::ArgumentCount].tag());
148
        }
149
        void setCurrentVPC(Instruction* vpc)
150
        {
151
            this[RegisterFile::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc);
152
        }
153
#else
154
        Instruction* currentVPC() const;
155
        void setCurrentVPC(Instruction* vpc);
156
#endif
138
157
139
        void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
158
        void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
140
        void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
159
        void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
- Source/JavaScriptCore/interpreter/Interpreter.cpp -16 / +45 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_CLASSIC_INTERPRETER) && !defined(__llvm__))
72
#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND ((ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)) && !defined(__llvm__))
73
73
74
using namespace std;
74
using namespace std;
75
75
Lines 543-576 Interpreter::Interpreter() Source/JavaScriptCore/interpreter/Interpreter.cpp_sec2
543
#if !ASSERT_DISABLED
543
#if !ASSERT_DISABLED
544
    , m_initialized(false)
544
    , m_initialized(false)
545
#endif
545
#endif
546
    , m_enabled(false)
546
    , m_classicEnabled(false)
547
{
547
{
548
}
548
}
549
549
550
void Interpreter::initialize(bool canUseJIT)
550
Interpreter::~Interpreter()
551
{
551
{
552
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
552
#if ENABLE(LLINT)
553
    if (m_classicEnabled)
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_CLASSIC_INTERPRETER) || ENABLE(LLINT)
563
#if !ENABLE(COMPUTED_GOTO_CLASSIC_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)
564
            m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
590
            m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
565
        
591
        
566
        m_enabled = true;
592
        m_classicEnabled = true;
567
    }
593
    }
568
#else
594
#else
569
    UNUSED_PARAM(canUseJIT);
570
#if ENABLE(CLASSIC_INTERPRETER)
595
#if ENABLE(CLASSIC_INTERPRETER)
571
    m_enabled = true;
596
    m_classicEnabled = true;
572
#else
597
#else
573
    m_enabled = false;
598
    m_classicEnabled = false;
574
#endif
599
#endif
575
#endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
600
#endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
576
#if !ASSERT_DISABLED
601
#if !ASSERT_DISABLED
Lines 667-675 void Interpreter::dumpRegisters(CallFram Source/JavaScriptCore/interpreter/Interpreter.cpp_sec3
667
692
668
bool Interpreter::isOpcode(Opcode opcode)
693
bool Interpreter::isOpcode(Opcode opcode)
669
{
694
{
670
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
695
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
671
    if (!m_enabled)
696
#if !ENABLE(LLINT)
697
    if (!m_classicEnabled)
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_sec4
726
    // have to subtract 1.
753
    // have to subtract 1.
727
#if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
754
#if ENABLE(JIT) && ENABLE(CLASSIC_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 857-863 static CallFrame* getCallerInfo(JSGlobal Source/JavaScriptCore/interpreter/Interpreter.cpp_sec5
857
            }
884
            }
858
        } else
885
        } else
859
    #endif
886
    #endif
860
            bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
887
            bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
861
#endif
888
#endif
862
    }
889
    }
863
890
Lines 1815-1821 JSValue Interpreter::privateExecute(Exec Source/JavaScriptCore/interpreter/Interpreter.cpp_sec6
1815
    }
1842
    }
1816
    
1843
    
1817
    ASSERT(m_initialized);
1844
    ASSERT(m_initialized);
1818
    ASSERT(m_enabled);
1845
    ASSERT(m_classicEnabled);
1819
    
1846
    
1820
#if ENABLE(JIT)
1847
#if ENABLE(JIT)
1821
#if ENABLE(CLASSIC_INTERPRETER)
1848
#if ENABLE(CLASSIC_INTERPRETER)
Lines 3466-3471 skip_id_custom_self: Source/JavaScriptCore/interpreter/Interpreter.cpp_sec7
3466
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3493
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3467
      skip_put_by_id:
3494
      skip_put_by_id:
3468
#endif
3495
#endif
3496
    DEFINE_OPCODE(op_put_by_id_transition_direct)
3497
    DEFINE_OPCODE(op_put_by_id_transition_normal)
3469
    DEFINE_OPCODE(op_put_by_id_transition) {
3498
    DEFINE_OPCODE(op_put_by_id_transition) {
3470
        /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
3499
        /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
3471
         
3500
         
Lines 5299-5308 void Interpreter::retrieveLastCaller(Cal Source/JavaScriptCore/interpreter/Interpreter.cpp_sec8
5299
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
5328
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
5300
#if ENABLE(JIT)
5329
#if ENABLE(JIT)
5301
    else
5330
    else
5302
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
5331
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
5303
#endif
5332
#endif
5304
#else
5333
#else
5305
    bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
5334
    bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
5306
#endif
5335
#endif
5307
    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
5336
    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
5308
    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
5337
    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
- Source/JavaScriptCore/interpreter/Interpreter.h -7 / +22 lines
Lines 34-39 Source/JavaScriptCore/interpreter/Interpreter.h_sec1
34
#include "JSFunction.h"
34
#include "JSFunction.h"
35
#include "JSValue.h"
35
#include "JSValue.h"
36
#include "JSObject.h"
36
#include "JSObject.h"
37
#include "LLIntData.h"
37
#include "Opcode.h"
38
#include "Opcode.h"
38
#include "RegisterFile.h"
39
#include "RegisterFile.h"
39
40
Lines 46-51 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec2
46
    class ExecutableBase;
47
    class ExecutableBase;
47
    class FunctionExecutable;
48
    class FunctionExecutable;
48
    class JSGlobalObject;
49
    class JSGlobalObject;
50
    class LLIntOffsetsExtractor;
49
    class ProgramExecutable;
51
    class ProgramExecutable;
50
    class Register;
52
    class Register;
51
    class ScopeChainNode;
53
    class ScopeChainNode;
Lines 158-176 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec3
158
160
159
    class Interpreter {
161
    class Interpreter {
160
        WTF_MAKE_FAST_ALLOCATED;
162
        WTF_MAKE_FAST_ALLOCATED;
161
        friend class JIT;
162
        friend class CachedCall;
163
        friend class CachedCall;
164
        friend class LLIntOffsetsExtractor;
165
        friend class JIT;
163
    public:
166
    public:
164
        Interpreter();
167
        Interpreter();
168
        ~Interpreter();
165
        
169
        
166
        void initialize(bool canUseJIT);
170
        void initialize(LLInt::Data*, bool canUseJIT);
167
171
168
        RegisterFile& registerFile() { return m_registerFile; }
172
        RegisterFile& registerFile() { return m_registerFile; }
169
        
173
        
170
        Opcode getOpcode(OpcodeID id)
174
        Opcode getOpcode(OpcodeID id)
171
        {
175
        {
172
            ASSERT(m_initialized);
176
            ASSERT(m_initialized);
173
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
177
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
174
            return m_opcodeTable[id];
178
            return m_opcodeTable[id];
175
#else
179
#else
176
            return id;
180
            return id;
Lines 180-188 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec4
180
        OpcodeID getOpcodeID(Opcode opcode)
184
        OpcodeID getOpcodeID(Opcode opcode)
181
        {
185
        {
182
            ASSERT(m_initialized);
186
            ASSERT(m_initialized);
183
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
187
#if ENABLE(LLINT)
188
            ASSERT(isOpcode(opcode));
189
            return m_opcodeIDTable.get(opcode);
190
#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
184
            ASSERT(isOpcode(opcode));
191
            ASSERT(isOpcode(opcode));
185
            if (!m_enabled)
192
            if (!m_classicEnabled)
186
                return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
193
                return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
187
194
188
            return m_opcodeIDTable.get(opcode);
195
            return m_opcodeIDTable.get(opcode);
Lines 190-195 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec5
190
            return opcode;
197
            return opcode;
191
#endif
198
#endif
192
        }
199
        }
200
        
201
        bool classicEnabled()
202
        {
203
            return m_classicEnabled;
204
        }
193
205
194
        bool isOpcode(Opcode);
206
        bool isOpcode(Opcode);
195
207
Lines 259-265 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec6
259
271
260
        RegisterFile m_registerFile;
272
        RegisterFile m_registerFile;
261
        
273
        
262
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
274
#if ENABLE(LLINT)
275
        Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
276
        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
277
#elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
263
        Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
278
        Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
264
        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
279
        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
265
#endif
280
#endif
Lines 267-273 namespace JSC { Source/JavaScriptCore/interpreter/Interpreter.h_sec7
267
#if !ASSERT_DISABLED
282
#if !ASSERT_DISABLED
268
        bool m_initialized;
283
        bool m_initialized;
269
#endif
284
#endif
270
        bool m_enabled;
285
        bool m_classicEnabled;
271
    };
286
    };
272
287
273
    // This value must not be an object that would require this conversion (WebCore's global object).
288
    // This value must not be an object that would require this conversion (WebCore's global object).
- 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/ExecutableAllocator.h -4 / +4 lines
Lines 89-100 inline size_t roundUpAllocationSize(size Source/JavaScriptCore/jit/ExecutableAllocator.h_sec1
89
89
90
}
90
}
91
91
92
#if ENABLE(JIT) && ENABLE(ASSEMBLER)
93
94
namespace JSC {
92
namespace JSC {
95
93
96
typedef WTF::MetaAllocatorHandle ExecutableMemoryHandle;
94
typedef WTF::MetaAllocatorHandle ExecutableMemoryHandle;
97
95
96
#if ENABLE(JIT) && ENABLE(ASSEMBLER)
97
98
class ExecutableAllocator {
98
class ExecutableAllocator {
99
    enum ProtectionSetting { Writable, Executable };
99
    enum ProtectionSetting { Writable, Executable };
100
100
Lines 235-242 private: Source/JavaScriptCore/jit/ExecutableAllocator.h_sec2
235
#endif
235
#endif
236
};
236
};
237
237
238
} // namespace JSC
239
240
#endif // ENABLE(JIT) && ENABLE(ASSEMBLER)
238
#endif // ENABLE(JIT) && ENABLE(ASSEMBLER)
241
239
240
} // namespace JSC
241
242
#endif // !defined(ExecutableAllocator)
242
#endif // !defined(ExecutableAllocator)
- Source/JavaScriptCore/jit/HostCallReturnValue.cpp +40 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
// Nothing to see here.
38
39
} // namespace JSC
40
- Source/JavaScriptCore/jit/HostCallReturnValue.h +67 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
// Unfortunately this only works on GCC-like compilers. And it's currently only used
34
// by LLInt and DFG, which also are restricted to GCC-like compilers. We should
35
// probably fix that at some point.
36
#if COMPILER(GCC)
37
38
#if CALLING_CONVENTION_IS_STDCALL
39
#define HOST_CALL_RETURN_VALUE_OPTION CDECL
40
#else
41
#define HOST_CALL_RETURN_VALUE_OPTION
42
#endif
43
44
namespace JSC {
45
46
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue();
47
48
// This is a public declaration only to convince CLANG not to elide it.
49
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*);
50
51
inline void initializeHostCallReturnValue()
52
{
53
    getHostCallReturnValueWithExecState(0);
54
}
55
56
}
57
58
#else // COMPILER(GCC)
59
60
namespace JSC {
61
inline void initializeHostCallReturnValue() { }
62
}
63
64
#endif // COMPILER(GCC)
65
66
#endif // HostCallReturnValue_h
67
- 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 486-491 void JIT::privateCompileSlowCases() Source/JavaScriptCore/jit/JIT.cpp_sec2
486
        DEFINE_SLOWCASE_OP(op_post_inc)
488
        DEFINE_SLOWCASE_OP(op_post_inc)
487
        DEFINE_SLOWCASE_OP(op_pre_dec)
489
        DEFINE_SLOWCASE_OP(op_pre_dec)
488
        DEFINE_SLOWCASE_OP(op_pre_inc)
490
        DEFINE_SLOWCASE_OP(op_pre_inc)
491
        case op_put_by_id_transition_direct:
492
        case op_put_by_id_transition_normal:
489
        DEFINE_SLOWCASE_OP(op_put_by_id)
493
        DEFINE_SLOWCASE_OP(op_put_by_id)
490
        DEFINE_SLOWCASE_OP(op_put_by_val)
494
        DEFINE_SLOWCASE_OP(op_put_by_val)
491
        DEFINE_SLOWCASE_OP(op_resolve_global)
495
        DEFINE_SLOWCASE_OP(op_resolve_global)
Lines 525-530 void JIT::privateCompileSlowCases() Source/JavaScriptCore/jit/JIT.cpp_sec3
525
529
526
JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
530
JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
527
{
531
{
532
#if ENABLE(JIT_VERBOSE_OSR)
533
    printf("Compiling JIT code!\n");
534
#endif
535
    
528
#if ENABLE(VALUE_PROFILER)
536
#if ENABLE(VALUE_PROFILER)
529
    m_canBeOptimized = m_codeBlock->canCompileWithDFG();
537
    m_canBeOptimized = m_codeBlock->canCompileWithDFG();
530
#endif
538
#endif
Lines 693-700 JITCode JIT::privateCompile(CodePtr* fun Source/JavaScriptCore/jit/JIT.cpp_sec4
693
        info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
701
        info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
694
    }
702
    }
695
703
696
#if ENABLE(DFG_JIT)
704
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
697
    if (m_canBeOptimized) {
705
    if (m_canBeOptimized
706
#if ENABLE(LLINT)
707
        || true
708
#endif
709
        ) {
698
        CompactJITCodeMap::Encoder jitCodeMapEncoder;
710
        CompactJITCodeMap::Encoder jitCodeMapEncoder;
699
        for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
711
        for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
700
            if (m_labels[bytecodeOffset].isSet())
712
            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 -1 / +11 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 62-70 inline bool jitCompileIfAppropriate(JSGl Source/JavaScriptCore/jit/JITDriver.h_sec2
62
68
63
inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
69
inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
64
{
70
{
71
    if (jitType == codeBlock->getJITType())
72
        return true;
73
    
65
    if (!globalData.canUseJIT())
74
    if (!globalData.canUseJIT())
66
        return true;
75
        return true;
67
    
76
    
77
    codeBlock->unlinkIncomingCalls();
78
    
68
    bool dfgCompiled = false;
79
    bool dfgCompiled = false;
69
    if (jitType == JITCode::DFGJIT)
80
    if (jitType == JITCode::DFGJIT)
70
        dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck);
81
        dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck);
Lines 79-85 inline bool jitCompileFunctionIfAppropri Source/JavaScriptCore/jit/JITDriver.h_sec3
79
        }
90
        }
80
        jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck);
91
        jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck);
81
    }
92
    }
82
    
83
    codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
93
    codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
84
    
94
    
85
    return true;
95
    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/JITInlineMethods.h -1 / +6 lines
Lines 265-272 ALWAYS_INLINE void JIT::restoreArgumentR Source/JavaScriptCore/jit/JITInlineMethods.h_sec1
265
ALWAYS_INLINE void JIT::updateTopCallFrame()
265
ALWAYS_INLINE void JIT::updateTopCallFrame()
266
{
266
{
267
    ASSERT(static_cast<int>(m_bytecodeOffset) >= 0);
267
    ASSERT(static_cast<int>(m_bytecodeOffset) >= 0);
268
    if (m_bytecodeOffset)
268
    if (m_bytecodeOffset) {
269
#if USE(JSVALUE32_64)
270
        storePtr(TrustedImmPtr(m_codeBlock->instructions().begin() + m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount));
271
#else
269
        store32(Imm32(m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount));
272
        store32(Imm32(m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount));
273
#endif
274
    }
270
    storePtr(callFrameRegister, &m_globalData->topCallFrame);
275
    storePtr(callFrameRegister, &m_globalData->topCallFrame);
271
}
276
}
272
277
- Source/JavaScriptCore/jit/JITStubs.cpp -35 / +5 lines
Lines 1446-1451 DEFINE_STUB_FUNCTION(void, op_put_by_id_ Source/JavaScriptCore/jit/JITStubs.cpp_sec1
1446
    PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1446
    PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1447
    JSValue baseValue = stackFrame.args[0].jsValue();
1447
    JSValue baseValue = stackFrame.args[0].jsValue();
1448
    ASSERT(baseValue.isObject());
1448
    ASSERT(baseValue.isObject());
1449
    
1449
    asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
1450
    asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
1450
    
1451
    
1451
    CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1452
    CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
Lines 1931-1937 DEFINE_STUB_FUNCTION(void, optimize_from Source/JavaScriptCore/jit/JITStubs.cpp_sec2
1931
    unsigned bytecodeIndex = stackFrame.args[0].int32();
1932
    unsigned bytecodeIndex = stackFrame.args[0].int32();
1932
1933
1933
#if ENABLE(JIT_VERBOSE_OSR)
1934
#if ENABLE(JIT_VERBOSE_OSR)
1934
    dataLog("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
1935
    dataLog("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
1935
#endif
1936
#endif
1936
1937
1937
    if (codeBlock->hasOptimizedReplacement()) {
1938
    if (codeBlock->hasOptimizedReplacement()) {
Lines 2186-2230 DEFINE_STUB_FUNCTION(void*, op_construct Source/JavaScriptCore/jit/JITStubs.cpp_sec3
2186
    return result;
2187
    return result;
2187
}
2188
}
2188
2189
2189
inline CallFrame* arityCheckFor(CallFrame* callFrame, RegisterFile* registerFile, CodeSpecializationKind kind)
2190
{
2191
    JSFunction* callee = asFunction(callFrame->callee());
2192
    ASSERT(!callee->isHostFunction());
2193
    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
2194
    int argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
2195
2196
    // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
2197
    if (!registerFile->grow(callFrame->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
2198
        return 0;
2199
2200
    ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
2201
2202
    // Too few arguments -- copy call frame and arguments, then fill in missing arguments with undefined.
2203
    size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
2204
    Register* src = callFrame->registers();
2205
    Register* dst = callFrame->registers() + delta;
2206
2207
    int i;
2208
    int end = -CallFrame::offsetFor(argumentCountIncludingThis);
2209
    for (i = -1; i >= end; --i)
2210
        dst[i] = src[i];
2211
2212
    end -= delta;
2213
    for ( ; i >= end; --i)
2214
        dst[i] = jsUndefined();
2215
2216
    CallFrame* newCallFrame = CallFrame::create(dst);
2217
    ASSERT((void*)newCallFrame <= registerFile->end());
2218
    return newCallFrame;
2219
}
2220
2221
DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
2190
DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
2222
{
2191
{
2223
    STUB_INIT_STACK_FRAME(stackFrame);
2192
    STUB_INIT_STACK_FRAME(stackFrame);
2224
2193
2225
    CallFrame* callFrame = stackFrame.callFrame;
2194
    CallFrame* callFrame = stackFrame.callFrame;
2226
2195
2227
    CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
2196
    CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
2228
    if (!newCallFrame)
2197
    if (!newCallFrame)
2229
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2198
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2230
2199
Lines 2237-2243 DEFINE_STUB_FUNCTION(void*, op_construct Source/JavaScriptCore/jit/JITStubs.cpp_sec4
2237
2206
2238
    CallFrame* callFrame = stackFrame.callFrame;
2207
    CallFrame* callFrame = stackFrame.callFrame;
2239
2208
2240
    CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
2209
    CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
2241
    if (!newCallFrame)
2210
    if (!newCallFrame)
2242
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2211
        return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2243
2212
Lines 2314-2319 DEFINE_STUB_FUNCTION(EncodedJSValue, op_ Source/JavaScriptCore/jit/JITStubs.cpp_sec5
2314
    STUB_INIT_STACK_FRAME(stackFrame);
2283
    STUB_INIT_STACK_FRAME(stackFrame);
2315
2284
2316
    CallFrame* callFrame = stackFrame.callFrame;
2285
    CallFrame* callFrame = stackFrame.callFrame;
2286
    
2317
    JSValue callee = callFrame->calleeAsValue();
2287
    JSValue callee = callFrame->calleeAsValue();
2318
2288
2319
    CallData callData;
2289
    CallData callData;
- Source/JavaScriptCore/jit/JITStubs.h -4 / +4 lines
Lines 37-44 Source/JavaScriptCore/jit/JITStubs.h_sec1
37
#include "ThunkGenerators.h"
37
#include "ThunkGenerators.h"
38
#include <wtf/HashMap.h>
38
#include <wtf/HashMap.h>
39
39
40
#if ENABLE(JIT)
41
42
namespace JSC {
40
namespace JSC {
43
41
44
    struct StructureStubInfo;
42
    struct StructureStubInfo;
Lines 263-268 namespace JSC { Source/JavaScriptCore/jit/JITStubs.h_sec2
263
261
264
#define JITSTACKFRAME_ARGS_INDEX (OBJECT_OFFSETOF(JITStackFrame, args) / sizeof(void*))
262
#define JITSTACKFRAME_ARGS_INDEX (OBJECT_OFFSETOF(JITStackFrame, args) / sizeof(void*))
265
263
264
#if ENABLE(JIT)
265
266
#define STUB_ARGS_DECLARATION void** args
266
#define STUB_ARGS_DECLARATION void** args
267
#define STUB_ARGS (args)
267
#define STUB_ARGS (args)
268
268
Lines 456-463 extern "C" { Source/JavaScriptCore/jit/JITStubs.h_sec3
456
    void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
456
    void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
457
} // extern "C"
457
} // extern "C"
458
458
459
} // namespace JSC
460
461
#endif // ENABLE(JIT)
459
#endif // ENABLE(JIT)
462
460
461
} // namespace JSC
462
463
#endif // JITStubs_h
463
#endif // JITStubs_h
- 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 +49 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
// Print every instruction executed.
30
#define LLINT_EXECUTION_TRACING 0
31
32
// Print some information for some of the more subtle slow paths.
33
#define LLINT_SLOW_PATH_TRACING 0
34
35
// Disable inline allocation in the interpreter. This is great if you're changing
36
// how the GC allocates.
37
#define LLINT_ALWAYS_ALLOCATE_SLOW 0
38
39
// Enable OSR into the JIT. Disabling this while the LLInt is enabled effectively
40
// turns off all JIT'ing, since in LLInt's parlance, OSR subsumes any form of JIT
41
// invocation.
42
#if ENABLE(JIT)
43
#define LLINT_OSR_TO_JIT 1
44
#else
45
#define LLINT_OSR_TO_JIT 0
46
#endif
47
48
#endif // LLIntCommon_h
49
- Source/JavaScriptCore/llint/LLIntData.cpp +116 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 "BytecodeConventions.h"
32
#include "CodeType.h"
33
#include "Instruction.h"
34
#include "LowLevelInterpreter.h"
35
#include "Opcode.h"
36
37
namespace JSC { namespace LLInt {
38
39
Data::Data()
40
    : m_exceptionInstructions(new Instruction[maxOpcodeLength + 1])
41
    , m_opcodeMap(new Opcode[numOpcodeIDs])
42
{
43
    for (int i = 0; i < maxOpcodeLength + 1; ++i)
44
        m_exceptionInstructions[i].u.pointer = bitwise_cast<void*>(&llint_throw_from_slow_path_trampoline);
45
#define OPCODE_ENTRY(opcode, length) m_opcodeMap[opcode] = bitwise_cast<void*>(&llint_##opcode);
46
    FOR_EACH_OPCODE_ID(OPCODE_ENTRY);
47
#undef OPCODE_ENTRY
48
}
49
50
#if COMPILER(CLANG)
51
#pragma clang diagnostic push
52
#pragma clang diagnostic ignored "-Wmissing-noreturn"
53
#endif
54
void Data::performAssertions(JSGlobalData& globalData)
55
{
56
    UNUSED_PARAM(globalData);
57
    
58
    // Assertions to match LowLevelInterpreter.asm.  If you change any of this code, be
59
    // prepared to change LowLevelInterpreter.asm as well!!
60
    ASSERT(RegisterFile::CallFrameHeaderSize * 8 == 48);
61
    ASSERT(RegisterFile::ArgumentCount * 8 == -48);
62
    ASSERT(RegisterFile::CallerFrame * 8 == -40);
63
    ASSERT(RegisterFile::Callee * 8 == -32);
64
    ASSERT(RegisterFile::ScopeChain * 8 == -24);
65
    ASSERT(RegisterFile::ReturnPC * 8 == -16);
66
    ASSERT(RegisterFile::CodeBlock * 8 == -8);
67
    ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -RegisterFile::CallFrameHeaderSize - 1);
68
#if CPU(BIG_ENDIAN)
69
    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 0);
70
    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 4);
71
#else
72
    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 4);
73
    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 0);
74
#endif
75
    ASSERT(JSValue::Int32Tag == -1);
76
    ASSERT(JSValue::BooleanTag == -2);
77
    ASSERT(JSValue::NullTag == -3);
78
    ASSERT(JSValue::UndefinedTag == -4);
79
    ASSERT(JSValue::CellTag == -5);
80
    ASSERT(JSValue::EmptyValueTag == -6);
81
    ASSERT(JSValue::DeletedValueTag == -7);
82
    ASSERT(JSValue::LowestTag == -7);
83
    ASSERT(StringType == 5);
84
    ASSERT(ObjectType == 13);
85
    ASSERT(MasqueradesAsUndefined == 1);
86
    ASSERT(ImplementsHasInstance == 2);
87
    ASSERT(ImplementsDefaultHasInstance == 8);
88
    ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3);
89
    ASSERT(FirstConstantRegisterIndex == 0x40000000);
90
    ASSERT(GlobalCode == 0);
91
    ASSERT(EvalCode == 1);
92
    ASSERT(FunctionCode == 2);
93
    
94
    // FIXME: make these assertions less horrible.
95
#if !ASSERT_DISABLED
96
    Vector<int> testVector;
97
    testVector.resize(42);
98
    ASSERT(bitwise_cast<size_t*>(&testVector)[0] == 42);
99
    ASSERT(bitwise_cast<int**>(&testVector)[1] == testVector.begin());
100
#endif
101
102
    ASSERT(StringImpl::s_hashFlag8BitBuffer == 64);
103
}
104
#if COMPILER(CLANG)
105
#pragma clang diagnostic pop
106
#endif
107
108
Data::~Data()
109
{
110
    delete[] m_exceptionInstructions;
111
    delete[] m_opcodeMap;
112
}
113
114
} } // namespace JSC::LLInt
115
116
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntData.h +93 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
class JSGlobalData;
35
struct Instruction;
36
37
namespace LLInt {
38
39
#if ENABLE(LLINT)
40
class Data {
41
public:
42
    Data();
43
    ~Data();
44
    
45
    void performAssertions(JSGlobalData&);
46
    
47
    Instruction* exceptionInstructions()
48
    {
49
        return m_exceptionInstructions;
50
    }
51
    
52
    Opcode* opcodeMap()
53
    {
54
        return m_opcodeMap;
55
    }
56
private:
57
    Instruction* m_exceptionInstructions;
58
    Opcode* m_opcodeMap;
59
};
60
#else // ENABLE(LLINT)
61
62
#if COMPILER(CLANG)
63
#pragma clang diagnostic push
64
#pragma clang diagnostic ignored "-Wmissing-noreturn"
65
#endif
66
67
class Data {
68
public:
69
    void performAssertions(JSGlobalData&) { }
70
71
    Instruction* exceptionInstructions()
72
    {
73
        ASSERT_NOT_REACHED();
74
        return 0;
75
    }
76
    
77
    Opcode* opcodeMap()
78
    {
79
        ASSERT_NOT_REACHED();
80
        return 0;
81
    }
82
};
83
84
#if COMPILER(CLANG)
85
#pragma clang diagnostic pop
86
#endif
87
88
#endif // ENABLE(LLINT)
89
90
} } // namespace JSC::LLInt
91
92
#endif // LLIntData_h
93
- 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, ReturnAddressPtr pc)
41
{
42
    JSGlobalData* globalData = &exec->globalData();
43
#if LLINT_SLOW_PATH_TRACING
44
    dataLog("Throwing exception %s.\n", globalData->exception.description());
45
#endif
46
    genericThrow(
47
        globalData, exec, globalData->exception,
48
        exec->codeBlock()->bytecodeOffset(exec, pc));
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_SLOW_PATH_TRACING
60
    dataLog("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_SLOW_PATH_TRACING
71
    dataLog("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 +66 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
#include "MacroAssemblerCodeRef.h"
35
36
namespace JSC {
37
38
class ExecState;
39
struct Instruction;
40
41
namespace LLInt {
42
43
// Throw the currently active exception in the context of the caller's call frame.
44
void interpreterThrowInCaller(ExecState* callerFrame, ReturnAddressPtr);
45
46
// Tells you where to jump to if you want to return-to-throw, after you've already
47
// set up all information needed to throw the exception.
48
Instruction* returnToThrowForThrownException(ExecState*);
49
50
// Saves the current PC in the global data for safe-keeping, and gives you a PC
51
// that you can tell the interpreter to go to, which when advanced between 1
52
// and 9 slots will give you an "instruction" that threads to the interpreter's
53
// exception handler. Note that if you give it the PC for exception handling,
54
// it's smart enough to just return that PC without doing anything else; this
55
// lets you thread exception handling through common helper functions used by
56
// other helpers.
57
Instruction* returnToThrow(ExecState*, Instruction*);
58
59
// Use this when you're throwing to a call thunk.
60
void* callToThrow(ExecState*, Instruction*);
61
62
} } // namespace JSC::LLInt
63
64
#endif // ENABLE(LLINT)
65
66
#endif // LLIntExceptions_h
- Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h +90 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/InlineAsm.h>
32
#include <wtf/Platform.h>
33
34
#if CPU(X86)
35
#define OFFLINE_ASM_X86 1
36
#else
37
#define OFFLINE_ASM_X86 0
38
#endif
39
40
#if CPU(ARM_THUMB2)
41
#define OFFLINE_ASM_ARMv7 1
42
#else
43
#define OFFLINE_ASM_ARMv7 0
44
#endif
45
46
#if !ASSERT_DISABLED
47
#define OFFLINE_ASM_ASSERT_ENABLED 1
48
#else
49
#define OFFLINE_ASM_ASSERT_ENABLED 0
50
#endif
51
52
#if CPU(BIG_ENDIAN)
53
#define OFFLINE_ASM_BIG_ENDIAN 1
54
#else
55
#define OFFLINE_ASM_BIG_ENDIAN 0
56
#endif
57
58
#if LLINT_OSR_TO_JIT
59
#define OFFLINE_ASM_JIT_ENABLED 1
60
#else
61
#define OFFLINE_ASM_JIT_ENABLED 0
62
#endif
63
64
#if LLINT_EXECUTION_TRACING
65
#define OFFLINE_ASM_EXECUTION_TRACING 1
66
#else
67
#define OFFLINE_ASM_EXECUTION_TRACING 0
68
#endif
69
70
#if LLINT_ALWAYS_ALLOCATE_SLOW
71
#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 1
72
#else
73
#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 0
74
#endif
75
76
#if CPU(ARM_THUMB2)
77
#define OFFLINE_ASM_GLOBAL_LABEL(label)          \
78
    ".globl " SYMBOL_STRING(label) "\n"          \
79
    HIDE_SYMBOL(name) "\n"                       \
80
    ".thumb\n"                                   \
81
    ".thumb_func " THUMB_FUNC_PARAM(label) "\n"  \
82
    SYMBOL_STRING(label) ":\n"
83
#else
84
#define OFFLINE_ASM_GLOBAL_LABEL(label)         \
85
    ".globl " SYMBOL_STRING(label) "\n"         \
86
    HIDE_SYMBOL(name) "\n"                      \
87
    SYMBOL_STRING(label) ":\n"
88
#endif
89
90
#endif // LLIntOfflineAsmConfig_h
- Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp +82 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 "CodeBlock.h"
29
#include "Executable.h"
30
#include "Heap.h"
31
#include "Interpreter.h"
32
#include "JITStubs.h"
33
#include "JSArray.h"
34
#include "JSCell.h"
35
#include "JSFunction.h"
36
#include "JSGlobalData.h"
37
#include "JSGlobalObject.h"
38
#include "JSObject.h"
39
#include "JSPropertyNameIterator.h"
40
#include "JSString.h"
41
#include "JSTypeInfo.h"
42
#include "JSVariableObject.h"
43
#include "JumpTable.h"
44
#include "LLIntOfflineAsmConfig.h"
45
#include "MarkedSpace.h"
46
#include "RegisterFile.h"
47
#include "ScopeChain.h"
48
#include "Structure.h"
49
#include "StructureChain.h"
50
#include "ValueProfile.h"
51
#include <wtf/text/StringImpl.h>
52
53
namespace JSC {
54
55
#define OFFLINE_ASM_OFFSETOF(clazz, field) OBJECT_OFFSETOF(clazz, field)
56
57
class LLIntOffsetsExtractor {
58
public:
59
    static const unsigned* dummy();
60
};
61
62
const unsigned* LLIntOffsetsExtractor::dummy()
63
{
64
// This is a file generated by offlineasm/generate_offsets_extractor.rb, and contains code
65
// to create a table of offsets, sizes, and a header identifying what combination of
66
// Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor
67
// because the fields whose offsets we're extracting are mostly private. So we make their
68
// classes friends with LLIntOffsetsExtractor, and include the header here, to get the C++
69
// compiler to kindly step aside and yield to our best intentions.
70
#include "LLIntDesiredOffsets.h"
71
    return extractorTable;
72
}
73
74
} // namespace JSC
75
76
int main(int, char**)
77
{
78
    // Out of an abundance of caution, make sure that LLIntOffsetsExtractor::dummy() is live,
79
    // and the extractorTable is live, too.
80
    printf("%p\n", JSC::LLIntOffsetsExtractor::dummy());
81
    return 0;
82
}
- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +1558 lines
Line 0 Source/JavaScriptCore/llint/LLIntSlowPaths.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 "LLIntSlowPaths.h"
28
29
#if ENABLE(LLINT)
30
31
#include "Arguments.h"
32
#include "CallFrame.h"
33
#include "CommonSlowPaths.h"
34
#include "GetterSetter.h"
35
#include "HostCallReturnValue.h"
36
#include "Interpreter.h"
37
#include "JIT.h"
38
#include "JITDriver.h"
39
#include "JSActivation.h"
40
#include "JSByteArray.h"
41
#include "JSGlobalObjectFunctions.h"
42
#include "JSPropertyNameIterator.h"
43
#include "JSStaticScopeObject.h"
44
#include "JSString.h"
45
#include "JSValue.h"
46
#include "LLIntCommon.h"
47
#include "LLIntExceptions.h"
48
#include "LowLevelInterpreter.h"
49
#include "Operations.h"
50
51
namespace JSC { namespace LLInt {
52
53
#define LLINT_BEGIN_NO_SET_PC() \
54
    JSGlobalData& globalData = exec->globalData();      \
55
    NativeCallFrameTracer tracer(&globalData, exec)
56
57
#define LLINT_SET_PC_FOR_STUBS() \
58
    exec->setCurrentVPC(pc + 1)
59
60
#define LLINT_BEGIN()                           \
61
    LLINT_BEGIN_NO_SET_PC();                    \
62
    LLINT_SET_PC_FOR_STUBS()
63
64
#define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
65
#define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
66
67
#define LLINT_RETURN_TWO(first, second) do {       \
68
        union {                                    \
69
            struct {                               \
70
                void* a;                           \
71
                void* b;                           \
72
            } pair;                                \
73
            int64_t i;                             \
74
        } __rt_u;                                  \
75
        __rt_u.pair.a = first;                     \
76
        __rt_u.pair.b = second;                    \
77
        return __rt_u.i;                           \
78
    } while (false)
79
80
#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
81
82
#define LLINT_THROW(exceptionToThrow) do {                        \
83
        globalData.exception = (exceptionToThrow);                \
84
        pc = returnToThrow(exec, pc);                             \
85
        LLINT_END_IMPL();                                         \
86
    } while (false)
87
88
#define LLINT_CHECK_EXCEPTION() do {                    \
89
        if (UNLIKELY(globalData.exception)) {           \
90
            pc = returnToThrow(exec, pc);               \
91
            LLINT_END_IMPL();                           \
92
        }                                               \
93
    } while (false)
94
95
#define LLINT_END() do {                        \
96
        LLINT_CHECK_EXCEPTION();                \
97
        LLINT_END_IMPL();                       \
98
    } while (false)
99
100
#define LLINT_BRANCH(opcode, condition) do {                      \
101
        bool __b_condition = (condition);                         \
102
        LLINT_CHECK_EXCEPTION();                                  \
103
        if (__b_condition)                                        \
104
            pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand;        \
105
        else                                                      \
106
            pc += OPCODE_LENGTH(opcode);                          \
107
        LLINT_END_IMPL();                                         \
108
    } while (false)
109
110
#define LLINT_RETURN(value) do {                \
111
        JSValue __r_returnValue = (value);      \
112
        LLINT_CHECK_EXCEPTION();                \
113
        LLINT_OP(1) = __r_returnValue;          \
114
        LLINT_END_IMPL();                       \
115
    } while (false)
116
117
#define LLINT_RETURN_PROFILED(opcode, value) do {               \
118
        JSValue __rp_returnValue = (value);                     \
119
        LLINT_CHECK_EXCEPTION();                                \
120
        LLINT_OP(1) = __rp_returnValue;                         \
121
        pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
122
            JSValue::encode(__rp_returnValue);                  \
123
        LLINT_END_IMPL();                                       \
124
    } while (false)
125
126
#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
127
128
#define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do {               \
129
        ExecState* __ct_exec = (exec);                                  \
130
        Instruction* __ct_pc = (pc);                                    \
131
        globalData.exception = (exceptionToThrow);                      \
132
        LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
133
    } while (false)
134
135
#define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do {                       \
136
        ExecState* __cce_exec = (exec);                                 \
137
        Instruction* __cce_pc = (pc);                                   \
138
        if (UNLIKELY(globalData.exception))                              \
139
            LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
140
    } while (false)
141
142
#define LLINT_CALL_RETURN(exec, pc, callTarget) do {                    \
143
        ExecState* __cr_exec = (exec);                                  \
144
        Instruction* __cr_pc = (pc);                                    \
145
        void* __cr_callTarget = (callTarget);                           \
146
        LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc);  \
147
        LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget);                \
148
    } while (false)
149
150
extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
151
{
152
    LLINT_BEGIN();
153
    dataLog("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
154
            exec->codeBlock(),
155
            exec,
156
            static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
157
            exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
158
            fromWhere,
159
            operand,
160
            pc[operand].u.operand);
161
    LLINT_END();
162
}
163
164
extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
165
{
166
    LLINT_BEGIN();
167
    JSValue value = LLINT_OP_C(operand).jsValue();
168
    union {
169
        struct {
170
            uint32_t tag;
171
            uint32_t payload;
172
        } bits;
173
        EncodedJSValue asValue;
174
    } u;
175
    u.asValue = JSValue::encode(value);
176
    dataLog("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
177
            exec->codeBlock(),
178
            exec,
179
            static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
180
            exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
181
            fromWhere,
182
            operand,
183
            pc[operand].u.operand,
184
            u.bits.tag,
185
            u.bits.payload,
186
            value.description());
187
    LLINT_END();
188
}
189
190
LLINT_SLOW_PATH_DECL(trace_prologue)
191
{
192
    LLINT_BEGIN();
193
    dataLog("%p / %p: in prologue.\n", exec->codeBlock(), exec);
194
    LLINT_END();
195
}
196
197
static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
198
{
199
    JSFunction* callee = asFunction(exec->callee());
200
    FunctionExecutable* executable = callee->jsExecutable();
201
    CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
202
    dataLog("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
203
            codeBlock, exec, comment, callee, executable,
204
            codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
205
            exec->callerFrame());
206
}
207
208
LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
209
{
210
    LLINT_BEGIN();
211
    traceFunctionPrologue(exec, "call prologue", CodeForCall);
212
    LLINT_END();
213
}
214
215
LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
216
{
217
    LLINT_BEGIN();
218
    traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
219
    LLINT_END();
220
}
221
222
LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
223
{
224
    LLINT_BEGIN();
225
    traceFunctionPrologue(exec, "call arity check", CodeForCall);
226
    LLINT_END();
227
}
228
229
LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
230
{
231
    LLINT_BEGIN();
232
    traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
233
    LLINT_END();
234
}
235
236
LLINT_SLOW_PATH_DECL(trace)
237
{
238
    LLINT_BEGIN();
239
    dataLog("%p / %p: executing bc#%zu, %s, scope %p\n",
240
            exec->codeBlock(),
241
            exec,
242
            static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
243
            opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)],
244
            exec->scopeChain());
245
    LLINT_END();
246
}
247
248
LLINT_SLOW_PATH_DECL(special_trace)
249
{
250
    LLINT_BEGIN();
251
    dataLog("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
252
            exec->codeBlock(),
253
            exec,
254
            static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
255
            exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
256
            exec->returnPC().value());
257
    LLINT_END();
258
}
259
260
inline bool shouldJIT(ExecState* exec)
261
{
262
    // You can modify this to turn off JITting without rebuilding the world.
263
    return exec->globalData().canUseJIT();
264
}
265
266
enum EntryKind { Prologue, ArityCheck };
267
static SlowPathReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
268
{
269
#if ENABLE(JIT_VERBOSE_OSR)
270
    dataLog("%p: Entered %s with executeCounter = %d\n", codeBlock, name, codeBlock->llintExecuteCounter());
271
#endif
272
    
273
    if (!shouldJIT(exec)) {
274
        codeBlock->dontJITAnytimeSoon();
275
        LLINT_RETURN_TWO(0, exec);
276
    }
277
    if (!codeBlock->jitCompile(exec->globalData())) {
278
#if ENABLE(JIT_VERBOSE_OSR)
279
        dataLog("    Code was already compiled.\n");
280
#endif
281
    }
282
    codeBlock->jitSoon();
283
    if (kind == Prologue)
284
        LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
285
    ASSERT(kind == ArityCheck);
286
    LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
287
}
288
289
LLINT_SLOW_PATH_DECL(entry_osr)
290
{
291
    return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
292
}
293
294
LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
295
{
296
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
297
}
298
299
LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
300
{
301
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
302
}
303
304
LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
305
{
306
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
307
}
308
309
LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
310
{
311
    return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
312
}
313
314
LLINT_SLOW_PATH_DECL(loop_osr)
315
{
316
    CodeBlock* codeBlock = exec->codeBlock();
317
    
318
#if ENABLE(JIT_VERBOSE_OSR)
319
    dataLog("%p: Entered loop_osr with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
320
#endif
321
    
322
    if (!shouldJIT(exec)) {
323
        codeBlock->dontJITAnytimeSoon();
324
        LLINT_RETURN_TWO(0, exec);
325
    }
326
    
327
    if (!codeBlock->jitCompile(exec->globalData())) {
328
#if ENABLE(JIT_VERBOSE_OSR)
329
        dataLog("    Code was already compiled.\n");
330
#endif
331
    }
332
    codeBlock->jitSoon();
333
    
334
    ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
335
    
336
    Vector<BytecodeAndMachineOffset> map;
337
    codeBlock->jitCodeMap()->decode(map);
338
    BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(map.begin(), map.size(), pc - codeBlock->instructions().begin());
339
    ASSERT(mapping);
340
    ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
341
    
342
    void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
343
    ASSERT(jumpTarget);
344
    
345
    LLINT_RETURN_TWO(jumpTarget, exec);
346
}
347
348
LLINT_SLOW_PATH_DECL(replace)
349
{
350
    CodeBlock* codeBlock = exec->codeBlock();
351
    
352
#if ENABLE(JIT_VERBOSE_OSR)
353
    dataLog("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
354
#endif
355
    
356
    if (shouldJIT(exec)) {
357
        if (!codeBlock->jitCompile(exec->globalData())) {
358
#if ENABLE(JIT_VERBOSE_OSR)
359
            dataLog("    Code was already compiled.\n");
360
#endif
361
        }
362
        codeBlock->jitSoon();
363
    } else
364
        codeBlock->dontJITAnytimeSoon();
365
    LLINT_END_IMPL();
366
}
367
368
LLINT_SLOW_PATH_DECL(register_file_check)
369
{
370
    LLINT_BEGIN();
371
#if LLINT_SLOW_PATH_TRACING
372
    dataLog("Checking stack height with exec = %p.\n", exec);
373
    dataLog("CodeBlock = %p.\n", exec->codeBlock());
374
    dataLog("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
375
    dataLog("Num vars = %u.\n", exec->codeBlock()->m_numVars);
376
    dataLog("Current end is at %p.\n", exec->globalData().interpreter->registerFile().end());
377
#endif
378
    ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end());
379
    if (UNLIKELY(!globalData.interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
380
        ReturnAddressPtr returnPC = exec->returnPC();
381
        exec = exec->callerFrame();
382
        globalData.exception = createStackOverflowError(exec);
383
        interpreterThrowInCaller(exec, returnPC);
384
        pc = returnToThrowForThrownException(exec);
385
    }
386
    LLINT_END_IMPL();
387
}
388
389
LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
390
{
391
    LLINT_BEGIN();
392
    ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForCall);
393
    if (!newExec) {
394
        ReturnAddressPtr returnPC = exec->returnPC();
395
        exec = exec->callerFrame();
396
        globalData.exception = createStackOverflowError(exec);
397
        interpreterThrowInCaller(exec, returnPC);
398
        LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
399
    }
400
    LLINT_RETURN_TWO(0, newExec);
401
}
402
403
LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck)
404
{
405
    LLINT_BEGIN();
406
    ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForConstruct);
407
    if (!newExec) {
408
        ReturnAddressPtr returnPC = exec->returnPC();
409
        exec = exec->callerFrame();
410
        globalData.exception = createStackOverflowError(exec);
411
        interpreterThrowInCaller(exec, returnPC);
412
        LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
413
    }
414
    LLINT_RETURN_TWO(0, newExec);
415
}
416
417
LLINT_SLOW_PATH_DECL(slow_path_create_activation)
418
{
419
    LLINT_BEGIN();
420
#if LLINT_SLOW_PATH_TRACING
421
    dataLog("Creating an activation, exec = %p!\n", exec);
422
#endif
423
    JSActivation* activation = JSActivation::create(globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
424
    exec->setScopeChain(exec->scopeChain()->push(activation));
425
    LLINT_RETURN(JSValue(activation));
426
}
427
428
LLINT_SLOW_PATH_DECL(slow_path_create_arguments)
429
{
430
    LLINT_BEGIN();
431
    JSValue arguments = JSValue(Arguments::create(globalData, exec));
432
    LLINT_CHECK_EXCEPTION();
433
    exec->uncheckedR(pc[1].u.operand) = arguments;
434
    exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
435
    LLINT_END();
436
}
437
438
LLINT_SLOW_PATH_DECL(slow_path_create_this)
439
{
440
    LLINT_BEGIN();
441
    JSFunction* constructor = asFunction(exec->callee());
442
    
443
#if !ASSERT_DISABLED
444
    ConstructData constructData;
445
    ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
446
#endif
447
    
448
    Structure* structure;
449
    JSValue proto = LLINT_OP(2).jsValue();
450
    if (proto.isObject())
451
        structure = asObject(proto)->inheritorID(globalData);
452
    else
453
        structure = constructor->scope()->globalObject->emptyObjectStructure();
454
    
455
    LLINT_RETURN(constructEmptyObject(exec, structure));
456
}
457
458
LLINT_SLOW_PATH_DECL(slow_path_convert_this)
459
{
460
    LLINT_BEGIN();
461
    JSValue v1 = LLINT_OP(1).jsValue();
462
    ASSERT(v1.isPrimitive());
463
    LLINT_RETURN(v1.toThisObject(exec));
464
}
465
466
LLINT_SLOW_PATH_DECL(slow_path_new_object)
467
{
468
    LLINT_BEGIN();
469
    LLINT_RETURN(constructEmptyObject(exec));
470
}
471
472
LLINT_SLOW_PATH_DECL(slow_path_new_array)
473
{
474
    LLINT_BEGIN();
475
    LLINT_RETURN(constructArray(exec, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
476
}
477
478
LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
479
{
480
    LLINT_BEGIN();
481
    LLINT_RETURN(constructArray(exec, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
482
}
483
484
LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
485
{
486
    LLINT_BEGIN();
487
    RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
488
    if (!regExp->isValid())
489
        LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
490
    LLINT_RETURN(RegExpObject::create(globalData, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
491
}
492
493
LLINT_SLOW_PATH_DECL(slow_path_not)
494
{
495
    LLINT_BEGIN();
496
    LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
497
}
498
499
LLINT_SLOW_PATH_DECL(slow_path_eq)
500
{
501
    LLINT_BEGIN();
502
    LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
503
}
504
505
LLINT_SLOW_PATH_DECL(slow_path_neq)
506
{
507
    LLINT_BEGIN();
508
    LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
509
}
510
511
LLINT_SLOW_PATH_DECL(slow_path_stricteq)
512
{
513
    LLINT_BEGIN();
514
    LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
515
}
516
517
LLINT_SLOW_PATH_DECL(slow_path_nstricteq)
518
{
519
    LLINT_BEGIN();
520
    LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
521
}
522
523
LLINT_SLOW_PATH_DECL(slow_path_less)
524
{
525
    LLINT_BEGIN();
526
    LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
527
}
528
529
LLINT_SLOW_PATH_DECL(slow_path_lesseq)
530
{
531
    LLINT_BEGIN();
532
    LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
533
}
534
535
LLINT_SLOW_PATH_DECL(slow_path_greater)
536
{
537
    LLINT_BEGIN();
538
    LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
539
}
540
541
LLINT_SLOW_PATH_DECL(slow_path_greatereq)
542
{
543
    LLINT_BEGIN();
544
    LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
545
}
546
547
LLINT_SLOW_PATH_DECL(slow_path_pre_inc)
548
{
549
    LLINT_BEGIN();
550
    LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
551
}
552
553
LLINT_SLOW_PATH_DECL(slow_path_pre_dec)
554
{
555
    LLINT_BEGIN();
556
    LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
557
}
558
559
LLINT_SLOW_PATH_DECL(slow_path_post_inc)
560
{
561
    LLINT_BEGIN();
562
    double result = LLINT_OP(2).jsValue().toNumber(exec);
563
    LLINT_OP(2) = jsNumber(result + 1);
564
    LLINT_RETURN(jsNumber(result));
565
}
566
567
LLINT_SLOW_PATH_DECL(slow_path_post_dec)
568
{
569
    LLINT_BEGIN();
570
    double result = LLINT_OP(2).jsValue().toNumber(exec);
571
    LLINT_OP(2) = jsNumber(result - 1);
572
    LLINT_RETURN(jsNumber(result));
573
}
574
575
LLINT_SLOW_PATH_DECL(slow_path_to_jsnumber)
576
{
577
    LLINT_BEGIN();
578
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
579
}
580
581
LLINT_SLOW_PATH_DECL(slow_path_negate)
582
{
583
    LLINT_BEGIN();
584
    LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
585
}
586
587
LLINT_SLOW_PATH_DECL(slow_path_add)
588
{
589
    LLINT_BEGIN();
590
    JSValue v1 = LLINT_OP_C(2).jsValue();
591
    JSValue v2 = LLINT_OP_C(3).jsValue();
592
    
593
#if LLINT_SLOW_PATH_TRACING
594
    dataLog("Trying to add %s", v1.description());
595
    dataLog(" to %s.\n", v2.description());
596
#endif
597
    
598
    if (v1.isString() && !v2.isObject())
599
        LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
600
    
601
    if (v1.isNumber() && v2.isNumber())
602
        LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
603
    
604
    LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
605
}
606
607
LLINT_SLOW_PATH_DECL(slow_path_mul)
608
{
609
    LLINT_BEGIN();
610
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) * LLINT_OP_C(3).jsValue().toNumber(exec)));
611
}
612
613
LLINT_SLOW_PATH_DECL(slow_path_sub)
614
{
615
    LLINT_BEGIN();
616
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) - LLINT_OP_C(3).jsValue().toNumber(exec)));
617
}
618
619
LLINT_SLOW_PATH_DECL(slow_path_div)
620
{
621
    LLINT_BEGIN();
622
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) / LLINT_OP_C(3).jsValue().toNumber(exec)));
623
}
624
625
LLINT_SLOW_PATH_DECL(slow_path_mod)
626
{
627
    LLINT_BEGIN();
628
    LLINT_RETURN(jsNumber(fmod(LLINT_OP_C(2).jsValue().toNumber(exec), LLINT_OP_C(3).jsValue().toNumber(exec))));
629
}
630
631
LLINT_SLOW_PATH_DECL(slow_path_lshift)
632
{
633
    LLINT_BEGIN();
634
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) << (LLINT_OP_C(3).jsValue().toUInt32(exec) & 31)));
635
}
636
637
LLINT_SLOW_PATH_DECL(slow_path_rshift)
638
{
639
    LLINT_BEGIN();
640
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) >> (LLINT_OP_C(3).jsValue().toUInt32(exec) & 31)));
641
}
642
643
LLINT_SLOW_PATH_DECL(slow_path_urshift)
644
{
645
    LLINT_BEGIN();
646
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toUInt32(exec) >> (LLINT_OP_C(3).jsValue().toUInt32(exec) & 31)));
647
}
648
649
LLINT_SLOW_PATH_DECL(slow_path_bitand)
650
{
651
    LLINT_BEGIN();
652
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) & LLINT_OP_C(3).jsValue().toInt32(exec)));
653
}
654
655
LLINT_SLOW_PATH_DECL(slow_path_bitor)
656
{
657
    LLINT_BEGIN();
658
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) | LLINT_OP_C(3).jsValue().toInt32(exec)));
659
}
660
661
LLINT_SLOW_PATH_DECL(slow_path_bitxor)
662
{
663
    LLINT_BEGIN();
664
    LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
665
}
666
667
LLINT_SLOW_PATH_DECL(slow_path_bitnot)
668
{
669
    LLINT_BEGIN();
670
    LLINT_RETURN(jsNumber(~LLINT_OP_C(2).jsValue().toInt32(exec)));
671
}
672
673
LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
674
{
675
    LLINT_BEGIN();
676
    JSValue baseVal = LLINT_OP_C(1).jsValue();
677
#ifndef NDEBUG
678
    TypeInfo typeInfo(UnspecifiedType);
679
    ASSERT(!baseVal.isObject()
680
           || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
681
#endif
682
    LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
683
}
684
685
LLINT_SLOW_PATH_DECL(slow_path_instanceof)
686
{
687
    LLINT_BEGIN();
688
    LLINT_RETURN(jsBoolean(CommonSlowPaths::opInstanceOfSlow(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue())));
689
}
690
691
LLINT_SLOW_PATH_DECL(slow_path_typeof)
692
{
693
    LLINT_BEGIN();
694
    LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
695
}
696
697
LLINT_SLOW_PATH_DECL(slow_path_is_undefined)
698
{
699
    LLINT_BEGIN();
700
    JSValue v = LLINT_OP_C(2).jsValue();
701
    LLINT_RETURN(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
702
}
703
704
LLINT_SLOW_PATH_DECL(slow_path_is_boolean)
705
{
706
    LLINT_BEGIN();
707
    LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isBoolean()));
708
}
709
710
LLINT_SLOW_PATH_DECL(slow_path_is_number)
711
{
712
    LLINT_BEGIN();
713
    LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isNumber()));
714
}
715
716
LLINT_SLOW_PATH_DECL(slow_path_is_string)
717
{
718
    LLINT_BEGIN();
719
    LLINT_RETURN(jsBoolean(isJSString(LLINT_OP_C(2).jsValue())));
720
}
721
722
LLINT_SLOW_PATH_DECL(slow_path_is_object)
723
{
724
    LLINT_BEGIN();
725
    LLINT_RETURN(jsBoolean(jsIsObjectType(LLINT_OP_C(2).jsValue())));
726
}
727
728
LLINT_SLOW_PATH_DECL(slow_path_is_function)
729
{
730
    LLINT_BEGIN();
731
    LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
732
}
733
734
LLINT_SLOW_PATH_DECL(slow_path_in)
735
{
736
    LLINT_BEGIN();
737
    LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
738
}
739
740
LLINT_SLOW_PATH_DECL(slow_path_resolve)
741
{
742
    LLINT_BEGIN();
743
    LLINT_RETURN_PROFILED(op_resolve, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
744
}
745
746
LLINT_SLOW_PATH_DECL(slow_path_resolve_skip)
747
{
748
    LLINT_BEGIN();
749
    LLINT_RETURN_PROFILED(
750
        op_resolve_skip,
751
        CommonSlowPaths::opResolveSkip(
752
            exec,
753
            exec->codeBlock()->identifier(pc[2].u.operand),
754
            pc[3].u.operand));
755
}
756
757
static JSValue resolveGlobal(ExecState* exec, Instruction* pc)
758
{
759
    CodeBlock* codeBlock = exec->codeBlock();
760
    JSGlobalObject* globalObject = codeBlock->globalObject();
761
    ASSERT(globalObject->isGlobalObject());
762
    int property = pc[2].u.operand;
763
    Structure* structure = pc[3].u.structure.get();
764
    
765
    ASSERT_UNUSED(structure, structure != globalObject->structure());
766
    
767
    Identifier& ident = codeBlock->identifier(property);
768
    PropertySlot slot(globalObject);
769
    
770
    if (globalObject->getPropertySlot(exec, ident, slot)) {
771
        JSValue result = slot.getValue(exec, ident);
772
        if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary()
773
            && slot.slotBase() == globalObject) {
774
            pc[3].u.structure.set(
775
                exec->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
776
            pc[4] = slot.cachedOffset();
777
        }
778
        
779
        return result;
780
    }
781
    
782
    exec->globalData().exception = createUndefinedVariableError(exec, ident);
783
    return JSValue();
784
}
785
786
LLINT_SLOW_PATH_DECL(slow_path_resolve_global)
787
{
788
    LLINT_BEGIN();
789
    LLINT_RETURN_PROFILED(op_resolve_global, resolveGlobal(exec, pc));
790
}
791
792
LLINT_SLOW_PATH_DECL(slow_path_resolve_global_dynamic)
793
{
794
    LLINT_BEGIN();
795
    LLINT_RETURN_PROFILED(op_resolve_global_dynamic, resolveGlobal(exec, pc));
796
}
797
798
LLINT_SLOW_PATH_DECL(slow_path_resolve_for_resolve_global_dynamic)
799
{
800
    LLINT_BEGIN();
801
    LLINT_RETURN_PROFILED(op_resolve_global_dynamic, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
802
}
803
804
LLINT_SLOW_PATH_DECL(slow_path_resolve_base)
805
{
806
    LLINT_BEGIN();
807
    Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
808
    if (pc[3].u.operand) {
809
        JSValue base = JSC::resolveBase(exec, ident, exec->scopeChain(), true);
810
        if (!base)
811
            LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
812
        LLINT_RETURN(base);
813
    }
814
    
815
    LLINT_RETURN_PROFILED(op_resolve_base, JSC::resolveBase(exec, ident, exec->scopeChain(), false));
816
}
817
818
LLINT_SLOW_PATH_DECL(slow_path_ensure_property_exists)
819
{
820
    LLINT_BEGIN();
821
    JSObject* object = asObject(LLINT_OP(1).jsValue());
822
    PropertySlot slot(object);
823
    Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
824
    if (!object->getPropertySlot(exec, ident, slot))
825
        LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
826
    LLINT_END();
827
}
828
829
LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base)
830
{
831
    LLINT_BEGIN();
832
    JSValue result = CommonSlowPaths::opResolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
833
    LLINT_CHECK_EXCEPTION();
834
    LLINT_OP(2) = result;
835
    // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
836
    LLINT_END();
837
}
838
839
LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this)
840
{
841
    LLINT_BEGIN();
842
    JSValue result = CommonSlowPaths::opResolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
843
    LLINT_CHECK_EXCEPTION();
844
    LLINT_OP(2) = result;
845
    // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
846
    LLINT_END();
847
}
848
849
LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
850
{
851
    LLINT_BEGIN();
852
    CodeBlock* codeBlock = exec->codeBlock();
853
    Identifier& ident = codeBlock->identifier(pc[3].u.operand);
854
    JSValue baseValue = LLINT_OP_C(2).jsValue();
855
    PropertySlot slot(baseValue);
856
857
    JSValue result = baseValue.get(exec, ident, slot);
858
    LLINT_CHECK_EXCEPTION();
859
    LLINT_OP(1) = result;
860
861
    if (baseValue.isCell()
862
        && slot.isCacheable()
863
        && slot.slotBase() == baseValue
864
        && slot.cachedPropertyType() == PropertySlot::Value) {
865
        
866
        JSCell* baseCell = baseValue.asCell();
867
        Structure* structure = baseCell->structure();
868
        
869
        if (!structure->isUncacheableDictionary()
870
            && !structure->typeInfo().prohibitsPropertyCaching()) {
871
            pc[4].u.structure.set(
872
                globalData, codeBlock->ownerExecutable(), structure);
873
            pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
874
        }
875
    }
876
    
877
    pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
878
    LLINT_END();
879
}
880
881
LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
882
{
883
    LLINT_BEGIN();
884
    CodeBlock* codeBlock = exec->codeBlock();
885
    Identifier& ident = codeBlock->identifier(pc[3].u.operand);
886
    JSValue baseValue = LLINT_OP(2).jsValue();
887
    PropertySlot slot(baseValue);
888
    LLINT_RETURN(baseValue.get(exec, ident, slot));
889
}
890
891
LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
892
{
893
    LLINT_BEGIN();
894
    CodeBlock* codeBlock = exec->codeBlock();
895
    Identifier& ident = codeBlock->identifier(pc[2].u.operand);
896
    
897
    JSValue baseValue = LLINT_OP_C(1).jsValue();
898
    PutPropertySlot slot(codeBlock->isStrictMode());
899
    if (pc[8].u.operand)
900
        asObject(baseValue)->putDirect(globalData, ident, LLINT_OP_C(3).jsValue(), slot);
901
    else
902
        baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
903
    LLINT_CHECK_EXCEPTION();
904
    
905
    if (baseValue.isCell()
906
        && slot.isCacheable()) {
907
        
908
        JSCell* baseCell = baseValue.asCell();
909
        Structure* structure = baseCell->structure();
910
        
911
        if (!structure->isUncacheableDictionary()
912
            && !structure->typeInfo().prohibitsPropertyCaching()
913
            && baseCell == slot.base()) {
914
            
915
            if (slot.type() == PutPropertySlot::NewProperty) {
916
                if (!structure->isDictionary() && structure->previousID()->propertyStorageCapacity() == structure->propertyStorageCapacity()) {
917
                    // This is needed because some of the methods we call
918
                    // below may GC.
919
                    pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
920
921
                    normalizePrototypeChain(exec, baseCell);
922
                    
923
                    ASSERT(structure->previousID()->isObject());
924
                    pc[4].u.structure.set(
925
                        globalData, codeBlock->ownerExecutable(), structure->previousID());
926
                    pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
927
                    pc[6].u.structure.set(
928
                        globalData, codeBlock->ownerExecutable(), structure);
929
                    StructureChain* chain = structure->prototypeChain(exec);
930
                    ASSERT(chain);
931
                    pc[7].u.structureChain.set(
932
                        globalData, codeBlock->ownerExecutable(), chain);
933
                    
934
                    if (pc[8].u.operand)
935
                        pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct);
936
                    else
937
                        pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal);
938
                }
939
            } else {
940
                pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
941
                pc[4].u.structure.set(
942
                    globalData, codeBlock->ownerExecutable(), structure);
943
                pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
944
            }
945
        }
946
    }
947
    
948
    LLINT_END();
949
}
950
951
LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
952
{
953
    LLINT_BEGIN();
954
    CodeBlock* codeBlock = exec->codeBlock();
955
    JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
956
    bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
957
    LLINT_CHECK_EXCEPTION();
958
    if (!couldDelete && codeBlock->isStrictMode())
959
        LLINT_THROW(createTypeError(exec, "Unable to delete property."));
960
    LLINT_RETURN(jsBoolean(couldDelete));
961
}
962
963
inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
964
{
965
    if (LIKELY(baseValue.isCell() && subscript.isString())) {
966
        if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
967
            return result;
968
    }
969
    
970
    if (subscript.isUInt32()) {
971
        uint32_t i = subscript.asUInt32();
972
        if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
973
            return asString(baseValue)->getIndex(exec, i);
974
        
975
        if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
976
            return asByteArray(baseValue)->getIndex(exec, i);
977
        
978
        return baseValue.get(exec, i);
979
    }
980
    
981
    Identifier property(exec, subscript.toString(exec)->value(exec));
982
    return baseValue.get(exec, property);
983
}
984
985
LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
986
{
987
    LLINT_BEGIN();
988
    LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
989
}
990
991
LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
992
{
993
    LLINT_BEGIN();
994
    JSValue arguments = LLINT_OP(2).jsValue();
995
    if (!arguments) {
996
        arguments = Arguments::create(globalData, exec);
997
        LLINT_CHECK_EXCEPTION();
998
        LLINT_OP(2) = arguments;
999
        exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
1000
    }
1001
    
1002
    LLINT_RETURN(getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
1003
}
1004
1005
LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
1006
{
1007
    LLINT_BEGIN();
1008
    LLINT_RETURN(getByVal(exec, LLINT_OP(2).jsValue(), LLINT_OP(3).jsValue()));
1009
}
1010
1011
LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
1012
{
1013
    LLINT_BEGIN();
1014
    
1015
    JSValue baseValue = LLINT_OP_C(1).jsValue();
1016
    JSValue subscript = LLINT_OP_C(2).jsValue();
1017
    JSValue value = LLINT_OP_C(3).jsValue();
1018
    
1019
    if (LIKELY(subscript.isUInt32())) {
1020
        uint32_t i = subscript.asUInt32();
1021
        if (isJSArray(baseValue)) {
1022
            JSArray* jsArray = asArray(baseValue);
1023
            if (jsArray->canSetIndex(i))
1024
                jsArray->setIndex(globalData, i, value);
1025
            else
1026
                JSArray::putByIndex(jsArray, exec, i, value);
1027
            LLINT_END();
1028
        }
1029
        if (isJSByteArray(baseValue)
1030
            && asByteArray(baseValue)->canAccessIndex(i)) {
1031
            JSByteArray* jsByteArray = asByteArray(baseValue);
1032
            if (value.isInt32()) {
1033
                jsByteArray->setIndex(i, value.asInt32());
1034
                LLINT_END();
1035
            }
1036
            if (value.isNumber()) {
1037
                jsByteArray->setIndex(i, value.asNumber());
1038
                LLINT_END();
1039
            }
1040
        }
1041
        baseValue.put(exec, i, value);
1042
        LLINT_END();
1043
    }
1044
    
1045
    Identifier property(exec, subscript.toString(exec)->value(exec));
1046
    LLINT_CHECK_EXCEPTION();
1047
    PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1048
    baseValue.put(exec, property, value, slot);
1049
    LLINT_END();
1050
}
1051
1052
LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
1053
{
1054
    LLINT_BEGIN();
1055
    JSValue baseValue = LLINT_OP_C(2).jsValue();
1056
    JSObject* baseObject = baseValue.toObject(exec);
1057
    
1058
    JSValue subscript = LLINT_OP_C(3).jsValue();
1059
    
1060
    bool couldDelete;
1061
    
1062
    uint32_t i;
1063
    if (subscript.getUInt32(i))
1064
        couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
1065
    else {
1066
        LLINT_CHECK_EXCEPTION();
1067
        Identifier property(exec, subscript.toString(exec)->value(exec));
1068
        LLINT_CHECK_EXCEPTION();
1069
        couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
1070
    }
1071
    
1072
    if (!couldDelete && exec->codeBlock()->isStrictMode())
1073
        LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1074
    
1075
    LLINT_RETURN(jsBoolean(couldDelete));
1076
}
1077
1078
LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
1079
{
1080
    LLINT_BEGIN();
1081
    LLINT_OP_C(1).jsValue().put(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
1082
    LLINT_END();
1083
}
1084
1085
LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
1086
{
1087
    LLINT_BEGIN();
1088
    ASSERT(LLINT_OP(1).jsValue().isObject());
1089
    JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1090
    
1091
    GetterSetter* accessor = GetterSetter::create(exec);
1092
    LLINT_CHECK_EXCEPTION();
1093
    
1094
    JSValue getter = LLINT_OP(3).jsValue();
1095
    JSValue setter = LLINT_OP(4).jsValue();
1096
    ASSERT(getter.isObject() || getter.isUndefined());
1097
    ASSERT(setter.isObject() || setter.isUndefined());
1098
    ASSERT(getter.isObject() || setter.isObject());
1099
    
1100
    if (!getter.isUndefined())
1101
        accessor->setGetter(globalData, asObject(getter));
1102
    if (!setter.isUndefined())
1103
        accessor->setSetter(globalData, asObject(setter));
1104
    baseObj->putDirectAccessor(
1105
        globalData,
1106
        exec->codeBlock()->identifier(pc[2].u.operand),
1107
        accessor, Accessor);
1108
    LLINT_END();
1109
}
1110
1111
LLINT_SLOW_PATH_DECL(slow_path_jmp_scopes)
1112
{
1113
    LLINT_BEGIN();
1114
    unsigned count = pc[1].u.operand;
1115
    ScopeChainNode* tmp = exec->scopeChain();
1116
    while (count--)
1117
        tmp = tmp->pop();
1118
    exec->setScopeChain(tmp);
1119
    pc += pc[2].u.operand;
1120
    LLINT_END();
1121
}
1122
1123
LLINT_SLOW_PATH_DECL(slow_path_jtrue)
1124
{
1125
    LLINT_BEGIN();
1126
    LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
1127
}
1128
1129
LLINT_SLOW_PATH_DECL(slow_path_jfalse)
1130
{
1131
    LLINT_BEGIN();
1132
    LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
1133
}
1134
1135
LLINT_SLOW_PATH_DECL(slow_path_jless)
1136
{
1137
    LLINT_BEGIN();
1138
    LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1139
}
1140
1141
LLINT_SLOW_PATH_DECL(slow_path_jnless)
1142
{
1143
    LLINT_BEGIN();
1144
    LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1145
}
1146
1147
LLINT_SLOW_PATH_DECL(slow_path_jgreater)
1148
{
1149
    LLINT_BEGIN();
1150
    LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1151
}
1152
1153
LLINT_SLOW_PATH_DECL(slow_path_jngreater)
1154
{
1155
    LLINT_BEGIN();
1156
    LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1157
}
1158
1159
LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
1160
{
1161
    LLINT_BEGIN();
1162
    LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1163
}
1164
1165
LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
1166
{
1167
    LLINT_BEGIN();
1168
    LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1169
}
1170
1171
LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
1172
{
1173
    LLINT_BEGIN();
1174
    LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1175
}
1176
1177
LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
1178
{
1179
    LLINT_BEGIN();
1180
    LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1181
}
1182
1183
LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
1184
{
1185
    LLINT_BEGIN();
1186
    JSValue scrutinee = LLINT_OP_C(3).jsValue();
1187
    ASSERT(scrutinee.isDouble());
1188
    double value = scrutinee.asDouble();
1189
    int32_t intValue = static_cast<int32_t>(value);
1190
    int defaultOffset = pc[2].u.operand;
1191
    if (value == intValue) {
1192
        CodeBlock* codeBlock = exec->codeBlock();
1193
        pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
1194
    } else
1195
        pc += defaultOffset;
1196
    LLINT_END();
1197
}
1198
1199
LLINT_SLOW_PATH_DECL(slow_path_switch_string)
1200
{
1201
    LLINT_BEGIN();
1202
    JSValue scrutinee = LLINT_OP_C(3).jsValue();
1203
    int defaultOffset = pc[2].u.operand;
1204
    if (!scrutinee.isString())
1205
        pc += defaultOffset;
1206
    else {
1207
        CodeBlock* codeBlock = exec->codeBlock();
1208
        pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1209
    }
1210
    LLINT_END();
1211
}
1212
1213
LLINT_SLOW_PATH_DECL(slow_path_new_func)
1214
{
1215
    LLINT_BEGIN();
1216
    CodeBlock* codeBlock = exec->codeBlock();
1217
    ASSERT(codeBlock->codeType() != FunctionCode
1218
           || !codeBlock->needsFullScopeChain()
1219
           || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
1220
#if LLINT_SLOW_PATH_TRACING
1221
    dataLog("Creating function!\n");
1222
#endif
1223
    LLINT_RETURN(codeBlock->functionDecl(pc[2].u.operand)->make(exec, exec->scopeChain()));
1224
}
1225
1226
LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1227
{
1228
    LLINT_BEGIN();
1229
    CodeBlock* codeBlock = exec->codeBlock();
1230
    FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
1231
    JSFunction* func = function->make(exec, exec->scopeChain());
1232
    
1233
    if (!function->name().isNull()) {
1234
        JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(exec, function->name(), func, ReadOnly | DontDelete);
1235
        func->setScope(globalData, func->scope()->push(functionScopeObject));
1236
    }
1237
    
1238
    LLINT_RETURN(func);
1239
}
1240
1241
static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1242
{
1243
    ExecState* exec = execCallee->callerFrame();
1244
    JSGlobalData& globalData = exec->globalData();
1245
    
1246
    execCallee->setScopeChain(exec->scopeChain());
1247
    execCallee->setCodeBlock(0);
1248
    execCallee->clearReturnPC();
1249
1250
    if (kind == CodeForCall) {
1251
        CallData callData;
1252
        CallType callType = getCallData(callee, callData);
1253
    
1254
        ASSERT(callType != CallTypeJS);
1255
    
1256
        if (callType == CallTypeHost) {
1257
            globalData.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1258
            
1259
            LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
1260
        }
1261
        
1262
#if LLINT_SLOW_PATH_TRACING
1263
        dataLog("Call callee is not a function: %s\n", callee.description());
1264
#endif
1265
1266
        ASSERT(callType == CallTypeNone);
1267
        LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
1268
    }
1269
1270
    ASSERT(kind == CodeForConstruct);
1271
    
1272
    ConstructData constructData;
1273
    ConstructType constructType = getConstructData(callee, constructData);
1274
    
1275
    ASSERT(constructType != ConstructTypeJS);
1276
    
1277
    if (constructType == ConstructTypeHost) {
1278
        globalData.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1279
1280
        LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
1281
    }
1282
    
1283
#if LLINT_SLOW_PATH_TRACING
1284
    dataLog("Constructor callee is not a function: %s\n", callee.description());
1285
#endif
1286
1287
    ASSERT(constructType == ConstructTypeNone);
1288
    LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
1289
}
1290
1291
inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1292
{
1293
#if LLINT_SLOW_PATH_TRACING
1294
    dataLog("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
1295
#endif
1296
1297
    JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1298
    if (!calleeAsFunctionCell)
1299
        return handleHostCall(execCallee, pc, calleeAsValue, kind);
1300
    
1301
    JSFunction* callee = asFunction(calleeAsFunctionCell);
1302
    ScopeChainNode* scope = callee->scopeUnchecked();
1303
    JSGlobalData& globalData = *scope->globalData;
1304
    execCallee->setScopeChain(scope);
1305
    ExecutableBase* executable = callee->executable();
1306
    
1307
    MacroAssemblerCodePtr codePtr;
1308
    CodeBlock* codeBlock = 0;
1309
    if (executable->isHostFunction())
1310
        codePtr = executable->generatedJITCodeFor(kind).addressForCall();
1311
    else {
1312
        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1313
        JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1314
        if (error)
1315
            LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1316
        codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1317
        ASSERT(codeBlock);
1318
        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1319
            codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1320
        else
1321
            codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
1322
    }
1323
    
1324
    if (callLinkInfo) {
1325
        if (callLinkInfo->isOnList())
1326
            callLinkInfo->remove();
1327
        ExecState* execCaller = execCallee->callerFrame();
1328
        callLinkInfo->callee.set(globalData, execCaller->codeBlock()->ownerExecutable(), callee);
1329
        callLinkInfo->lastSeenCallee.set(globalData, execCaller->codeBlock()->ownerExecutable(), callee);
1330
        callLinkInfo->machineCodeTarget = codePtr;
1331
        if (codeBlock)
1332
            codeBlock->linkIncomingCall(callLinkInfo);
1333
    }
1334
    
1335
    LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1336
}
1337
1338
inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1339
{
1340
    // This needs to:
1341
    // - Set up a call frame.
1342
    // - Figure out what to call and compile it if necessary.
1343
    // - If possible, link the call's inline cache.
1344
    // - Return a tuple of machine code address to call and the new call frame.
1345
    
1346
    JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1347
    
1348
    ExecState* execCallee = exec + pc[3].u.operand;
1349
    
1350
    execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1351
    execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
1352
    execCallee->setCallerFrame(exec);
1353
    
1354
    ASSERT(pc[4].u.callLinkInfo);
1355
    return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
1356
}
1357
1358
LLINT_SLOW_PATH_DECL(slow_path_call)
1359
{
1360
    LLINT_BEGIN_NO_SET_PC();
1361
    return genericCall(exec, pc, CodeForCall);
1362
}
1363
1364
LLINT_SLOW_PATH_DECL(slow_path_construct)
1365
{
1366
    LLINT_BEGIN_NO_SET_PC();
1367
    return genericCall(exec, pc, CodeForConstruct);
1368
}
1369
1370
LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1371
{
1372
    LLINT_BEGIN();
1373
    // This needs to:
1374
    // - Set up a call frame while respecting the variable arguments.
1375
    // - Figure out what to call and compile it if necessary.
1376
    // - Return a tuple of machine code address to call and the new call frame.
1377
    
1378
    JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1379
    
1380
    ExecState* execCallee = loadVarargs(
1381
        exec, &globalData.interpreter->registerFile(),
1382
        LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
1383
    LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1384
    
1385
    execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
1386
    execCallee->setCallerFrame(exec);
1387
    exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_varargs));
1388
    
1389
    return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1390
}
1391
1392
LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1393
{
1394
    LLINT_BEGIN_NO_SET_PC();
1395
    JSValue calleeAsValue = LLINT_OP(1).jsValue();
1396
    
1397
    ExecState* execCallee = exec + pc[3].u.operand;
1398
    
1399
    execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1400
    execCallee->setCallerFrame(exec);
1401
    execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
1402
    execCallee->setScopeChain(exec->scopeChain());
1403
    execCallee->setReturnPC(bitwise_cast<Instruction*>(&llint_generic_return_point));
1404
    execCallee->setCodeBlock(0);
1405
    exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_eval));
1406
    
1407
    if (!isHostFunction(calleeAsValue, globalFuncEval))
1408
        return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1409
    
1410
    globalData.hostCallReturnValue = eval(execCallee);
1411
    LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
1412
}
1413
1414
LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1415
{
1416
    LLINT_BEGIN();
1417
    ASSERT(exec->codeBlock()->needsFullScopeChain());
1418
    JSValue activationValue = LLINT_OP(1).jsValue();
1419
    if (!activationValue) {
1420
        if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue()) {
1421
            if (!exec->codeBlock()->isStrictMode())
1422
                asArguments(v)->tearOff(exec);
1423
        }
1424
        LLINT_END();
1425
    }
1426
    JSActivation* activation = asActivation(activationValue);
1427
    activation->tearOff(globalData);
1428
    if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue())
1429
        asArguments(v)->didTearOffActivation(globalData, activation);
1430
    LLINT_END();
1431
}
1432
1433
LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1434
{
1435
    LLINT_BEGIN();
1436
    ASSERT(exec->codeBlock()->usesArguments() && !exec->codeBlock()->needsFullScopeChain());
1437
    asArguments(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue())->tearOff(exec);
1438
    LLINT_END();
1439
}
1440
1441
LLINT_SLOW_PATH_DECL(slow_path_strcat)
1442
{
1443
    LLINT_BEGIN();
1444
    LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1445
}
1446
1447
LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1448
{
1449
    LLINT_BEGIN();
1450
    LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1451
}
1452
1453
LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1454
{
1455
    LLINT_BEGIN();
1456
    JSValue v = LLINT_OP(2).jsValue();
1457
    if (v.isUndefinedOrNull()) {
1458
        pc += pc[5].u.operand;
1459
        LLINT_END();
1460
    }
1461
    
1462
    JSObject* o = v.toObject(exec);
1463
    Structure* structure = o->structure();
1464
    JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1465
    if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1466
        jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1467
    
1468
    LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1469
    LLINT_OP(2) = JSValue(o);
1470
    LLINT_OP(3) = Register::withInt(0);
1471
    LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1472
    
1473
    pc += OPCODE_LENGTH(op_get_pnames);
1474
    LLINT_END();
1475
}
1476
1477
LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1478
{
1479
    LLINT_BEGIN();
1480
    JSObject* base = asObject(LLINT_OP(2).jsValue());
1481
    JSString* property = asString(LLINT_OP(1).jsValue());
1482
    if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1483
        // Go to target.
1484
        pc += pc[6].u.operand;
1485
    } // Else, don't change the PC, so the interpreter will reloop.
1486
    LLINT_END();
1487
}
1488
1489
LLINT_SLOW_PATH_DECL(slow_path_push_scope)
1490
{
1491
    LLINT_BEGIN();
1492
    JSValue v = LLINT_OP(1).jsValue();
1493
    JSObject* o = v.toObject(exec);
1494
    LLINT_CHECK_EXCEPTION();
1495
    
1496
    LLINT_OP(1) = o;
1497
    exec->setScopeChain(exec->scopeChain()->push(o));
1498
    
1499
    LLINT_END();
1500
}
1501
1502
LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1503
{
1504
    LLINT_BEGIN();
1505
    exec->setScopeChain(exec->scopeChain()->pop());
1506
    LLINT_END();
1507
}
1508
1509
LLINT_SLOW_PATH_DECL(slow_path_push_new_scope)
1510
{
1511
    LLINT_BEGIN();
1512
    CodeBlock* codeBlock = exec->codeBlock();
1513
    JSObject* scope = JSStaticScopeObject::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), DontDelete);
1514
    exec->setScopeChain(exec->scopeChain()->push(scope));
1515
    LLINT_RETURN(scope);
1516
}
1517
1518
LLINT_SLOW_PATH_DECL(slow_path_throw)
1519
{
1520
    LLINT_BEGIN();
1521
    LLINT_THROW(LLINT_OP_C(1).jsValue());
1522
}
1523
1524
LLINT_SLOW_PATH_DECL(slow_path_throw_reference_error)
1525
{
1526
    LLINT_BEGIN();
1527
    LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1528
}
1529
1530
LLINT_SLOW_PATH_DECL(slow_path_debug)
1531
{
1532
    LLINT_BEGIN();
1533
    int debugHookID = pc[1].u.operand;
1534
    int firstLine = pc[2].u.operand;
1535
    int lastLine = pc[3].u.operand;
1536
    
1537
    globalData.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
1538
    
1539
    LLINT_END();
1540
}
1541
1542
LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1543
{
1544
    LLINT_BEGIN();
1545
    (*Profiler::enabledProfilerReference())->willExecute(exec, LLINT_OP(1).jsValue());
1546
    LLINT_END();
1547
}
1548
1549
LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1550
{
1551
    LLINT_BEGIN();
1552
    (*Profiler::enabledProfilerReference())->didExecute(exec, LLINT_OP(1).jsValue());
1553
    LLINT_END();
1554
}
1555
1556
} } // namespace JSC::LLInt
1557
1558
#endif // ENABLE(LLINT)
- Source/JavaScriptCore/llint/LLIntSlowPaths.h +171 lines
Line 0 Source/JavaScriptCore/llint/LLIntSlowPaths.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 LLIntSlowPaths_h
27
#define LLIntSlowPaths_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 SlowPathReturnType;
42
43
extern "C" SlowPathReturnType llint_trace_operand(ExecState*, Instruction*, int fromWhere, int operand);
44
extern "C" SlowPathReturnType llint_trace_value(ExecState*, Instruction*, int fromWhere, int operand);
45
46
#define LLINT_SLOW_PATH_DECL(name) \
47
    extern "C" SlowPathReturnType llint_##name(ExecState* exec, Instruction* pc)
48
49
LLINT_SLOW_PATH_DECL(trace_prologue);
50
LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call);
51
LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct);
52
LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call);
53
LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct);
54
LLINT_SLOW_PATH_DECL(trace);
55
LLINT_SLOW_PATH_DECL(special_trace);
56
LLINT_SLOW_PATH_DECL(entry_osr);
57
LLINT_SLOW_PATH_DECL(entry_osr_function_for_call);
58
LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct);
59
LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck);
60
LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck);
61
LLINT_SLOW_PATH_DECL(loop_osr);
62
LLINT_SLOW_PATH_DECL(replace);
63
LLINT_SLOW_PATH_DECL(register_file_check);
64
LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck);
65
LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck);
66
LLINT_SLOW_PATH_DECL(slow_path_create_activation);
67
LLINT_SLOW_PATH_DECL(slow_path_create_arguments);
68
LLINT_SLOW_PATH_DECL(slow_path_create_this);
69
LLINT_SLOW_PATH_DECL(slow_path_convert_this);
70
LLINT_SLOW_PATH_DECL(slow_path_new_object);
71
LLINT_SLOW_PATH_DECL(slow_path_new_array);
72
LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer);
73
LLINT_SLOW_PATH_DECL(slow_path_new_regexp);
74
LLINT_SLOW_PATH_DECL(slow_path_not);
75
LLINT_SLOW_PATH_DECL(slow_path_eq);
76
LLINT_SLOW_PATH_DECL(slow_path_neq);
77
LLINT_SLOW_PATH_DECL(slow_path_stricteq);
78
LLINT_SLOW_PATH_DECL(slow_path_nstricteq);
79
LLINT_SLOW_PATH_DECL(slow_path_less);
80
LLINT_SLOW_PATH_DECL(slow_path_lesseq);
81
LLINT_SLOW_PATH_DECL(slow_path_greater);
82
LLINT_SLOW_PATH_DECL(slow_path_greatereq);
83
LLINT_SLOW_PATH_DECL(slow_path_pre_inc);
84
LLINT_SLOW_PATH_DECL(slow_path_pre_dec);
85
LLINT_SLOW_PATH_DECL(slow_path_post_inc);
86
LLINT_SLOW_PATH_DECL(slow_path_post_dec);
87
LLINT_SLOW_PATH_DECL(slow_path_to_jsnumber);
88
LLINT_SLOW_PATH_DECL(slow_path_negate);
89
LLINT_SLOW_PATH_DECL(slow_path_add);
90
LLINT_SLOW_PATH_DECL(slow_path_mul);
91
LLINT_SLOW_PATH_DECL(slow_path_sub);
92
LLINT_SLOW_PATH_DECL(slow_path_div);
93
LLINT_SLOW_PATH_DECL(slow_path_mod);
94
LLINT_SLOW_PATH_DECL(slow_path_lshift);
95
LLINT_SLOW_PATH_DECL(slow_path_rshift);
96
LLINT_SLOW_PATH_DECL(slow_path_urshift);
97
LLINT_SLOW_PATH_DECL(slow_path_bitand);
98
LLINT_SLOW_PATH_DECL(slow_path_bitor);
99
LLINT_SLOW_PATH_DECL(slow_path_bitxor);
100
LLINT_SLOW_PATH_DECL(slow_path_bitnot);
101
LLINT_SLOW_PATH_DECL(slow_path_check_has_instance);
102
LLINT_SLOW_PATH_DECL(slow_path_instanceof);
103
LLINT_SLOW_PATH_DECL(slow_path_typeof);
104
LLINT_SLOW_PATH_DECL(slow_path_is_undefined);
105
LLINT_SLOW_PATH_DECL(slow_path_is_boolean);
106
LLINT_SLOW_PATH_DECL(slow_path_is_number);
107
LLINT_SLOW_PATH_DECL(slow_path_is_string);
108
LLINT_SLOW_PATH_DECL(slow_path_is_object);
109
LLINT_SLOW_PATH_DECL(slow_path_is_function);
110
LLINT_SLOW_PATH_DECL(slow_path_in);
111
LLINT_SLOW_PATH_DECL(slow_path_resolve);
112
LLINT_SLOW_PATH_DECL(slow_path_resolve_skip);
113
LLINT_SLOW_PATH_DECL(slow_path_resolve_global);
114
LLINT_SLOW_PATH_DECL(slow_path_resolve_global_dynamic);
115
LLINT_SLOW_PATH_DECL(slow_path_resolve_for_resolve_global_dynamic);
116
LLINT_SLOW_PATH_DECL(slow_path_resolve_base);
117
LLINT_SLOW_PATH_DECL(slow_path_ensure_property_exists);
118
LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base);
119
LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this);
120
LLINT_SLOW_PATH_DECL(slow_path_get_by_id);
121
LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length);
122
LLINT_SLOW_PATH_DECL(slow_path_put_by_id);
123
LLINT_SLOW_PATH_DECL(slow_path_del_by_id);
124
LLINT_SLOW_PATH_DECL(slow_path_get_by_val);
125
LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val);
126
LLINT_SLOW_PATH_DECL(slow_path_get_by_pname);
127
LLINT_SLOW_PATH_DECL(slow_path_put_by_val);
128
LLINT_SLOW_PATH_DECL(slow_path_del_by_val);
129
LLINT_SLOW_PATH_DECL(slow_path_put_by_index);
130
LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter);
131
LLINT_SLOW_PATH_DECL(slow_path_jmp_scopes);
132
LLINT_SLOW_PATH_DECL(slow_path_jtrue);
133
LLINT_SLOW_PATH_DECL(slow_path_jfalse);
134
LLINT_SLOW_PATH_DECL(slow_path_jless);
135
LLINT_SLOW_PATH_DECL(slow_path_jnless);
136
LLINT_SLOW_PATH_DECL(slow_path_jgreater);
137
LLINT_SLOW_PATH_DECL(slow_path_jngreater);
138
LLINT_SLOW_PATH_DECL(slow_path_jlesseq);
139
LLINT_SLOW_PATH_DECL(slow_path_jnlesseq);
140
LLINT_SLOW_PATH_DECL(slow_path_jgreatereq);
141
LLINT_SLOW_PATH_DECL(slow_path_jngreatereq);
142
LLINT_SLOW_PATH_DECL(slow_path_switch_imm);
143
LLINT_SLOW_PATH_DECL(slow_path_switch_char);
144
LLINT_SLOW_PATH_DECL(slow_path_switch_string);
145
LLINT_SLOW_PATH_DECL(slow_path_new_func);
146
LLINT_SLOW_PATH_DECL(slow_path_new_func_exp);
147
LLINT_SLOW_PATH_DECL(slow_path_call);
148
LLINT_SLOW_PATH_DECL(slow_path_construct);
149
LLINT_SLOW_PATH_DECL(slow_path_call_varargs);
150
LLINT_SLOW_PATH_DECL(slow_path_call_eval);
151
LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation);
152
LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments);
153
LLINT_SLOW_PATH_DECL(slow_path_strcat);
154
LLINT_SLOW_PATH_DECL(slow_path_to_primitive);
155
LLINT_SLOW_PATH_DECL(slow_path_get_pnames);
156
LLINT_SLOW_PATH_DECL(slow_path_next_pname);
157
LLINT_SLOW_PATH_DECL(slow_path_push_scope);
158
LLINT_SLOW_PATH_DECL(slow_path_pop_scope);
159
LLINT_SLOW_PATH_DECL(slow_path_push_new_scope);
160
LLINT_SLOW_PATH_DECL(slow_path_throw);
161
LLINT_SLOW_PATH_DECL(slow_path_throw_reference_error);
162
LLINT_SLOW_PATH_DECL(slow_path_debug);
163
LLINT_SLOW_PATH_DECL(slow_path_profile_will_call);
164
LLINT_SLOW_PATH_DECL(slow_path_profile_did_call);
165
166
} } // namespace JSC::LLInt
167
168
#endif // ENABLE(LLINT)
169
170
#endif // LLIntSlowPaths_h
171
- 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 +2390 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
# Below we have a bunch of constant declarations. Each constant must have
71
# a corresponding ASSERT() in LLIntData.cpp.
72
73
# These declarations must match interpreter/RegisterFile.h.
74
const CallFrameHeaderSize = 48
75
const ArgumentCount = -48
76
const CallerFrame = -40
77
const Callee = -32
78
const ScopeChain = -24
79
const ReturnPC = -16
80
const CodeBlock = -8
81
82
const ThisArgumentOffset = -CallFrameHeaderSize - 8
83
84
# Declare some aliases for the registers we will use.
85
const PC = t4
86
87
# Offsets needed for reasoning about value representation.
88
if BIG_ENDIAN
89
    const TagOffset = 0
90
    const PayloadOffset = 4
91
else
92
    const TagOffset = 4
93
    const PayloadOffset = 0
94
end
95
96
# Value representation constants.
97
const Int32Tag = -1
98
const BooleanTag = -2
99
const NullTag = -3
100
const UndefinedTag = -4
101
const CellTag = -5
102
const EmptyValueTag = -6
103
const DeletedValueTag = -7
104
const LowestTag = DeletedValueTag
105
106
# Type constants.
107
const StringType = 5
108
const ObjectType = 13
109
110
# Type flags constants.
111
const MasqueradesAsUndefined = 1
112
const ImplementsHasInstance = 2
113
const ImplementsDefaultHasInstance = 8
114
115
# Heap allocation constants.
116
const JSFinalObjectSizeClassIndex = 3
117
118
# Bytecode operand constants.
119
const FirstConstantRegisterIndex = 0x40000000
120
121
# Code type constants.
122
const GlobalCode = 0
123
const EvalCode = 1
124
const FunctionCode = 2
125
126
# The interpreter steals the tag word of the argument count.
127
const LLIntReturnPC = ArgumentCount + TagOffset
128
129
# This must match wtf/Vector.h.
130
const VectorSizeOffset = 0
131
const VectorBufferOffset = 4
132
133
# String flags.
134
const HashFlags8BitBuffer = 64
135
136
# Utilities
137
macro crash()
138
    storei 0, 0xbbadbeef[]
139
    move 0, t0
140
    call t0
141
end
142
143
macro assert(assertion)
144
    if ASSERT_ENABLED
145
        assertion(.ok)
146
        crash()
147
    .ok:
148
    end
149
end
150
151
macro preserveReturnAddressAfterCall(destinationRegister)
152
    if ARMv7
153
        move lr, destinationRegister
154
    elsif X86
155
        pop destinationRegister
156
    else
157
        error
158
    end
159
end
160
161
macro restoreReturnAddressBeforeReturn(sourceRegister)
162
    if ARMv7
163
        move sourceRegister, lr
164
    elsif X86
165
        push sourceRegister
166
    else
167
        error
168
    end
169
end
170
171
macro dispatch(advance)
172
    addp advance * 4, PC
173
    jmp [PC]
174
end
175
176
macro dispatchBranchWithOffset(pcOffset)
177
    lshifti 2, pcOffset
178
    addp pcOffset, PC
179
    jmp [PC]
180
end
181
182
macro dispatchBranch(pcOffset)
183
    loadi pcOffset, t0
184
    dispatchBranchWithOffset(t0)
185
end
186
187
macro dispatchAfterCall()
188
    loadi ArgumentCount + TagOffset[cfr], PC
189
    jmp [PC]
190
end
191
192
macro cCall2(function, arg1, arg2)
193
    if ARMv7
194
        move arg1, t0
195
        move arg2, t1
196
    elsif X86
197
        poke arg1, 0
198
        poke arg2, 1
199
    else
200
        error
201
    end
202
    call function
203
end
204
205
# This barely works. arg3 and arg4 should probably be immediates.
206
macro cCall4(function, arg1, arg2, arg3, arg4)
207
    if ARMv7
208
        move arg1, t0
209
        move arg2, t1
210
        move arg3, t2
211
        move arg4, t3
212
    elsif X86
213
        poke arg1, 0
214
        poke arg2, 1
215
        poke arg3, 2
216
        poke arg4, 3
217
    else
218
        error
219
    end
220
    call function
221
end
222
223
macro callSlowPath(slow_path)
224
    cCall2(slow_path, cfr, PC)
225
    move t0, PC
226
    move t1, cfr
227
end
228
229
# Debugging operation if you'd like to print an operand in the instruction stream. fromWhere
230
# should be an immediate integer - any integer you like; use it to identify the place you're
231
# debugging from. operand should likewise be an immediate, and should identify the operand
232
# in the instruction stream you'd like to print out.
233
macro traceOperand(fromWhere, operand)
234
    cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
235
    move t0, PC
236
    move t1, cfr
237
end
238
239
# Debugging operation if you'd like to print the value of an operand in the instruction
240
# stream. Same as traceOperand(), but assumes that the operand is a register, and prints its
241
# value.
242
macro traceValue(fromWhere, operand)
243
    cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
244
    move t0, PC
245
    move t1, cfr
246
end
247
248
macro traceExecution()
249
    if EXECUTION_TRACING
250
        callSlowPath(_llint_trace)
251
    end
252
end
253
254
# Call a slow_path for call opcodes.
255
macro callCallSlowPath(advance, slow_path, action)
256
    addp advance * 4, PC, t0
257
    storep t0, ArgumentCount + TagOffset[cfr]
258
    cCall2(slow_path, cfr, PC)
259
    move t1, cfr
260
    action(t0)
261
end
262
263
macro slowPathForCall(advance, slow_path)
264
    callCallSlowPath(
265
        advance,
266
        slow_path,
267
        macro (callee)
268
            call callee
269
            dispatchAfterCall()
270
        end)
271
end
272
273
macro checkSwitchToJIT(increment, action)
274
    if JIT_ENABLED
275
        loadp CodeBlock[cfr], t0
276
        baddis increment, CodeBlock::m_llintExecuteCounter[t0], .continue
277
        action()
278
    .continue:
279
    end
280
end
281
282
macro checkSwitchToJITForLoop()
283
    checkSwitchToJIT(
284
        1,
285
        macro ()
286
            storei PC, ArgumentCount + TagOffset[cfr]
287
            cCall2(_llint_loop_osr, cfr, PC)
288
            move t1, cfr
289
            btpz t0, .recover
290
            jmp t0
291
        .recover:
292
            loadi ArgumentCount + TagOffset[cfr], PC
293
        end)
294
end
295
296
macro checkSwitchToJITForEpilogue()
297
    checkSwitchToJIT(
298
        10,
299
        macro ()
300
            callSlowPath(_llint_replace)
301
        end)
302
end
303
304
macro assertNotConstant(index)
305
    assert(macro (ok) bilt index, FirstConstantRegisterIndex, ok end)
306
end
307
308
# Index, tag, and payload must be different registers. Index is not
309
# changed.
310
macro loadConstantOrVariable(index, tag, payload)
311
    bigteq index, FirstConstantRegisterIndex, .constant
312
    loadi TagOffset[cfr, index, 8], tag
313
    loadi PayloadOffset[cfr, index, 8], payload
314
    jmp .done
315
.constant:
316
    loadp CodeBlock[cfr], payload
317
    loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
318
    # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
319
    # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
320
    loadp TagOffset[payload, index, 8], tag
321
    loadp PayloadOffset[payload, index, 8], payload
322
.done:
323
end
324
325
# Index and payload may be the same register. Index may be clobbered.
326
macro loadConstantOrVariable2Reg(index, tag, payload)
327
    bigteq index, FirstConstantRegisterIndex, .constant
328
    loadi TagOffset[cfr, index, 8], tag
329
    loadi PayloadOffset[cfr, index, 8], payload
330
    jmp .done
331
.constant:
332
    loadp CodeBlock[cfr], tag
333
    loadp CodeBlock::m_constantRegisters + VectorBufferOffset[tag], tag
334
    # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
335
    # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
336
    lshifti 3, index
337
    addp index, tag
338
    loadp PayloadOffset[tag], payload
339
    loadp TagOffset[tag], tag
340
.done:
341
end
342
343
macro loadConstantOrVariablePayloadTagCustom(index, tagCheck, payload)
344
    bigteq index, FirstConstantRegisterIndex, .constant
345
    tagCheck(TagOffset[cfr, index, 8])
346
    loadi PayloadOffset[cfr, index, 8], payload
347
    jmp .done
348
.constant:
349
    loadp CodeBlock[cfr], payload
350
    loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
351
    # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
352
    # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
353
    tagCheck(TagOffset[payload, index, 8])
354
    loadp PayloadOffset[payload, index, 8], payload
355
.done:
356
end
357
358
# Index and payload must be different registers. Index is not mutated. Use
359
# this if you know what the tag of the variable should be. Doing the tag
360
# test as part of loading the variable reduces register use, but may not
361
# be faster than doing loadConstantOrVariable followed by a branch on the
362
# tag.
363
macro loadConstantOrVariablePayload(index, expectedTag, payload, slow)
364
    loadConstantOrVariablePayloadTagCustom(
365
        index,
366
        macro (actualTag) bineq actualTag, expectedTag, slow end,
367
        payload)
368
end
369
370
macro loadConstantOrVariablePayloadUnchecked(index, payload)
371
    loadConstantOrVariablePayloadTagCustom(
372
        index,
373
        macro (actualTag) end,
374
        payload)
375
end
376
377
macro writeBarrier(tag, payload)
378
    # Nothing to do, since we don't have a generational or incremental collector.
379
end
380
381
macro valueProfile(tag, payload, profile)
382
    if JIT_ENABLED
383
        storei tag, ValueProfile::m_buckets + TagOffset[profile]
384
        storei payload, ValueProfile::m_buckets + PayloadOffset[profile]
385
    end
386
end
387
388
389
# Indicate the beginning of LLInt.
390
_llint_begin:
391
    crash()
392
393
394
# Entrypoints into the interpreter
395
396
macro functionForCallCodeBlockGetter(targetRegister)
397
    loadp Callee[cfr], targetRegister
398
    loadp JSFunction::m_executable[targetRegister], targetRegister
399
    loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
400
end
401
402
macro functionForConstructCodeBlockGetter(targetRegister)
403
    loadp Callee[cfr], targetRegister
404
    loadp JSFunction::m_executable[targetRegister], targetRegister
405
    loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
406
end
407
408
macro notFunctionCodeBlockGetter(targetRegister)
409
    loadp CodeBlock[cfr], targetRegister
410
end
411
412
macro functionCodeBlockSetter(sourceRegister)
413
    storep sourceRegister, CodeBlock[cfr]
414
end
415
416
macro notFunctionCodeBlockSetter(sourceRegister)
417
    # Nothing to do!
418
end
419
420
# Do the bare minimum required to execute code. Sets up the PC, leave the CodeBlock*
421
# in t1. May also trigger prologue entry OSR.
422
macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
423
    preserveReturnAddressAfterCall(t2)
424
    
425
    # Set up the call frame and check if we should OSR.
426
    storep t2, ReturnPC[cfr]
427
    if EXECUTION_TRACING
428
        callSlowPath(traceSlowPath)
429
    end
430
    codeBlockGetter(t1)
431
    if JIT_ENABLED
432
        baddis 5, CodeBlock::m_llintExecuteCounter[t1], .continue
433
        cCall2(osrSlowPath, cfr, PC)
434
        move t1, cfr
435
        btpz t0, .recover
436
        loadp ReturnPC[cfr], t2
437
        restoreReturnAddressBeforeReturn(t2)
438
        jmp t0
439
    .recover:
440
        codeBlockGetter(t1)
441
    .continue:
442
    end
443
    codeBlockSetter(t1)
444
    
445
    # Set up the PC.
446
    loadp CodeBlock::m_instructions[t1], t0
447
    loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
448
end
449
450
# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
451
# Must call dispatch(0) after calling this.
452
macro functionInitialization(profileArgSkip)
453
    if JIT_ENABLED
454
        # Profile the arguments. Unfortunately, we have no choice but to do this. This
455
        # code is pretty horrendous because of the difference in ordering between
456
        # arguments and value profiles, the desire to have a simple loop-down-to-zero
457
        # loop, and the desire to use only three registers so as to preserve the PC and
458
        # the code block. It is likely that this code should be rewritten in a more
459
        # optimal way for architectures that have more than five registers available
460
        # for arbitrary use in the interpreter.
461
        loadi CodeBlock::m_numParameters[t1], t0
462
        addi -profileArgSkip, t0 # Use addi because that's what has the peephole
463
        assert(macro (ok) bigteq t0, 0, ok end)
464
        btiz t0, .argumentProfileDone
465
        loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
466
        muli sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
467
        negi t0
468
        lshifti 3, t0
469
        addp t2, t3
470
    .argumentProfileLoop:
471
        loadi ThisArgumentOffset + TagOffset + 8 - profileArgSkip * 8[cfr, t0], t2
472
        subp sizeof ValueProfile, t3
473
        storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
474
        loadi ThisArgumentOffset + PayloadOffset + 8 - profileArgSkip * 8[cfr, t0], t2
475
        storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
476
        baddinz 8, t0, .argumentProfileLoop
477
    .argumentProfileDone:
478
    end
479
        
480
    # Check stack height.
481
    loadi CodeBlock::m_numCalleeRegisters[t1], t0
482
    loadp CodeBlock::m_globalData[t1], t2
483
    loadp JSGlobalData::interpreter[t2], t2   # FIXME: Can get to the RegisterFile from the JITStackFrame
484
    lshifti 3, t0
485
    addp t0, cfr, t0
486
    bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK
487
488
    # Stack height check failed - need to call a slow_path.
489
    callSlowPath(_llint_register_file_check)
490
.stackHeightOK:
491
end
492
493
# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
494
macro functionArityCheck(doneLabel, slow_path)
495
    loadi PayloadOffset + ArgumentCount[cfr], t0
496
    biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
497
    cCall2(slow_path, cfr, PC)   # This slow_path has a simple protocol: t0 = 0 => no error, t0 != 0 => error
498
    move t1, cfr
499
    btiz t0, .continue
500
    loadp JITStackFrame::globalData[sp], t1
501
    loadp JSGlobalData::callFrameForThrow[t1], t0
502
    jmp JSGlobalData::targetMachinePCForThrow[t1]
503
.continue:
504
    # Reload CodeBlock and PC, since the slow_path clobbered it.
505
    loadp CodeBlock[cfr], t1
506
    loadp CodeBlock::m_instructions[t1], t0
507
    loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
508
    jmp doneLabel
509
end
510
511
_llint_program_prologue:
512
    prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
513
    dispatch(0)
514
515
516
_llint_eval_prologue:
517
    prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
518
    dispatch(0)
519
520
521
_llint_function_for_call_prologue:
522
    prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call)
523
.functionForCallBegin:
524
    functionInitialization(0)
525
    dispatch(0)
526
    
527
528
_llint_function_for_construct_prologue:
529
    prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct)
530
.functionForConstructBegin:
531
    functionInitialization(1)
532
    dispatch(0)
533
    
534
535
_llint_function_for_call_arity_check:
536
    prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call)
537
    functionArityCheck(.functionForCallBegin, _llint_slow_path_call_arityCheck)
538
539
540
_llint_function_for_construct_arity_check:
541
    prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct)
542
    functionArityCheck(.functionForConstructBegin, _llint_slow_path_construct_arityCheck)
543
544
# Instruction implementations
545
546
_llint_op_enter:
547
    traceExecution()
548
    loadp CodeBlock[cfr], t2
549
    loadi CodeBlock::m_numVars[t2], t2
550
    btiz t2, .opEnterDone
551
    move UndefinedTag, t0
552
    move 0, t1
553
.opEnterLoop:
554
    subi 1, t2
555
    storei t0, TagOffset[cfr, t2, 8]
556
    storei t1, PayloadOffset[cfr, t2, 8]
557
    btinz t2, .opEnterLoop
558
.opEnterDone:
559
    dispatch(1)
560
561
562
_llint_op_create_activation:
563
    traceExecution()
564
    loadi 4[PC], t0
565
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateActivationDone
566
    callSlowPath(_llint_slow_path_create_activation)
567
.opCreateActivationDone:
568
    dispatch(2)
569
570
571
_llint_op_init_lazy_reg:
572
    traceExecution()
573
    loadi 4[PC], t0
574
    storei EmptyValueTag, TagOffset[cfr, t0, 8]
575
    storei 0, PayloadOffset[cfr, t0, 8]
576
    dispatch(2)
577
578
579
_llint_op_create_arguments:
580
    traceExecution()
581
    loadi 4[PC], t0
582
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
583
    callSlowPath(_llint_slow_path_create_arguments)
584
.opCreateArgumentsDone:
585
    dispatch(2)
586
587
588
macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result, scratch1, scratch2, slowCase)
589
    if ALWAYS_ALLOCATE_SLOW
590
        jmp slowCase
591
    else
592
        const offsetOfMySizeClass =
593
            JSGlobalData::heap +
594
            Heap::m_objectSpace +
595
            MarkedSpace::m_normalSpace +
596
            MarkedSpace::Subspace::preciseAllocators +
597
            sizeClassIndex * sizeof MarkedAllocator
598
        
599
        # FIXME: we can get the global data in one load from the stack.
600
        loadp CodeBlock[cfr], scratch1
601
        loadp CodeBlock::m_globalData[scratch1], scratch1
602
        
603
        # Get the object from the free list.    
604
        loadp offsetOfMySizeClass + MarkedAllocator::m_firstFreeCell[scratch1], result
605
        btpz result, slowCase
606
        
607
        # Remove the object from the free list.
608
        loadp [result], scratch2
609
        storep scratch2, offsetOfMySizeClass + MarkedAllocator::m_firstFreeCell[scratch1]
610
    
611
        # Initialize the object.
612
        loadp classInfoOffset[scratch1], scratch2
613
        storep scratch2, [result]
614
        storep structure, JSCell::m_structure[result]
615
        storep 0, JSObject::m_inheritorID[result]
616
        addp sizeof JSObject, result, scratch1
617
        storep scratch1, JSObject::m_propertyStorage[result]
618
    end
619
end
620
621
_llint_op_create_this:
622
    traceExecution()
623
    loadi 8[PC], t0
624
    assertNotConstant(t0)
625
    bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow
626
    loadi PayloadOffset[cfr, t0, 8], t0
627
    loadp JSCell::m_structure[t0], t1
628
    bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
629
    loadp JSObject::m_inheritorID[t0], t2
630
    btpz t2, .opCreateThisSlow
631
    allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
632
    loadi 4[PC], t1
633
    storei CellTag, TagOffset[cfr, t1, 8]
634
    storei t0, PayloadOffset[cfr, t1, 8]
635
    dispatch(3)
636
637
.opCreateThisSlow:
638
    callSlowPath(_llint_slow_path_create_this)
639
    dispatch(3)
640
641
642
_llint_op_get_callee:
643
    traceExecution()
644
    loadi 4[PC], t0
645
    loadp PayloadOffset + Callee[cfr], t1
646
    storei CellTag, TagOffset[cfr, t0, 8]
647
    storei t1, PayloadOffset[cfr, t0, 8]
648
    dispatch(2)
649
650
651
_llint_op_convert_this:
652
    traceExecution()
653
    loadi 4[PC], t0
654
    bineq TagOffset[cfr, t0, 8], CellTag, .opConvertThisSlow
655
    loadi PayloadOffset[cfr, t0, 8], t0
656
    loadp JSCell::m_structure[t0], t0
657
    bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
658
    dispatch(2)
659
660
.opConvertThisSlow:
661
    callSlowPath(_llint_slow_path_convert_this)
662
    dispatch(2)
663
664
665
_llint_op_new_object:
666
    traceExecution()
667
    loadp CodeBlock[cfr], t0
668
    loadp CodeBlock::m_globalObject[t0], t0
669
    loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
670
    allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
671
    loadi 4[PC], t1
672
    storei CellTag, TagOffset[cfr, t1, 8]
673
    storei t0, PayloadOffset[cfr, t1, 8]
674
    dispatch(2)
675
676
.opNewObjectSlow:
677
    callSlowPath(_llint_slow_path_new_object)
678
    dispatch(2)
679
680
681
_llint_op_new_array:
682
    traceExecution()
683
    callSlowPath(_llint_slow_path_new_array)
684
    dispatch(4)
685
686
687
_llint_op_new_array_buffer:
688
    traceExecution()
689
    callSlowPath(_llint_slow_path_new_array_buffer)
690
    dispatch(4)
691
692
693
_llint_op_new_regexp:
694
    traceExecution()
695
    callSlowPath(_llint_slow_path_new_regexp)
696
    dispatch(3)
697
698
699
_llint_op_mov:
700
    traceExecution()
701
    loadi 8[PC], t1
702
    loadi 4[PC], t0
703
    loadConstantOrVariable(t1, t2, t3)
704
    storei t2, TagOffset[cfr, t0, 8]
705
    storei t3, PayloadOffset[cfr, t0, 8]
706
    dispatch(3)
707
708
709
_llint_op_not:
710
    traceExecution()
711
    loadi 8[PC], t0
712
    loadi 4[PC], t1
713
    loadConstantOrVariable(t0, t2, t3)
714
    bineq t2, BooleanTag, .opNotSlow
715
    xori 1, t3
716
    storei t2, TagOffset[cfr, t1, 8]
717
    storei t3, PayloadOffset[cfr, t1, 8]
718
    dispatch(3)
719
720
.opNotSlow:
721
    callSlowPath(_llint_slow_path_not)
722
    dispatch(3)
723
724
725
_llint_op_eq:
726
    traceExecution()
727
    loadi 12[PC], t2
728
    loadi 8[PC], t0
729
    loadConstantOrVariable(t2, t3, t1)
730
    loadConstantOrVariable2Reg(t0, t2, t0)
731
    bineq t2, t3, .opEqSlow
732
    bieq t2, CellTag, .opEqSlow
733
    bib t2, LowestTag, .opEqSlow
734
    loadi 4[PC], t2
735
    cieq t0, t1, t0
736
    storei BooleanTag, TagOffset[cfr, t2, 8]
737
    storei t0, PayloadOffset[cfr, t2, 8]
738
    dispatch(4)
739
740
.opEqSlow:
741
    callSlowPath(_llint_slow_path_eq)
742
    dispatch(4)
743
744
745
_llint_op_eq_null:
746
    traceExecution()
747
    loadi 8[PC], t0
748
    loadi 4[PC], t3
749
    assertNotConstant(t0)
750
    loadi TagOffset[cfr, t0, 8], t1
751
    loadi PayloadOffset[cfr, t0, 8], t0
752
    bineq t1, CellTag, .opEqNullImmediate
753
    loadp JSCell::m_structure[t0], t1
754
    tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
755
    jmp .opEqNullNotImmediate
756
.opEqNullImmediate:
757
    cieq t1, NullTag, t2
758
    cieq t1, UndefinedTag, t1
759
    ori t2, t1
760
.opEqNullNotImmediate:
761
    storei BooleanTag, TagOffset[cfr, t3, 8]
762
    storei t1, PayloadOffset[cfr, t3, 8]
763
    dispatch(3)
764
765
766
_llint_op_neq:
767
    traceExecution()
768
    loadi 12[PC], t2
769
    loadi 8[PC], t0
770
    loadConstantOrVariable(t2, t3, t1)
771
    loadConstantOrVariable2Reg(t0, t2, t0)
772
    bineq t2, t3, .opNeqSlow
773
    bieq t2, CellTag, .opNeqSlow
774
    bib t2, LowestTag, .opNeqSlow
775
    loadi 4[PC], t2
776
    cineq t0, t1, t0
777
    storei BooleanTag, TagOffset[cfr, t2, 8]
778
    storei t0, PayloadOffset[cfr, t2, 8]
779
    dispatch(4)
780
781
.opNeqSlow:
782
    callSlowPath(_llint_slow_path_neq)
783
    dispatch(4)
784
    
785
786
_llint_op_neq_null:
787
    traceExecution()
788
    loadi 8[PC], t0
789
    loadi 4[PC], t3
790
    assertNotConstant(t0)
791
    loadi TagOffset[cfr, t0, 8], t1
792
    loadi PayloadOffset[cfr, t0, 8], t0
793
    bineq t1, CellTag, .opNeqNullImmediate
794
    loadp JSCell::m_structure[t0], t1
795
    tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
796
    jmp .opNeqNullNotImmediate
797
.opNeqNullImmediate:
798
    cineq t1, NullTag, t2
799
    cineq t1, UndefinedTag, t1
800
    andi t2, t1
801
.opNeqNullNotImmediate:
802
    storei BooleanTag, TagOffset[cfr, t3, 8]
803
    storei t1, PayloadOffset[cfr, t3, 8]
804
    dispatch(3)
805
806
807
macro strictEq(equalityOperation, slow_path)
808
    loadi 12[PC], t2
809
    loadi 8[PC], t0
810
    loadConstantOrVariable(t2, t3, t1)
811
    loadConstantOrVariable2Reg(t0, t2, t0)
812
    bineq t2, t3, .slow
813
    bib t2, LowestTag, .slow
814
    bineq t2, CellTag, .notString
815
    loadp JSCell::m_structure[t0], t2
816
    loadp JSCell::m_structure[t1], t3
817
    bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .notString
818
    bbeq Structure::m_typeInfo + TypeInfo::m_type[t3], StringType, .slow
819
.notString:
820
    loadi 4[PC], t2
821
    equalityOperation(t0, t1, t0)
822
    storei BooleanTag, TagOffset[cfr, t2, 8]
823
    storei t0, PayloadOffset[cfr, t2, 8]
824
    dispatch(4)
825
826
.slow:
827
    callSlowPath(slow_path)
828
    dispatch(4)
829
end
830
831
_llint_op_stricteq:
832
    traceExecution()
833
    strictEq(macro (left, right, result) cieq left, right, result end, _llint_slow_path_stricteq)
834
835
836
_llint_op_nstricteq:
837
    traceExecution()
838
    strictEq(macro (left, right, result) cineq left, right, result end, _llint_slow_path_nstricteq)
839
840
841
_llint_op_less:
842
    traceExecution()
843
    callSlowPath(_llint_slow_path_less)
844
    dispatch(4)
845
846
847
_llint_op_lesseq:
848
    traceExecution()
849
    callSlowPath(_llint_slow_path_lesseq)
850
    dispatch(4)
851
852
853
_llint_op_greater:
854
    traceExecution()
855
    callSlowPath(_llint_slow_path_greater)
856
    dispatch(4)
857
858
859
_llint_op_greatereq:
860
    traceExecution()
861
    callSlowPath(_llint_slow_path_greatereq)
862
    dispatch(4)
863
864
865
_llint_op_pre_inc:
866
    traceExecution()
867
    loadi 4[PC], t0
868
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
869
    loadi PayloadOffset[cfr, t0, 8], t1
870
    baddio 1, t1, .opPreIncSlow
871
    storei t1, PayloadOffset[cfr, t0, 8]
872
    dispatch(2)
873
874
.opPreIncSlow:
875
    callSlowPath(_llint_slow_path_pre_inc)
876
    dispatch(2)
877
878
879
_llint_op_pre_dec:
880
    traceExecution()
881
    loadi 4[PC], t0
882
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
883
    loadi PayloadOffset[cfr, t0, 8], t1
884
    bsubio 1, t1, .opPreDecSlow
885
    storei t1, PayloadOffset[cfr, t0, 8]
886
    dispatch(2)
887
888
.opPreDecSlow:
889
    callSlowPath(_llint_slow_path_pre_dec)
890
    dispatch(2)
891
892
893
_llint_op_post_inc:
894
    traceExecution()
895
    loadi 8[PC], t0
896
    loadi 4[PC], t1
897
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
898
    bieq t0, t1, .opPostIncDone
899
    loadi PayloadOffset[cfr, t0, 8], t2
900
    move t2, t3
901
    baddio 1, t3, .opPostIncSlow
902
    storei Int32Tag, TagOffset[cfr, t1, 8]
903
    storei t2, PayloadOffset[cfr, t1, 8]
904
    storei t3, PayloadOffset[cfr, t0, 8]
905
.opPostIncDone:
906
    dispatch(3)
907
908
.opPostIncSlow:
909
    callSlowPath(_llint_slow_path_post_inc)
910
    dispatch(3)
911
912
913
_llint_op_post_dec:
914
    traceExecution()
915
    loadi 8[PC], t0
916
    loadi 4[PC], t1
917
    bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
918
    bieq t0, t1, .opPostDecDone
919
    loadi PayloadOffset[cfr, t0, 8], t2
920
    move t2, t3
921
    bsubio 1, t3, .opPostDecSlow
922
    storei Int32Tag, TagOffset[cfr, t1, 8]
923
    storei t2, PayloadOffset[cfr, t1, 8]
924
    storei t3, PayloadOffset[cfr, t0, 8]
925
.opPostDecDone:
926
    dispatch(3)
927
928
.opPostDecSlow:
929
    callSlowPath(_llint_slow_path_post_dec)
930
    dispatch(3)
931
932
933
_llint_op_to_jsnumber:
934
    traceExecution()
935
    loadi 8[PC], t0
936
    loadi 4[PC], t1
937
    loadConstantOrVariable(t0, t2, t3)
938
    bieq t2, Int32Tag, .opToJsnumberIsInt
939
    biaeq t2, EmptyValueTag, .opToJsnumberSlow
940
.opToJsnumberIsInt:
941
    storei t2, TagOffset[cfr, t1, 8]
942
    storei t3, PayloadOffset[cfr, t1, 8]
943
    dispatch(3)
944
945
.opToJsnumberSlow:
946
    callSlowPath(_llint_slow_path_to_jsnumber)
947
    dispatch(3)
948
949
950
_llint_op_negate:
951
    traceExecution()
952
    loadi 8[PC], t0
953
    loadi 4[PC], t3
954
    loadConstantOrVariable(t0, t1, t2)
955
    bineq t1, Int32Tag, .opNegateSrcNotInt
956
    btiz t2, 0x7fffffff, .opNegateSlow
957
    negi t2
958
    storei Int32Tag, TagOffset[cfr, t3, 8]
959
    storei t2, PayloadOffset[cfr, t3, 8]
960
    dispatch(3)
961
.opNegateSrcNotInt:
962
    bia t1, LowestTag, .opNegateSlow
963
    xori 0x80000000, t1
964
    storei t1, TagOffset[cfr, t3, 8]
965
    storei t2, PayloadOffset[cfr, t3, 8]
966
    dispatch(3)
967
968
.opNegateSlow:
969
    callSlowPath(_llint_slow_path_negate)
970
    dispatch(3)
971
972
973
macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slow_path)
974
    loadi 12[PC], t2
975
    loadi 8[PC], t0
976
    loadConstantOrVariable(t2, t3, t1)
977
    loadConstantOrVariable2Reg(t0, t2, t0)
978
    bineq t2, Int32Tag, .op1NotInt
979
    bineq t3, Int32Tag, .op2NotInt
980
    loadi 4[PC], t2
981
    integerOperationAndStore(t3, t1, t0, .slow, t2)
982
    dispatch(5)
983
984
.op1NotInt:
985
    # First operand is definitely not an int, the second operand could be anything.
986
    bia t2, LowestTag, .slow
987
    bib t3, LowestTag, .op1NotIntOp2Double
988
    bineq t3, Int32Tag, .slow
989
    ci2d t1, ft1
990
    jmp .op1NotIntReady
991
.op1NotIntOp2Double:
992
    fii2d t1, t3, ft1
993
.op1NotIntReady:
994
    loadi 4[PC], t1
995
    fii2d t0, t2, ft0
996
    doubleOperation(ft1, ft0)
997
    stored ft0, [cfr, t1, 8]
998
    dispatch(5)
999
1000
.op2NotInt:
1001
    # First operand is definitely an int, the second operand is definitely not.
1002
    loadi 4[PC], t2
1003
    bia t3, LowestTag, .slow
1004
    ci2d t0, ft0
1005
    fii2d t1, t3, ft1
1006
    doubleOperation(ft1, ft0)
1007
    stored ft0, [cfr, t2, 8]
1008
    dispatch(5)
1009
1010
.slow:
1011
    callSlowPath(slow_path)
1012
    dispatch(5)
1013
end
1014
1015
macro binaryOp(integerOperation, doubleOperation, slow_path)
1016
    binaryOpCustomStore(
1017
        macro (int32Tag, left, right, slow, index)
1018
            integerOperation(left, right, slow)
1019
            storei int32Tag, TagOffset[cfr, index, 8]
1020
            storei right, PayloadOffset[cfr, index, 8]
1021
        end,
1022
        doubleOperation, slow_path)
1023
end
1024
1025
_llint_op_add:
1026
    traceExecution()
1027
    binaryOp(
1028
        macro (left, right, slow) baddio left, right, slow end,
1029
        macro (left, right) addd left, right end,
1030
        _llint_slow_path_add)
1031
1032
1033
_llint_op_mul:
1034
    traceExecution()
1035
    binaryOpCustomStore(
1036
        macro (int32Tag, left, right, slow, index)
1037
            const scratch = int32Tag   # We know that we can reuse the int32Tag register since it has a constant.
1038
            move right, scratch
1039
            bmulio left, scratch, slow
1040
            btinz scratch, .done
1041
            bilt left, 0, slow
1042
            bilt right, 0, slow
1043
        .done:
1044
            storei Int32Tag, TagOffset[cfr, index, 8]
1045
            storei scratch, PayloadOffset[cfr, index, 8]
1046
        end,
1047
        macro (left, right) muld left, right end,
1048
        _llint_slow_path_mul)
1049
1050
1051
_llint_op_sub:
1052
    traceExecution()
1053
    binaryOp(
1054
        macro (left, right, slow) bsubio left, right, slow end,
1055
        macro (left, right) subd left, right end,
1056
        _llint_slow_path_sub)
1057
1058
1059
_llint_op_div:
1060
    traceExecution()
1061
    binaryOpCustomStore(
1062
        macro (int32Tag, left, right, slow, index)
1063
            ci2d left, ft0
1064
            ci2d right, ft1
1065
            divd ft0, ft1
1066
            bcd2i ft1, right, .notInt
1067
            storei int32Tag, TagOffset[cfr, index, 8]
1068
            storei right, PayloadOffset[cfr, index, 8]
1069
            jmp .done
1070
        .notInt:
1071
            stored ft1, [cfr, index, 8]
1072
        .done:
1073
        end,
1074
        macro (left, right) divd left, right end,
1075
        _llint_slow_path_div)
1076
1077
1078
_llint_op_mod:
1079
    traceExecution()
1080
    callSlowPath(_llint_slow_path_mod)
1081
    dispatch(4)
1082
1083
1084
macro bitOp(operation, slow_path, advance)
1085
    loadi 12[PC], t2
1086
    loadi 8[PC], t0
1087
    loadConstantOrVariable(t2, t3, t1)
1088
    loadConstantOrVariable2Reg(t0, t2, t0)
1089
    bineq t3, Int32Tag, .slow
1090
    bineq t2, Int32Tag, .slow
1091
    loadi 4[PC], t2
1092
    operation(t1, t0, .slow)
1093
    storei t3, TagOffset[cfr, t2, 8]
1094
    storei t0, PayloadOffset[cfr, t2, 8]
1095
    dispatch(advance)
1096
1097
.slow:
1098
    callSlowPath(slow_path)
1099
    dispatch(advance)
1100
end
1101
1102
_llint_op_lshift:
1103
    traceExecution()
1104
    bitOp(
1105
        macro (left, right, slow) lshifti left, right end,
1106
        _llint_slow_path_lshift,
1107
        4)
1108
1109
1110
_llint_op_rshift:
1111
    traceExecution()
1112
    bitOp(
1113
        macro (left, right, slow) rshifti left, right end,
1114
        _llint_slow_path_rshift,
1115
        4)
1116
1117
1118
_llint_op_urshift:
1119
    traceExecution()
1120
    bitOp(
1121
        macro (left, right, slow)
1122
            urshifti left, right
1123
            bilt right, 0, slow
1124
        end,
1125
        _llint_slow_path_urshift,
1126
        4)
1127
1128
1129
_llint_op_bitand:
1130
    traceExecution()
1131
    bitOp(
1132
        macro (left, right, slow) andi left, right end,
1133
        _llint_slow_path_bitand,
1134
        5)
1135
1136
1137
_llint_op_bitxor:
1138
    traceExecution()
1139
    bitOp(
1140
        macro (left, right, slow) xori left, right end,
1141
        _llint_slow_path_bitxor,
1142
        5)
1143
1144
1145
_llint_op_bitor:
1146
    traceExecution()
1147
    bitOp(
1148
        macro (left, right, slow) ori left, right end,
1149
        _llint_slow_path_bitor,
1150
        5)
1151
1152
1153
_llint_op_bitnot:
1154
    traceExecution()
1155
    loadi 8[PC], t1
1156
    loadi 4[PC], t0
1157
    loadConstantOrVariable(t1, t2, t3)
1158
    bineq t2, Int32Tag, .opBitnotSlow
1159
    noti t3
1160
    storei t2, TagOffset[cfr, t0, 8]
1161
    storei t3, PayloadOffset[cfr, t0, 8]
1162
    dispatch(3)
1163
1164
.opBitnotSlow:
1165
    callSlowPath(_llint_slow_path_bitnot)
1166
    dispatch(3)
1167
1168
1169
_llint_op_check_has_instance:
1170
    traceExecution()
1171
    loadi 4[PC], t1
1172
    loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
1173
    loadp JSCell::m_structure[t0], t0
1174
    btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
1175
    dispatch(2)
1176
1177
.opCheckHasInstanceSlow:
1178
    callSlowPath(_llint_slow_path_check_has_instance)
1179
    dispatch(2)
1180
1181
1182
_llint_op_instanceof:
1183
    traceExecution()
1184
    # Check that baseVal implements the default HasInstance behavior.
1185
    # FIXME: This should be deprecated.
1186
    loadi 12[PC], t1
1187
    loadConstantOrVariablePayloadUnchecked(t1, t0)
1188
    loadp JSCell::m_structure[t0], t0
1189
    btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
1190
    
1191
    # Actually do the work.
1192
    loadi 16[PC], t0
1193
    loadi 4[PC], t3
1194
    loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
1195
    loadp JSCell::m_structure[t1], t2
1196
    bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
1197
    loadi 8[PC], t0
1198
    loadConstantOrVariablePayload(t0, CellTag, t2, .opInstanceofSlow)
1199
    
1200
    # Register state: t1 = prototype, t2 = value
1201
    move 1, t0
1202
.opInstanceofLoop:
1203
    loadp JSCell::m_structure[t2], t2
1204
    loadi Structure::m_prototype + PayloadOffset[t2], t2
1205
    bpeq t2, t1, .opInstanceofDone
1206
    btinz t2, .opInstanceofLoop
1207
1208
    move 0, t0
1209
.opInstanceofDone:
1210
    storei BooleanTag, TagOffset[cfr, t3, 8]
1211
    storei t0, PayloadOffset[cfr, t3, 8]
1212
    dispatch(5)
1213
1214
.opInstanceofSlow:
1215
    callSlowPath(_llint_slow_path_instanceof)
1216
    dispatch(5)
1217
1218
1219
_llint_op_typeof:
1220
    traceExecution()
1221
    callSlowPath(_llint_slow_path_typeof)
1222
    dispatch(3)
1223
1224
1225
_llint_op_is_undefined:
1226
    traceExecution()
1227
    callSlowPath(_llint_slow_path_is_undefined)
1228
    dispatch(3)
1229
1230
1231
_llint_op_is_boolean:
1232
    traceExecution()
1233
    callSlowPath(_llint_slow_path_is_boolean)
1234
    dispatch(3)
1235
1236
1237
_llint_op_is_number:
1238
    traceExecution()
1239
    callSlowPath(_llint_slow_path_is_number)
1240
    dispatch(3)
1241
1242
1243
_llint_op_is_string:
1244
    traceExecution()
1245
    callSlowPath(_llint_slow_path_is_string)
1246
    dispatch(3)
1247
1248
1249
_llint_op_is_object:
1250
    traceExecution()
1251
    callSlowPath(_llint_slow_path_is_object)
1252
    dispatch(3)
1253
1254
1255
_llint_op_is_function:
1256
    traceExecution()
1257
    callSlowPath(_llint_slow_path_is_function)
1258
    dispatch(3)
1259
1260
1261
_llint_op_in:
1262
    traceExecution()
1263
    callSlowPath(_llint_slow_path_in)
1264
    dispatch(4)
1265
1266
1267
_llint_op_resolve:
1268
    traceExecution()
1269
    callSlowPath(_llint_slow_path_resolve)
1270
    dispatch(4)
1271
1272
1273
_llint_op_resolve_skip:
1274
    traceExecution()
1275
    callSlowPath(_llint_slow_path_resolve_skip)
1276
    dispatch(5)
1277
1278
1279
macro resolveGlobal(size, slow)
1280
    # Operands are as follows:
1281
    # 4[PC]   Destination for the load.
1282
    # 8[PC]   Property identifier index in the code block.
1283
    # 12[PC]  Structure pointer, initialized to 0 by bytecode generator.
1284
    # 16[PC]  Offset in global object, initialized to 0 by bytecode generator.
1285
    loadp CodeBlock[cfr], t0
1286
    loadp CodeBlock::m_globalObject[t0], t0
1287
    loadp JSCell::m_structure[t0], t1
1288
    bpneq t1, 12[PC], slow
1289
    loadi 16[PC], t1
1290
    loadp JSObject::m_propertyStorage[t0], t0
1291
    loadi TagOffset[t0, t1, 8], t2
1292
    loadi PayloadOffset[t0, t1, 8], t3
1293
    loadi 4[PC], t0
1294
    storei t2, TagOffset[cfr, t0, 8]
1295
    storei t3, PayloadOffset[cfr, t0, 8]
1296
    loadi (size - 1) * 4[PC], t0
1297
    valueProfile(t2, t3, t0)
1298
end
1299
1300
_llint_op_resolve_global:
1301
    traceExecution()
1302
    resolveGlobal(6, .opResolveGlobalSlow)
1303
    dispatch(6)
1304
1305
.opResolveGlobalSlow:
1306
    callSlowPath(_llint_slow_path_resolve_global)
1307
    dispatch(6)
1308
1309
1310
# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
1311
# scopes as they are traversed. scopeCheck() is called with two arguments: the register
1312
# holding the scope, and a register that can be used for scratch. Note that this does not
1313
# use t3, so you can hold stuff in t3 if need be.
1314
macro getScope(deBruijinIndexOperand, scopeCheck)
1315
    loadp ScopeChain + PayloadOffset[cfr], t0
1316
    loadi deBruijinIndexOperand, t2
1317
    
1318
    btiz t2, .done
1319
    
1320
    loadp CodeBlock[cfr], t1
1321
    bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
1322
    btbz CodeBlock::m_needsFullScopeChain[t1], .loop
1323
    
1324
    loadi CodeBlock::m_activationRegister[t1], t1
1325
1326
    # Need to conditionally skip over one scope.
1327
    bieq TagOffset[cfr, t1, 8], EmptyValueTag, .noActivation
1328
    scopeCheck(t0, t1)
1329
    loadp ScopeChainNode::next[t0], t0
1330
.noActivation:
1331
    subi 1, t2
1332
    
1333
    btiz t2, .done
1334
.loop:
1335
    scopeCheck(t0, t1)
1336
    loadp ScopeChainNode::next[t0], t0
1337
    subi 1, t2
1338
    btinz t2, .loop
1339
1340
.done:
1341
end
1342
1343
_llint_op_resolve_global_dynamic:
1344
    traceExecution()
1345
    loadp JITStackFrame::globalData[sp], t3
1346
    loadp JSGlobalData::activationStructure[t3], t3
1347
    getScope(
1348
        20[PC],
1349
        macro (scope, scratch)
1350
            loadp ScopeChainNode::object[scope], scratch
1351
            bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
1352
        end)
1353
    resolveGlobal(7, .opResolveGlobalDynamicSlow)
1354
    dispatch(7)
1355
1356
.opResolveGlobalDynamicSuperSlow:
1357
    callSlowPath(_llint_slow_path_resolve_for_resolve_global_dynamic)
1358
    dispatch(7)
1359
1360
.opResolveGlobalDynamicSlow:
1361
    callSlowPath(_llint_slow_path_resolve_global_dynamic)
1362
    dispatch(7)
1363
1364
1365
_llint_op_get_scoped_var:
1366
    traceExecution()
1367
    # Operands are as follows:
1368
    # 4[PC]   Destination for the load.
1369
    # 8[PC]   Index of register in the scope.
1370
    # 12[PC]  De Bruijin index.
1371
    getScope(12[PC], macro (scope, scratch) end)
1372
    loadi 4[PC], t1
1373
    loadi 8[PC], t2
1374
    loadp ScopeChainNode::object[t0], t0
1375
    loadp JSVariableObject::m_registers[t0], t0
1376
    loadi TagOffset[t0, t2, 8], t3
1377
    loadi PayloadOffset[t0, t2, 8], t0
1378
    storei t3, TagOffset[cfr, t1, 8]
1379
    storei t0, PayloadOffset[cfr, t1, 8]
1380
    loadi 16[PC], t1
1381
    valueProfile(t3, t0, t1)
1382
    dispatch(5)
1383
1384
1385
_llint_op_put_scoped_var:
1386
    traceExecution()
1387
    getScope(8[PC], macro (scope, scratch) end)
1388
    loadi 12[PC], t1
1389
    loadConstantOrVariable(t1, t3, t2)
1390
    loadi 4[PC], t1
1391
    writeBarrier(t3, t2)
1392
    loadp ScopeChainNode::object[t0], t0
1393
    loadp JSVariableObject::m_registers[t0], t0
1394
    storei t3, TagOffset[t0, t1, 8]
1395
    storei t2, PayloadOffset[t0, t1, 8]
1396
    dispatch(4)
1397
1398
1399
_llint_op_get_global_var:
1400
    traceExecution()
1401
    loadi 8[PC], t1
1402
    loadi 4[PC], t3
1403
    loadp CodeBlock[cfr], t0
1404
    loadp CodeBlock::m_globalObject[t0], t0
1405
    loadp JSGlobalObject::m_registers[t0], t0
1406
    loadi TagOffset[t0, t1, 8], t2
1407
    loadi PayloadOffset[t0, t1, 8], t1
1408
    storei t2, TagOffset[cfr, t3, 8]
1409
    storei t1, PayloadOffset[cfr, t3, 8]
1410
    loadi 12[PC], t3
1411
    valueProfile(t2, t1, t3)
1412
    dispatch(4)
1413
1414
1415
_llint_op_put_global_var:
1416
    traceExecution()
1417
    loadi 8[PC], t1
1418
    loadp CodeBlock[cfr], t0
1419
    loadp CodeBlock::m_globalObject[t0], t0
1420
    loadp JSGlobalObject::m_registers[t0], t0
1421
    loadConstantOrVariable(t1, t2, t3)
1422
    loadi 4[PC], t1
1423
    writeBarrier(t2, t3)
1424
    storei t2, TagOffset[t0, t1, 8]
1425
    storei t3, PayloadOffset[t0, t1, 8]
1426
    dispatch(3)
1427
1428
1429
_llint_op_resolve_base:
1430
    traceExecution()
1431
    callSlowPath(_llint_slow_path_resolve_base)
1432
    dispatch(5)
1433
1434
1435
_llint_op_ensure_property_exists:
1436
    traceExecution()
1437
    callSlowPath(_llint_slow_path_ensure_property_exists)
1438
    dispatch(3)
1439
1440
1441
_llint_op_resolve_with_base:
1442
    traceExecution()
1443
    callSlowPath(_llint_slow_path_resolve_with_base)
1444
    dispatch(5)
1445
1446
1447
_llint_op_resolve_with_this:
1448
    traceExecution()
1449
    callSlowPath(_llint_slow_path_resolve_with_this)
1450
    dispatch(5)
1451
1452
1453
_llint_op_get_by_id:
1454
    traceExecution()
1455
    # We only do monomorphic get_by_id caching for now, and we do not modify the
1456
    # opcode. We do, however, allow for the cache to change anytime if fails, since
1457
    # ping-ponging is free. At best we get lucky and the get_by_id will continue
1458
    # to take fast path on the new cache. At worst we take slow path, which is what
1459
    # we would have been doing anyway.
1460
    loadi 8[PC], t0
1461
    loadi 16[PC], t1
1462
    loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
1463
    loadi 20[PC], t2
1464
    loadp JSObject::m_propertyStorage[t3], t0
1465
    bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
1466
    loadi 4[PC], t1
1467
    loadi TagOffset[t0, t2], t3
1468
    loadi PayloadOffset[t0, t2], t2
1469
    storei t3, TagOffset[cfr, t1, 8]
1470
    storei t2, PayloadOffset[cfr, t1, 8]
1471
    loadi 32[PC], t1
1472
    valueProfile(t3, t2, t1)
1473
    dispatch(9)
1474
1475
.opGetByIdSlow:
1476
    callSlowPath(_llint_slow_path_get_by_id)
1477
    dispatch(9)
1478
1479
1480
_llint_op_get_arguments_length:
1481
    traceExecution()
1482
    loadi 8[PC], t0
1483
    loadi 4[PC], t1
1484
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
1485
    loadi ArgumentCount + PayloadOffset[cfr], t2
1486
    subi 1, t2
1487
    storei Int32Tag, TagOffset[cfr, t1, 8]
1488
    storei t2, PayloadOffset[cfr, t1, 8]
1489
    dispatch(4)
1490
1491
.opGetArgumentsLengthSlow:
1492
    callSlowPath(_llint_slow_path_get_arguments_length)
1493
    dispatch(4)
1494
1495
1496
_llint_op_put_by_id:
1497
    traceExecution()
1498
    loadi 4[PC], t3
1499
    loadi 16[PC], t1
1500
    loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
1501
    loadi 12[PC], t2
1502
    loadp JSObject::m_propertyStorage[t0], t3
1503
    bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
1504
    loadi 20[PC], t1
1505
    loadConstantOrVariable2Reg(t2, t0, t2)
1506
    writeBarrier(t0, t2)
1507
    storei t0, TagOffset[t3, t1]
1508
    storei t2, PayloadOffset[t3, t1]
1509
    dispatch(9)
1510
1511
.opPutByIdSlow:
1512
    callSlowPath(_llint_slow_path_put_by_id)
1513
    dispatch(9)
1514
1515
1516
macro putByIdTransition(additionalChecks)
1517
    traceExecution()
1518
    loadi 4[PC], t3
1519
    loadi 16[PC], t1
1520
    loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
1521
    loadi 12[PC], t2
1522
    bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
1523
    additionalChecks(t1, t3, .opPutByIdSlow)
1524
    loadi 20[PC], t1
1525
    loadp JSObject::m_propertyStorage[t0], t3
1526
    addp t1, t3
1527
    loadConstantOrVariable2Reg(t2, t1, t2)
1528
    writeBarrier(t1, t2)
1529
    storei t1, TagOffset[t3]
1530
    loadi 24[PC], t1
1531
    storei t2, PayloadOffset[t3]
1532
    storep t1, JSCell::m_structure[t0]
1533
    dispatch(9)
1534
end
1535
1536
_llint_op_put_by_id_transition_direct:
1537
    putByIdTransition(macro (oldStructure, scratch, slow) end)
1538
1539
1540
_llint_op_put_by_id_transition_normal:
1541
    putByIdTransition(
1542
        macro (oldStructure, scratch, slow)
1543
            const protoCell = oldStructure   # Reusing the oldStructure register for the proto
1544
        
1545
            loadp 28[PC], scratch
1546
            assert(macro (ok) btpnz scratch, ok end)
1547
            loadp StructureChain::m_vector[scratch], scratch
1548
            assert(macro (ok) btpnz scratch, ok end)
1549
            bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
1550
        .loop:
1551
            loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
1552
            loadp JSCell::m_structure[protoCell], oldStructure
1553
            bpneq oldStructure, [scratch], slow
1554
            addp 4, scratch
1555
            bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
1556
        .done:
1557
        end)
1558
1559
1560
_llint_op_del_by_id:
1561
    traceExecution()
1562
    callSlowPath(_llint_slow_path_del_by_id)
1563
    dispatch(4)
1564
1565
1566
_llint_op_get_by_val:
1567
    traceExecution()
1568
    loadp CodeBlock[cfr], t1
1569
    loadi 8[PC], t2
1570
    loadi 12[PC], t3
1571
    loadp CodeBlock::m_globalData[t1], t1
1572
    loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
1573
    loadp JSGlobalData::jsArrayClassInfo[t1], t2
1574
    loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
1575
    bpneq [t0], t2, .opGetByValSlow
1576
    loadp JSArray::m_storage[t0], t3
1577
    biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
1578
    loadi 4[PC], t0
1579
    loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
1580
    loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
1581
    bieq t2, EmptyValueTag, .opGetByValSlow
1582
    storei t2, TagOffset[cfr, t0, 8]
1583
    storei t1, PayloadOffset[cfr, t0, 8]
1584
    loadi 16[PC], t0
1585
    valueProfile(t2, t1, t0)
1586
    dispatch(5)
1587
1588
.opGetByValSlow:
1589
    callSlowPath(_llint_slow_path_get_by_val)
1590
    dispatch(5)
1591
1592
1593
_llint_op_get_argument_by_val:
1594
    traceExecution()
1595
    loadi 8[PC], t0
1596
    loadi 12[PC], t1
1597
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
1598
    loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
1599
    addi 1, t2
1600
    loadi ArgumentCount + PayloadOffset[cfr], t1
1601
    biaeq t2, t1, .opGetArgumentByValSlow
1602
    negi t2
1603
    loadi 4[PC], t3
1604
    loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
1605
    loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1
1606
    storei t0, TagOffset[cfr, t3, 8]
1607
    storei t1, PayloadOffset[cfr, t3, 8]
1608
    dispatch(5)
1609
1610
.opGetArgumentByValSlow:
1611
    callSlowPath(_llint_slow_path_get_argument_by_val)
1612
    dispatch(5)
1613
1614
1615
_llint_op_get_by_pname:
1616
    traceExecution()
1617
    loadi 12[PC], t0
1618
    loadConstantOrVariablePayload(t0, CellTag, t1, .opGetByPnameSlow)
1619
    loadi 16[PC], t0
1620
    bpneq t1, PayloadOffset[cfr, t0, 8], .opGetByPnameSlow
1621
    loadi 8[PC], t0
1622
    loadConstantOrVariablePayload(t0, CellTag, t2, .opGetByPnameSlow)
1623
    loadi 20[PC], t0
1624
    loadi PayloadOffset[cfr, t0, 8], t3
1625
    loadp JSCell::m_structure[t2], t0
1626
    bpneq t0, JSPropertyNameIterator::m_cachedStructure[t3], .opGetByPnameSlow
1627
    loadi 24[PC], t0
1628
    loadi [cfr, t0, 8], t0
1629
    subi 1, t0
1630
    biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
1631
    loadp JSObject::m_propertyStorage[t2], t2
1632
    loadi TagOffset[t2, t0, 8], t1
1633
    loadi PayloadOffset[t2, t0, 8], t3
1634
    loadi 4[PC], t0
1635
    storei t1, TagOffset[cfr, t0, 8]
1636
    storei t3, PayloadOffset[cfr, t0, 8]
1637
    dispatch(7)
1638
1639
.opGetByPnameSlow:
1640
    callSlowPath(_llint_slow_path_get_by_pname)
1641
    dispatch(7)
1642
1643
1644
_llint_op_put_by_val:
1645
    traceExecution()
1646
    loadi 4[PC], t0
1647
    loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
1648
    loadi 8[PC], t0
1649
    loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
1650
    loadp CodeBlock[cfr], t0
1651
    loadp CodeBlock::m_globalData[t0], t0
1652
    loadp JSGlobalData::jsArrayClassInfo[t0], t0
1653
    bpneq [t1], t0, .opPutByValSlow
1654
    biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
1655
    loadp JSArray::m_storage[t1], t0
1656
    bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
1657
.opPutByValStoreResult:
1658
    loadi 12[PC], t3
1659
    loadConstantOrVariable2Reg(t3, t1, t3)
1660
    writeBarrier(t1, t3)
1661
    storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
1662
    storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
1663
    dispatch(4)
1664
1665
.opPutByValEmpty:
1666
    addi 1, ArrayStorage::m_numValuesInVector[t0]
1667
    bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
1668
    addi 1, t2, t1
1669
    storei t1, ArrayStorage::m_length[t0]
1670
    jmp .opPutByValStoreResult
1671
1672
.opPutByValSlow:
1673
    callSlowPath(_llint_slow_path_put_by_val)
1674
    dispatch(4)
1675
1676
1677
_llint_op_del_by_val:
1678
    traceExecution()
1679
    callSlowPath(_llint_slow_path_del_by_val)
1680
    dispatch(4)
1681
1682
1683
_llint_op_put_by_index:
1684
    traceExecution()
1685
    callSlowPath(_llint_slow_path_put_by_index)
1686
    dispatch(4)
1687
1688
1689
_llint_op_put_getter_setter:
1690
    traceExecution()
1691
    callSlowPath(_llint_slow_path_put_getter_setter)
1692
    dispatch(5)
1693
1694
1695
_llint_op_loop:
1696
    nop
1697
_llint_op_jmp:
1698
    traceExecution()
1699
    dispatchBranch(4[PC])
1700
1701
1702
_llint_op_jmp_scopes:
1703
    traceExecution()
1704
    callSlowPath(_llint_slow_path_jmp_scopes)
1705
    dispatch(0)
1706
1707
1708
macro jumpTrueOrFalse(conditionOp, slow)
1709
    loadi 4[PC], t1
1710
    loadConstantOrVariablePayload(t1, BooleanTag, t0, .slow)
1711
    conditionOp(t0, .target)
1712
    dispatch(3)
1713
1714
.target:
1715
    dispatchBranch(8[PC])
1716
1717
.slow:
1718
    callSlowPath(slow)
1719
    dispatch(0)
1720
end
1721
1722
_llint_op_loop_if_true:
1723
    nop
1724
_llint_op_jtrue:
1725
    traceExecution()
1726
    jumpTrueOrFalse(
1727
        macro (value, target) btinz value, target end,
1728
        _llint_slow_path_jtrue)
1729
1730
1731
_llint_op_loop_if_false:
1732
    nop
1733
_llint_op_jfalse:
1734
    traceExecution()
1735
    jumpTrueOrFalse(
1736
        macro (value, target) btiz value, target end,
1737
        _llint_slow_path_jfalse)
1738
1739
1740
macro equalNull(cellHandler, immediateHandler)
1741
    loadi 4[PC], t0
1742
    loadi TagOffset[cfr, t0, 8], t1
1743
    loadi PayloadOffset[cfr, t0, 8], t0
1744
    bineq t1, CellTag, .immediate
1745
    loadp JSCell::m_structure[t0], t2
1746
    cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
1747
    dispatch(3)
1748
1749
.target:
1750
    dispatchBranch(8[PC])
1751
1752
.immediate:
1753
    ori 1, t1
1754
    immediateHandler(t1, .target)
1755
    dispatch(3)
1756
end
1757
1758
_llint_op_jeq_null:
1759
    traceExecution()
1760
    equalNull(
1761
        macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
1762
        macro (value, target) bieq value, NullTag, target end)
1763
    
1764
1765
_llint_op_jneq_null:
1766
    traceExecution()
1767
    equalNull(
1768
        macro (value, target) btbz value, MasqueradesAsUndefined, target end,
1769
        macro (value, target) bineq value, NullTag, target end)
1770
1771
1772
_llint_op_jneq_ptr:
1773
    traceExecution()
1774
    loadi 4[PC], t0
1775
    loadi 8[PC], t1
1776
    bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
1777
    bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
1778
.opJneqPtrBranch:
1779
    dispatchBranch(12[PC])
1780
.opJneqPtrFallThrough:
1781
    dispatch(4)
1782
1783
1784
macro compare(integerCompare, doubleCompare, slow_path)
1785
    loadi 4[PC], t2
1786
    loadi 8[PC], t3
1787
    loadConstantOrVariable(t2, t0, t1)
1788
    loadConstantOrVariable2Reg(t3, t2, t3)
1789
    bineq t0, Int32Tag, .op1NotInt
1790
    bineq t2, Int32Tag, .op2NotInt
1791
    integerCompare(t1, t3, .jumpTarget)
1792
    dispatch(4)
1793
1794
.op1NotInt:
1795
    bia t0, LowestTag, .slow
1796
    bib t2, LowestTag, .op1NotIntOp2Double
1797
    bineq t2, Int32Tag, .slow
1798
    ci2d t3, ft1
1799
    jmp .op1NotIntReady
1800
.op1NotIntOp2Double:
1801
    fii2d t3, t2, ft1
1802
.op1NotIntReady:
1803
    fii2d t1, t0, ft0
1804
    doubleCompare(ft0, ft1, .jumpTarget)
1805
    dispatch(4)
1806
1807
.op2NotInt:
1808
    ci2d t1, ft0
1809
    bia t2, LowestTag, .slow
1810
    fii2d t3, t2, ft1
1811
    doubleCompare(ft0, ft1, .jumpTarget)
1812
    dispatch(4)
1813
1814
.jumpTarget:
1815
    dispatchBranch(12[PC])
1816
1817
.slow:
1818
    callSlowPath(slow_path)
1819
    dispatch(0)
1820
end
1821
1822
_llint_op_loop_if_less:
1823
    nop
1824
_llint_op_jless:
1825
    traceExecution()
1826
    compare(
1827
        macro (left, right, target) bilt left, right, target end,
1828
        macro (left, right, target) bdlt left, right, target end,
1829
        _llint_slow_path_jless)
1830
1831
1832
_llint_op_jnless:
1833
    traceExecution()
1834
    compare(
1835
        macro (left, right, target) bigteq left, right, target end,
1836
        macro (left, right, target) bdgtequn left, right, target end,
1837
        _llint_slow_path_jnless)
1838
1839
1840
_llint_op_loop_if_greater:
1841
    nop
1842
_llint_op_jgreater:
1843
    traceExecution()
1844
    compare(
1845
        macro (left, right, target) bigt left, right, target end,
1846
        macro (left, right, target) bdgt left, right, target end,
1847
        _llint_slow_path_jgreater)
1848
1849
1850
_llint_op_jngreater:
1851
    traceExecution()
1852
    compare(
1853
        macro (left, right, target) bilteq left, right, target end,
1854
        macro (left, right, target) bdltequn left, right, target end,
1855
        _llint_slow_path_jngreater)
1856
1857
1858
_llint_op_loop_if_lesseq:
1859
    nop
1860
_llint_op_jlesseq:
1861
    traceExecution()
1862
    compare(
1863
        macro (left, right, target) bilteq left, right, target end,
1864
        macro (left, right, target) bdlteq left, right, target end,
1865
        _llint_slow_path_jlesseq)
1866
1867
1868
_llint_op_jnlesseq:
1869
    traceExecution()
1870
    compare(
1871
        macro (left, right, target) bigt left, right, target end,
1872
        macro (left, right, target) bdgtun left, right, target end,
1873
        _llint_slow_path_jnlesseq)
1874
1875
1876
_llint_op_loop_if_greatereq:
1877
    nop
1878
_llint_op_jgreatereq:
1879
    traceExecution()
1880
    compare(
1881
        macro (left, right, target) bigteq left, right, target end,
1882
        macro (left, right, target) bdgteq left, right, target end,
1883
        _llint_slow_path_jgreatereq)
1884
1885
1886
_llint_op_jngreatereq:
1887
    traceExecution()
1888
    compare(
1889
        macro (left, right, target) bilt left, right, target end,
1890
        macro (left, right, target) bdltun left, right, target end,
1891
        _llint_slow_path_jngreatereq)
1892
1893
1894
_llint_op_loop_hint:
1895
    traceExecution()
1896
    checkSwitchToJITForLoop()
1897
    dispatch(1)
1898
1899
1900
_llint_op_switch_imm:
1901
    traceExecution()
1902
    loadi 12[PC], t2
1903
    loadi 4[PC], t3
1904
    loadConstantOrVariable(t2, t1, t0)
1905
    loadp CodeBlock[cfr], t2
1906
    loadp CodeBlock::m_rareData[t2], t2
1907
    muli sizeof SimpleJumpTable, t3   # FIXME: would be nice to peephole this!
1908
    loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
1909
    addp t3, t2
1910
    bineq t1, Int32Tag, .opSwitchImmNotInt
1911
    subi SimpleJumpTable::min[t2], t0
1912
    biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
1913
    loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
1914
    loadi [t3, t0, 4], t1
1915
    btiz t1, .opSwitchImmFallThrough
1916
    dispatchBranchWithOffset(t1)
1917
1918
.opSwitchImmNotInt:
1919
    bib t1, LowestTag, .opSwitchImmSlow  # Go to slow path if it's a double.
1920
.opSwitchImmFallThrough:
1921
    dispatchBranch(8[PC])
1922
1923
.opSwitchImmSlow:
1924
    callSlowPath(_llint_slow_path_switch_imm)
1925
    dispatch(0)
1926
1927
1928
_llint_op_switch_char:
1929
    traceExecution()
1930
    loadi 12[PC], t2
1931
    loadi 4[PC], t3
1932
    loadConstantOrVariable(t2, t1, t0)
1933
    loadp CodeBlock[cfr], t2
1934
    loadp CodeBlock::m_rareData[t2], t2
1935
    muli sizeof SimpleJumpTable, t3
1936
    loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
1937
    addp t3, t2
1938
    bineq t1, CellTag, .opSwitchCharFallThrough
1939
    loadp JSCell::m_structure[t0], t1
1940
    bbneq Structure::m_typeInfo + TypeInfo::m_type[t1], StringType, .opSwitchCharFallThrough
1941
    loadp JSString::m_value[t0], t0
1942
    bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
1943
    loadp StringImpl::m_data8[t0], t1
1944
    btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
1945
    loadh [t1], t0
1946
    jmp .opSwitchCharReady
1947
.opSwitchChar8Bit:
1948
    loadb [t1], t0
1949
.opSwitchCharReady:
1950
    subi SimpleJumpTable::min[t2], t0
1951
    biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
1952
    loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
1953
    loadi [t2, t0, 4], t1
1954
    btiz t1, .opSwitchImmFallThrough
1955
    dispatchBranchWithOffset(t1)
1956
1957
.opSwitchCharFallThrough:
1958
    dispatchBranch(8[PC])
1959
1960
1961
_llint_op_switch_string:
1962
    traceExecution()
1963
    callSlowPath(_llint_slow_path_switch_string)
1964
    dispatch(0)
1965
1966
1967
_llint_op_new_func:
1968
    traceExecution()
1969
    btiz 12[PC], .opNewFuncUnchecked
1970
    loadi 4[PC], t1
1971
    bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
1972
.opNewFuncUnchecked:
1973
    callSlowPath(_llint_slow_path_new_func)
1974
.opNewFuncDone:
1975
    dispatch(4)
1976
1977
1978
_llint_op_new_func_exp:
1979
    traceExecution()
1980
    callSlowPath(_llint_slow_path_new_func_exp)
1981
    dispatch(3)
1982
1983
1984
macro doCall(slow_path)
1985
    loadi 4[PC], t0
1986
    loadi 16[PC], t1
1987
    loadp LLIntCallLinkInfo::callee[t1], t2
1988
    loadConstantOrVariablePayload(t0, CellTag, t3, .opCallSlow)
1989
    bineq t3, t2, .opCallSlow
1990
    loadi 12[PC], t3
1991
    addp 24, PC
1992
    lshifti 3, t3
1993
    addp cfr, t3  # t3 contains the new value of cfr
1994
    loadp JSFunction::m_scopeChain[t2], t0
1995
    storei t2, Callee + PayloadOffset[t3]
1996
    storei t0, ScopeChain + PayloadOffset[t3]
1997
    loadi 8 - 24[PC], t2
1998
    storei PC, ArgumentCount + TagOffset[cfr]
1999
    storep cfr, CallerFrame[t3]
2000
    storei t2, ArgumentCount + PayloadOffset[t3]
2001
    storei CellTag, Callee + TagOffset[t3]
2002
    storei CellTag, ScopeChain + TagOffset[t3]
2003
    move t3, cfr
2004
    call LLIntCallLinkInfo::machineCodeTarget[t1]
2005
    dispatchAfterCall()
2006
2007
.opCallSlow:
2008
    slowPathForCall(6, slow_path)
2009
end
2010
2011
_llint_op_call:
2012
    traceExecution()
2013
    doCall(_llint_slow_path_call)
2014
2015
2016
_llint_op_construct:
2017
    traceExecution()
2018
    doCall(_llint_slow_path_construct)
2019
2020
2021
_llint_op_call_varargs:
2022
    traceExecution()
2023
    slowPathForCall(6, _llint_slow_path_call_varargs)
2024
2025
2026
_llint_op_call_eval:
2027
    traceExecution()
2028
    
2029
    # Eval is executed in one of two modes:
2030
    #
2031
    # 1) We find that we're really invoking eval() in which case the
2032
    #    execution is perfomed entirely inside the slow_path, and it
2033
    #    returns the PC of a function that just returns the return value
2034
    #    that the eval returned.
2035
    #
2036
    # 2) We find that we're invoking something called eval() that is not
2037
    #    the real eval. Then the slow_path returns the PC of the thing to
2038
    #    call, and we call it.
2039
    #
2040
    # This allows us to handle two cases, which would require a total of
2041
    # up to four pieces of state that cannot be easily packed into two
2042
    # registers (C functions can return up to two registers, easily):
2043
    #
2044
    # - The call frame register. This may or may not have been modified
2045
    #   by the slow_path, but the convention is that it returns it. It's not
2046
    #   totally clear if that's necessary, since the cfr is callee save.
2047
    #   But that's our style in this here interpreter so we stick with it.
2048
    #
2049
    # - A bit to say if the slow_path successfully executed the eval and has
2050
    #   the return value, or did not execute the eval but has a PC for us
2051
    #   to call.
2052
    #
2053
    # - Either:
2054
    #   - The JS return value (two registers), or
2055
    #
2056
    #   - The PC to call.
2057
    #
2058
    # It turns out to be easier to just always have this return the cfr
2059
    # and a PC to call, and that PC may be a dummy thunk that just
2060
    # returns the JS value that the eval returned.
2061
    
2062
    slowPathForCall(4, _llint_slow_path_call_eval)
2063
2064
2065
_llint_generic_return_point:
2066
    dispatchAfterCall()
2067
2068
2069
_llint_op_tear_off_activation:
2070
    traceExecution()
2071
    loadi 4[PC], t0
2072
    loadi 8[PC], t1
2073
    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationCreated
2074
    bieq TagOffset[cfr, t1, 8], EmptyValueTag, .opTearOffActivationNotCreated
2075
.opTearOffActivationCreated:
2076
    callSlowPath(_llint_slow_path_tear_off_activation)
2077
.opTearOffActivationNotCreated:
2078
    dispatch(3)
2079
2080
2081
_llint_op_tear_off_arguments:
2082
    traceExecution()
2083
    loadi 4[PC], t0
2084
    subi 1, t0   # Get the unmodifiedArgumentsRegister
2085
    bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
2086
    callSlowPath(_llint_slow_path_tear_off_arguments)
2087
.opTearOffArgumentsNotCreated:
2088
    dispatch(2)
2089
2090
2091
macro doReturn()
2092
    loadp ReturnPC[cfr], t2
2093
    loadp CallerFrame[cfr], cfr
2094
    restoreReturnAddressBeforeReturn(t2)
2095
    ret
2096
end
2097
2098
_llint_op_ret:
2099
    traceExecution()
2100
    checkSwitchToJITForEpilogue()
2101
    loadi 4[PC], t2
2102
    loadConstantOrVariable(t2, t1, t0)
2103
    doReturn()
2104
2105
2106
_llint_op_call_put_result:
2107
    loadi 4[PC], t2
2108
    loadi 8[PC], t3
2109
    storei t1, TagOffset[cfr, t2, 8]
2110
    storei t0, PayloadOffset[cfr, t2, 8]
2111
    valueProfile(t1, t0, t3)
2112
    traceExecution() # Needs to be here because it would clobber t1, t0
2113
    dispatch(3)
2114
2115
2116
_llint_op_ret_object_or_this:
2117
    traceExecution()
2118
    checkSwitchToJITForEpilogue()
2119
    loadi 4[PC], t2
2120
    loadConstantOrVariable(t2, t1, t0)
2121
    bineq t1, CellTag, .opRetObjectOrThisNotObject
2122
    loadp JSCell::m_structure[t0], t2
2123
    bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
2124
    doReturn()
2125
2126
.opRetObjectOrThisNotObject:
2127
    loadi 8[PC], t2
2128
    loadConstantOrVariable(t2, t1, t0)
2129
    doReturn()
2130
2131
2132
_llint_op_method_check:
2133
    traceExecution()
2134
    # We ignore method checks and use normal get_by_id optimizations.
2135
    dispatch(1)
2136
2137
2138
_llint_op_strcat:
2139
    traceExecution()
2140
    callSlowPath(_llint_slow_path_strcat)
2141
    dispatch(4)
2142
2143
2144
_llint_op_to_primitive:
2145
    traceExecution()
2146
    loadi 8[PC], t2
2147
    loadi 4[PC], t3
2148
    loadConstantOrVariable(t2, t1, t0)
2149
    bineq t1, CellTag, .opToPrimitiveIsImm
2150
    loadp JSCell::m_structure[t0], t2
2151
    bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
2152
.opToPrimitiveIsImm:
2153
    storei t1, TagOffset[cfr, t3, 8]
2154
    storei t0, PayloadOffset[cfr, t3, 8]
2155
    dispatch(3)
2156
2157
.opToPrimitiveSlowCase:
2158
    callSlowPath(_llint_slow_path_to_primitive)
2159
    dispatch(3)
2160
2161
2162
_llint_op_get_pnames:
2163
    traceExecution()
2164
    callSlowPath(_llint_slow_path_get_pnames)
2165
    dispatch(0) # The slow_path either advances the PC or jumps us to somewhere else.
2166
2167
2168
_llint_op_next_pname:
2169
    traceExecution()
2170
    loadi 12[PC], t1
2171
    loadi 16[PC], t2
2172
    loadi PayloadOffset[cfr, t1, 8], t0
2173
    bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
2174
    loadi 20[PC], t2
2175
    loadi PayloadOffset[cfr, t2, 8], t2
2176
    loadp JSPropertyNameIterator::m_jsStrings[t2], t3
2177
    loadi [t3, t0, 8], t3
2178
    addi 1, t0
2179
    storei t0, PayloadOffset[cfr, t1, 8]
2180
    loadi 4[PC], t1
2181
    storei CellTag, TagOffset[cfr, t1, 8]
2182
    storei t3, PayloadOffset[cfr, t1, 8]
2183
    loadi 8[PC], t3
2184
    loadi PayloadOffset[cfr, t3, 8], t3
2185
    loadp JSCell::m_structure[t3], t1
2186
    bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
2187
    loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
2188
    loadp StructureChain::m_vector[t0], t0
2189
    btpz [t0], .opNextPnameTarget
2190
.opNextPnameCheckPrototypeLoop:
2191
    bieq Structure::m_prototype + TagOffset[t1], NullTag, .opNextPnameSlow
2192
    loadp Structure::m_prototype + PayloadOffset[t1], t2
2193
    loadp JSCell::m_structure[t2], t1
2194
    bpneq t1, [t0], .opNextPnameSlow
2195
    addp 4, t0
2196
    btpnz [t0], .opNextPnameCheckPrototypeLoop
2197
.opNextPnameTarget:
2198
    dispatchBranch(24[PC])
2199
2200
.opNextPnameEnd:
2201
    dispatch(7)
2202
2203
.opNextPnameSlow:
2204
    callSlowPath(_llint_slow_path_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
2205
    dispatch(0)
2206
2207
2208
_llint_op_push_scope:
2209
    traceExecution()
2210
    callSlowPath(_llint_slow_path_push_scope)
2211
    dispatch(2)
2212
2213
2214
_llint_op_pop_scope:
2215
    traceExecution()
2216
    callSlowPath(_llint_slow_path_pop_scope)
2217
    dispatch(1)
2218
2219
2220
_llint_op_push_new_scope:
2221
    traceExecution()
2222
    callSlowPath(_llint_slow_path_push_new_scope)
2223
    dispatch(4)
2224
2225
2226
_llint_op_catch:
2227
    # This is where we end up from the JIT's throw trampoline (because the
2228
    # machine code return address will be set to _llint_op_catch), and from
2229
    # the interpreter's throw trampoline (see _llint_throw_trampoline).
2230
    # The JIT throwing protocol calls for the cfr to be in t0. The throwing
2231
    # code must have known that we were throwing to the interpreter, and have
2232
    # set JSGlobalData::targetInterpreterPCForThrow.
2233
    move t0, cfr
2234
    loadp JITStackFrame::globalData[sp], t3
2235
    loadi JSGlobalData::targetInterpreterPCForThrow[t3], PC
2236
    loadi JSGlobalData::exception + PayloadOffset[t3], t0
2237
    loadi JSGlobalData::exception + TagOffset[t3], t1
2238
    storei 0, JSGlobalData::exception + PayloadOffset[t3]
2239
    storei EmptyValueTag, JSGlobalData::exception + TagOffset[t3]       
2240
    loadi 4[PC], t2
2241
    storei t0, PayloadOffset[cfr, t2, 8]
2242
    storei t1, TagOffset[cfr, t2, 8]
2243
    traceExecution()  # This needs to be here because we don't want to clobber t0, t1, t2, t3 above.
2244
    dispatch(2)
2245
2246
2247
_llint_op_throw:
2248
    traceExecution()
2249
    callSlowPath(_llint_slow_path_throw)
2250
    dispatch(2)
2251
2252
2253
_llint_op_throw_reference_error:
2254
    traceExecution()
2255
    callSlowPath(_llint_slow_path_throw_reference_error)
2256
    dispatch(2)
2257
2258
2259
_llint_op_jsr:
2260
    traceExecution()
2261
    loadi 4[PC], t0
2262
    addi 3 * 4, PC, t1
2263
    storei t1, [cfr, t0, 8]
2264
    dispatchBranch(8[PC])
2265
2266
2267
_llint_op_sret:
2268
    traceExecution()
2269
    loadi 4[PC], t0
2270
    loadp [cfr, t0, 8], PC
2271
    dispatch(0)
2272
2273
2274
_llint_op_debug:
2275
    traceExecution()
2276
    callSlowPath(_llint_slow_path_debug)
2277
    dispatch(4)
2278
2279
2280
_llint_op_profile_will_call:
2281
    traceExecution()
2282
    loadp JITStackFrame::enabledProfilerReference[sp], t0
2283
    btpz [t0], .opProfileWillCallDone
2284
    callSlowPath(_llint_slow_path_profile_will_call)
2285
.opProfileWillCallDone:
2286
    dispatch(2)
2287
2288
2289
_llint_op_profile_did_call:
2290
    traceExecution()
2291
    loadp JITStackFrame::enabledProfilerReference[sp], t0
2292
    btpz [t0], .opProfileWillCallDone
2293
    callSlowPath(_llint_slow_path_profile_did_call)
2294
.opProfileDidCallDone:
2295
    dispatch(2)
2296
2297
2298
_llint_op_end:
2299
    traceExecution()
2300
    checkSwitchToJITForEpilogue()
2301
    loadi 4[PC], t0
2302
    loadi TagOffset[cfr, t0, 8], t1
2303
    loadi PayloadOffset[cfr, t0, 8], t0
2304
    doReturn()
2305
2306
2307
_llint_throw_from_slow_path_trampoline:
2308
    # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
2309
    # the throw target is not necessarily interpreted code, we come to here.
2310
    # This essentially emulates the JIT's throwing protocol.
2311
    loadp JITStackFrame::globalData[sp], t1
2312
    loadp JSGlobalData::callFrameForThrow[t1], t0
2313
    jmp JSGlobalData::targetMachinePCForThrow[t1]
2314
2315
2316
_llint_throw_during_call_trampoline:
2317
    preserveReturnAddressAfterCall(t2)
2318
    loadp JITStackFrame::globalData[sp], t1
2319
    loadp JSGlobalData::callFrameForThrow[t1], t0
2320
    jmp JSGlobalData::targetMachinePCForThrow[t1]
2321
2322
2323
# Lastly, make sure that we can link even though we don't support all opcodes.
2324
# These opcodes should never arise when using LLInt or either JIT. We assert
2325
# as much.
2326
2327
macro notSupported()
2328
    if ASSERT_ENABLED
2329
        crash()
2330
    else
2331
        # We should use whatever the smallest possible instruction is, just to
2332
        # ensure that there is a gap between instruction labels. If multiple
2333
        # smallest instructions exist, we should pick the one that is most
2334
        # likely result in execution being halted. Currently that is the break
2335
        # instruction on all architectures we're interested in. (Break is int3
2336
        # on Intel, which is 1 byte, and bkpt on ARMv7, which is 2 bytes.)
2337
        break
2338
    end
2339
end
2340
2341
_llint_op_get_array_length:
2342
    notSupported()
2343
2344
_llint_op_get_by_id_chain:
2345
    notSupported()
2346
2347
_llint_op_get_by_id_custom_chain:
2348
    notSupported()
2349
2350
_llint_op_get_by_id_custom_proto:
2351
    notSupported()
2352
2353
_llint_op_get_by_id_custom_self:
2354
    notSupported()
2355
2356
_llint_op_get_by_id_generic:
2357
    notSupported()
2358
2359
_llint_op_get_by_id_getter_chain:
2360
    notSupported()
2361
2362
_llint_op_get_by_id_getter_proto:
2363
    notSupported()
2364
2365
_llint_op_get_by_id_getter_self:
2366
    notSupported()
2367
2368
_llint_op_get_by_id_proto:
2369
    notSupported()
2370
2371
_llint_op_get_by_id_self:
2372
    notSupported()
2373
2374
_llint_op_get_string_length:
2375
    notSupported()
2376
2377
_llint_op_put_by_id_generic:
2378
    notSupported()
2379
2380
_llint_op_put_by_id_replace:
2381
    notSupported()
2382
2383
_llint_op_put_by_id_transition:
2384
    notSupported()
2385
2386
2387
# Indicate the end of LLInt.
2388
_llint_end:
2389
    crash()
2390
- Source/JavaScriptCore/llint/LowLevelInterpreter.cpp +38 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
#include <wtf/InlineASM.h>
33
34
// This is a file generated by offlineasm, which contains all of the assembly code
35
// for the interpreter, as compiled from LowLevelInterpreter.asm.
36
#include "LLIntAssembly.h"
37
38
#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_slow_path_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 +1032 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
require "ast"
25
require "opt"
26
27
class Node
28
    def armV7Single
29
        doubleOperand = armV7Operand
30
        raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^d/
31
        "s" + ($~.post_match.to_i * 2).to_s
32
    end
33
end
34
35
class SpecialRegister < NoChildren
36
    def initialize(name)
37
        @name = name
38
    end
39
    
40
    def armV7Operand
41
        @name
42
    end
43
    
44
    def address?
45
        false
46
    end
47
    
48
    def label?
49
        false
50
    end
51
    
52
    def immediate?
53
        false
54
    end
55
    
56
    def register?
57
        true
58
    end
59
end
60
61
ARMv7_EXTRA_GPRS = [SpecialRegister.new("r9"), SpecialRegister.new("r8"), SpecialRegister.new("r3")]
62
ARMv7_EXTRA_FPRS = [SpecialRegister.new("d7")]
63
ARMv7_SCRATCH_FPR = SpecialRegister.new("d8")
64
65
def armV7MoveImmediate(value, register)
66
    # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
67
    if value >= 0 && value < 256
68
        $asm.puts "movw #{register.armV7Operand}, \##{value}"
69
    elsif (~value) >= 0 && (~value) < 256
70
        $asm.puts "mvn #{register.armV7Operand}, \##{~value}"
71
    else
72
        $asm.puts "movw #{register.armV7Operand}, \##{value & 0xffff}"
73
        if (value & 0xffff0000) != 0
74
            $asm.puts "movt #{register.armV7Operand}, \##{value >> 16}"
75
        end
76
    end
77
end
78
79
class RegisterID
80
    def armV7Operand
81
        case name
82
        when "t0", "a0", "r0"
83
            "r0"
84
        when "t1", "a1", "r1"
85
            "r1"
86
        when "t2", "a2"
87
            "r2"
88
        when "a3"
89
            "r3"
90
        when "t3"
91
            "r4"
92
        when "t4"
93
            "r7"
94
        when "cfr"
95
            "r5"
96
        when "lr"
97
            "lr"
98
        when "sp"
99
            "sp"
100
        else
101
            raise "Bad register #{name} for ARMv7 at #{codeOriginString}"
102
        end
103
    end
104
end
105
106
class FPRegisterID
107
    def armV7Operand
108
        case name
109
        when "ft0", "fr"
110
            "d0"
111
        when "ft1"
112
            "d1"
113
        when "ft2"
114
            "d2"
115
        when "ft3"
116
            "d3"
117
        when "ft4"
118
            "d4"
119
        when "ft5"
120
            "d5"
121
        else
122
            raise "Bad register #{name} for ARMv7 at #{codeOriginString}"
123
        end
124
    end
125
end
126
127
class Immediate
128
    def armV7Operand
129
        raise "Invalid immediate #{value} at #{codeOriginString}" if value < 0 or value > 255
130
        "\##{value}"
131
    end
132
end
133
134
class Address
135
    def armV7Operand
136
        raise "Bad offset at #{codeOriginString}" if offset.value < -0xff or offset.value > 0xfff
137
        "[#{base.armV7Operand}, \##{offset.value}]"
138
    end
139
end
140
141
class BaseIndex
142
    def armV7Operand
143
        raise "Bad offset at #{codeOriginString}" if offset.value != 0
144
        "[#{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scaleShift}]"
145
    end
146
end
147
148
class AbsoluteAddress
149
    def armV7Operand
150
        raise "Unconverted absolute address at #{codeOriginString}"
151
    end
152
end
153
154
#
155
# Lowering of branch ops. For example:
156
#
157
# baddiz foo, bar, baz
158
#
159
# will become:
160
#
161
# addi foo, bar
162
# bz baz
163
#
164
165
def armV7LowerBranchOps(list)
166
    newList = []
167
    list.each {
168
        | node |
169
        if node.is_a? Instruction
170
            case node.opcode
171
            when /^b(addi|subi|ori|addp)/
172
                op = $1
173
                branch = "b" + $~.post_match
174
                
175
                case op
176
                when "addi", "addp"
177
                    op = "addis"
178
                when "subi"
179
                    op = "subis"
180
                when "ori"
181
                    op = "oris"
182
                end
183
                
184
                newList << Instruction.new(node.codeOrigin, op, node.operands[0..-2])
185
                newList << Instruction.new(node.codeOrigin, branch, [node.operands[-1]])
186
            when "bmulio"
187
                tmp1 = Tmp.new(node.codeOrigin, :gpr)
188
                tmp2 = Tmp.new(node.codeOrigin, :gpr)
189
                newList << Instruction.new(node.codeOrigin, "smulli", [node.operands[0], node.operands[1], node.operands[1], tmp1])
190
                newList << Instruction.new(node.codeOrigin, "rshifti", [node.operands[-2], Immediate.new(node.codeOrigin, 31), tmp2])
191
                newList << Instruction.new(node.codeOrigin, "bineq", [tmp1, tmp2, node.operands[-1]])
192
            when /^bmuli/
193
                condition = $~.post_match
194
                newList << Instruction.new(node.codeOrigin, "muli", node.operands[0..-2])
195
                newList << Instruction.new(node.codeOrigin, "bti" + condition, [node.operands[-2], node.operands[-1]])
196
            else
197
                newList << node
198
            end
199
        else
200
            newList << node
201
        end
202
    }
203
    newList
204
end
205
206
#
207
# Lowering of shift ops. For example:
208
#
209
# lshifti foo, bar
210
#
211
# will become:
212
#
213
# andi foo, 31, tmp
214
# lshifti tmp, bar
215
#
216
217
def armV7SanitizeShift(operand, list)
218
    return operand if operand.immediate?
219
    
220
    tmp = Tmp.new(operand.codeOrigin, :gpr)
221
    list << Instruction.new(operand.codeOrigin, "andi", [operand, Immediate.new(operand.codeOrigin, 31), tmp])
222
    tmp
223
end
224
225
def armV7LowerShiftOps(list)
226
    newList = []
227
    list.each {
228
        | node |
229
        if node.is_a? Instruction
230
            case node.opcode
231
            when "lshifti", "rshifti", "urshifti"
232
                if node.operands.size == 2
233
                    newList << Instruction.new(node.codeOrigin, node.opcode, [armV7SanitizeShift(node.operands[0], newList), node.operands[1]])
234
                else
235
                    newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], armV7SanitizeShift(node.operands[1], newList), node.operands[2]])
236
                    raise "Wrong number of operands for shift at #{node.codeOriginString}" unless node.operands.size == 3
237
                end
238
            else
239
                newList << node
240
            end
241
        else
242
            newList << node
243
        end
244
    }
245
    newList
246
end
247
248
#
249
# Lowering of malformed addresses. For example:
250
#
251
# loadp 10000[foo], bar
252
#
253
# will become:
254
#
255
# move 10000, tmp
256
# addp foo, tmp
257
# loadp 0[tmp], bar
258
#
259
260
class Node
261
    def armV7LowerMalformedAddressesRecurse(list)
262
        mapChildren {
263
            | node |
264
            node.armV7LowerMalformedAddressesRecurse(list)
265
        }
266
    end
267
end
268
269
class Address
270
    def armV7LowerMalformedAddressesRecurse(list)
271
        if offset.value < -0xff or offset.value > 0xfff
272
            tmp = Tmp.new(codeOrigin, :gpr)
273
            list << Instruction.new(codeOrigin, "move", [offset, tmp])
274
            list << Instruction.new(codeOrigin, "addp", [base, tmp])
275
            Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
276
        else
277
            self
278
        end
279
    end
280
end
281
282
class BaseIndex
283
    def armV7LowerMalformedAddressesRecurse(list)
284
        if offset.value != 0
285
            tmp = Tmp.new(codeOrigin, :gpr)
286
            list << Instruction.new(codeOrigin, "move", [offset, tmp])
287
            list << Instruction.new(codeOrigin, "addp", [base, tmp])
288
            BaseIndex.new(codeOrigin, tmp, index, scale, Immediate.new(codeOrigin, 0))
289
        else
290
            self
291
        end
292
    end
293
end
294
295
class AbsoluteAddress
296
    def armV7LowerMalformedAddressesRecurse(list)
297
        tmp = Tmp.new(codeOrigin, :gpr)
298
        list << Instruction.new(codeOrigin, "move", [address, tmp])
299
        Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
300
    end
301
end
302
303
def armV7LowerMalformedAddresses(list)
304
    newList = []
305
    list.each {
306
        | node |
307
        newList << node.armV7LowerMalformedAddressesRecurse(newList)
308
    }
309
    newList
310
end
311
312
#
313
# Lowering of malformed addresses in double loads and stores. For example:
314
#
315
# loadd [foo, bar, 8], baz
316
#
317
# becomes:
318
#
319
# leap [foo, bar, 8], tmp
320
# loadd [tmp], baz
321
#
322
323
class Node
324
    def armV7DoubleAddress(list)
325
        self
326
    end
327
end
328
329
class BaseIndex
330
    def armV7DoubleAddress(list)
331
        tmp = Tmp.new(codeOrigin, :gpr)
332
        list << Instruction.new(codeOrigin, "leap", [self, tmp])
333
        Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
334
    end
335
end
336
337
def armV7LowerMalformedAddressesDouble(list)
338
    newList = []
339
    list.each {
340
        | node |
341
        if node.is_a? Instruction
342
            case node.opcode
343
            when "loadd"
344
                newList << Instruction.new(node.codeOrigin, "loadd", [node.operands[0].armV7DoubleAddress(newList), node.operands[1]])
345
            when "stored"
346
                newList << Instruction.new(node.codeOrigin, "stored", [node.operands[0], node.operands[1].armV7DoubleAddress(newList)])
347
            else
348
                newList << node
349
            end
350
        else
351
            newList << node
352
        end
353
    }
354
    newList
355
end
356
357
#
358
# Lowering of misplaced immediates. For example:
359
#
360
# storei 0, [foo]
361
#
362
# will become:
363
#
364
# move 0, tmp
365
# storei tmp, [foo]
366
#
367
368
def armV7LowerMisplacedImmediates(list)
369
    newList = []
370
    list.each {
371
        | node |
372
        if node.is_a? Instruction
373
            case node.opcode
374
            when "storei", "storep"
375
                operands = node.operands
376
                newOperands = []
377
                operands.each {
378
                    | operand |
379
                    if operand.is_a? Immediate
380
                        tmp = Tmp.new(operand.codeOrigin, :gpr)
381
                        newList << Instruction.new(operand.codeOrigin, "move", [operand, tmp])
382
                        newOperands << tmp
383
                    else
384
                        newOperands << operand
385
                    end
386
                }
387
                newList << Instruction.new(node.codeOrigin, node.opcode, newOperands)
388
            else
389
                newList << node
390
            end
391
        else
392
            newList << node
393
        end
394
    }
395
    newList
396
end
397
398
#
399
# Lowering of malformed immediates except when used in a "move" instruction.
400
# For example:
401
#
402
# addp 642641, foo
403
#
404
# will become:
405
#
406
# move 642641, tmp
407
# addp tmp, foo
408
#
409
410
class Node
411
    def armV7LowerMalformedImmediatesRecurse(list)
412
        mapChildren {
413
            | node |
414
            node.armV7LowerMalformedImmediatesRecurse(list)
415
        }
416
    end
417
end
418
419
class Address
420
    def armV7LowerMalformedImmediatesRecurse(list)
421
        self
422
    end
423
end
424
425
class BaseIndex
426
    def armV7LowerMalformedImmediatesRecurse(list)
427
        self
428
    end
429
end
430
431
class AbsoluteAddress
432
    def armV7LowerMalformedImmediatesRecurse(list)
433
        self
434
    end
435
end
436
437
class Immediate
438
    def armV7LowerMalformedImmediatesRecurse(list)
439
        if value < 0 or value > 255
440
            tmp = Tmp.new(codeOrigin, :gpr)
441
            list << Instruction.new(codeOrigin, "move", [self, tmp])
442
            tmp
443
        else
444
            self
445
        end
446
    end
447
end
448
449
def armV7LowerMalformedImmediates(list)
450
    newList = []
451
    list.each {
452
        | node |
453
        if node.is_a? Instruction
454
            case node.opcode
455
            when "move"
456
                newList << node
457
            when "addi", "addp", "addis", "subi", "subp", "subis"
458
                if node.operands[0].is_a? Immediate and
459
                        node.operands[0].value < 0 and
460
                        node.operands[0].value >= 255 and
461
                        node.operands.size == 2
462
                    if node.opcode =~ /add/
463
                        newOpcode = "sub" + node.opcode[-1..-1]
464
                    else
465
                        newOpcode = "add" + node.opcode[-1..-1]
466
                    end
467
                    newList << Instruction.new(node.codeOrigin, newOpcode,
468
                                               [Immediate.new(-node.operands[0].value)] + node.operands[1..-1])
469
                else
470
                    newList << node.armV7LowerMalformedImmediatesRecurse(newList)
471
                end
472
            when "muli"
473
                if node.operands[0].is_a? Immediate
474
                    tmp = Tmp.new(codeOrigin, :gpr)
475
                    newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
476
                    newList << Instruction.new(node.codeOrigin, "muli", [tmp] + node.operands[1..-1])
477
                else
478
                    newList << node.armV7LowerMalformedImmediatesRecurse(newList)
479
                end
480
            else
481
                newList << node.armV7LowerMalformedImmediatesRecurse(newList)
482
            end
483
        else
484
            newList << node
485
        end
486
    }
487
    newList
488
end
489
490
#
491
# Lowering of misplaced addresses. For example:
492
#
493
# addi foo, [bar]
494
#
495
# will become:
496
#
497
# loadi [bar], tmp
498
# addi foo, tmp
499
# storei tmp, [bar]
500
#
501
# Another example:
502
#
503
# addi [foo], bar
504
#
505
# will become:
506
#
507
# loadi [foo], tmp
508
# addi tmp, bar
509
#
510
511
def armV7AsRegister(preList, postList, operand, suffix, needStore)
512
    return operand unless operand.address?
513
    
514
    tmp = Tmp.new(operand.codeOrigin, if suffix == "d" then :fpr else :gpr end)
515
    preList << Instruction.new(operand.codeOrigin, "load" + suffix, [operand, tmp])
516
    if needStore
517
        postList << Instruction.new(operand.codeOrigin, "store" + suffix, [tmp, operand])
518
    end
519
    tmp
520
end
521
522
def armV7AsRegisters(preList, postList, operands, suffix)
523
    newOperands = []
524
    operands.each_with_index {
525
        | operand, index |
526
        newOperands << armV7AsRegister(preList, postList, operand, suffix, index == operands.size - 1)
527
    }
528
    newOperands
529
end
530
531
def armV7LowerMisplacedAddresses(list)
532
    newList = []
533
    list.each {
534
        | node |
535
        if node.is_a? Instruction
536
            postInstructions = []
537
            case node.opcode
538
            when "addi", "addp", "addis", "andi", "andp", "lshifti", "muli", "negi", "noti", "ori", "oris",
539
                "orp", "rshifti", "urshifti", "subi", "subp", "subis", "xori", "xorp", /^bi/, /^bp/, /^bti/,
540
                /^btp/, /^ci/, /^cp/, /^ti/
541
                newList << Instruction.new(node.codeOrigin,
542
                                           node.opcode,
543
                                           armV7AsRegisters(newList, postInstructions, node.operands, "i"))
544
            when "bbeq", "bbneq", "bba", "bbaeq", "bbb", "bbbeq", "btbo", "btbz", "btbnz", "tbz", "tbnz",
545
                "tbo"
546
                newList << Instruction.new(node.codeOrigin,
547
                                           node.opcode,
548
                                           armV7AsRegisters(newList, postInstructions, node.operands, "b"))
549
            when "bbgt", "bbgteq", "bblt", "bblteq", "btbs", "tbs"
550
                newList << Instruction.new(node.codeOrigin,
551
                                           node.opcode,
552
                                           armV7AsRegisters(newList, postInstructions, node.operands, "bs"))
553
            when "addd", "divd", "subd", "muld", "sqrtd", /^bd/
554
                newList << Instruction.new(node.codeOrigin,
555
                                           node.opcode,
556
                                           armV7AsRegisters(newList, postInstructions, node.operands, "d"))
557
            when "jmp", "call"
558
                newList << Instruction.new(node.codeOrigin,
559
                                           node.opcode,
560
                                           [armV7AsRegister(newList, postInstructions, node.operands[0], "p", false)])
561
            else
562
                newList << node
563
            end
564
            newList += postInstructions
565
        else
566
            newList << node
567
        end
568
    }
569
    newList
570
end
571
572
#
573
# Lowering of register reuse in compare instructions. For example:
574
#
575
# cieq t0, t1, t0
576
#
577
# will become:
578
#
579
# mov tmp, t0
580
# cieq tmp, t1, t0
581
#
582
583
def armV7LowerRegisterReuse(list)
584
    newList = []
585
    list.each {
586
        | node |
587
        if node.is_a? Instruction
588
            case node.opcode
589
            when "cieq", "cineq", "cia", "ciaeq", "cib", "cibeq", "cigt", "cigteq", "cilt", "cilteq",
590
                "cpeq", "cpneq", "cpa", "cpaeq", "cpb", "cpbeq", "cpgt", "cpgteq", "cplt", "cplteq",
591
                "tio", "tis", "tiz", "tinz", "tbo", "tbs", "tbz", "tbnz"
592
                if node.operands.size == 2
593
                    if node.operands[0] == node.operands[1]
594
                        tmp = Tmp.new(node.codeOrigin, :gpr)
595
                        newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
596
                        newList << Instruction.new(node.codeOrigin, node.opcode, [tmp, node.operands[1]])
597
                    else
598
                        newList << node
599
                    end
600
                else
601
                    raise "Wrong number of arguments at #{node.codeOriginString}" unless node.operands.size == 3
602
                    if node.operands[0] == node.operands[2]
603
                        tmp = Tmp.new(node.codeOrigin, :gpr)
604
                        newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
605
                        newList << Instruction.new(node.codeOrigin, node.opcode, [tmp, node.operands[1], node.operands[2]])
606
                    elsif node.operands[1] == node.operands[2]
607
                        tmp = Tmp.new(node.codeOrigin, :gpr)
608
                        newList << Instruction.new(node.codeOrigin, "move", [node.operands[1], tmp])
609
                        newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], tmp, node.operands[2]])
610
                    else
611
                        newList << node
612
                    end
613
                end
614
            else
615
                newList << node
616
            end
617
        else
618
            newList << node
619
        end
620
    }
621
    newList
622
end
623
624
#
625
# Lea support.
626
#
627
628
class Address
629
    def armV7EmitLea(destination)
630
        if destination == base
631
            $asm.puts "adds #{destination.armV7Operand}, \##{offset.value}"
632
        else
633
            $asm.puts "adds #{destination.armV7Operand}, #{base.armV7Operand}, \##{offset.value}"
634
        end
635
    end
636
end
637
638
class BaseIndex
639
    def armV7EmitLea(destination)
640
        raise "Malformed BaseIndex, offset should be zero at #{codeOriginString}" unless offset.value == 0
641
        $asm.puts "add.w #{destination.armV7Operand}, #{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scaleShift}"
642
    end
643
end
644
645
# FIXME: we could support AbsoluteAddress for lea, but we don't.
646
647
#
648
# Actual lowering code follows.
649
#
650
651
class Sequence
652
    def lowerARMv7
653
        myList = @list
654
        
655
        # Verify that we will only see instructions and labels.
656
        myList.each {
657
            | node |
658
            unless node.is_a? Instruction or
659
                    node.is_a? Label or
660
                    node.is_a? LocalLabel or
661
                    node.is_a? Skip
662
                raise "Unexpected #{node.inspect} at #{node.codeOrigin}" 
663
            end
664
        }
665
        
666
        myList = armV7LowerBranchOps(myList)
667
        myList = armV7LowerShiftOps(myList)
668
        myList = armV7LowerMalformedAddresses(myList)
669
        myList = armV7LowerMalformedAddressesDouble(myList)
670
        myList = armV7LowerMisplacedImmediates(myList)
671
        myList = armV7LowerMalformedImmediates(myList)
672
        myList = armV7LowerMisplacedAddresses(myList)
673
        myList = armV7LowerRegisterReuse(myList)
674
        myList = assignRegistersToTemporaries(myList, :gpr, ARMv7_EXTRA_GPRS)
675
        myList = assignRegistersToTemporaries(myList, :fpr, ARMv7_EXTRA_FPRS)
676
        myList.each {
677
            | node |
678
            node.lower("ARMv7")
679
        }
680
    end
681
end
682
683
def armV7Operands(operands)
684
    operands.map{|v| v.armV7Operand}.join(", ")
685
end
686
687
def armV7FlippedOperands(operands)
688
    armV7Operands([operands[-1]] + operands[0..-2])
689
end
690
691
def emitArmV7Compact(opcode2, opcode3, operands)
692
    if operands.size == 3
693
        $asm.puts "#{opcode3} #{armV7FlippedOperands(operands)}"
694
    else
695
        raise unless operands.size == 2
696
        raise unless operands[1].is_a? RegisterID
697
        if operands[0].is_a? Immediate
698
            $asm.puts "#{opcode3} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
699
        else
700
            $asm.puts "#{opcode2} #{armV7FlippedOperands(operands)}"
701
        end
702
    end
703
end
704
705
def emitArmV7(opcode, operands)
706
    if operands.size == 3
707
        $asm.puts "#{opcode} #{armV7FlippedOperands(operands)}"
708
    else
709
        raise unless operands.size == 2
710
        $asm.puts "#{opcode} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
711
    end
712
end
713
714
def emitArmV7DoubleBranch(branchOpcode, operands)
715
    $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
716
    $asm.puts "vmrs apsr_nzcv, fpscr"
717
    $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
718
end
719
720
def emitArmV7Test(operands)
721
    value = operands[0]
722
    case operands.size
723
    when 2
724
        mask = Immediate.new(codeOrigin, -1)
725
    when 3
726
        mask = operands[1]
727
    else
728
        raise "Expected 2 or 3 operands but got #{operands.size} at #{codeOriginString}"
729
    end
730
    
731
    if mask.is_a? Immediate and mask.value == -1
732
        $asm.puts "tst #{value.armV7Operand}, #{value.armV7Operand}"
733
    elsif mask.is_a? Immediate
734
        $asm.puts "tst.w #{value.armV7Operand}, #{mask.armV7Operand}"
735
    else
736
        $asm.puts "tst #{value.armV7Operand}, #{mask.armV7Operand}"
737
    end
738
end
739
740
def emitArmV7Compare(operands, code)
741
    $asm.puts "movs #{operands[2].armV7Operand}, \#0"
742
    $asm.puts "cmp #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
743
    $asm.puts "it #{code}"
744
    $asm.puts "mov#{code} #{operands[2].armV7Operand}, \#1"
745
end
746
747
def emitArmV7TestSet(operands, code)
748
    $asm.puts "movs #{operands[-1].armV7Operand}, \#0"
749
    emitArmV7Test(operands)
750
    $asm.puts "it #{code}"
751
    $asm.puts "mov#{code} #{operands[-1].armV7Operand}, \#1"
752
end
753
754
class Instruction
755
    def lowerARMv7
756
        $asm.comment codeOriginString
757
        case opcode
758
        when "addi", "addp", "addis"
759
            if opcode == "addis"
760
                suffix = "s"
761
            else
762
                suffix = ""
763
            end
764
            if operands.size == 3 and operands[0].is_a? Immediate
765
                raise unless operands[1].is_a? RegisterID
766
                raise unless operands[2].is_a? RegisterID
767
                if operands[0].value == 0 and suffix.empty?
768
                    unless operands[1] == operands[2]
769
                        $asm.puts "mov #{operands[2].armV7Operand}, #{operands[1].armV7Operand}"
770
                    end
771
                else
772
                    $asm.puts "adds #{operands[2].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
773
                end
774
            elsif operands.size == 3 and operands[0].is_a? RegisterID
775
                raise unless operands[1].is_a? RegisterID
776
                raise unless operands[2].is_a? RegisterID
777
                $asm.puts "adds #{armV7FlippedOperands(operands)}"
778
            else
779
                if operands[0].is_a? Immediate
780
                    unless Immediate.new(nil, 0) == operands[0]
781
                        $asm.puts "adds #{armV7FlippedOperands(operands)}"
782
                    end
783
                else
784
                    $asm.puts "add#{suffix} #{armV7FlippedOperands(operands)}"
785
                end
786
            end
787
        when "andi", "andp"
788
            emitArmV7Compact("ands", "and", operands)
789
        when "ori", "orp"
790
            emitArmV7Compact("orrs", "orr", operands)
791
        when "oris"
792
            emitArmV7Compact("orrs", "orrs", operands)
793
        when "xori", "xorp"
794
            emitArmV7Compact("eors", "eor", operands)
795
        when "lshifti"
796
            emitArmV7Compact("lsls", "lsls", operands)
797
        when "rshifti"
798
            emitArmV7Compact("asrs", "asrs", operands)
799
        when "urshifti"
800
            emitArmV7Compact("lsrs", "lsrs", operands)
801
        when "muli"
802
            if operands.size == 2 or operands[0] == operands[2] or operands[1] == operands[2]
803
                emitArmV7("muls", operands)
804
            else
805
                $asm.puts "mov #{operands[2].armV7Operand}, #{operands[0].armV7Operand}"
806
                $asm.puts "muls #{operands[2].armV7Operand}, #{operands[2].armV7Operand}, #{operands[1].armV7Operand}"
807
            end
808
        when "subi", "subp", "subis"
809
            emitArmV7Compact("subs", "subs", operands)
810
        when "negi"
811
            $asm.puts "rsbs #{operands[0].armV7Operand}, #{operands[0].armV7Operand}, \#0"
812
        when "noti"
813
            $asm.puts "mvns #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
814
        when "loadi", "loadp"
815
            $asm.puts "ldr #{armV7FlippedOperands(operands)}"
816
        when "storei", "storep"
817
            $asm.puts "str #{armV7Operands(operands)}"
818
        when "loadb"
819
            $asm.puts "ldrb #{armV7FlippedOperands(operands)}"
820
        when "loadbs"
821
            $asm.puts "ldrsb.w #{armV7FlippedOperands(operands)}"
822
        when "storeb"
823
            $asm.puts "strb #{armV7Operands(operands)}"
824
        when "loadh"
825
            $asm.puts "ldrh #{armV7FlippedOperands(operands)}"
826
        when "loadhs"
827
            $asm.puts "ldrsh.w #{armV7FlippedOperands(operands)}"
828
        when "storeh"
829
            $asm.puts "strh #{armV7Operands(operands)}"
830
        when "loadd"
831
            $asm.puts "vldr.64 #{armV7FlippedOperands(operands)}"
832
        when "stored"
833
            $asm.puts "vstr.64 #{armV7Operands(operands)}"
834
        when "addd"
835
            emitArmV7("vadd.f64", operands)
836
        when "divd"
837
            emitArmV7("vdiv.f64", operands)
838
        when "subd"
839
            emitArmV7("vsub.f64", operands)
840
        when "muld"
841
            emitArmV7("vmul.f64", operands)
842
        when "sqrtd"
843
            $asm.puts "vsqrt.f64 #{armV7FlippedOperands(operands)}"
844
        when "ci2d"
845
            $asm.puts "vmov #{operands[1].armV7Single}, #{operands[0].armV7Operand}"
846
            $asm.puts "vcvt.f64.s32 #{operands[1].armV7Operand}, #{operands[1].armV7Single}"
847
        when "bdeq"
848
            emitArmV7DoubleBranch("beq", operands)
849
        when "bdneq"
850
            $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
851
            $asm.puts "vmrs apsr_nzcv, fpscr"
852
            isUnordered = LocalLabel.unique("bdneq")
853
            $asm.puts "bvs #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
854
            $asm.puts "bne #{operands[2].asmLabel}"
855
            isUnordered.lower("ARMv7")
856
        when "bdgt"
857
            emitArmV7DoubleBranch("bgt", operands)
858
        when "bdgteq"
859
            emitArmV7DoubleBranch("bge", operands)
860
        when "bdlt"
861
            emitArmV7DoubleBranch("bmi", operands)
862
        when "bdlteq"
863
            emitArmV7DoubleBranch("bls", operands)
864
        when "bdequn"
865
            $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
866
            $asm.puts "vmrs apsr_nzcv, fpscr"
867
            $asm.puts "bvs #{operands[2].asmLabel}"
868
            $asm.puts "beq #{operands[2].asmLabel}"
869
        when "bdnequn"
870
            emitArmV7DoubleBranch("bne", operands)
871
        when "bdgtun"
872
            emitArmV7DoubleBranch("bhi", operands)
873
        when "bdgtequn"
874
            emitArmV7DoubleBranch("bpl", operands)
875
        when "bdltun"
876
            emitArmV7DoubleBranch("blt", operands)
877
        when "bdltequn"
878
            emitArmV7DoubleBranch("ble", operands)
879
        when "btd2i"
880
            # FIXME: may be a good idea to just get rid of this instruction, since the interpreter
881
            # currently does not use it.
882
            raise "ARMv7 does not support this opcode yet, #{codeOrigin}"
883
        when "td2i"
884
            $asm.puts "vcvt.s32.f64 #{ARMv7_SCRATCH_FPR.armV7Single}, #{operands[0].armV7Operand}"
885
            $asm.puts "vmov #{operands[1].armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
886
        when "bcd2i"
887
            $asm.puts "vcvt.s32.f64 #{ARMv7_SCRATCH_FPR.armV7Single}, #{operands[0].armV7Operand}"
888
            $asm.puts "vmov #{operands[1].armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
889
            $asm.puts "vcvt.f64.s32 #{ARMv7_SCRATCH_FPR.armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
890
            emitArmV7DoubleBranch("bne", [ARMv7_SCRATCH_FPR, operands[0], operands[2]])
891
            $asm.puts "tst #{operands[1].armV7Operand}, #{operands[1].armV7Operand}"
892
            $asm.puts "beq #{operands[2].asmLabel}"
893
        when "movdz"
894
            # FIXME: either support this or remove it.
895
            raise "ARMv7 does not support this opcode yet, #{codeOrigin}"
896
        when "pop"
897
            $asm.puts "pop #{operands[0].armV7Operand}"
898
        when "push"
899
            $asm.puts "push #{operands[0].armV7Operand}"
900
        when "move", "sxi2p", "zxi2p"
901
            if operands[0].is_a? Immediate
902
                armV7MoveImmediate(operands[0].value, operands[1])
903
            else
904
                $asm.puts "mov #{armV7FlippedOperands(operands)}"
905
            end
906
        when "nop"
907
            $asm.puts "nop"
908
        when "bieq", "bpeq", "bbeq"
909
            if Immediate.new(nil, 0) == operands[0]
910
                $asm.puts "tst #{operands[1].armV7Operand}, #{operands[1].armV7Operand}"
911
            elsif Immediate.new(nil, 0) == operands[1]
912
                $asm.puts "tst #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
913
            else
914
                $asm.puts "cmp #{armV7Operands(operands[0..1])}"
915
            end
916
            $asm.puts "beq #{operands[2].asmLabel}"
917
        when "bineq", "bpneq", "bbneq"
918
            if Immediate.new(nil, 0) == operands[0]
919
                $asm.puts "tst #{operands[1].armV7Operand}, #{operands[1].armV7Operand}"
920
            elsif Immediate.new(nil, 0) == operands[1]
921
                $asm.puts "tst #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
922
            else
923
                $asm.puts "cmp #{armV7Operands(operands[0..1])}"
924
            end
925
            $asm.puts "bne #{operands[2].asmLabel}"
926
        when "bia", "bpa", "bba"
927
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
928
            $asm.puts "bhi #{operands[2].asmLabel}"
929
        when "biaeq", "bpaeq", "bbaeq"
930
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
931
            $asm.puts "bhs #{operands[2].asmLabel}"
932
        when "bib", "bpb", "bbb"
933
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
934
            $asm.puts "blo #{operands[2].asmLabel}"
935
        when "bibeq", "bpbeq", "bbbeq"
936
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
937
            $asm.puts "bls #{operands[2].asmLabel}"
938
        when "bigt", "bpgt", "bbgt"
939
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
940
            $asm.puts "bgt #{operands[2].asmLabel}"
941
        when "bigteq", "bpgteq", "bbgteq"
942
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
943
            $asm.puts "bge #{operands[2].asmLabel}"
944
        when "bilt", "bplt", "bblt"
945
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
946
            $asm.puts "blt #{operands[2].asmLabel}"
947
        when "bilteq", "bplteq", "bblteq"
948
            $asm.puts "cmp #{armV7Operands(operands[0..1])}"
949
            $asm.puts "ble #{operands[2].asmLabel}"
950
        when "btiz", "btpz", "btbz"
951
            emitArmV7Test(operands)
952
            $asm.puts "beq #{operands[-1].asmLabel}"
953
        when "btinz", "btpnz", "btbnz"
954
            emitArmV7Test(operands)
955
            $asm.puts "bne #{operands[-1].asmLabel}"
956
        when "btio", "btpo", "btbo"
957
            emitArmV7Test(operands)
958
            $asm.puts "bvs #{operands[-1].asmLabel}"
959
        when "btis", "btps", "btbs"
960
            emitArmV7Test(operands)
961
            $asm.puts "bmi #{operands[-1].asmLabel}"
962
        when "jmp"
963
            if operands[0].label?
964
                $asm.puts "b #{operands[0].asmLabel}"
965
            else
966
                $asm.puts "mov pc, #{operands[0].armV7Operand}"
967
            end
968
        when "call"
969
            if operands[0].label?
970
                $asm.puts "blx #{operands[0].asmLabel}"
971
            else
972
                $asm.puts "blx #{operands[0].armV7Operand}"
973
            end
974
        when "break"
975
            $asm.puts "bkpt"
976
        when "ret"
977
            $asm.puts "bx lr"
978
        when "cieq", "cpeq"
979
            emitArmV7Compare(operands, "eq")
980
        when "cineq", "cpneq"
981
            emitArmV7Compare(operands, "ne")
982
        when "cia", "cpa"
983
            emitArmV7Compare(operands, "hi")
984
        when "ciaeq", "cpaeq"
985
            emitArmV7Compare(operands, "hs")
986
        when "cib", "cpb"
987
            emitArmV7Compare(operands, "lo")
988
        when "cibeq", "cpbeq"
989
            emitArmV7Compare(operands, "ls")
990
        when "cigt", "cpgt"
991
            emitArmV7Compare(operands, "gt")
992
        when "cigteq", "cpgteq"
993
            emitArmV7Compare(operands, "ge")
994
        when "cilt", "cplt"
995
            emitArmV7Compare(operands, "lt")
996
        when "cilteq", "cplteq"
997
            emitArmV7Compare(operands, "le")
998
        when "tio", "tbo"
999
            emitArmV7TestSet(operands, "vs")
1000
        when "tis", "tbs"
1001
            emitArmV7TestSet(operands, "mi")
1002
        when "tiz", "tbz"
1003
            emitArmV7TestSet(operands, "eq")
1004
        when "tinz", "tbnz"
1005
            emitArmV7TestSet(operands, "ne")
1006
        when "peek"
1007
            $asm.puts "ldr #{operands[1].armV7Operand}, [sp, \##{operands[0].value * 4}]"
1008
        when "poke"
1009
            $asm.puts "str #{operands[1].armV7Operand}, [sp, \##{operands[0].value * 4}]"
1010
        when "fii2d"
1011
            $asm.puts "vmov #{operands[2].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
1012
        when "fd2ii"
1013
            $asm.puts "vmov #{operands[1].armV7Operand}, #{operands[2].armV7Operand}, #{operands[0].armV7Operand}"
1014
        when "bo"
1015
            $asm.puts "bvs #{operands[0].asmLabel}"
1016
        when "bs"
1017
            $asm.puts "bmi #{operands[0].asmLabel}"
1018
        when "bz"
1019
            $asm.puts "beq #{operands[0].asmLabel}"
1020
        when "bnz"
1021
            $asm.puts "bne #{operands[0].asmLabel}"
1022
        when "leai", "leap"
1023
            operands[0].armV7EmitLea(operands[1])
1024
        when "smulli"
1025
            raise "Wrong number of arguments to smull in #{self.inspect} at #{codeOriginString}" unless operands.length == 4
1026
            $asm.puts "smull #{operands[2].armV7Operand}, #{operands[3].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
1027
        else
1028
            raise "Unhandled opcode #{opcode} at #{codeOriginString}"
1029
        end
1030
    end
1031
end
1032
- Source/JavaScriptCore/offlineasm/asm.rb +176 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 "self_hash"
33
require "settings"
34
require "transform"
35
36
class Assembler
37
    def initialize(outp)
38
        @outp = outp
39
        @state = :cpp
40
        @commentState = :none
41
        @comment = nil
42
    end
43
    
44
    def enterAsm
45
        @outp.puts "asm ("
46
        @state = :asm
47
    end
48
    
49
    def leaveAsm
50
        putsLastComment
51
        @outp.puts ");"
52
        @state = :cpp
53
    end
54
    
55
    def inAsm
56
        enterAsm
57
        yield
58
        leaveAsm
59
    end
60
    
61
    def lastComment
62
        if @comment
63
            result = "// #{@comment}"
64
        else
65
            result = ""
66
        end
67
        @commentState = :none
68
        @comment = nil
69
        result
70
    end
71
    
72
    def putsLastComment
73
        comment = lastComment
74
        unless comment.empty?
75
            @outp.puts comment
76
        end
77
    end
78
    
79
    def puts(*line)
80
        raise unless @state == :asm
81
        @outp.puts("\"\\t" + line.join('') + "\\n\" #{lastComment}")
82
    end
83
    
84
    def print(line)
85
        raise unless @state == :asm
86
        @outp.print("\"" + line + "\"")
87
    end
88
    
89
    def putsLabel(labelName)
90
        raise unless @state == :asm
91
        @outp.puts("OFFLINE_ASM_GLOBAL_LABEL(#{labelName}) #{lastComment}")
92
    end
93
    
94
    def putsLocalLabel(labelName)
95
        raise unless @state == :asm
96
        @outp.puts("LOCAL_LABEL_STRING(#{labelName}) \":\\n\" #{lastComment}")
97
    end
98
    
99
    def self.labelReference(labelName)
100
        "\" SYMBOL_STRING(#{labelName}) \""
101
    end
102
    
103
    def self.localLabelReference(labelName)
104
        "\" LOCAL_LABEL_STRING(#{labelName}) \""
105
    end
106
    
107
    def comment(text)
108
        case @commentState
109
        when :none
110
            @comment = text
111
            @commentState = :one
112
        when :one
113
            @outp.puts "// #{@comment}"
114
            @outp.puts "// #{text}"
115
            @comment = nil
116
            @commentState = :many
117
        when :many
118
            @outp.puts "// #{text}"
119
        else
120
            raise
121
        end
122
    end
123
end
124
125
asmFile = ARGV.shift
126
offsetsFile = ARGV.shift
127
outputFlnm = ARGV.shift
128
129
$stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating assembly file #{outputFlnm}."
130
131
configurationList = offsetsAndConfigurationIndex(offsetsFile)
132
inputData = IO::read(asmFile)
133
134
inputHash =
135
    "// offlineasm input hash: " + Digest::SHA1.hexdigest(inputData) +
136
    " " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) +
137
    " " + selfHash
138
139
if FileTest.exist? outputFlnm
140
    File.open(outputFlnm, "r") {
141
        | inp |
142
        firstLine = inp.gets
143
        if firstLine and firstLine.chomp == inputHash
144
            $stderr.puts "offlineasm: Nothing changed."
145
            exit 0
146
        end
147
    }
148
end
149
150
File.open(outputFlnm, "w") {
151
    | outp |
152
    $output = outp
153
    $output.puts inputHash
154
    
155
    $asm = Assembler.new($output)
156
    
157
    ast = parse(lex(inputData))
158
    
159
    configurationList.each {
160
        | configuration |
161
        offsetsList = configuration[0]
162
        configIndex = configuration[1]
163
        forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
164
            | concreteSettings, lowLevelAST, backend |
165
            lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
166
            emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
167
                $asm.inAsm {
168
                    lowLevelAST.lower(backend)
169
                }
170
            }
171
        }
172
    }
173
}
174
175
$stderr.puts "offlineasm: Assembly file #{outputFlnm} successfully generated."
176
- Source/JavaScriptCore/offlineasm/ast.rb +1039 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
    
142
    def address?
143
        false
144
    end
145
    
146
    def label?
147
        false
148
    end
149
    
150
    def immediate?
151
        true
152
    end
153
    
154
    def register?
155
        false
156
    end
157
end
158
159
class Sizeof < NoChildren
160
    attr_reader :struct
161
    
162
    def initialize(codeOrigin, struct)
163
        super(codeOrigin)
164
        @struct = struct
165
    end
166
    
167
    @@mapping = {}
168
    
169
    def self.forName(codeOrigin, struct)
170
        unless @@mapping[struct]
171
            @@mapping[struct] = Sizeof.new(codeOrigin, struct)
172
        end
173
        @@mapping[struct]
174
    end
175
    
176
    def dump
177
        "sizeof #{@struct}"
178
    end
179
    
180
    def <=>(other)
181
        @struct <=> other.struct
182
    end
183
    
184
    def address?
185
        false
186
    end
187
    
188
    def label?
189
        false
190
    end
191
    
192
    def immediate?
193
        true
194
    end
195
    
196
    def register?
197
        false
198
    end
199
end
200
201
class Immediate < NoChildren
202
    attr_reader :value
203
    
204
    def initialize(codeOrigin, value)
205
        super(codeOrigin)
206
        @value = value
207
        raise "Bad immediate value #{value.inspect} at #{codeOriginString}" unless value.is_a? Integer
208
    end
209
    
210
    def dump
211
        "#{value}"
212
    end
213
    
214
    def ==(other)
215
        other.is_a? Immediate and other.value == @value
216
    end
217
    
218
    def address?
219
        false
220
    end
221
    
222
    def label?
223
        false
224
    end
225
    
226
    def immediate?
227
        true
228
    end
229
    
230
    def register?
231
        false
232
    end
233
end
234
235
class AddImmediates < Node
236
    attr_reader :left, :right
237
    
238
    def initialize(codeOrigin, left, right)
239
        super(codeOrigin)
240
        @left = left
241
        @right = right
242
    end
243
    
244
    def children
245
        [@left, @right]
246
    end
247
    
248
    def mapChildren
249
        AddImmediates.new(codeOrigin, (yield @left), (yield @right))
250
    end
251
    
252
    def dump
253
        "(#{left.dump} + #{right.dump})"
254
    end
255
    
256
    def address?
257
        false
258
    end
259
    
260
    def label?
261
        false
262
    end
263
    
264
    def immediate?
265
        true
266
    end
267
    
268
    def register?
269
        false
270
    end
271
end
272
273
class SubImmediates < Node
274
    attr_reader :left, :right
275
    
276
    def initialize(codeOrigin, left, right)
277
        super(codeOrigin)
278
        @left = left
279
        @right = right
280
    end
281
    
282
    def children
283
        [@left, @right]
284
    end
285
    
286
    def mapChildren
287
        SubImmediates.new(codeOrigin, (yield @left), (yield @right))
288
    end
289
    
290
    def dump
291
        "(#{left.dump} - #{right.dump})"
292
    end
293
    
294
    def address?
295
        false
296
    end
297
    
298
    def label?
299
        false
300
    end
301
    
302
    def immediate?
303
        true
304
    end
305
    
306
    def register?
307
        false
308
    end
309
end
310
311
class MulImmediates < Node
312
    attr_reader :left, :right
313
    
314
    def initialize(codeOrigin, left, right)
315
        super(codeOrigin)
316
        @left = left
317
        @right = right
318
    end
319
    
320
    def children
321
        [@left, @right]
322
    end
323
    
324
    def mapChildren
325
        MulImmediates.new(codeOrigin, (yield @left), (yield @right))
326
    end
327
    
328
    def dump
329
        "(#{left.dump} * #{right.dump})"
330
    end
331
    
332
    def address?
333
        false
334
    end
335
    
336
    def label?
337
        false
338
    end
339
    
340
    def immediate?
341
        true
342
    end
343
    
344
    def register?
345
        false
346
    end
347
end
348
349
class NegImmediate < Node
350
    attr_reader :child
351
    
352
    def initialize(codeOrigin, child)
353
        super(codeOrigin)
354
        @child = child
355
    end
356
    
357
    def children
358
        [@child]
359
    end
360
    
361
    def mapChildren
362
        NegImmediate.new(codeOrigin, (yield @child))
363
    end
364
    
365
    def dump
366
        "(-#{@child.dump})"
367
    end
368
    
369
    def address?
370
        false
371
    end
372
    
373
    def label?
374
        false
375
    end
376
    
377
    def immediate?
378
        true
379
    end
380
    
381
    def register?
382
        false
383
    end
384
end
385
386
class RegisterID < NoChildren
387
    attr_reader :name
388
    
389
    def initialize(codeOrigin, name)
390
        super(codeOrigin)
391
        @name = name
392
    end
393
    
394
    @@mapping = {}
395
    
396
    def self.forName(codeOrigin, name)
397
        unless @@mapping[name]
398
            @@mapping[name] = RegisterID.new(codeOrigin, name)
399
        end
400
        @@mapping[name]
401
    end
402
    
403
    def dump
404
        name
405
    end
406
    
407
    def address?
408
        false
409
    end
410
    
411
    def label?
412
        false
413
    end
414
    
415
    def immediate?
416
        false
417
    end
418
    
419
    def register?
420
        true
421
    end
422
end
423
424
class FPRegisterID < NoChildren
425
    attr_reader :name
426
    
427
    def initialize(codeOrigin, name)
428
        super(codeOrigin)
429
        @name = name
430
    end
431
    
432
    @@mapping = {}
433
    
434
    def self.forName(codeOrigin, name)
435
        unless @@mapping[name]
436
            @@mapping[name] = FPRegisterID.new(codeOrigin, name)
437
        end
438
        @@mapping[name]
439
    end
440
    
441
    def dump
442
        name
443
    end
444
    
445
    def address?
446
        false
447
    end
448
    
449
    def label?
450
        false
451
    end
452
    
453
    def immediate?
454
        false
455
    end
456
    
457
    def register?
458
        true
459
    end
460
end
461
462
class Variable < NoChildren
463
    attr_reader :name
464
    
465
    def initialize(codeOrigin, name)
466
        super(codeOrigin)
467
        @name = name
468
    end
469
    
470
    @@mapping = {}
471
    
472
    def self.forName(codeOrigin, name)
473
        unless @@mapping[name]
474
            @@mapping[name] = Variable.new(codeOrigin, name)
475
        end
476
        @@mapping[name]
477
    end
478
    
479
    def dump
480
        name
481
    end
482
end
483
484
class Address < Node
485
    attr_reader :base, :offset
486
    
487
    def initialize(codeOrigin, base, offset)
488
        super(codeOrigin)
489
        @base = base
490
        @offset = offset
491
        raise "Bad base for address #{base.inspect} at #{codeOriginString}" unless base.is_a? Variable or base.register?
492
        raise "Bad offset for address #{offset.inspect} at #{codeOriginString}" unless offset.is_a? Variable or offset.immediate?
493
    end
494
    
495
    def children
496
        [@base, @offset]
497
    end
498
    
499
    def mapChildren
500
        Address.new(codeOrigin, (yield @base), (yield @offset))
501
    end
502
    
503
    def dump
504
        "#{offset.dump}[#{base.dump}]"
505
    end
506
    
507
    def address?
508
        true
509
    end
510
    
511
    def label?
512
        false
513
    end
514
    
515
    def immediate?
516
        false
517
    end
518
    
519
    def register?
520
        false
521
    end
522
end
523
524
class BaseIndex < Node
525
    attr_reader :base, :index, :scale, :offset
526
    
527
    def initialize(codeOrigin, base, index, scale, offset)
528
        super(codeOrigin)
529
        @base = base
530
        @index = index
531
        @scale = scale
532
        raise unless [1, 2, 4, 8].member? @scale
533
        @offset = offset
534
    end
535
    
536
    def scaleShift
537
        case scale
538
        when 1
539
            0
540
        when 2
541
            1
542
        when 4
543
            2
544
        when 8
545
            3
546
        else
547
            raise "Bad scale at #{codeOriginString}"
548
        end
549
    end
550
    
551
    def children
552
        [@base, @index, @offset]
553
    end
554
    
555
    def mapChildren
556
        BaseIndex.new(codeOrigin, (yield @base), (yield @index), @scale, (yield @offset))
557
    end
558
    
559
    def dump
560
        "#{offset.dump}[#{base.dump}, #{index.dump}, #{scale}]"
561
    end
562
    
563
    def address?
564
        true
565
    end
566
    
567
    def label?
568
        false
569
    end
570
    
571
    def immediate?
572
        false
573
    end
574
    
575
    def register?
576
        false
577
    end
578
end
579
580
class AbsoluteAddress < NoChildren
581
    attr_reader :address
582
    
583
    def initialize(codeOrigin, address)
584
        super(codeOrigin)
585
        @address = address
586
    end
587
    
588
    def dump
589
        "#{address.dump}[]"
590
    end
591
    
592
    def address?
593
        true
594
    end
595
    
596
    def label?
597
        false
598
    end
599
    
600
    def immediate?
601
        false
602
    end
603
    
604
    def register?
605
        false
606
    end
607
end
608
609
class Instruction < Node
610
    attr_reader :opcode, :operands
611
    
612
    def initialize(codeOrigin, opcode, operands)
613
        super(codeOrigin)
614
        @opcode = opcode
615
        @operands = operands
616
    end
617
    
618
    def children
619
        operands
620
    end
621
    
622
    def mapChildren(&proc)
623
        Instruction.new(codeOrigin, @opcode, @operands.map(&proc))
624
    end
625
    
626
    def dump
627
        "\t" + opcode.to_s + " " + operands.collect{|v| v.dump}.join(", ")
628
    end
629
end
630
631
class Error < NoChildren
632
    def initialize(codeOrigin)
633
        super(codeOrigin)
634
    end
635
    
636
    def dump
637
        "\terror"
638
    end
639
end
640
641
class ConstDecl < Node
642
    attr_reader :variable, :value
643
    
644
    def initialize(codeOrigin, variable, value)
645
        super(codeOrigin)
646
        @variable = variable
647
        @value = value
648
    end
649
    
650
    def children
651
        [@variable, @value]
652
    end
653
    
654
    def mapChildren
655
        ConstDecl.new(codeOrigin, (yield @variable), (yield @value))
656
    end
657
    
658
    def dump
659
        "const #{@variable.dump} = #{@value.dump}"
660
    end
661
end
662
663
$labelMapping = {}
664
665
class Label < NoChildren
666
    attr_reader :name
667
    
668
    def initialize(codeOrigin, name)
669
        super(codeOrigin)
670
        @name = name
671
    end
672
    
673
    def self.forName(codeOrigin, name)
674
        if $labelMapping[name]
675
            raise "Label name collision: #{name}" unless $labelMapping[name].is_a? Label
676
        else
677
            $labelMapping[name] = Label.new(codeOrigin, name)
678
        end
679
        $labelMapping[name]
680
    end
681
    
682
    def dump
683
        "#{name}:"
684
    end
685
end
686
687
class LocalLabel < NoChildren
688
    attr_reader :name
689
    
690
    def initialize(codeOrigin, name)
691
        super(codeOrigin)
692
        @name = name
693
    end
694
695
    @@uniqueNameCounter = 0
696
    
697
    def self.forName(codeOrigin, name)
698
        if $labelMapping[name]
699
            raise "Label name collision: #{name}" unless $labelMapping[name].is_a? LocalLabel
700
        else
701
            $labelMapping[name] = LocalLabel.new(codeOrigin, name)
702
        end
703
        $labelMapping[name]
704
    end
705
    
706
    def self.unique(comment)
707
        newName = "_#{comment}"
708
        if $labelMapping[newName]
709
            while $labelMapping[newName = "_#{@@uniqueNameCounter}_#{comment}"]
710
                @@uniqueNameCounter += 1
711
            end
712
        end
713
        forName(nil, newName)
714
    end
715
    
716
    def cleanName
717
        if name =~ /^\./
718
            "_" + name[1..-1]
719
        else
720
            name
721
        end
722
    end
723
    
724
    def dump
725
        "#{name}:"
726
    end
727
end
728
729
class LabelReference < Node
730
    attr_reader :label
731
    
732
    def initialize(codeOrigin, label)
733
        super(codeOrigin)
734
        @label = label
735
    end
736
    
737
    def children
738
        [@label]
739
    end
740
    
741
    def mapChildren
742
        LabelReference.new(codeOrigin, (yield @label))
743
    end
744
    
745
    def name
746
        label.name
747
    end
748
    
749
    def dump
750
        label.name
751
    end
752
    
753
    def address?
754
        false
755
    end
756
    
757
    def label?
758
        true
759
    end
760
end
761
762
class LocalLabelReference < NoChildren
763
    attr_reader :label
764
    
765
    def initialize(codeOrigin, label)
766
        super(codeOrigin)
767
        @label = label
768
    end
769
    
770
    def children
771
        [@label]
772
    end
773
    
774
    def mapChildren
775
        LocalLabelReference.new(codeOrigin, (yield @label))
776
    end
777
    
778
    def name
779
        label.name
780
    end
781
    
782
    def dump
783
        label.name
784
    end
785
    
786
    def address?
787
        false
788
    end
789
    
790
    def label?
791
        true
792
    end
793
end
794
795
class Sequence < Node
796
    attr_reader :list
797
    
798
    def initialize(codeOrigin, list)
799
        super(codeOrigin)
800
        @list = list
801
    end
802
    
803
    def children
804
        list
805
    end
806
    
807
    def mapChildren(&proc)
808
        Sequence.new(codeOrigin, @list.map(&proc))
809
    end
810
    
811
    def dump
812
        list.collect{|v| v.dump}.join("\n")
813
    end
814
end
815
816
class True < NoChildren
817
    def initialize
818
        super(nil)
819
    end
820
    
821
    @@instance = True.new
822
    
823
    def self.instance
824
        @@instance
825
    end
826
    
827
    def value
828
        true
829
    end
830
    
831
    def dump
832
        "true"
833
    end
834
end
835
836
class False < NoChildren
837
    def initialize
838
        super(nil)
839
    end
840
    
841
    @@instance = False.new
842
    
843
    def self.instance
844
        @@instance
845
    end
846
    
847
    def value
848
        false
849
    end
850
    
851
    def dump
852
        "false"
853
    end
854
end
855
856
class TrueClass
857
    def asNode
858
        True.instance
859
    end
860
end
861
862
class FalseClass
863
    def asNode
864
        False.instance
865
    end
866
end
867
868
class Setting < NoChildren
869
    attr_reader :name
870
    
871
    def initialize(codeOrigin, name)
872
        super(codeOrigin)
873
        @name = name
874
    end
875
    
876
    @@mapping = {}
877
    
878
    def self.forName(codeOrigin, name)
879
        unless @@mapping[name]
880
            @@mapping[name] = Setting.new(codeOrigin, name)
881
        end
882
        @@mapping[name]
883
    end
884
    
885
    def dump
886
        name
887
    end
888
end
889
890
class And < Node
891
    attr_reader :left, :right
892
    
893
    def initialize(codeOrigin, left, right)
894
        super(codeOrigin)
895
        @left = left
896
        @right = right
897
    end
898
    
899
    def children
900
        [@left, @right]
901
    end
902
    
903
    def mapChildren
904
        And.new(codeOrigin, (yield @left), (yield @right))
905
    end
906
    
907
    def dump
908
        "(#{left.dump} and #{right.dump})"
909
    end
910
end
911
912
class Or < Node
913
    attr_reader :left, :right
914
    
915
    def initialize(codeOrigin, left, right)
916
        super(codeOrigin)
917
        @left = left
918
        @right = right
919
    end
920
    
921
    def children
922
        [@left, @right]
923
    end
924
    
925
    def mapChildren
926
        Or.new(codeOrigin, (yield @left), (yield @right))
927
    end
928
    
929
    def dump
930
        "(#{left.dump} or #{right.dump})"
931
    end
932
end
933
934
class Not < Node
935
    attr_reader :child
936
    
937
    def initialize(codeOrigin, child)
938
        super(codeOrigin)
939
        @child = child
940
    end
941
    
942
    def children
943
        [@left, @right]
944
    end
945
    
946
    def mapChildren
947
        Not.new(codeOrigin, (yield @child))
948
    end
949
    
950
    def dump
951
        "(not #{child.dump})"
952
    end
953
end
954
955
class Skip < NoChildren
956
    def initialize(codeOrigin)
957
        super(codeOrigin)
958
    end
959
    
960
    def dump
961
        "\tskip"
962
    end
963
end
964
965
class IfThenElse < Node
966
    attr_reader :predicate, :thenCase
967
    attr_accessor :elseCase
968
    
969
    def initialize(codeOrigin, predicate, thenCase)
970
        super(codeOrigin)
971
        @predicate = predicate
972
        @thenCase = thenCase
973
        @elseCase = Skip.new(codeOrigin)
974
    end
975
    
976
    def children
977
        if @elseCase
978
            [@predicate, @thenCase, @elseCase]
979
        else
980
            [@predicate, @thenCase]
981
        end
982
    end
983
    
984
    def mapChildren
985
        IfThenElse.new(codeOrigin, (yield @predicate), (yield @thenCase), (yield @elseCase))
986
    end
987
    
988
    def dump
989
        "if #{predicate.dump}\n" + thenCase.dump + "\nelse\n" + elseCase.dump + "\nend"
990
    end
991
end
992
993
class Macro < Node
994
    attr_reader :name, :variables, :body
995
    
996
    def initialize(codeOrigin, name, variables, body)
997
        super(codeOrigin)
998
        @name = name
999
        @variables = variables
1000
        @body = body
1001
    end
1002
    
1003
    def children
1004
        @variables + [@body]
1005
    end
1006
    
1007
    def mapChildren
1008
        Macro.new(codeOrigin, @name, @variables.map{|v| yield v}, (yield @body))
1009
    end
1010
    
1011
    def dump
1012
        "macro #{name}(" + variables.collect{|v| v.dump}.join(", ") + ")\n" + body.dump + "\nend"
1013
    end
1014
end
1015
1016
class MacroCall < Node
1017
    attr_reader :name, :operands
1018
    
1019
    def initialize(codeOrigin, name, operands)
1020
        super(codeOrigin)
1021
        @name = name
1022
        @operands = operands
1023
        raise unless @operands
1024
        @operands.each{|v| raise unless v}
1025
    end
1026
    
1027
    def children
1028
        @operands
1029
    end
1030
    
1031
    def mapChildren(&proc)
1032
        MacroCall.new(codeOrigin, @name, @operands.map(&proc))
1033
    end
1034
    
1035
    def dump
1036
        "\t#{name}(" + operands.collect{|v| v.dump}.join(", ") + ")"
1037
    end
1038
end
1039
- Source/JavaScriptCore/offlineasm/backends.rb +96 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 "armv7"
25
require "ast"
26
require "x86"
27
28
BACKENDS =
29
    [
30
     "X86",
31
     "ARMv7"
32
    ]
33
34
# Keep the set of working backends separate from the set of backends that might be
35
# supported. This is great because the BACKENDS list is almost like a reserved
36
# words list, in that it causes settings resolution to treat those words specially.
37
# Hence this lets us set aside the name of a backend we might want to support in
38
# the future while not actually supporting the backend yet.
39
WORKING_BACKENDS =
40
    [
41
     "X86",
42
     "ARMv7"
43
    ]
44
45
BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
46
47
class Node
48
    def lower(name)
49
        send("lower" + name)
50
    end
51
end
52
53
# Overrides for lower() for those nodes that are backend-agnostic
54
55
class Label
56
    def lower(name)
57
        $asm.putsLabel(self.name[1..-1])
58
    end
59
end
60
61
class LocalLabel
62
    def lower(name)
63
        $asm.putsLocalLabel "_offlineasm_#{self.name[1..-1]}"
64
    end
65
end
66
67
class LabelReference
68
    def asmLabel
69
        Assembler.labelReference(name[1..-1])
70
    end
71
end
72
73
class LocalLabelReference
74
    def asmLabel
75
        Assembler.localLabelReference("_offlineasm_"+name[1..-1])
76
    end
77
end
78
79
class Skip
80
    def lower(name)
81
    end
82
end
83
84
class Sequence
85
    def lower(name)
86
        if respond_to? "lower#{name}"
87
            send("lower#{name}")
88
        else
89
            @list.each {
90
                | node |
91
                node.lower(name)
92
            }
93
        end
94
    end
95
end
96
- Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb +146 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 "self_hash"
33
require "settings"
34
require "transform"
35
36
inputFlnm = ARGV.shift
37
outputFlnm = ARGV.shift
38
39
$stderr.puts "offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
40
41
def emitMagicNumber
42
    OFFSET_MAGIC_NUMBERS.each {
43
        | number |
44
        $output.puts "#{number},"
45
    }
46
end
47
48
inputData = IO::read(inputFlnm)
49
inputHash = "// offlineasm input hash: #{Digest::SHA1.hexdigest(inputData)} #{selfHash}"
50
51
if FileTest.exist? outputFlnm
52
    File.open(outputFlnm, "r") {
53
        | inp |
54
        firstLine = inp.gets
55
        if firstLine and firstLine.chomp == inputHash
56
            $stderr.puts "offlineasm: Nothing changed."
57
            exit 0
58
        end
59
    }
60
end
61
62
originalAST = parse(lex(inputData))
63
64
#
65
# Optimize the AST to make configuration extraction faster. This reduces the AST to a form
66
# that only contains the things that matter for our purposes: offsets, sizes, and if
67
# statements.
68
#
69
70
class Node
71
    def offsetsPruneTo(sequence)
72
        children.each {
73
            | child |
74
            child.offsetsPruneTo(sequence)
75
        }
76
    end
77
    
78
    def offsetsPrune
79
        result = Sequence.new(codeOrigin, [])
80
        offsetsPruneTo(result)
81
        result
82
    end
83
end
84
85
class IfThenElse
86
    def offsetsPruneTo(sequence)
87
        ifThenElse = IfThenElse.new(codeOrigin, predicate, thenCase.offsetsPrune)
88
        ifThenElse.elseCase = elseCase.offsetsPrune
89
        sequence.list << ifThenElse
90
    end
91
end
92
93
class StructOffset
94
    def offsetsPruneTo(sequence)
95
        sequence.list << self
96
    end
97
end
98
99
class Sizeof
100
    def offsetsPruneTo(sequence)
101
        sequence.list << self
102
    end
103
end
104
105
prunedAST = originalAST.offsetsPrune
106
107
File.open(outputFlnm, "w") {
108
    | outp |
109
    $output = outp
110
    outp.puts inputHash
111
    length = 0
112
    emitCodeInAllConfigurations(prunedAST) {
113
        | settings, ast, backend, index |
114
        offsetsList = ast.filter(StructOffset).uniq.sort
115
        sizesList = ast.filter(Sizeof).uniq.sort
116
        length += OFFSET_HEADER_MAGIC_NUMBERS.size + (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size)
117
    }
118
    outp.puts "static const unsigned extractorTable[#{length}] = {"
119
    emitCodeInAllConfigurations(prunedAST) {
120
        | settings, ast, backend, index |
121
        OFFSET_HEADER_MAGIC_NUMBERS.each {
122
            | number |
123
            $output.puts "#{number},"
124
        }
125
126
        offsetsList = ast.filter(StructOffset).uniq.sort
127
        sizesList = ast.filter(Sizeof).uniq.sort
128
        
129
        emitMagicNumber
130
        outp.puts "#{index},"
131
        offsetsList.each {
132
            | offset |
133
            emitMagicNumber
134
            outp.puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
135
        }
136
        sizesList.each {
137
            | offset |
138
            emitMagicNumber
139
            outp.puts "sizeof(#{offset.struct}),"
140
        }
141
    }
142
    outp.puts "};"
143
}
144
145
$stderr.puts "offlineasm: offset extractor #{outputFlnm} successfully generated."
146
- Source/JavaScriptCore/offlineasm/instructions.rb +217 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
# Interesting invariant, which we take advantage of: branching instructions
25
# always begin with "b", and no non-branching instructions begin with "b".
26
# Terminal instructions are "jmp" and "ret".
27
28
MACRO_INSTRUCTIONS =
29
    [
30
     "addi",
31
     "andi",
32
     "lshifti",
33
     "muli",
34
     "negi",
35
     "noti",
36
     "ori",
37
     "rshifti",
38
     "urshifti",
39
     "subi",
40
     "xori",
41
     "loadi",
42
     "loadb",
43
     "loadbs",
44
     "loadh",
45
     "loadhs",
46
     "storei",
47
     "storeb",
48
     "loadd",
49
     "moved",
50
     "stored",
51
     "addd",
52
     "divd",
53
     "subd",
54
     "muld",
55
     "sqrtd",
56
     "ci2d",
57
     "fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr>
58
     "fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
59
     "bdeq",
60
     "bdneq",
61
     "bdgt",
62
     "bdgteq",
63
     "bdlt",
64
     "bdlteq",
65
     "bdequn",
66
     "bdnequn",
67
     "bdgtun",
68
     "bdgtequn",
69
     "bdltun",
70
     "bdltequn",
71
     "btd2i",
72
     "td2i",
73
     "bcd2i",
74
     "movdz",
75
     "pop",
76
     "push",
77
     "move",
78
     "sxi2p",
79
     "zxi2p",
80
     "nop",
81
     "bieq",
82
     "bineq",
83
     "bia",
84
     "biaeq",
85
     "bib",
86
     "bibeq",
87
     "bigt",
88
     "bigteq",
89
     "bilt",
90
     "bilteq",
91
     "bbeq",
92
     "bbneq",
93
     "bba",
94
     "bbaeq",
95
     "bbb",
96
     "bbbeq",
97
     "bbgt",
98
     "bbgteq",
99
     "bblt",
100
     "bblteq",
101
     "btio",
102
     "btis",
103
     "btiz",
104
     "btinz",
105
     "btbo",
106
     "btbs",
107
     "btbz",
108
     "btbnz",
109
     "jmp",
110
     "baddio",
111
     "baddis",
112
     "baddiz",
113
     "baddinz",
114
     "bsubio",
115
     "bsubis",
116
     "bsubiz",
117
     "bsubinz",
118
     "bmulio",
119
     "bmulis",
120
     "bmuliz",
121
     "bmulinz",
122
     "borio",
123
     "boris",
124
     "boriz",
125
     "borinz",
126
     "break",
127
     "call",
128
     "ret",
129
     "cieq",
130
     "cineq",
131
     "cia",
132
     "ciaeq",
133
     "cib",
134
     "cibeq",
135
     "cigt",
136
     "cigteq",
137
     "cilt",
138
     "cilteq",
139
     "tio",
140
     "tis",
141
     "tiz",
142
     "tinz",
143
     "tbo",
144
     "tbs",
145
     "tbz",
146
     "tbnz",
147
     "peek",
148
     "poke",
149
     "bpeq",
150
     "bpneq",
151
     "bpa",
152
     "bpaeq",
153
     "bpb",
154
     "bpbeq",
155
     "bpgt",
156
     "bpgteq",
157
     "bplt",
158
     "bplteq",
159
     "addp",
160
     "andp",
161
     "orp",
162
     "subp",
163
     "xorp",
164
     "loadp",
165
     "cpeq",
166
     "cpneq",
167
     "cpa",
168
     "cpaeq",
169
     "cpb",
170
     "cpbeq",
171
     "cpgt",
172
     "cpgteq",
173
     "cplt",
174
     "cplteq",
175
     "storep",
176
     "btpo",
177
     "btps",
178
     "btpz",
179
     "btpnz",
180
     "baddpo",
181
     "baddps",
182
     "baddpz",
183
     "baddpnz",
184
     "bo",
185
     "bs",
186
     "bz",
187
     "bnz",
188
     "leai",
189
     "leap",
190
    ]
191
192
X86_INSTRUCTIONS =
193
    [
194
     "cdqi",
195
     "idivi"
196
    ]
197
198
ARMv7_INSTRUCTIONS =
199
    [
200
     "smulli",
201
     "addis",
202
     "subis",
203
     "oris"
204
    ]
205
206
INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARMv7_INSTRUCTIONS
207
208
INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
209
210
def isBranch(instruction)
211
    instruction =~ /^b/
212
end
213
214
def hasFallThrough(instruction)
215
    instruction != "ret" and instruction != "jmp"
216
end
217
- Source/JavaScriptCore/offlineasm/offsets.rb +173 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
26
OFFSET_HEADER_MAGIC_NUMBERS = [ 0x9e43fd66, 0x4379bfba ]
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
    endiannessMarkerBytes = nil
54
    result = []
55
    
56
    def readInt(endianness, bytes)
57
        if endianness == :little
58
            # Little endian
59
            (bytes[0] << 0 |
60
             bytes[1] << 8 |
61
             bytes[2] << 16 |
62
             bytes[3] << 24)
63
        else
64
            # Big endian
65
            (bytes[0] << 24 |
66
             bytes[1] << 16 |
67
             bytes[2] << 8 |
68
             bytes[3] << 0)
69
        end
70
    end
71
    
72
    def prepareMagic(endianness, numbers)
73
        magicBytes = []
74
        numbers.each {
75
            | number |
76
            currentBytes = []
77
            4.times {
78
                currentBytes << (number & 0xff)
79
                number >>= 8
80
            }
81
            if endianness == :big
82
                currentBytes.reverse!
83
            end
84
            magicBytes += currentBytes
85
        }
86
        magicBytes
87
    end
88
    
89
    fileBytes = []
90
    
91
    File.open(file, "r") {
92
        | inp |
93
        loop {
94
            byte = inp.getbyte
95
            break unless byte
96
            fileBytes << byte
97
        }
98
    }
99
    
100
    def sliceByteArrays(byteArray, pattern)
101
        result = []
102
        lastSlicePoint = 0
103
        (byteArray.length - pattern.length + 1).times {
104
            | index |
105
            foundOne = true
106
            pattern.length.times {
107
                | subIndex |
108
                if byteArray[index + subIndex] != pattern[subIndex]
109
                    foundOne = false
110
                    break
111
                end
112
            }
113
            if foundOne
114
                result << byteArray[lastSlicePoint...index]
115
                lastSlicePoint = index + pattern.length
116
            end
117
        }
118
        
119
        result << byteArray[lastSlicePoint...(byteArray.length)]
120
        
121
        result
122
    end
123
    
124
    [:little, :big].each {
125
        | endianness |
126
        headerMagicBytes = prepareMagic(endianness, OFFSET_HEADER_MAGIC_NUMBERS)
127
        magicBytes = prepareMagic(endianness, OFFSET_MAGIC_NUMBERS)
128
        
129
        bigArray = sliceByteArrays(fileBytes, headerMagicBytes)
130
        unless bigArray.size <= 1
131
            bigArray[1..-1].each {
132
                | configArray |
133
                array = sliceByteArrays(configArray, magicBytes)
134
                index = readInt(endianness, array[1])
135
                offsets = []
136
                array[2..-1].each {
137
                    | data |
138
                    offsets << readInt(endianness, data)
139
                }
140
                result << [offsets, index]
141
            }
142
        end
143
    }
144
    
145
    raise unless result.length >= 1
146
    raise if result.map{|v| v[1]}.uniq.size < result.map{|v| v[1]}.size
147
    
148
    result
149
end
150
151
#
152
# buildOffsetsMap(ast, offsetsList) -> [offsets, sizes]
153
#
154
# Builds a mapping between StructOffset nodes and their values.
155
#
156
157
def buildOffsetsMap(ast, offsetsList)
158
    offsetsMap = {}
159
    sizesMap = {}
160
    astOffsetsList = offsetsList(ast)
161
    astSizesList = sizesList(ast)
162
    raise unless astOffsetsList.size + astSizesList.size == offsetsList.size
163
    offsetsList(ast).each_with_index {
164
        | structOffset, index |
165
        offsetsMap[structOffset] = offsetsList.shift
166
    }
167
    sizesList(ast).each_with_index {
168
        | sizeof, index |
169
        sizesMap[sizeof] = offsetsList.shift
170
    }
171
    [offsetsMap, sizesMap]
172
end
173
- Source/JavaScriptCore/offlineasm/opt.rb +134 lines
Line 0 Source/JavaScriptCore/offlineasm/opt.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
# "Optimization" passes. These are used to lower the representation for
28
# backends that cannot handle some of our higher-level instructions.
29
#
30
31
#
32
# A temporary - a variable that will be allocated to a register after we're
33
# done.
34
#
35
36
class Node
37
    def replaceTemporariesWithRegisters(kind)
38
        mapChildren {
39
            | node |
40
            node.replaceTemporariesWithRegisters(kind)
41
        }
42
    end
43
end
44
45
class Tmp < NoChildren
46
    attr_reader :firstMention, :lastMention
47
    attr_reader :kind
48
    attr_accessor :register
49
50
    def initialize(codeOrigin, kind)
51
        super(codeOrigin)
52
        @kind = kind
53
    end
54
    
55
    def dump
56
        "$tmp#{object_id}"
57
    end
58
    
59
    def mention!(position)
60
        if not @firstMention or position < @firstMention
61
            @firstMention = position
62
        end
63
        if not @lastMention or position > @lastMention
64
            @lastMention = position
65
        end
66
    end
67
    
68
    def replaceTemporariesWithRegisters(kind)
69
        if @kind == kind
70
            raise "Did not allocate register to temporary at #{codeOriginString}" unless @register
71
            @register
72
        else
73
            self
74
        end
75
    end
76
    
77
    def address?
78
        false
79
    end
80
    
81
    def label?
82
        false
83
    end
84
    
85
    def immediate?
86
        false
87
    end
88
    
89
    def register?
90
        true
91
    end
92
end
93
94
# Assign registers to temporaries, by finding which temporaries interfere
95
# with each other. Note that this relies on temporary live ranges not crossing
96
# basic block boundaries.
97
98
def assignRegistersToTemporaries(list, kind, registers)
99
    list.each_with_index {
100
        | node, index |
101
        node.filter(Tmp).uniq.each {
102
            | tmp |
103
            if tmp.kind == kind
104
                tmp.mention! index
105
            end
106
        }
107
    }
108
    
109
    freeRegisters = registers.dup
110
    list.each_with_index {
111
        | node, index |
112
        tmpList = node.filter(Tmp).uniq
113
        tmpList.each {
114
            | tmp |
115
            if tmp.kind == kind and tmp.firstMention == index
116
                raise "Could not allocate register to temporary at #{node.codeOriginString}" if freeRegisters.empty?
117
                tmp.register = freeRegisters.pop
118
            end
119
        }
120
        tmpList.each {
121
            | tmp |
122
            if tmp.kind == kind and tmp.lastMention == index
123
                freeRegisters.push tmp.register
124
                raise "Register allocation inconsistency at #{node.codeOriginString}" if freeRegisters.size > registers.size
125
            end
126
        }
127
    }
128
    
129
    list.map {
130
        | node |
131
        node.replaceTemporariesWithRegisters(kind)
132
    }
133
end
134
- Source/JavaScriptCore/offlineasm/parser.rb +586 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
        skipNewLine
374
        if couldBeExpression
375
            expr = parseExpression
376
            if @tokens[@idx] == "["
377
                parseAddress(expr)
378
            else
379
                expr
380
            end
381
        elsif @tokens[@idx] == "["
382
            parseAddress(Immediate.new(@tokens[@idx].codeOrigin, 0))
383
        elsif isLabel @tokens[@idx]
384
            result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
385
            @idx += 1
386
            result
387
        elsif isLocalLabel @tokens[@idx]
388
            result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
389
            @idx += 1
390
            result
391
        else
392
            parseError(comment)
393
        end
394
    end
395
    
396
    def parseMacroVariables
397
        skipNewLine
398
        consume(/\A\(\Z/)
399
        variables = []
400
        loop {
401
            skipNewLine
402
            if @tokens[@idx] == ")"
403
                @idx += 1
404
                break
405
            elsif isIdentifier(@tokens[@idx])
406
                variables << Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
407
                @idx += 1
408
                skipNewLine
409
                if @tokens[@idx] == ")"
410
                    @idx += 1
411
                    break
412
                elsif @tokens[@idx] == ","
413
                    @idx += 1
414
                else
415
                    parseError
416
                end
417
            else
418
                parseError
419
            end
420
        }
421
        variables
422
    end
423
    
424
    def parseSequence(final, comment)
425
        firstCodeOrigin = @tokens[@idx].codeOrigin
426
        list = []
427
        loop {
428
            if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
429
                break
430
            elsif @tokens[@idx] == "\n"
431
                # ignore
432
                @idx += 1
433
            elsif @tokens[@idx] == "const"
434
                @idx += 1
435
                parseError unless isVariable @tokens[@idx]
436
                variable = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
437
                @idx += 1
438
                parseError unless @tokens[@idx] == "="
439
                @idx += 1
440
                value = parseOperand("while inside of const #{variable.name}")
441
                list << ConstDecl.new(@tokens[@idx].codeOrigin, variable, value)
442
            elsif @tokens[@idx] == "error"
443
                list << Error.new(@tokens[@idx].codeOrigin)
444
                @idx += 1
445
            elsif @tokens[@idx] == "if"
446
                codeOrigin = @tokens[@idx].codeOrigin
447
                @idx += 1
448
                skipNewLine
449
                predicate = parsePredicate
450
                consume(/\A((then)|(\n))\Z/)
451
                skipNewLine
452
                ifThenElse = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
453
                list << ifThenElse
454
                while @tokens[@idx] == "elsif"
455
                    codeOrigin = @tokens[@idx].codeOrigin
456
                    @idx += 1
457
                    skipNewLine
458
                    predicate = parsePredicate
459
                    consume(/\A((then)|(\n))\Z/)
460
                    skipNewLine
461
                    elseCase = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
462
                    ifThenElse.elseCase = elseCase
463
                    ifThenElse = elseCase
464
                end
465
                if @tokens[@idx] == "else"
466
                    @idx += 1
467
                    ifThenElse.elseCase = parseSequence(/\Aend\Z/, "while inside of else case for \"if #{predicate.dump}\"")
468
                    @idx += 1
469
                else
470
                    parseError unless @tokens[@idx] == "end"
471
                    @idx += 1
472
                end
473
            elsif @tokens[@idx] == "macro"
474
                codeOrigin = @tokens[@idx].codeOrigin
475
                @idx += 1
476
                skipNewLine
477
                parseError unless isIdentifier(@tokens[@idx])
478
                name = @tokens[@idx].string
479
                @idx += 1
480
                variables = parseMacroVariables
481
                body = parseSequence(/\Aend\Z/, "while inside of macro #{name}")
482
                @idx += 1
483
                list << Macro.new(codeOrigin, name, variables, body)
484
            elsif isInstruction @tokens[@idx]
485
                codeOrigin = @tokens[@idx].codeOrigin
486
                name = @tokens[@idx].string
487
                @idx += 1
488
                if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
489
                    # Zero operand instruction, and it's the last one.
490
                    list << Instruction.new(codeOrigin, name, [])
491
                    break
492
                elsif @tokens[@idx] == "\n"
493
                    # Zero operand instruction.
494
                    list << Instruction.new(codeOrigin, name, [])
495
                    @idx += 1
496
                else
497
                    # It's definitely an instruction, and it has at least one operand.
498
                    operands = []
499
                    endOfSequence = false
500
                    loop {
501
                        operands << parseOperand("while inside of instruction #{name}")
502
                        if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
503
                            # The end of the instruction and of the sequence.
504
                            endOfSequence = true
505
                            break
506
                        elsif @tokens[@idx] == ","
507
                            # Has another operand.
508
                            @idx += 1
509
                        elsif @tokens[@idx] == "\n"
510
                            # The end of the instruction.
511
                            @idx += 1
512
                            break
513
                        else
514
                            parseError("Expected a comma, newline, or #{final} after #{operands.last.dump}")
515
                        end
516
                    }
517
                    list << Instruction.new(codeOrigin, name, operands)
518
                    if endOfSequence
519
                        break
520
                    end
521
                end
522
            elsif isIdentifier @tokens[@idx]
523
                codeOrigin = @tokens[@idx].codeOrigin
524
                name = @tokens[@idx].string
525
                @idx += 1
526
                if @tokens[@idx] == "("
527
                    # Macro invocation.
528
                    @idx += 1
529
                    operands = []
530
                    skipNewLine
531
                    if @tokens[@idx] == ")"
532
                        @idx += 1
533
                    else
534
                        loop {
535
                            skipNewLine
536
                            if @tokens[@idx] == "macro"
537
                                # It's a macro lambda!
538
                                codeOriginInner = @tokens[@idx].codeOrigin
539
                                @idx += 1
540
                                variables = parseMacroVariables
541
                                body = parseSequence(/\Aend\Z/, "while inside of anonymous macro passed as argument to #{name}")
542
                                @idx += 1
543
                                operands << Macro.new(codeOriginInner, nil, variables, body)
544
                            else
545
                                operands << parseOperand("while inside of macro call to #{name}")
546
                            end
547
                            skipNewLine
548
                            if @tokens[@idx] == ")"
549
                                @idx += 1
550
                                break
551
                            elsif @tokens[@idx] == ","
552
                                @idx += 1
553
                            else
554
                                parseError "Unexpected #{@tokens[@idx].string.inspect} while parsing invocation of macro #{name}"
555
                            end
556
                        }
557
                    end
558
                    list << MacroCall.new(codeOrigin, name, operands)
559
                else
560
                    parseError "Expected \"(\" after #{name}"
561
                end
562
            elsif isLabel @tokens[@idx] or isLocalLabel @tokens[@idx]
563
                codeOrigin = @tokens[@idx].codeOrigin
564
                name = @tokens[@idx].string
565
                @idx += 1
566
                parseError unless @tokens[@idx] == ":"
567
                # It's a label.
568
                if isLabel name
569
                    list << Label.forName(codeOrigin, name)
570
                else
571
                    list << LocalLabel.forName(codeOrigin, name)
572
                end
573
                @idx += 1
574
            else
575
                parseError "Expecting terminal #{final} #{comment}"
576
            end
577
        }
578
        Sequence.new(firstCodeOrigin, list)
579
    end
580
end
581
582
def parse(tokens)
583
    parser = Parser.new(tokens)
584
    parser.parseSequence(nil, "")
585
end
586
- Source/JavaScriptCore/offlineasm/registers.rb +60 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
     "lr"
38
    ]
39
40
FPRS =
41
    [
42
     "ft0",
43
     "ft1",
44
     "ft2",
45
     "ft3",
46
     "ft4",
47
     "ft5",
48
     "fa0",
49
     "fa1",
50
     "fa2",
51
     "fa3",
52
     "fr"
53
    ]
54
55
REGISTERS = GPRS + FPRS
56
57
GPR_PATTERN = Regexp.new('\\A((' + GPRS.join(')|(') + '))\\Z')
58
FPR_PATTERN = Regexp.new('\\A((' + FPRS.join(')|(') + '))\\Z')
59
60
REGISTER_PATTERN = Regexp.new('\\A((' + REGISTERS.join(')|(') + '))\\Z')
- Source/JavaScriptCore/offlineasm/self_hash.rb +46 lines
Line 0 Source/JavaScriptCore/offlineasm/self_hash.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 "digest/sha1"
25
require "pathname"
26
27
#
28
# selfHash -> SHA1 hexdigest
29
#
30
# Returns a hash of the offlineasm source code. This allows dependency
31
# tracking for not just changes in input, but also changes in the assembler
32
# itself.
33
#
34
35
def selfHash
36
    contents = ""
37
    myPath = Pathname.new(__FILE__).dirname
38
    Dir.foreach(myPath) {
39
        | entry |
40
        if entry =~ /\.rb$/
41
            contents += IO::read(myPath + entry)
42
        end
43
    }
44
    return Digest::SHA1.hexdigest(contents)
45
end
46
- 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 +681 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 "Bad register #{name} for X86 at #{codeOriginString}"
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 "Bad register #{name} for X86 at #{codeOriginString}"
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 x86CallOperand(kind)
201
        asmLabel
202
    end
203
end
204
205
class LocalLabelReference
206
    def x86CallOperand(kind)
207
        asmLabel
208
    end
209
end
210
211
class Instruction
212
    def x86Operands(*kinds)
213
        raise unless kinds.size == operands.size
214
        result = []
215
        kinds.size.times {
216
            | idx |
217
            result << operands[idx].x86Operand(kinds[idx])
218
        }
219
        result.join(", ")
220
    end
221
222
    def x86Suffix(kind)
223
        case kind
224
        when :byte
225
            "b"
226
        when :half
227
            "w"
228
        when :int
229
            "l"
230
        when :double
231
            "sd"
232
        else
233
            raise
234
        end
235
    end
236
    
237
    def handleX86OpWithNumOperands(opcode, kind, numOperands)
238
        if numOperands == 3
239
            if operands[0] == operands[2]
240
                $asm.puts "#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
241
            elsif operands[1] == operands[2]
242
                $asm.puts "#{opcode} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
243
            else
244
                $asm.puts "mov#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
245
                $asm.puts "#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
246
            end
247
        else
248
            $asm.puts "#{opcode} #{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
249
        end
250
    end
251
    
252
    def handleX86Op(opcode, kind)
253
        handleX86OpWithNumOperands(opcode, kind, operands.size)
254
    end
255
    
256
    def handleX86Shift(opcode, kind)
257
        if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
258
            $asm.puts "#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
259
        else
260
            $asm.puts "xchgl #{operands[0].x86Operand(:int)}, %ecx"
261
            $asm.puts "#{opcode} %cl, #{operands[1].x86Operand(kind)}"
262
            $asm.puts "xchgl #{operands[0].x86Operand(:int)}, %ecx"
263
        end
264
    end
265
    
266
    def handleX86DoubleBranch(branchOpcode, mode)
267
        case mode
268
        when :normal
269
            $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
270
        when :reverse
271
            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
272
        else
273
            raise mode.inspect
274
        end
275
        $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
276
    end
277
    
278
    def handleX86IntCompare(opcodeSuffix, kind)
279
        if operands[0].is_a? Immediate and operands[0].value == 0 and operands[1].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
280
            $asm.puts "test#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}"
281
        elsif operands[1].is_a? Immediate and operands[1].value == 0 and operands[0].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
282
            $asm.puts "test#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}"
283
        else
284
            $asm.puts "cmp#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
285
        end
286
    end
287
    
288
    def handleX86IntBranch(branchOpcode, kind)
289
        handleX86IntCompare(branchOpcode[1..-1], kind)
290
        $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
291
    end
292
    
293
    def handleX86Set(setOpcode, operand)
294
        if operand.supports8BitOnX86
295
            $asm.puts "#{setOpcode} #{operand.x86Operand(:byte)}"
296
            $asm.puts "movzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
297
        else
298
            $asm.puts "xchgl #{operand.x86Operand(:int)}, %eax"
299
            $asm.puts "#{setOpcode} %al"
300
            $asm.puts "movzbl %al, %eax"
301
            $asm.puts "xchgl #{operand.x86Operand(:int)}, %eax"
302
        end
303
    end
304
    
305
    def handleX86IntCompareSet(setOpcode, kind)
306
        handleX86IntCompare(setOpcode[3..-1], kind)
307
        handleX86Set(setOpcode, operands[2])
308
    end
309
    
310
    def handleX86Test(kind)
311
        value = operands[0]
312
        case operands.size
313
        when 2
314
            mask = Immediate.new(codeOrigin, -1)
315
        when 3
316
            mask = operands[1]
317
        else
318
            raise "Expected 2 or 3 operands, but got #{operands.size} at #{codeOriginString}"
319
        end
320
        
321
        if mask.is_a? Immediate and mask.value == -1
322
            if value.is_a? RegisterID
323
                $asm.puts "test#{x86Suffix(kind)} #{value.x86Operand(kind)}, #{value.x86Operand(kind)}"
324
            else
325
                $asm.puts "cmp#{x86Suffix(kind)} $0, #{value.x86Operand(kind)}"
326
            end
327
        else
328
            $asm.puts "test#{x86Suffix(kind)} #{mask.x86Operand(kind)}, #{value.x86Operand(kind)}"
329
        end
330
    end
331
    
332
    def handleX86BranchTest(branchOpcode, kind)
333
        handleX86Test(kind)
334
        $asm.puts "#{branchOpcode} #{operands.last.asmLabel}"
335
    end
336
    
337
    def handleX86SetTest(setOpcode, kind)
338
        handleX86Test(kind)
339
        handleX86Set(setOpcode, operands.last)
340
    end
341
    
342
    def handleX86OpBranch(opcode, branchOpcode, kind)
343
        handleX86OpWithNumOperands(opcode, kind, operands.size - 1)
344
        case operands.size
345
        when 4
346
            jumpTarget = operands[3]
347
        when 3
348
            jumpTarget = operands[2]
349
        else
350
            raise self.inspect
351
        end
352
        $asm.puts "#{branchOpcode} #{jumpTarget.asmLabel}"
353
    end
354
    
355
    def handleX86SubBranch(branchOpcode, kind)
356
        if operands.size == 4 and operands[1] == operands[2]
357
            $asm.puts "negl #{operands[2].x86Operand(:int)}"
358
            $asm.puts "addl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
359
        else
360
            handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind, operands.size - 1)
361
        end
362
        case operands.size
363
        when 4
364
            jumpTarget = operands[3]
365
        when 3
366
            jumpTarget = operands[2]
367
        else
368
            raise self.inspect
369
        end
370
        $asm.puts "#{branchOpcode} #{jumpTarget.asmLabel}"
371
    end
372
    
373
    def lowerX86
374
        $asm.comment codeOriginString
375
        case opcode
376
        when "addi", "addp"
377
            if operands.size == 3 and operands[0].is_a? Immediate
378
                raise unless operands[1].is_a? RegisterID
379
                raise unless operands[2].is_a? RegisterID
380
                if operands[0].value == 0
381
                    unless operands[1] == operands[2]
382
                        $asm.puts "movl #{operands[1].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
383
                    end
384
                else
385
                    $asm.puts "leal #{operands[0].value}(#{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
386
                end
387
            elsif operands.size == 3 and operands[0].is_a? RegisterID
388
                raise unless operands[1].is_a? RegisterID
389
                raise unless operands[2].is_a? RegisterID
390
                $asm.puts "leal (#{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
391
            else
392
                unless Immediate.new(nil, 0) == operands[0]
393
                    $asm.puts "addl #{x86Operands(:int, :int)}"
394
                end
395
            end
396
        when "andi", "andp"
397
            handleX86Op("andl", :int)
398
        when "lshifti"
399
            handleX86Shift("sall", :int)
400
        when "muli"
401
            if operands.size == 3 and operands[0].is_a? Immediate
402
                $asm.puts "imull #{x86Operands(:int, :int, :int)}"
403
            else
404
                # FIXME: could do some peephole in case the left operand is immediate and it's
405
                # a power of two.
406
                handleX86Op("imull", :int)
407
            end
408
        when "negi"
409
            $asm.puts "negl #{x86Operands(:int)}"
410
        when "noti"
411
            $asm.puts "notl #{x86Operands(:int)}"
412
        when "ori", "orp"
413
            handleX86Op("orl", :int)
414
        when "rshifti"
415
            handleX86Shift("sarl", :int)
416
        when "urshifti"
417
            handleX86Shift("shrl", :int)
418
        when "subi", "subp"
419
            if operands.size == 3 and operands[1] == operands[2]
420
                $asm.puts "negl #{operands[2].x86Operand(:int)}"
421
                $asm.puts "addl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
422
            else
423
                handleX86Op("subl", :int)
424
            end
425
        when "xori", "xorp"
426
            handleX86Op("xorl", :int)
427
        when "loadi", "storei", "loadp", "storep"
428
            $asm.puts "movl #{x86Operands(:int, :int)}"
429
        when "loadb"
430
            $asm.puts "movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
431
        when "loadbs"
432
            $asm.puts "movsbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
433
        when "loadh"
434
            $asm.puts "movzwl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
435
        when "loadhs"
436
            $asm.puts "movswl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
437
        when "storeb"
438
            $asm.puts "movb #{x86Operands(:byte, :byte)}"
439
        when "loadd", "moved", "stored"
440
            $asm.puts "movsd #{x86Operands(:double, :double)}"
441
        when "addd"
442
            $asm.puts "addsd #{x86Operands(:double, :double)}"
443
        when "divd"
444
            $asm.puts "divsd #{x86Operands(:double, :double)}"
445
        when "subd"
446
            $asm.puts "subsd #{x86Operands(:double, :double)}"
447
        when "muld"
448
            $asm.puts "mulsd #{x86Operands(:double, :double)}"
449
        when "sqrtd"
450
            $asm.puts "sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
451
        when "ci2d"
452
            $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
453
        when "bdeq"
454
            isUnordered = LocalLabel.unique("bdeq")
455
            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
456
            $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
457
            $asm.puts "je #{LabelReference.new(codeOrigin, operands[2]).asmLabel}"
458
            isUnordered.lower("X86")
459
        when "bdneq"
460
            handleX86DoubleBranch("jne", :normal)
461
        when "bdgt"
462
            handleX86DoubleBranch("ja", :normal)
463
        when "bdgteq"
464
            handleX86DoubleBranch("jae", :normal)
465
        when "bdlt"
466
            handleX86DoubleBranch("ja", :reverse)
467
        when "bdlteq"
468
            handleX86DoubleBranch("jae", :reverse)
469
        when "bdequn"
470
            handleX86DoubleBranch("je", :normal)
471
        when "bdnequn"
472
            isUnordered = LocalLabel.unique("bdnequn")
473
            isEqual = LocalLabel.unique("bdnequn")
474
            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
475
            $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
476
            $asm.puts "je #{LabelReference.new(codeOrigin, isEqual).asmLabel}"
477
            isUnordered.lower("X86")
478
            $asm.puts "jmp #{operands[2].asmLabel}"
479
            isEqual.lower("X86")
480
        when "bdgtun"
481
            handleX86DoubleBranch("jb", :reverse)
482
        when "bdgtequn"
483
            handleX86DoubleBranch("jbe", :reverse)
484
        when "bdltun"
485
            handleX86DoubleBranch("jb", :normal)
486
        when "bdltequn"
487
            handleX86DoubleBranch("jbe", :normal)
488
        when "btd2i"
489
            $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
490
            $asm.puts "cmpl $0x80000000 #{operands[1].x86Operand(:int)}"
491
            $asm.puts "je #{operands[2].asmLabel}"
492
        when "td2i"
493
            $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
494
        when "bcd2i"
495
            $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
496
            $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
497
            $asm.puts "je #{operands[2].asmLabel}"
498
            $asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
499
            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
500
            $asm.puts "jp #{operands[2].asmLabel}"
501
            $asm.puts "jne #{operands[2].asmLabel}"
502
        when "movdz"
503
            $asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
504
        when "pop"
505
            $asm.puts "pop #{operands[0].x86Operand(:int)}"
506
        when "push"
507
            $asm.puts "push #{operands[0].x86Operand(:int)}"
508
        when "move", "sxi2p", "zxi2p"
509
            if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
510
                $asm.puts "xorl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
511
            elsif operands[0] != operands[1]
512
                $asm.puts "movl #{x86Operands(:int, :int)}"
513
            end
514
        when "nop"
515
            $asm.puts "nop"
516
        when "bieq", "bpeq"
517
            handleX86IntBranch("je", :int)
518
        when "bineq", "bpneq"
519
            handleX86IntBranch("jne", :int)
520
        when "bia", "bpa"
521
            handleX86IntBranch("ja", :int)
522
        when "biaeq", "bpaeq"
523
            handleX86IntBranch("jae", :int)
524
        when "bib", "bpb"
525
            handleX86IntBranch("jb", :int)
526
        when "bibeq", "bpbeq"
527
            handleX86IntBranch("jbe", :int)
528
        when "bigt", "bpgt"
529
            handleX86IntBranch("jg", :int)
530
        when "bigteq", "bpgteq"
531
            handleX86IntBranch("jge", :int)
532
        when "bilt", "bplt"
533
            handleX86IntBranch("jl", :int)
534
        when "bilteq", "bplteq"
535
            handleX86IntBranch("jle", :int)
536
        when "bbeq"
537
            handleX86IntBranch("je", :byte)
538
        when "bbneq"
539
            handleX86IntBranch("jne", :byte)
540
        when "bba"
541
            handleX86IntBranch("ja", :byte)
542
        when "bbaeq"
543
            handleX86IntBranch("jae", :byte)
544
        when "bbb"
545
            handleX86IntBranch("jb", :byte)
546
        when "bbbeq"
547
            handleX86IntBranch("jbe", :byte)
548
        when "bbgt"
549
            handleX86IntBranch("jg", :byte)
550
        when "bbgteq"
551
            handleX86IntBranch("jge", :byte)
552
        when "bblt"
553
            handleX86IntBranch("jl", :byte)
554
        when "bblteq"
555
            handleX86IntBranch("jlteq", :byte)
556
        when "btio", "btpo"
557
            handleX86BranchTest("jo", :int)
558
        when "btis", "btps"
559
            handleX86BranchTest("js", :int)
560
        when "btiz", "btpz"
561
            handleX86BranchTest("jz", :int)
562
        when "btinz", "btpnz"
563
            handleX86BranchTest("jnz", :int)
564
        when "btbo"
565
            handleX86BranchTest("jo", :byte)
566
        when "btbs"
567
            handleX86BranchTest("js", :byte)
568
        when "btbz"
569
            handleX86BranchTest("jz", :byte)
570
        when "btbnz"
571
            handleX86BranchTest("jnz", :byte)
572
        when "jmp"
573
            $asm.puts "jmp #{operands[0].x86CallOperand(:int)}"
574
        when "baddio", "baddpo"
575
            handleX86OpBranch("addl", "jo", :int)
576
        when "baddis", "baddps"
577
            handleX86OpBranch("addl", "js", :int)
578
        when "baddiz", "baddpz"
579
            handleX86OpBranch("addl", "jz", :int)
580
        when "baddinz", "baddpnz"
581
            handleX86OpBranch("addl", "jnz", :int)
582
        when "bsubio"
583
            handleX86SubBranch("jo", :int)
584
        when "bsubis"
585
            handleX86SubBranch("js", :int)
586
        when "bsubiz"
587
            handleX86SubBranch("jz", :int)
588
        when "bsubinz"
589
            handleX86SubBranch("jnz", :int)
590
        when "bmulio"
591
            handleX86OpBranch("imull", "jo", :int)
592
        when "bmulis"
593
            handleX86OpBranch("imull", "js", :int)
594
        when "bmuliz"
595
            handleX86OpBranch("imull", "jz", :int)
596
        when "bmulinz"
597
            handleX86OpBranch("imull", "jnz", :int)
598
        when "borio"
599
            handleX86OpBranch("orl", "jo", :int)
600
        when "boris"
601
            handleX86OpBranch("orl", "js", :int)
602
        when "boriz"
603
            handleX86OpBranch("orl", "jz", :int)
604
        when "borinz"
605
            handleX86OpBranch("orl", "jnz", :int)
606
        when "break"
607
            $asm.puts "int $3"
608
        when "call"
609
            $asm.puts "call #{operands[0].x86CallOperand(:int)}"
610
        when "ret"
611
            $asm.puts "ret"
612
        when "cieq", "cpeq"
613
            handleX86IntCompareSet("sete", :int)
614
        when "cineq", "cpneq"
615
            handleX86IntCompareSet("setne", :int)
616
        when "cia", "cpa"
617
            handleX86IntCompareSet("seta", :int)
618
        when "ciaeq", "cpaeq"
619
            handleX86IntCompareSet("setae", :int)
620
        when "cib", "cpb"
621
            handleX86IntCompareSet("setb", :int)
622
        when "cibeq", "cpbeq"
623
            handleX86IntCompareSet("setbe", :int)
624
        when "cigt", "cpgt"
625
            handleX86IntCompareSet("setg", :int)
626
        when "cigteq", "cpgteq"
627
            handleX86IntCompareSet("setge", :int)
628
        when "cilt", "cplt"
629
            handleX86IntCompareSet("setl", :int)
630
        when "cilteq", "cplteq"
631
            handleX86IntCompareSet("setle", :int)
632
        when "tio"
633
            handleX86SetTest("seto", :int)
634
        when "tis"
635
            handleX86SetTest("sets", :int)
636
        when "tiz"
637
            handleX86SetTest("setz", :int)
638
        when "tinz"
639
            handleX86SetTest("setnz", :int)
640
        when "tbo"
641
            handleX86SetTest("seto", :byte)
642
        when "tbs"
643
            handleX86SetTest("sets", :byte)
644
        when "tbz"
645
            handleX86SetTest("setz", :byte)
646
        when "tbnz"
647
            handleX86SetTest("setnz", :byte)
648
        when "peek"
649
            $asm.puts "movl #{operands[0].value * 4}(%esp), #{operands[1].x86Operand(:int)}"
650
        when "poke"
651
            $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].value * 4}(%esp)"
652
        when "cdqi"
653
            $asm.puts "cdq"
654
        when "idivi"
655
            $asm.puts "idivl #{operands[0].x86Operand(:int)}"
656
        when "fii2d"
657
            $asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
658
            $asm.puts "movd #{operands[1].x86Operand(:int)}, %xmm7"
659
            $asm.puts "psllq $32, %xmm7"
660
            $asm.puts "por %xmm7, #{operands[2].x86Operand(:double)}"
661
        when "fd2ii"
662
            $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
663
            $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
664
            $asm.puts "psrlq $32, %xmm7"
665
            $asm.puts "movsd %xmm7, #{operands[2].x86Operand(:int)}"
666
        when "bo"
667
            $asm.puts "jo #{operands[0].asmLabel}"
668
        when "bs"
669
            $asm.puts "js #{operands[0].asmLabel}"
670
        when "bz"
671
            $asm.puts "jz #{operands[0].asmLabel}"
672
        when "bnz"
673
            $asm.puts "jnz #{operands[0].asmLabel}"
674
        when "leai", "leap"
675
            $asm.puts "leal #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
676
        else
677
            raise "Bad opcode: #{opcode}"
678
        end
679
    end
680
end
681
- 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 / +56 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 88-94 Intrinsic NativeExecutable::intrinsic() Source/JavaScriptCore/runtime/Executable.cpp_sec2
88
template<typename T>
89
template<typename T>
89
static void jettisonCodeBlock(JSGlobalData& globalData, OwnPtr<T>& codeBlock)
90
static void jettisonCodeBlock(JSGlobalData& globalData, OwnPtr<T>& codeBlock)
90
{
91
{
91
    ASSERT(codeBlock->getJITType() != JITCode::BaselineJIT);
92
    ASSERT(JITCode::isOptimizingJIT(codeBlock->getJITType()));
92
    ASSERT(codeBlock->alternative());
93
    ASSERT(codeBlock->alternative());
93
    OwnPtr<T> codeBlockToJettison = codeBlock.release();
94
    OwnPtr<T> codeBlockToJettison = codeBlock.release();
94
    codeBlock = static_pointer_cast<T>(codeBlockToJettison->releaseAlternative());
95
    codeBlock = static_pointer_cast<T>(codeBlockToJettison->releaseAlternative());
Lines 175-183 JSObject* EvalExecutable::compileOptimiz Source/JavaScriptCore/runtime/Executable.cpp_sec3
175
    return error;
176
    return error;
176
}
177
}
177
178
179
#if ENABLE(JIT)
180
void EvalExecutable::jitCompile(JSGlobalData& globalData)
181
{
182
    bool result = jitCompileIfAppropriate(globalData, m_evalCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
183
    ASSERT_UNUSED(result, result);
184
}
185
#endif
186
187
inline const char* samplingDescription(JITCode::JITType jitType)
188
{
189
    switch (jitType) {
190
    case JITCode::InterpreterThunk:
191
        return "Interpreter Compilation (TOTAL)";
192
    case JITCode::BaselineJIT:
193
        return "Baseline Compilation (TOTAL)";
194
    case JITCode::DFGJIT:
195
        return "DFG Compilation (TOTAL)";
196
    default:
197
        ASSERT_NOT_REACHED();
198
        return 0;
199
    }
200
}
201
178
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
202
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
179
{
203
{
180
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
204
    SamplingRegion samplingRegion(samplingDescription(jitType));
181
    
205
    
182
#if !ENABLE(JIT)
206
#if !ENABLE(JIT)
183
    UNUSED_PARAM(jitType);
207
    UNUSED_PARAM(jitType);
Lines 218-224 JSObject* EvalExecutable::compileInterna Source/JavaScriptCore/runtime/Executable.cpp_sec4
218
    }
242
    }
219
243
220
#if ENABLE(JIT)
244
#if ENABLE(JIT)
221
    if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
245
    if (!prepareForExecution(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
222
        return 0;
246
        return 0;
223
#endif
247
#endif
224
248
Lines 303-311 JSObject* ProgramExecutable::compileOpti Source/JavaScriptCore/runtime/Executable.cpp_sec5
303
    return error;
327
    return error;
304
}
328
}
305
329
330
#if ENABLE(JIT)
331
void ProgramExecutable::jitCompile(JSGlobalData& globalData)
332
{
333
    bool result = jitCompileIfAppropriate(globalData, m_programCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
334
    ASSERT_UNUSED(result, result);
335
}
336
#endif
337
306
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
338
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
307
{
339
{
308
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
340
    SamplingRegion samplingRegion(samplingDescription(jitType));
309
    
341
    
310
#if !ENABLE(JIT)
342
#if !ENABLE(JIT)
311
    UNUSED_PARAM(jitType);
343
    UNUSED_PARAM(jitType);
Lines 344-350 JSObject* ProgramExecutable::compileInte Source/JavaScriptCore/runtime/Executable.cpp_sec6
344
    }
376
    }
345
377
346
#if ENABLE(JIT)
378
#if ENABLE(JIT)
347
    if (!jitCompileIfAppropriate(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
379
    if (!prepareForExecution(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
348
        return 0;
380
        return 0;
349
#endif
381
#endif
350
382
Lines 420-426 FunctionCodeBlock* FunctionExecutable::b Source/JavaScriptCore/runtime/Executable.cpp_sec7
420
    while (result->alternative())
452
    while (result->alternative())
421
        result = static_cast<FunctionCodeBlock*>(result->alternative());
453
        result = static_cast<FunctionCodeBlock*>(result->alternative());
422
    ASSERT(result);
454
    ASSERT(result);
423
    ASSERT(result->getJITType() == JITCode::BaselineJIT);
455
    ASSERT(JITCode::isBaselineCode(result->getJITType()));
424
    return result;
456
    return result;
425
}
457
}
426
458
Lines 446-451 JSObject* FunctionExecutable::compileOpt Source/JavaScriptCore/runtime/Executable.cpp_sec8
446
    return error;
478
    return error;
447
}
479
}
448
480
481
#if ENABLE(JIT)
482
void FunctionExecutable::jitCompileForCall(JSGlobalData& globalData)
483
{
484
    bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
485
    ASSERT_UNUSED(result, result);
486
}
487
488
void FunctionExecutable::jitCompileForConstruct(JSGlobalData& globalData)
489
{
490
    bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
491
    ASSERT_UNUSED(result, result);
492
}
493
#endif
494
449
FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
495
FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
450
{
496
{
451
    FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);
497
    FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);
Lines 490-496 PassOwnPtr<FunctionCodeBlock> FunctionEx Source/JavaScriptCore/runtime/Executable.cpp_sec9
490
536
491
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
537
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
492
{
538
{
493
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
539
    SamplingRegion samplingRegion(samplingDescription(jitType));
494
    
540
    
495
#if !ENABLE(JIT)
541
#if !ENABLE(JIT)
496
    UNUSED_PARAM(exec);
542
    UNUSED_PARAM(exec);
Lines 512-518 JSObject* FunctionExecutable::compileFor Source/JavaScriptCore/runtime/Executable.cpp_sec10
512
    m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
558
    m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
513
559
514
#if ENABLE(JIT)
560
#if ENABLE(JIT)
515
    if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType))
561
    if (!prepareFunctionForExecution(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, CodeForCall))
516
        return 0;
562
        return 0;
517
#endif
563
#endif
518
564
Lines 532-538 JSObject* FunctionExecutable::compileFor Source/JavaScriptCore/runtime/Executable.cpp_sec11
532
578
533
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
579
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
534
{
580
{
535
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
581
    SamplingRegion samplingRegion(samplingDescription(jitType));
536
    
582
    
537
#if !ENABLE(JIT)
583
#if !ENABLE(JIT)
538
    UNUSED_PARAM(jitType);
584
    UNUSED_PARAM(jitType);
Lines 554-560 JSObject* FunctionExecutable::compileFor Source/JavaScriptCore/runtime/Executable.cpp_sec12
554
    m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
600
    m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
555
601
556
#if ENABLE(JIT)
602
#if ENABLE(JIT)
557
    if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType))
603
    if (!prepareFunctionForExecution(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, CodeForConstruct))
558
        return 0;
604
        return 0;
559
#endif
605
#endif
560
606
- 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 325-330 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec3
325
    };
326
    };
326
327
327
    class EvalExecutable : public ScriptExecutable {
328
    class EvalExecutable : public ScriptExecutable {
329
        friend class LLIntOffsetsExtractor;
328
    public:
330
    public:
329
        typedef ScriptExecutable Base;
331
        typedef ScriptExecutable Base;
330
332
Lines 344-349 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec4
344
        
346
        
345
#if ENABLE(JIT)
347
#if ENABLE(JIT)
346
        void jettisonOptimizedCode(JSGlobalData&);
348
        void jettisonOptimizedCode(JSGlobalData&);
349
        void jitCompile(JSGlobalData&);
347
#endif
350
#endif
348
351
349
        EvalCodeBlock& generatedBytecode()
352
        EvalCodeBlock& generatedBytecode()
Lines 390-395 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec5
390
    };
393
    };
391
394
392
    class ProgramExecutable : public ScriptExecutable {
395
    class ProgramExecutable : public ScriptExecutable {
396
        friend class LLIntOffsetsExtractor;
393
    public:
397
    public:
394
        typedef ScriptExecutable Base;
398
        typedef ScriptExecutable Base;
395
399
Lines 417-422 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec6
417
        
421
        
418
#if ENABLE(JIT)
422
#if ENABLE(JIT)
419
        void jettisonOptimizedCode(JSGlobalData&);
423
        void jettisonOptimizedCode(JSGlobalData&);
424
        void jitCompile(JSGlobalData&);
420
#endif
425
#endif
421
426
422
        ProgramCodeBlock& generatedBytecode()
427
        ProgramCodeBlock& generatedBytecode()
Lines 459-464 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec7
459
464
460
    class FunctionExecutable : public ScriptExecutable {
465
    class FunctionExecutable : public ScriptExecutable {
461
        friend class JIT;
466
        friend class JIT;
467
        friend class LLIntOffsetsExtractor;
462
    public:
468
    public:
463
        typedef ScriptExecutable Base;
469
        typedef ScriptExecutable Base;
464
470
Lines 514-519 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec8
514
        
520
        
515
#if ENABLE(JIT)
521
#if ENABLE(JIT)
516
        void jettisonOptimizedCodeForCall(JSGlobalData&);
522
        void jettisonOptimizedCodeForCall(JSGlobalData&);
523
        void jitCompileForCall(JSGlobalData&);
517
#endif
524
#endif
518
525
519
        bool isGeneratedForCall() const
526
        bool isGeneratedForCall() const
Lines 541-546 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec9
541
        
548
        
542
#if ENABLE(JIT)
549
#if ENABLE(JIT)
543
        void jettisonOptimizedCodeForConstruct(JSGlobalData&);
550
        void jettisonOptimizedCodeForConstruct(JSGlobalData&);
551
        void jitCompileForConstruct(JSGlobalData&);
544
#endif
552
#endif
545
553
546
        bool isGeneratedForConstruct() const
554
        bool isGeneratedForConstruct() const
Lines 588-593 namespace JSC { Source/JavaScriptCore/runtime/Executable.h_sec10
588
                jettisonOptimizedCodeForConstruct(globalData);
596
                jettisonOptimizedCodeForConstruct(globalData);
589
            }
597
            }
590
        }
598
        }
599
        
600
        void jitCompileFor(JSGlobalData& globalData, CodeSpecializationKind kind)
601
        {
602
            if (kind == CodeForCall) {
603
                jitCompileForCall(globalData);
604
                return;
605
            }
606
            ASSERT(kind == CodeForConstruct);
607
            jitCompileForConstruct(globalData);
608
        }
591
#endif
609
#endif
592
        
610
        
593
        bool isGeneratedFor(CodeSpecializationKind kind)
611
        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/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 163-168 namespace JSC { Source/JavaScriptCore/runtime/JSCell.h_sec2
163
        static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
164
        static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
164
165
165
    private:
166
    private:
167
        friend class LLIntOffsetsExtractor;
168
        
166
        const ClassInfo* m_classInfo;
169
        const ClassInfo* m_classInfo;
167
        WriteBarrier<Structure> m_structure;
170
        WriteBarrier<Structure> m_structure;
168
    };
171
    };
- 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 / +8 lines
Lines 35-40 Source/JavaScriptCore/runtime/JSGlobalData.cpp_sec1
35
#include "DebuggerActivation.h"
35
#include "DebuggerActivation.h"
36
#include "FunctionConstructor.h"
36
#include "FunctionConstructor.h"
37
#include "GetterSetter.h"
37
#include "GetterSetter.h"
38
#include "HostCallReturnValue.h"
38
#include "Interpreter.h"
39
#include "Interpreter.h"
39
#include "JSActivation.h"
40
#include "JSActivation.h"
40
#include "JSAPIValueWrapper.h"
41
#include "JSAPIValueWrapper.h"
Lines 141-146 JSGlobalData::JSGlobalData(GlobalDataTyp Source/JavaScriptCore/runtime/JSGlobalData.cpp_sec2
141
    , keywords(adoptPtr(new Keywords(this)))
142
    , keywords(adoptPtr(new Keywords(this)))
142
    , interpreter(0)
143
    , interpreter(0)
143
    , heap(this, heapSize)
144
    , heap(this, heapSize)
145
    , jsArrayClassInfo(&JSArray::s_info)
146
    , jsFinalObjectClassInfo(&JSFinalObject::s_info)
144
#if ENABLE(DFG_JIT)
147
#if ENABLE(DFG_JIT)
145
    , sizeOfLastScratchBuffer(0)
148
    , sizeOfLastScratchBuffer(0)
146
#endif
149
#endif
Lines 216-224 JSGlobalData::JSGlobalData(GlobalDataTyp Source/JavaScriptCore/runtime/JSGlobalData.cpp_sec3
216
    jitStubs = adoptPtr(new JITThunks(this));
219
    jitStubs = adoptPtr(new JITThunks(this));
217
#endif
220
#endif
218
221
219
    interpreter->initialize(this->canUseJIT());
222
    interpreter->initialize(&llintData, this->canUseJIT());
223
    
224
    initializeHostCallReturnValue(); // This is needed to convince the linker not to drop host call return support.
220
225
221
    heap.notifyIsSafeToCollect();
226
    heap.notifyIsSafeToCollect();
227
    
228
    llintData.performAssertions(*this);
222
}
229
}
223
230
224
void JSGlobalData::clearBuiltinStructures()
231
void JSGlobalData::clearBuiltinStructures()
- Source/JavaScriptCore/runtime/JSGlobalData.h -4 / +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-247 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalData.h_sec3
241
        Heap heap;
243
        Heap heap;
242
244
243
        JSValue exception;
245
        JSValue exception;
244
#if ENABLE(JIT)
246
247
        const ClassInfo* const jsArrayClassInfo;
248
        const ClassInfo* const jsFinalObjectClassInfo;
249
250
        LLInt::Data llintData;
251
245
        ReturnAddressPtr exceptionLocation;
252
        ReturnAddressPtr exceptionLocation;
246
        JSValue hostCallReturnValue;
253
        JSValue hostCallReturnValue;
247
        CallFrame* callFrameForThrow;
254
        CallFrame* callFrameForThrow;
Lines 271-277 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalData.h_sec4
271
            return scratchBuffers.last();
278
            return scratchBuffers.last();
272
        }
279
        }
273
#endif
280
#endif
274
#endif
275
281
276
        HashMap<OpaqueJSClass*, OwnPtr<OpaqueJSClassContextData> > opaqueJSClassData;
282
        HashMap<OpaqueJSClass*, OwnPtr<OpaqueJSClassContextData> > opaqueJSClassData;
277
283
Lines 346-351 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalData.h_sec5
346
#undef registerTypedArrayFunction
352
#undef registerTypedArrayFunction
347
353
348
    private:
354
    private:
355
        friend class LLIntOffsetsExtractor;
356
        
349
        JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
357
        JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
350
        static JSGlobalData*& sharedInstanceInternal();
358
        static JSGlobalData*& sharedInstanceInternal();
351
        void createNativeThunk();
359
        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 340-345 namespace JSC { Source/JavaScriptCore/runtime/JSGlobalObject.h_sec2
340
        JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
341
        JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
341
342
342
    private:
343
    private:
344
        friend class LLIntOffsetsExtractor;
345
        
343
        // FIXME: Fold reset into init.
346
        // FIXME: Fold reset into init.
344
        JS_EXPORT_PRIVATE void init(JSObject* thisValue);
347
        JS_EXPORT_PRIVATE void init(JSObject* thisValue);
345
        void reset(JSValue prototype);
348
        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 264-269 namespace JSC { Source/JavaScriptCore/runtime/JSObject.h_sec2
264
        JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
265
        JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
265
266
266
    private:
267
    private:
268
        friend class LLIntOffsetsExtractor;
269
        
267
        // Nobody should ever ask any of these questions on something already known to be a JSObject.
270
        // Nobody should ever ask any of these questions on something already known to be a JSObject.
268
        using JSCell::isAPIValueWrapper;
271
        using JSCell::isAPIValueWrapper;
269
        using JSCell::isGetterSetter;
272
        using JSCell::isGetterSetter;
Lines 369-374 COMPILE_ASSERT((JSFinalObject_inlineStor Source/JavaScriptCore/runtime/JSObject.h_sec3
369
        }
372
        }
370
373
371
    private:
374
    private:
375
        friend class LLIntOffsetsExtractor;
376
        
372
        explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
377
        explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
373
            : JSObject(globalData, structure, m_inlineStorage)
378
            : JSObject(globalData, structure, m_inlineStorage)
374
        {
379
        {
- 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 -3 / +3 lines
Lines 118-124 JSObject* JSValue::synthesizePrototype(E Source/JavaScriptCore/runtime/JSValue.cpp_sec1
118
118
119
char* JSValue::description()
119
char* JSValue::description()
120
{
120
{
121
    static const size_t size = 64;
121
    static const size_t size = 128;
122
    static char description[size];
122
    static char description[size];
123
123
124
    if (!*this)
124
    if (!*this)
Lines 127-140 char* JSValue::description() Source/JavaScriptCore/runtime/JSValue.cpp_sec2
127
        snprintf(description, size, "Int32: %d", asInt32());
127
        snprintf(description, size, "Int32: %d", asInt32());
128
    else if (isDouble()) {
128
    else if (isDouble()) {
129
#if USE(JSVALUE64)
129
#if USE(JSVALUE64)
130
        snprintf(description, size, "Double: %lf, %lx", asDouble(), reinterpretDoubleToIntptr(asDouble()));
130
        snprintf(description, size, "Double: %lx, %lf", reinterpretDoubleToIntptr(asDouble()), asDouble());
131
#else
131
#else
132
        union {
132
        union {
133
            double asDouble;
133
            double asDouble;
134
            uint32_t asTwoInt32s[2];
134
            uint32_t asTwoInt32s[2];
135
        } u;
135
        } u;
136
        u.asDouble = asDouble();
136
        u.asDouble = asDouble();
137
        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());
138
#endif
138
#endif
139
    } else if (isCell())
139
    } else if (isCell())
140
        snprintf(description, size, "Cell: %p", asCell());
140
        snprintf(description, size, "Cell: %p", asCell());
- Source/JavaScriptCore/runtime/JSValue.h +4 lines
Lines 55-60 namespace JSC { Source/JavaScriptCore/runtime/JSValue.h_sec1
55
        class SpeculativeJIT;
55
        class SpeculativeJIT;
56
    }
56
    }
57
#endif
57
#endif
58
    namespace LLInt {
59
        class Data;
60
    }
58
61
59
    struct ClassInfo;
62
    struct ClassInfo;
60
    struct Instruction;
63
    struct Instruction;
Lines 118-123 namespace JSC { Source/JavaScriptCore/runtime/JSValue.h_sec2
118
        friend class DFG::OSRExitCompiler;
121
        friend class DFG::OSRExitCompiler;
119
        friend class DFG::SpeculativeJIT;
122
        friend class DFG::SpeculativeJIT;
120
#endif
123
#endif
124
        friend class LLInt::Data;
121
125
122
    public:
126
    public:
123
        static EncodedJSValue encode(JSValue);
127
        static EncodedJSValue encode(JSValue);
- 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.cpp -1 / +1 lines
Lines 325-331 Structure* Structure::addPropertyTransit Source/JavaScriptCore/runtime/Structure.cpp_sec1
325
            transition->growPropertyStorageCapacity();
325
            transition->growPropertyStorageCapacity();
326
        return transition;
326
        return transition;
327
    }
327
    }
328
328
    
329
    Structure* transition = create(globalData, structure);
329
    Structure* transition = create(globalData, structure);
330
330
331
    transition->m_cachedPrototypeChain.setMayBeNull(globalData, transition, structure->m_cachedPrototypeChain.get());
331
    transition->m_cachedPrototypeChain.setMayBeNull(globalData, transition, structure->m_cachedPrototypeChain.get());
- 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 206-211 namespace JSC { Source/JavaScriptCore/runtime/Structure.h_sec2
206
        static JS_EXPORTDATA const ClassInfo s_info;
207
        static JS_EXPORTDATA const ClassInfo s_info;
207
208
208
    private:
209
    private:
210
        friend class LLIntOffsetsExtractor;
211
        
209
        JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
212
        JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
210
        Structure(JSGlobalData&);
213
        Structure(JSGlobalData&);
211
        Structure(JSGlobalData&, const Structure*);
214
        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/InlineASM.h +7 lines
Lines 70-73 Source/JavaScriptCore/wtf/InlineASM.h_sec1
70
#define HIDE_SYMBOL(name)
70
#define HIDE_SYMBOL(name)
71
#endif
71
#endif
72
72
73
// FIXME: figure out how this works on all the platforms. I know that
74
// on Linux, the preferred form is ".Lstuff" as opposed to "Lstuff".
75
// Don't know about any of the others.
76
#if PLATFORM(MAC)
77
#define LOCAL_LABEL_STRING(name) "L" #name
78
#endif
79
73
#endif // InlineASM_h
80
#endif // InlineASM_h
- Source/JavaScriptCore/wtf/Platform.h +6 lines
Lines 928-933 Source/JavaScriptCore/wtf/Platform.h_sec1
928
#define ENABLE_JIT 1
928
#define ENABLE_JIT 1
929
#endif
929
#endif
930
930
931
/* On some of the platforms where we have a JIT, we want to also have the 
932
   low-level interpreter. */
933
#if !defined(ENABLE_LLINT) && ENABLE(JIT) && OS(DARWIN) && (CPU(X86) || CPU(ARM_THUMB2)) && USE(JSVALUE32_64)
934
#define ENABLE_LLINT 1
935
#endif
936
931
#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
937
#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
932
/* Enable the DFG JIT on X86 and X86_64.  Only tested on Mac and GNU/Linux. */
938
/* Enable the DFG JIT on X86 and X86_64.  Only tested on Mac and GNU/Linux. */
933
#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
939
#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 / +5 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
namespace LLInt { class Data; }
47
class LLIntOffsetsExtractor;
46
template <typename T> struct IdentifierCharBufferTranslator;
48
template <typename T> struct IdentifierCharBufferTranslator;
47
struct IdentifierLCharFromUCharTranslator;
49
struct IdentifierLCharFromUCharTranslator;
48
}
50
}
Lines 72-78 class StringImpl { Source/JavaScriptCore/wtf/text/StringImpl.h_sec2
72
    friend struct WTF::SubstringTranslator;
74
    friend struct WTF::SubstringTranslator;
73
    friend struct WTF::UCharBufferTranslator;
75
    friend struct WTF::UCharBufferTranslator;
74
    friend class AtomicStringImpl;
76
    friend class AtomicStringImpl;
75
77
    friend class JSC::LLInt::Data;
78
    friend class JSC::LLIntOffsetsExtractor;
79
    
76
private:
80
private:
77
    enum BufferOwnership {
81
    enum BufferOwnership {
78
        BufferInternal,
82
        BufferInternal,
- Source/WebCore/ChangeLog -10 lines
Lines 1-13 Source/WebCore/ChangeLog_sec1
1
2012-02-21  Adam Roben  <aroben@apple.com>
2
3
        Roll out r108309, r108323, and r108326
4
5
        They broke the 32-bit Lion build.
6
7
        Original bugs is <http://webkit.org/b/75812> <rdar://problem/10079694>.
8
9
        * CMakeLists.txt:
10
11
2012-02-21  Alexander Pavlov  <apavlov@chromium.org>
1
2012-02-21  Alexander Pavlov  <apavlov@chromium.org>
12
2
13
        Web Inspector: [SuggestBox] textPrompt.css disablement displays garbled suggest box
3
        Web Inspector: [SuggestBox] textPrompt.css disablement displays garbled suggest box
- Source/WebCore/CMakeLists.txt +1 lines
Lines 75-80 SET(WebCore_INCLUDE_DIRECTORIES Source/WebCore/CMakeLists.txt_sec1
75
    "${JAVASCRIPTCORE_DIR}/debugger"
75
    "${JAVASCRIPTCORE_DIR}/debugger"
76
    "${JAVASCRIPTCORE_DIR}/interpreter"
76
    "${JAVASCRIPTCORE_DIR}/interpreter"
77
    "${JAVASCRIPTCORE_DIR}/jit"
77
    "${JAVASCRIPTCORE_DIR}/jit"
78
    "${JAVASCRIPTCORE_DIR}/llint"
78
    "${JAVASCRIPTCORE_DIR}/parser"
79
    "${JAVASCRIPTCORE_DIR}/parser"
79
    "${JAVASCRIPTCORE_DIR}/profiler"
80
    "${JAVASCRIPTCORE_DIR}/profiler"
80
    "${JAVASCRIPTCORE_DIR}/runtime"
81
    "${JAVASCRIPTCORE_DIR}/runtime"
- Source/WebKit/ChangeLog -10 lines
Lines 1-13 Source/WebKit/ChangeLog_sec1
1
2012-02-21  Adam Roben  <aroben@apple.com>
2
3
        Roll out r108309, r108323, and r108326
4
5
        They broke the 32-bit Lion build.
6
7
        Original bugs is <http://webkit.org/b/75812> <rdar://problem/10079694>.
8
9
        * CMakeLists.txt:
10
11
2012-02-20  Filip Pizlo  <fpizlo@apple.com>
1
2012-02-20  Filip Pizlo  <fpizlo@apple.com>
12
2
13
        JSC should be a triple-tier VM
3
        JSC should be a triple-tier VM
- Source/WebKit/CMakeLists.txt +1 lines
Lines 45-50 SET(WebKit_INCLUDE_DIRECTORIES Source/WebKit/CMakeLists.txt_sec1
45
    "${JAVASCRIPTCORE_DIR}/debugger"
45
    "${JAVASCRIPTCORE_DIR}/debugger"
46
    "${JAVASCRIPTCORE_DIR}/interpreter"
46
    "${JAVASCRIPTCORE_DIR}/interpreter"
47
    "${JAVASCRIPTCORE_DIR}/jit"
47
    "${JAVASCRIPTCORE_DIR}/jit"
48
    "${JAVASCRIPTCORE_DIR}/llint"
48
    "${JAVASCRIPTCORE_DIR}/parser"
49
    "${JAVASCRIPTCORE_DIR}/parser"
49
    "${JAVASCRIPTCORE_DIR}/profiler"
50
    "${JAVASCRIPTCORE_DIR}/profiler"
50
    "${JAVASCRIPTCORE_DIR}/runtime"
51
    "${JAVASCRIPTCORE_DIR}/runtime"
- Tools/ChangeLog -10 lines
Lines 1-13 Tools/ChangeLog_sec1
1
2012-02-21  Adam Roben  <aroben@apple.com>
2
3
        Roll out r108309, r108323, and r108326
4
5
        They broke the 32-bit Lion build.
6
7
        Original bugs is <http://webkit.org/b/75812> <rdar://problem/10079694>.
8
9
        * DumpRenderTree/efl/CMakeLists.txt:
10
11
2012-02-21  Andras Becsi  <andras.becsi@nokia.com>
1
2012-02-21  Andras Becsi  <andras.becsi@nokia.com>
12
2
13
        [Qt][WK2] Get rid of the dependency to QtWidgets
3
        [Qt][WK2] Get rid of the dependency to QtWidgets
- Tools/DumpRenderTree/efl/CMakeLists.txt +2 lines
Lines 70-79 SET(DumpRenderTree_INCLUDE_DIRECTORIES Tools/DumpRenderTree/efl/CMakeLists.txt_sec1
70
    ${JAVASCRIPTCORE_DIR}
70
    ${JAVASCRIPTCORE_DIR}
71
    ${JAVASCRIPTCORE_DIR}/API
71
    ${JAVASCRIPTCORE_DIR}/API
72
    ${JAVASCRIPTCORE_DIR}/assembler
72
    ${JAVASCRIPTCORE_DIR}/assembler
73
    ${JAVASCRIPTCORE_DIR}/bytecode
73
    ${JAVASCRIPTCORE_DIR}/dfg
74
    ${JAVASCRIPTCORE_DIR}/dfg
74
    ${JAVASCRIPTCORE_DIR}/heap
75
    ${JAVASCRIPTCORE_DIR}/heap
75
    ${JAVASCRIPTCORE_DIR}/interpreter
76
    ${JAVASCRIPTCORE_DIR}/interpreter
76
    ${JAVASCRIPTCORE_DIR}/jit
77
    ${JAVASCRIPTCORE_DIR}/jit
78
    ${JAVASCRIPTCORE_DIR}/llint
77
    ${JAVASCRIPTCORE_DIR}/runtime
79
    ${JAVASCRIPTCORE_DIR}/runtime
78
    ${JAVASCRIPTCORE_DIR}/ForwardingHeaders
80
    ${JAVASCRIPTCORE_DIR}/ForwardingHeaders
79
    ${JAVASCRIPTCORE_DIR}/wtf
81
    ${JAVASCRIPTCORE_DIR}/wtf

Return to Bug 75812