summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-25 19:08:45 +0100
committerSteve Block <steveblock@google.com>2011-06-08 13:51:31 +0100
commit2bde8e466a4451c7319e3a072d118917957d6554 (patch)
tree28f4a1b869a513e565c7760d0e6a06e7cf1fe95a /Source/JavaScriptCore
parent6939c99b71d9372d14a0c74a772108052e8c48c8 (diff)
downloadexternal_webkit-2bde8e466a4451c7319e3a072d118917957d6554.zip
external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.gz
external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.bz2
Merge WebKit at r82507: Initial merge by git
Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/API/APIShims.h2
-rw-r--r--Source/JavaScriptCore/API/JSBase.h5
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.h4
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.h4
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.h4
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.cpp10
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.h2
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.cpp4
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.cpp6
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp11
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h11
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.h4
-rw-r--r--Source/JavaScriptCore/CMakeLists.txt1
-rw-r--r--Source/JavaScriptCore/ChangeLog3315
-rw-r--r--Source/JavaScriptCore/Configurations/Base.xcconfig14
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--Source/JavaScriptCore/DerivedSources.make1
-rw-r--r--Source/JavaScriptCore/GNUmakefile.am7
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.exp27
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.gypi61
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.pri1
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.pro10
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make1
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln22
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def22
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj34
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops15
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln18
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj24
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebug.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugAll.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugCairoCFLite.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFProduction.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFRelease.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleaseCairoCFLite.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj116
-rw-r--r--Source/JavaScriptCore/Makefile1
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h44
-rw-r--r--Source/JavaScriptCore/assembler/AssemblerBuffer.h15
-rw-r--r--Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h56
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssembler.h66
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h90
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h148
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h46
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h126
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86.h24
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h385
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h99
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h49
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp73
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h131
-rw-r--r--Source/JavaScriptCore/bytecode/EvalCodeCache.h16
-rw-r--r--Source/JavaScriptCore/bytecode/Instruction.h45
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.h9
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.cpp39
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.h3
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp80
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h16
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp5
-rw-r--r--Source/JavaScriptCore/collector/handles/Handle.h14
-rw-r--r--Source/JavaScriptCore/collector/handles/HandleHeap.cpp9
-rw-r--r--Source/JavaScriptCore/collector/handles/HandleHeap.h4
-rw-r--r--Source/JavaScriptCore/collector/handles/HandleStack.cpp63
-rw-r--r--Source/JavaScriptCore/collector/handles/HandleStack.h129
-rw-r--r--Source/JavaScriptCore/collector/handles/Local.h157
-rw-r--r--Source/JavaScriptCore/collector/handles/LocalScope.h78
-rw-r--r--Source/JavaScriptCore/config.h23
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.cpp24
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.cpp2
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.h4
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp17
-rw-r--r--Source/JavaScriptCore/dfg/DFGAliasTracker.h121
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp744
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.h47
-rw-r--r--Source/JavaScriptCore/dfg/DFGGenerationInfo.h249
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.cpp141
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h69
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp563
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h955
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.cpp429
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.h325
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h293
-rw-r--r--Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp585
-rw-r--r--Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.h211
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp220
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h83
-rw-r--r--Source/JavaScriptCore/dfg/DFGRegisterBank.h253
-rw-r--r--Source/JavaScriptCore/dfg/DFGScoreBoard.h127
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp663
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h356
-rw-r--r--Source/JavaScriptCore/gyp/JavaScriptCore.gyp168
-rwxr-xr-xSource/JavaScriptCore/gyp/generate-dtrace-header.sh9
-rwxr-xr-xSource/JavaScriptCore/gyp/run-if-exists.sh5
-rwxr-xr-xSource/JavaScriptCore/gyp/update-info-plist.sh4
-rw-r--r--Source/JavaScriptCore/interpreter/CachedCall.h2
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h2
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp55
-rw-r--r--Source/JavaScriptCore/interpreter/Register.h66
-rw-r--r--Source/JavaScriptCore/interpreter/RegisterFile.cpp11
-rw-r--r--Source/JavaScriptCore/interpreter/RegisterFile.h8
-rw-r--r--Source/JavaScriptCore/jit/JIT.cpp31
-rw-r--r--Source/JavaScriptCore/jit/JIT.h5
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic.cpp18
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic32_64.cpp160
-rw-r--r--Source/JavaScriptCore/jit/JITCall.cpp29
-rw-r--r--Source/JavaScriptCore/jit/JITCall32_64.cpp49
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h92
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp235
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp334
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess.cpp145
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp159
-rw-r--r--Source/JavaScriptCore/jit/JITStubCall.h4
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp57
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h13
-rw-r--r--Source/JavaScriptCore/jit/JSInterfaceJIT.h67
-rw-r--r--Source/JavaScriptCore/jit/SpecializedThunkJIT.h16
-rw-r--r--Source/JavaScriptCore/jit/ThunkGenerators.cpp10
-rw-r--r--Source/JavaScriptCore/jsc.cpp10
-rw-r--r--Source/JavaScriptCore/jsc.pro4
-rw-r--r--Source/JavaScriptCore/profiler/CallIdentifier.h2
-rw-r--r--Source/JavaScriptCore/profiler/ProfileGenerator.cpp18
-rw-r--r--Source/JavaScriptCore/profiler/ProfileGenerator.h9
-rw-r--r--Source/JavaScriptCore/profiler/Profiler.cpp25
-rw-r--r--Source/JavaScriptCore/profiler/Profiler.h2
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.h2
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h14
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp106
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/Completion.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.cpp25
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.h57
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/DateConversion.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.h8
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.h6
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.h4
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp68
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h77
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.h4
-rw-r--r--Source/JavaScriptCore/runtime/Heap.cpp66
-rw-r--r--Source/JavaScriptCore/runtime/Heap.h21
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSAPIValueWrapper.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp59
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h31
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h93
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h75
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp40
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp82
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h17
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp317
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h270
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSNumberCell.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp125
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h44
-rw-r--r--Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.h22
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h16
-rw-r--r--Source/JavaScriptCore/runtime/JSTypeInfo.h11
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h51
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h47
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.h19
-rw-r--r--Source/JavaScriptCore/runtime/JSZombie.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/JSZombie.h4
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.cpp80
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.h31
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.cpp89
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.h127
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.h12
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.h17
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.h9
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/PropertyMapHashTable.h2
-rw-r--r--Source/JavaScriptCore/runtime/PropertyNameArray.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/PutPropertySlot.h9
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp49
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.h18
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.h4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp22
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.h6
-rw-r--r--Source/JavaScriptCore/runtime/RegExpKey.h49
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp44
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.h32
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp20
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChain.h15
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.cpp35
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.h20
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h10
-rw-r--r--Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h6
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp19
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.h10
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h29
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.h9
-rw-r--r--Source/JavaScriptCore/runtime/TimeoutChecker.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h54
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input.js36
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input_as_array.js36
-rw-r--r--Source/JavaScriptCore/wtf/Assertions.cpp6
-rw-r--r--Source/JavaScriptCore/wtf/Assertions.h16
-rw-r--r--Source/JavaScriptCore/wtf/Atomics.h8
-rw-r--r--Source/JavaScriptCore/wtf/CMakeLists.txt3
-rw-r--r--Source/JavaScriptCore/wtf/CrossThreadRefCounted.h12
-rw-r--r--Source/JavaScriptCore/wtf/DateMath.cpp9
-rw-r--r--Source/JavaScriptCore/wtf/ExportMacros.h46
-rw-r--r--Source/JavaScriptCore/wtf/HexNumber.h107
-rw-r--r--Source/JavaScriptCore/wtf/MathExtras.h11
-rw-r--r--Source/JavaScriptCore/wtf/MessageQueue.h2
-rw-r--r--Source/JavaScriptCore/wtf/Platform.h36
-rw-r--r--Source/JavaScriptCore/wtf/RefCounted.h12
-rw-r--r--Source/JavaScriptCore/wtf/StdLibExtras.h47
-rw-r--r--Source/JavaScriptCore/wtf/StringHasher.h22
-rw-r--r--Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h (renamed from Source/JavaScriptCore/wtf/ThreadSafeShared.h)27
-rw-r--r--Source/JavaScriptCore/wtf/Threading.h2
-rw-r--r--Source/JavaScriptCore/wtf/ThreadingPthreads.cpp10
-rw-r--r--Source/JavaScriptCore/wtf/Vector.h10
-rw-r--r--Source/JavaScriptCore/wtf/text/AtomicString.cpp8
-rw-r--r--Source/JavaScriptCore/wtf/text/StringConcatenate.h28
-rw-r--r--Source/JavaScriptCore/wtf/text/StringHash.h4
-rw-r--r--Source/JavaScriptCore/wtf/text/StringImpl.h7
-rw-r--r--Source/JavaScriptCore/wtf/unicode/UTF8.cpp2
-rw-r--r--Source/JavaScriptCore/yarr/YarrInterpreter.cpp24
-rw-r--r--Source/JavaScriptCore/yarr/YarrInterpreter.h8
-rw-r--r--Source/JavaScriptCore/yarr/YarrJIT.cpp66
290 files changed, 14905 insertions, 3107 deletions
diff --git a/Source/JavaScriptCore/API/APIShims.h b/Source/JavaScriptCore/API/APIShims.h
index 26db2dc..2e13851 100644
--- a/Source/JavaScriptCore/API/APIShims.h
+++ b/Source/JavaScriptCore/API/APIShims.h
@@ -42,7 +42,7 @@ protected:
UNUSED_PARAM(registerThread);
#if ENABLE(JSC_MULTIPLE_THREADS)
if (registerThread)
- globalData->heap.machineStackMarker().registerThread();
+ globalData->heap.machineThreads().addCurrentThread();
#endif
m_globalData->heap.activityCallback()->synchronize();
m_globalData->timeoutChecker.start();
diff --git a/Source/JavaScriptCore/API/JSBase.h b/Source/JavaScriptCore/API/JSBase.h
index d962b01..fed54fe 100644
--- a/Source/JavaScriptCore/API/JSBase.h
+++ b/Source/JavaScriptCore/API/JSBase.h
@@ -80,6 +80,11 @@ typedef struct OpaqueJSValue* JSObjectRef;
#define JS_EXPORT
#endif /* defined(JS_NO_EXPORT) */
+/* JS tests uses WTF but has no config.h, so we need to set the export defines here. */
+#ifndef WTF_EXPORT_PRIVATE
+#define WTF_EXPORT_PRIVATE JS_EXPORT
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.h b/Source/JavaScriptCore/API/JSCallbackConstructor.h
index cd307a6..001c416 100644
--- a/Source/JavaScriptCore/API/JSCallbackConstructor.h
+++ b/Source/JavaScriptCore/API/JSCallbackConstructor.h
@@ -39,9 +39,9 @@ public:
JSObjectCallAsConstructorCallback callback() const { return m_callback; }
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.h b/Source/JavaScriptCore/API/JSCallbackFunction.h
index d8ae608..11fb95c 100644
--- a/Source/JavaScriptCore/API/JSCallbackFunction.h
+++ b/Source/JavaScriptCore/API/JSCallbackFunction.h
@@ -39,9 +39,9 @@ public:
// InternalFunction mish-mashes constructor and function behavior -- we should
// refactor the code so this override isn't necessary
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.h b/Source/JavaScriptCore/API/JSCallbackObject.h
index 732cc1d..a0adb44 100644
--- a/Source/JavaScriptCore/API/JSCallbackObject.h
+++ b/Source/JavaScriptCore/API/JSCallbackObject.h
@@ -128,9 +128,9 @@ public:
JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
bool inherits(JSClassRef) const;
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount, &s_info);
}
JSValue getPrivateProperty(const Identifier& propertyName) const
diff --git a/Source/JavaScriptCore/API/JSClassRef.cpp b/Source/JavaScriptCore/API/JSClassRef.cpp
index d953dce..70668bd 100644
--- a/Source/JavaScriptCore/API/JSClassRef.cpp
+++ b/Source/JavaScriptCore/API/JSClassRef.cpp
@@ -84,8 +84,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
// Use a local variable here to sidestep an RVCT compiler bug.
StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes);
StringImpl* impl = valueName.impl();
- impl->ref();
- m_staticValues->add(impl, entry);
+ StaticValueEntry* existingEntry = m_staticValues->get(impl);
+ m_staticValues->set(impl, entry);
+ delete existingEntry;
}
++staticValue;
}
@@ -99,8 +100,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
// Use a local variable here to sidestep an RVCT compiler bug.
StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes);
StringImpl* impl = functionName.impl();
- impl->ref();
- m_staticFunctions->add(impl, entry);
+ StaticFunctionEntry* existingEntry = m_staticFunctions->get(impl);
+ m_staticFunctions->set(impl, entry);
+ delete existingEntry;
}
++staticFunction;
}
diff --git a/Source/JavaScriptCore/API/JSClassRef.h b/Source/JavaScriptCore/API/JSClassRef.h
index 0f4119a..239c5a4 100644
--- a/Source/JavaScriptCore/API/JSClassRef.h
+++ b/Source/JavaScriptCore/API/JSClassRef.h
@@ -85,7 +85,7 @@ public:
JSC::WeakGCPtr<JSC::JSObject> cachedPrototype;
};
-struct OpaqueJSClass : public ThreadSafeShared<OpaqueJSClass> {
+struct OpaqueJSClass : public ThreadSafeRefCounted<OpaqueJSClass> {
static PassRefPtr<OpaqueJSClass> create(const JSClassDefinition*);
static PassRefPtr<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
~OpaqueJSClass();
diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp
index ccab953..e5c778f 100644
--- a/Source/JavaScriptCore/API/JSContextRef.cpp
+++ b/Source/JavaScriptCore/API/JSContextRef.cpp
@@ -93,11 +93,11 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
#endif
if (!globalObjectClass) {
- JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject;
+ JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject(*globalData);
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
- JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass, JSCallbackObject<JSGlobalObject>::createStructure(jsNull()));
+ JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass, JSCallbackObject<JSGlobalObject>::createStructure(*globalData, jsNull()));
ExecState* exec = globalObject->globalExec();
JSValue prototype = globalObjectClass->prototype(exec);
if (!prototype)
diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp
index 36ca338..b7030e4 100644
--- a/Source/JavaScriptCore/API/JSObjectRef.cpp
+++ b/Source/JavaScriptCore/API/JSObjectRef.cpp
@@ -124,7 +124,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
args.append(jsString(exec, parameterNames[i]->ustring()));
args.append(jsString(exec, body->ustring()));
- JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber);
+ JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->ustring(), startingLineNumber);
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
@@ -168,7 +168,7 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
- JSObject* result = constructDate(exec, argList);
+ JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), argList);
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
@@ -207,7 +207,7 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
- JSObject* result = constructRegExp(exec, argList);
+ JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList);
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
index bc5e383..54dfda6 100644
--- a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
@@ -68,14 +68,11 @@ JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* k
return toRef(static_cast<JSObject*>(map->map().get(key)));
}
-bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object)
+// We need to keep this function in the build to keep the nightlies running.
+JS_EXPORT bool JSWeakObjectMapClear(JSContextRef, JSWeakObjectMapRef, void*, JSObjectRef);
+bool JSWeakObjectMapClear(JSContextRef, JSWeakObjectMapRef, void*, JSObjectRef)
{
- ExecState* exec = toJS(ctx);
- APIEntryShim entryShim(exec);
- JSObject* obj = toJS(object);
- if (map->map().deprecatedRemove(key, obj))
- return true;
- return false;
+ return true;
}
#ifdef __cplusplus
diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
index bb3fe96..01e0611 100644
--- a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
@@ -76,17 +76,6 @@ JS_EXPORT void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void
*/
JS_EXPORT JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key);
-/*!
- @function
- @abstract Clears the association between a key and an object in a JSWeakObjectMapRef
- @param ctx The execution context to use.
- @param map The map to clear the key association from.
- @param key The key to use.
- @param object The old object value.
- @result Returns true if the key/object association was present in map, and has been removed.
- */
-JS_EXPORT bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object);
-
#ifdef __cplusplus
}
#endif
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.h b/Source/JavaScriptCore/API/OpaqueJSString.h
index 473c815..69c0962 100644
--- a/Source/JavaScriptCore/API/OpaqueJSString.h
+++ b/Source/JavaScriptCore/API/OpaqueJSString.h
@@ -33,7 +33,7 @@ namespace JSC {
class JSGlobalData;
}
-struct OpaqueJSString : public ThreadSafeShared<OpaqueJSString> {
+struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
static PassRefPtr<OpaqueJSString> create() // null
{
@@ -54,7 +54,7 @@ struct OpaqueJSString : public ThreadSafeShared<OpaqueJSString> {
JSC::Identifier identifier(JSC::JSGlobalData*) const;
private:
- friend class WTF::ThreadSafeShared<OpaqueJSString>;
+ friend class WTF::ThreadSafeRefCounted<OpaqueJSString>;
OpaqueJSString()
: m_characters(0)
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 97f100e..247d372 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -42,6 +42,7 @@ SET(JavaScriptCore_SOURCES
bytecompiler/NodesCodegen.cpp
collector/handles/HandleHeap.cpp
+ collector/handles/HandleStack.cpp
debugger/Debugger.cpp
debugger/DebuggerActivation.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 162f23f..7cc1d15 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,3318 @@
+2011-03-30 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Make StructureChain GC allocated
+ https://bugs.webkit.org/show_bug.cgi?id=56695
+
+ Make StructureChain GC allocated, and make the various owners
+ mark it correctly.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::CodeBlock::refStructures):
+ (JSC::CodeBlock::markAggregate):
+ * bytecode/Instruction.h:
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+ (JSC::PolymorphicAccessStructureList::derefStructures):
+ (JSC::PolymorphicAccessStructureList::markAggregate):
+ (JSC::Instruction::Instruction):
+ * bytecode/StructureStubInfo.cpp:
+ (JSC::StructureStubInfo::deref):
+ (JSC::StructureStubInfo::markAggregate):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::initGetByIdChain):
+ (JSC::StructureStubInfo::initPutByIdTransition):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
+ (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_jneq_ptr):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_jneq_ptr):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdChainList):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompileGetByIdChainList):
+ * jit/JITStubs.cpp:
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSCell.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::markIfNeeded):
+ * runtime/JSGlobalObject.h:
+ (JSC::Structure::prototypeChain):
+ * runtime/JSObject.h:
+ (JSC::JSObject::markChildrenDirect):
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::create):
+ (JSC::JSPropertyNameIterator::get):
+ (JSC::JSPropertyNameIterator::markChildren):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::setCachedPrototypeChain):
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::append):
+ * runtime/Structure.h:
+ (JSC::Structure::cachedPrototypeChainSlot):
+ * runtime/StructureChain.cpp:
+ (JSC::StructureChain::StructureChain):
+ * runtime/StructureChain.h:
+ (JSC::StructureChain::create):
+ (JSC::StructureChain::createStructure):
+
+2011-03-30 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Update Windows production build logic for new production configurations
+ https://bugs.webkit.org/show_bug.cgi?id=57494
+
+ * JavaScriptCore.vcproj/JavaScriptCore.make:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops:
+ * JavaScriptCore.vcproj/WTF/WTFProduction.vsprops:
+ * JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops:
+ * JavaScriptCore.vcproj/jsc/jscProduction.vsprops:
+ * JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops:
+ * JavaScriptCore.vcproj/testapi/testapiProduction.vsprops:
+
+2011-03-30 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Rename Windows configuration Release_LTCG to Production for clarity
+ https://bugs.webkit.org/show_bug.cgi?id=57465
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseLTCG.vsprops.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseLTCG.vsprops: Removed.
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.vcproj/WTF/WTFProduction.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleaseLTCG.vsprops.
+ * JavaScriptCore.vcproj/WTF/WTFReleaseLTCG.vsprops: Removed.
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.vcproj/jsc/jscProduction.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseLTCG.vsprops.
+ * JavaScriptCore.vcproj/jsc/jscReleaseLTCG.vsprops: Removed.
+ * JavaScriptCore.vcproj/testapi/testapi.vcproj:
+ * JavaScriptCore.vcproj/testapi/testapiProduction.vsprops: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseLTCG.vsprops.
+ * JavaScriptCore.vcproj/testapi/testapiReleaseLTCG.vsprops: Removed.
+
+2011-03-30 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Maciej Stachowiak.
+
+ Add the NEXT_OPCODE() macro to the DFG-JIT parser
+ https://bugs.webkit.org/show_bug.cgi?id=57322
+
+ In JavaScriptCore we use macros to jump to the next opcode
+ (both in interpreter and JIT). This macro is added to the
+ DFG-JIT parser as well.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parse):
+
+2011-03-29 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ ~25% regression on v8-splay in the SunSpider harness
+ https://bugs.webkit.org/show_bug.cgi?id=56128
+
+ I'm not sure if this is the root cause of the regression Stephanie
+ measured, but it seems to get us back to previous v8-splay times.
+
+ SunSpider reports no change. v8-splay says 41% faster.
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::reset): Make marking proportional to 1X the size of the heap,
+ not .5X the size of the heap. When the heap is large, this makes a big
+ difference. (Our old heap growth policy matched this. You can see by
+ looking at resizeBlocks in revisions prior to r77699.)
+
+2011-03-29 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Use per-configuration vsprops in JavaScriptCore to avoid WebKitVSPropsRedirectionDir removal by MSVC IDE
+ https://bugs.webkit.org/show_bug.cgi?id=57350
+
+ Visual Studio's IDE was removing instances of $(WebKitVSPropsRedirectionDir) from
+ InheritedPropertySheet rules in our vcproj files when the vcproj was edited from within
+ the IDE. To avoid this, add a separate vsprops file for each project configuration that
+ contains the required inherited property sheets.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseLTCG.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops: Added.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.vcproj/WTF/WTFDebug.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTFDebugAll.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTFDebugCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTFRelease.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTFReleaseCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTFReleaseLTCG.vsprops: Added.
+ * JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.vcproj/jsc/jscDebug.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jscRelease.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jscReleaseLTCG.vsprops: Added.
+ * JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops: Added.
+ * JavaScriptCore.vcproj/testapi/testapi.vcproj:
+ * JavaScriptCore.vcproj/testapi/testapiDebug.vsprops: Added.
+ * JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops: Added.
+ * JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/testapi/testapiRelease.vsprops: Added.
+ * JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/testapi/testapiReleaseLTCG.vsprops: Added.
+
+2011-03-29 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Eric Seidel.
+
+ REGRESSION(r82173): Causes assertion and test failures in run-javascriptcore-tests on Windows (Requested by aroben on #webkit).
+ https://bugs.webkit.org/show_bug.cgi?id=57333
+
+ constructDate now takes the global object explicitly as it may be called
+ by functions other than the constructor itself.
+
+ * API/JSObjectRef.cpp:
+ (JSObjectMakeDate):
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ (JSC::constructWithDateConstructor):
+ * runtime/DateConstructor.h:
+
+2011-03-29 Ben Taylor <bentaylor.solx86@gmail.com>
+
+ Reviewed by Benjamin Poulain.
+
+ https://bugs.webkit.org/show_bug.cgi?id=41953
+
+ Fix compile error on Solaris 10/Sun Studio 12 CC emanating from MathExtras.h
+
+ * wtf/MathExtras.h:
+
+2011-03-29 Ben Taylor <bentaylor.solx86@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=57231
+ Add conditional for SUNCC supporting alignment macros
+
+ Compile fix for Solaris 10/Sun Studio 12 CC
+
+ * wtf/Vector.h:
+
+2011-03-29 Ben Taylor <bentaylor.solx86@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=57256
+
+ Fix crash on misaligned reads on Solaris 10/Sparc
+
+ * wtf/text/AtomicString.cpp:
+ (WTF::equal):
+
+2011-03-28 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ instanceof Array test fails when using iframes
+ https://bugs.webkit.org/show_bug.cgi?id=17250
+
+ This is a problem with all built in constructors, the use of
+ lexicalGlobalObject rather than the constructors own
+ global object reference means that a builtin will always use
+ the prototype from the lexical global object rather than that
+ of the constructors origin.
+
+ * API/JSObjectRef.cpp:
+ (JSObjectMakeFunction):
+ (JSObjectMakeRegExp):
+ * JavaScriptCore.exp:
+ * runtime/ArrayConstructor.cpp:
+ (JSC::constructArrayWithSizeQuirk):
+ * runtime/BooleanConstructor.cpp:
+ (JSC::constructBoolean):
+ (JSC::constructBooleanFromImmediateBoolean):
+ * runtime/BooleanConstructor.h:
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ * runtime/DateInstance.cpp:
+ * runtime/DateInstance.h:
+ * runtime/ErrorConstructor.cpp:
+ (JSC::constructWithErrorConstructor):
+ (JSC::callErrorConstructor):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructWithFunctionConstructor):
+ (JSC::callFunctionConstructor):
+ (JSC::constructFunction):
+ * runtime/FunctionConstructor.h:
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::getOwnPropertySlot):
+ (JSC::JSCell::put):
+ (JSC::JSCell::deleteProperty):
+ (JSC::JSCell::toThisObject):
+ (JSC::JSCell::toObject):
+ * runtime/JSCell.h:
+ (JSC::JSCell::JSValue::toObject):
+ * runtime/JSNotAnObject.cpp:
+ (JSC::JSNotAnObject::toObject):
+ * runtime/JSNotAnObject.h:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::toObject):
+ * runtime/JSObject.h:
+ * runtime/JSString.cpp:
+ (JSC::StringObject::create):
+ (JSC::JSString::toObject):
+ (JSC::JSString::toThisObject):
+ * runtime/JSString.h:
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::toObjectSlowCase):
+ (JSC::JSValue::toThisObjectSlowCase):
+ (JSC::JSValue::synthesizeObject):
+ * runtime/JSValue.h:
+ * runtime/NumberConstructor.cpp:
+ (JSC::constructWithNumberConstructor):
+ * runtime/NumberObject.cpp:
+ (JSC::constructNumber):
+ * runtime/NumberObject.h:
+ * runtime/ObjectConstructor.cpp:
+ (JSC::constructObject):
+ (JSC::constructWithObjectConstructor):
+ (JSC::callObjectConstructor):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::constructRegExp):
+ (JSC::constructWithRegExpConstructor):
+ (JSC::callRegExpConstructor):
+ * runtime/RegExpConstructor.h:
+ * runtime/StringConstructor.cpp:
+ (JSC::constructWithStringConstructor):
+ * runtime/StringObject.h:
+
+2011-03-28 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ REGRESSION [r78794-r79249] Allocation of memory is slow when number of active objects is large
+ https://bugs.webkit.org/show_bug.cgi?id=56823
+
+ Partial fix for most of the problem. (TOT still shows a regression, though.)
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::reportExtraMemoryCostSlowCase): Use highWaterMark(), instead of
+ capacity(), since capacity() is O(n) relative to the size of the heap.
+
+ In limited circumstances, capacity() is also worse than highWaterMark()
+ for measuring extra cost relative to heap size, since capacity() only
+ measures the *current* capacity of the heap, but the heap will grow if
+ necessary to attain highWaterMark().
+
+2011-03-28 Oliver Hunt <oliver@apple.com>
+
+ REGRESSION(r82130): It made all tests crash (Requested by Ossy on #webkit).
+ https://bugs.webkit.org/show_bug.cgi?id=57251
+
+ Build fix, had remnant of another patch in r82130
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdChainList):
+
+2011-03-27 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Add additional immediate types to allow us to distinguish the source of a JIT immediate
+ https://bugs.webkit.org/show_bug.cgi?id=57190
+
+ Allow us to distinguish whether a JIT immediate is a value that we
+ control (TrustedImm32 and TrustedImmPtr) vs. ones that can be controlled
+ or influenced by code we are compiling. Currently we do nothing with this
+ information -- this change is large and mechanical but would obscure any
+ logic changes that we would have made.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::TrustedImmPtr::TrustedImmPtr):
+ (JSC::AbstractMacroAssembler::ImmPtr::ImmPtr):
+ (JSC::AbstractMacroAssembler::TrustedImm32::TrustedImm32):
+ (JSC::AbstractMacroAssembler::Imm32::Imm32):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::pop):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::branchPtr):
+ (JSC::MacroAssembler::branch32):
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::andPtr):
+ (JSC::MacroAssembler::orPtr):
+ (JSC::MacroAssembler::subPtr):
+ (JSC::MacroAssembler::xorPtr):
+ (JSC::MacroAssembler::setPtr):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::branchTestPtr):
+ (JSC::MacroAssembler::branchSubPtr):
+ (JSC::MacroAssembler::branchTest8):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::add32):
+ (JSC::MacroAssemblerARM::and32):
+ (JSC::MacroAssemblerARM::lshift32):
+ (JSC::MacroAssemblerARM::mul32):
+ (JSC::MacroAssemblerARM::or32):
+ (JSC::MacroAssemblerARM::rshift32):
+ (JSC::MacroAssemblerARM::urshift32):
+ (JSC::MacroAssemblerARM::sub32):
+ (JSC::MacroAssemblerARM::xor32):
+ (JSC::MacroAssemblerARM::store32):
+ (JSC::MacroAssemblerARM::push):
+ (JSC::MacroAssemblerARM::move):
+ (JSC::MacroAssemblerARM::branch8):
+ (JSC::MacroAssemblerARM::branch32):
+ (JSC::MacroAssemblerARM::branch32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerARM::branch16):
+ (JSC::MacroAssemblerARM::branchTest8):
+ (JSC::MacroAssemblerARM::branchTest32):
+ (JSC::MacroAssemblerARM::branchAdd32):
+ (JSC::MacroAssemblerARM::branchMul32):
+ (JSC::MacroAssemblerARM::branchSub32):
+ (JSC::MacroAssemblerARM::set32Compare32):
+ (JSC::MacroAssemblerARM::set8Compare32):
+ (JSC::MacroAssemblerARM::set32Test32):
+ (JSC::MacroAssemblerARM::set32Test8):
+ (JSC::MacroAssemblerARM::moveWithPatch):
+ (JSC::MacroAssemblerARM::branchPtrWithPatch):
+ (JSC::MacroAssemblerARM::storePtrWithPatch):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::add32):
+ (JSC::MacroAssemblerARMv7::and32):
+ (JSC::MacroAssemblerARMv7::lshift32):
+ (JSC::MacroAssemblerARMv7::mul32):
+ (JSC::MacroAssemblerARMv7::or32):
+ (JSC::MacroAssemblerARMv7::rshift32):
+ (JSC::MacroAssemblerARMv7::urshift32):
+ (JSC::MacroAssemblerARMv7::sub32):
+ (JSC::MacroAssemblerARMv7::xor32):
+ (JSC::MacroAssemblerARMv7::load32):
+ (JSC::MacroAssemblerARMv7::load32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerARMv7::load16):
+ (JSC::MacroAssemblerARMv7::store32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerARMv7::store32):
+ (JSC::MacroAssemblerARMv7::loadDouble):
+ (JSC::MacroAssemblerARMv7::storeDouble):
+ (JSC::MacroAssemblerARMv7::push):
+ (JSC::MacroAssemblerARMv7::move):
+ (JSC::MacroAssemblerARMv7::compare32):
+ (JSC::MacroAssemblerARMv7::test32):
+ (JSC::MacroAssemblerARMv7::branch32):
+ (JSC::MacroAssemblerARMv7::branch32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerARMv7::branch16):
+ (JSC::MacroAssemblerARMv7::branch8):
+ (JSC::MacroAssemblerARMv7::branchTest32):
+ (JSC::MacroAssemblerARMv7::branchTest8):
+ (JSC::MacroAssemblerARMv7::branchAdd32):
+ (JSC::MacroAssemblerARMv7::branchMul32):
+ (JSC::MacroAssemblerARMv7::branchSub32):
+ (JSC::MacroAssemblerARMv7::nearCall):
+ (JSC::MacroAssemblerARMv7::call):
+ (JSC::MacroAssemblerARMv7::set32Compare32):
+ (JSC::MacroAssemblerARMv7::set8Compare32):
+ (JSC::MacroAssemblerARMv7::set32Test32):
+ (JSC::MacroAssemblerARMv7::set32Test8):
+ (JSC::MacroAssemblerARMv7::moveWithPatch):
+ (JSC::MacroAssemblerARMv7::branchPtrWithPatch):
+ (JSC::MacroAssemblerARMv7::storePtrWithPatch):
+ (JSC::MacroAssemblerARMv7::tailRecursiveCall):
+ (JSC::MacroAssemblerARMv7::makeJump):
+ (JSC::MacroAssemblerARMv7::makeBranch):
+ (JSC::MacroAssemblerARMv7::setupArmAddress):
+ (JSC::MacroAssemblerARMv7::makeBaseIndexBase):
+ (JSC::MacroAssemblerARMv7::moveFixedWidthEncoding):
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::add32):
+ (JSC::MacroAssemblerMIPS::and32):
+ (JSC::MacroAssemblerMIPS::lshift32):
+ (JSC::MacroAssemblerMIPS::mul32):
+ (JSC::MacroAssemblerMIPS::or32):
+ (JSC::MacroAssemblerMIPS::rshift32):
+ (JSC::MacroAssemblerMIPS::urshift32):
+ (JSC::MacroAssemblerMIPS::sub32):
+ (JSC::MacroAssemblerMIPS::xor32):
+ (JSC::MacroAssemblerMIPS::load32):
+ (JSC::MacroAssemblerMIPS::load32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerMIPS::store32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerMIPS::store32):
+ (JSC::MacroAssemblerMIPS::push):
+ (JSC::MacroAssemblerMIPS::move):
+ (JSC::MacroAssemblerMIPS::branch8):
+ (JSC::MacroAssemblerMIPS::branch32):
+ (JSC::MacroAssemblerMIPS::branch32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerMIPS::branch16):
+ (JSC::MacroAssemblerMIPS::branchTest32):
+ (JSC::MacroAssemblerMIPS::branchTest8):
+ (JSC::MacroAssemblerMIPS::branchAdd32):
+ (JSC::MacroAssemblerMIPS::branchMul32):
+ (JSC::MacroAssemblerMIPS::branchSub32):
+ (JSC::MacroAssemblerMIPS::set8Compare32):
+ (JSC::MacroAssemblerMIPS::set32Compare32):
+ (JSC::MacroAssemblerMIPS::set32Test8):
+ (JSC::MacroAssemblerMIPS::set32Test32):
+ (JSC::MacroAssemblerMIPS::moveWithPatch):
+ (JSC::MacroAssemblerMIPS::branchPtrWithPatch):
+ (JSC::MacroAssemblerMIPS::storePtrWithPatch):
+ (JSC::MacroAssemblerMIPS::tailRecursiveCall):
+ (JSC::MacroAssemblerMIPS::loadDouble):
+ (JSC::MacroAssemblerMIPS::storeDouble):
+ (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
+ * assembler/MacroAssemblerX86.h:
+ (JSC::MacroAssemblerX86::add32):
+ (JSC::MacroAssemblerX86::addWithCarry32):
+ (JSC::MacroAssemblerX86::and32):
+ (JSC::MacroAssemblerX86::or32):
+ (JSC::MacroAssemblerX86::sub32):
+ (JSC::MacroAssemblerX86::store32):
+ (JSC::MacroAssemblerX86::branch32):
+ (JSC::MacroAssemblerX86::moveWithPatch):
+ (JSC::MacroAssemblerX86::branchPtrWithPatch):
+ (JSC::MacroAssemblerX86::storePtrWithPatch):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::add32):
+ (JSC::MacroAssemblerX86Common::and32):
+ (JSC::MacroAssemblerX86Common::lshift32):
+ (JSC::MacroAssemblerX86Common::mul32):
+ (JSC::MacroAssemblerX86Common::or32):
+ (JSC::MacroAssemblerX86Common::rshift32):
+ (JSC::MacroAssemblerX86Common::urshift32):
+ (JSC::MacroAssemblerX86Common::sub32):
+ (JSC::MacroAssemblerX86Common::xor32):
+ (JSC::MacroAssemblerX86Common::store32):
+ (JSC::MacroAssemblerX86Common::branchTruncateDoubleToInt32):
+ (JSC::MacroAssemblerX86Common::push):
+ (JSC::MacroAssemblerX86Common::move):
+ (JSC::MacroAssemblerX86Common::branch8):
+ (JSC::MacroAssemblerX86Common::branch32):
+ (JSC::MacroAssemblerX86Common::branch32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerX86Common::branch16):
+ (JSC::MacroAssemblerX86Common::branchTest32):
+ (JSC::MacroAssemblerX86Common::branchTest8):
+ (JSC::MacroAssemblerX86Common::branchAdd32):
+ (JSC::MacroAssemblerX86Common::branchMul32):
+ (JSC::MacroAssemblerX86Common::branchSub32):
+ (JSC::MacroAssemblerX86Common::set8Compare32):
+ (JSC::MacroAssemblerX86Common::set32Compare32):
+ (JSC::MacroAssemblerX86Common::set32Test8):
+ (JSC::MacroAssemblerX86Common::set32Test32):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::add32):
+ (JSC::MacroAssemblerX86_64::and32):
+ (JSC::MacroAssemblerX86_64::or32):
+ (JSC::MacroAssemblerX86_64::sub32):
+ (JSC::MacroAssemblerX86_64::loadDouble):
+ (JSC::MacroAssemblerX86_64::addDouble):
+ (JSC::MacroAssemblerX86_64::convertInt32ToDouble):
+ (JSC::MacroAssemblerX86_64::store32):
+ (JSC::MacroAssemblerX86_64::call):
+ (JSC::MacroAssemblerX86_64::tailRecursiveCall):
+ (JSC::MacroAssemblerX86_64::makeTailRecursiveCall):
+ (JSC::MacroAssemblerX86_64::addPtr):
+ (JSC::MacroAssemblerX86_64::andPtr):
+ (JSC::MacroAssemblerX86_64::orPtr):
+ (JSC::MacroAssemblerX86_64::subPtr):
+ (JSC::MacroAssemblerX86_64::xorPtr):
+ (JSC::MacroAssemblerX86_64::storePtr):
+ (JSC::MacroAssemblerX86_64::setPtr):
+ (JSC::MacroAssemblerX86_64::branchPtr):
+ (JSC::MacroAssemblerX86_64::branchTestPtr):
+ (JSC::MacroAssemblerX86_64::branchSubPtr):
+ (JSC::MacroAssemblerX86_64::moveWithPatch):
+ (JSC::MacroAssemblerX86_64::branchPtrWithPatch):
+ (JSC::MacroAssemblerX86_64::storePtrWithPatch):
+ (JSC::MacroAssemblerX86_64::branchTest8):
+ * dfg/DFGJITCodeGenerator.h:
+ (JSC::DFG::JITCodeGenerator::callOperation):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::jitAssertIsInt32):
+ (JSC::DFG::JITCompiler::emitCount):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::emitPutImmediateToCallFrameHeader):
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JIT.cpp:
+ (JSC::JIT::emitTimeoutCheck):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_urshift):
+ (JSC::JIT::emitSlow_op_urshift):
+ (JSC::JIT::emit_op_post_inc):
+ (JSC::JIT::emit_op_post_dec):
+ (JSC::JIT::emit_op_pre_inc):
+ (JSC::JIT::emit_op_pre_dec):
+ (JSC::JIT::emit_op_mod):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emit_op_negate):
+ (JSC::JIT::emit_op_jnless):
+ (JSC::JIT::emit_op_jless):
+ (JSC::JIT::emit_op_jlesseq):
+ (JSC::JIT::emit_op_lshift):
+ (JSC::JIT::emitRightShift):
+ (JSC::JIT::emitRightShiftSlowCase):
+ (JSC::JIT::emit_op_bitand):
+ (JSC::JIT::emit_op_bitor):
+ (JSC::JIT::emit_op_bitxor):
+ (JSC::JIT::emit_op_bitnot):
+ (JSC::JIT::emit_op_post_inc):
+ (JSC::JIT::emit_op_post_dec):
+ (JSC::JIT::emitSlow_op_post_dec):
+ (JSC::JIT::emit_op_pre_inc):
+ (JSC::JIT::emit_op_pre_dec):
+ (JSC::JIT::emit_op_add):
+ (JSC::JIT::emitAdd32Constant):
+ (JSC::JIT::emit_op_sub):
+ (JSC::JIT::emitSub32Constant):
+ (JSC::JIT::emitBinaryDoubleOp):
+ (JSC::JIT::emit_op_mul):
+ (JSC::JIT::emitSlow_op_mul):
+ (JSC::JIT::emit_op_div):
+ (JSC::JIT::emit_op_mod):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutCellToCallFrameHeader):
+ (JSC::JIT::emitPutIntToCallFrameHeader):
+ (JSC::JIT::emitPutImmediateToCallFrameHeader):
+ (JSC::JIT::emitLoadCharacterString):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ (JSC::JIT::checkStructure):
+ (JSC::JIT::setSamplingFlag):
+ (JSC::JIT::clearSamplingFlag):
+ (JSC::JIT::emitCount):
+ (JSC::JIT::sampleInstruction):
+ (JSC::JIT::sampleCodeBlock):
+ (JSC::JIT::emitStoreInt32):
+ (JSC::JIT::emitStoreCell):
+ (JSC::JIT::emitStoreBool):
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+ (JSC::JIT::emitInitRegister):
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitJumpIfImmediateInteger):
+ (JSC::JIT::emitJumpIfNotImmediateInteger):
+ (JSC::JIT::emitFastArithDeTagImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitTagAsBoolImmediate):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_check_has_instance):
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ (JSC::JIT::emit_op_resolve):
+ (JSC::JIT::emit_op_to_primitive):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emit_op_ensure_property_exists):
+ (JSC::JIT::emit_op_resolve_skip):
+ (JSC::JIT::emit_op_resolve_global):
+ (JSC::JIT::emitSlow_op_resolve_global):
+ (JSC::JIT::emit_op_not):
+ (JSC::JIT::emit_op_jfalse):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_jneq_ptr):
+ (JSC::JIT::emit_op_jsr):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emit_op_new_func_exp):
+ (JSC::JIT::emit_op_jtrue):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::emit_op_to_jsnumber):
+ (JSC::JIT::emit_op_push_new_scope):
+ (JSC::JIT::emit_op_catch):
+ (JSC::JIT::emit_op_eq_null):
+ (JSC::JIT::emit_op_neq_null):
+ (JSC::JIT::emit_op_init_lazy_reg):
+ (JSC::JIT::emit_op_convert_this):
+ (JSC::JIT::emit_op_convert_this_strict):
+ (JSC::JIT::emitSlow_op_not):
+ (JSC::JIT::emitSlow_op_neq):
+ (JSC::JIT::emit_op_get_arguments_length):
+ (JSC::JIT::emitSlow_op_get_arguments_length):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ (JSC::JIT::emitSlow_op_resolve_global_dynamic):
+ (JSC::JIT::emit_op_new_regexp):
+ (JSC::JIT::emit_op_load_varargs):
+ (JSC::JIT::emitSlow_op_load_varargs):
+ (JSC::JIT::emit_op_new_func):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_loop_if_lesseq):
+ (JSC::JIT::emit_op_check_has_instance):
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_tear_off_activation):
+ (JSC::JIT::emit_op_tear_off_arguments):
+ (JSC::JIT::emit_op_resolve):
+ (JSC::JIT::emit_op_to_primitive):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emit_op_ensure_property_exists):
+ (JSC::JIT::emit_op_resolve_skip):
+ (JSC::JIT::emit_op_resolve_global):
+ (JSC::JIT::emitSlow_op_resolve_global):
+ (JSC::JIT::emit_op_not):
+ (JSC::JIT::emit_op_jfalse):
+ (JSC::JIT::emit_op_jtrue):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_jneq_ptr):
+ (JSC::JIT::emit_op_jsr):
+ (JSC::JIT::emit_op_eq):
+ (JSC::JIT::emitSlow_op_eq):
+ (JSC::JIT::emit_op_neq):
+ (JSC::JIT::emitSlow_op_neq):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emit_op_eq_null):
+ (JSC::JIT::emit_op_neq_null):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emit_op_new_func_exp):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::emit_op_to_jsnumber):
+ (JSC::JIT::emit_op_push_new_scope):
+ (JSC::JIT::emit_op_catch):
+ (JSC::JIT::emit_op_create_activation):
+ (JSC::JIT::emit_op_create_arguments):
+ (JSC::JIT::emit_op_convert_this):
+ (JSC::JIT::emit_op_convert_this_strict):
+ (JSC::JIT::emit_op_get_arguments_length):
+ (JSC::JIT::emitSlow_op_get_arguments_length):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ (JSC::JIT::softModulo):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emit_op_get_by_pname):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emit_op_put_by_index):
+ (JSC::JIT::emit_op_put_getter):
+ (JSC::JIT::emit_op_put_setter):
+ (JSC::JIT::emit_op_del_by_id):
+ (JSC::JIT::emit_op_get_by_id):
+ (JSC::JIT::emit_op_put_by_id):
+ (JSC::JIT::emit_op_method_check):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::emitSlow_op_put_by_id):
+ (JSC::JIT::testPrototype):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_put_getter):
+ (JSC::JIT::emit_op_put_setter):
+ (JSC::JIT::emit_op_del_by_id):
+ (JSC::JIT::emit_op_get_by_id):
+ (JSC::JIT::emit_op_put_by_id):
+ (JSC::JIT::emit_op_method_check):
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::emitSlow_op_put_by_id):
+ (JSC::JIT::testPrototype):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::emit_op_get_by_pname):
+ * jit/JITStubCall.h:
+ (JSC::JITStubCall::addArgument):
+ * jit/JITStubs.cpp:
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JSInterfaceJIT.h:
+ (JSC::JSInterfaceJIT::emitJumpIfNotJSCell):
+ (JSC::JSInterfaceJIT::emitLoadInt32):
+ (JSC::JSInterfaceJIT::emitLoadDouble):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::SpecializedThunkJIT):
+ (JSC::SpecializedThunkJIT::loadJSStringArgument):
+ (JSC::SpecializedThunkJIT::tagReturnAsInt32):
+ (JSC::SpecializedThunkJIT::tagReturnAsJSCell):
+ * jit/ThunkGenerators.cpp:
+ (JSC::charToString):
+ (JSC::powThunkGenerator):
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::matchCharacterClass):
+ (JSC::Yarr::YarrGenerator::storeToFrame):
+ (JSC::Yarr::YarrGenerator::storeToFrameWithPatch):
+ (JSC::Yarr::YarrGenerator::ParenthesesTail::generateCode):
+ (JSC::Yarr::YarrGenerator::generatePatternCharacterSingle):
+ (JSC::Yarr::YarrGenerator::generatePatternCharacterFixed):
+ (JSC::Yarr::YarrGenerator::generatePatternCharacterGreedy):
+ (JSC::Yarr::YarrGenerator::generatePatternCharacterNonGreedy):
+ (JSC::Yarr::YarrGenerator::generateCharacterClassFixed):
+ (JSC::Yarr::YarrGenerator::generateCharacterClassGreedy):
+ (JSC::Yarr::YarrGenerator::generateCharacterClassNonGreedy):
+ (JSC::Yarr::YarrGenerator::generateParenthesesSingle):
+ (JSC::Yarr::YarrGenerator::generateDisjunction):
+
+2011-03-28 Andras Becsi <abecsi@webkit.org>
+
+ Reviewed by Csaba Osztrogonác.
+
+ [Qt] Fix the linking of jsc with MinGW after r81963.
+
+ * jsc.pro: add -l and remove the lib suffix.
+
+2011-03-27 Ben Taylor <bentaylor.solx86@gmail.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=57170 Fix last elements
+ in an enum to remove a trailing comma. Sun Studio 12 CC errors out.
+
+ Compile fix only, no actual code change.
+
+ * wtf/MessageQueue.h:
+
+2011-03-25 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Allow defineOwnProperty to work on DOMObjects
+ https://bugs.webkit.org/show_bug.cgi?id=57129
+
+ Fix a couple of places where we uses getter()/setter() rather
+ than [gs]etterPresent().
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::defineOwnProperty):
+
+2011-03-25 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Crash when paused at a breakpoint caused by inaccurate Activation records.
+ https://bugs.webkit.org/show_bug.cgi?id=57120
+
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::symbolTableGet):
+ (JSC::JSActivation::symbolTablePut):
+ (JSC::JSActivation::getOwnPropertyNames):
+ (JSC::JSActivation::symbolTablePutWithAttributes):
+
+2011-03-24 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Crash in debugger beneath MarkStack::drain @ me.com, ibm.com
+ https://bugs.webkit.org/show_bug.cgi?id=57080
+ <rdar://problem/8525907>
+
+ The crash was caused by changes in the executable after recompilation.
+
+ The fix is for the activation to copy the data it needs instead of
+ relying on the data in the executable.
+
+ SunSpider and v8 report no change.
+
+ * runtime/Arguments.h:
+ (JSC::JSActivation::copyRegisters): Use our own data members instead of
+ reading data out of the executable.
+
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::JSActivation): Initialize our data members.
+
+ (JSC::JSActivation::markChildren):
+ (JSC::JSActivation::symbolTableGet):
+ (JSC::JSActivation::symbolTablePut):
+ (JSC::JSActivation::getOwnPropertyNames):
+ (JSC::JSActivation::symbolTablePutWithAttributes):
+ (JSC::JSActivation::isDynamicScope):
+ (JSC::JSActivation::argumentsGetter): Use our own data members instead of
+ reading data out of the executable.
+
+ * runtime/JSActivation.h: Added new data members to track data previously
+ tracked by the executable. Since I've removed the executable pointer,
+ on a 64bit system, I've only made activations bigger by an int.
+
+2011-03-25 David Kilzer <ddkilzer@apple.com>
+
+ Remove duplicate entry from JavaScriptCore.exp
+
+ JSC::createStackOverflowError(JSC::ExecState*) was originally
+ exported in r60057, then duplicated in r60392.
+
+ * JavaScriptCore.exp: Removed duplicate entry.
+
+2011-03-25 Jarred Nicholls <jarred@sencha.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] MSVC Build Error - need to link advapi32.lib for jsc.exe
+ https://bugs.webkit.org/show_bug.cgi?id=56098
+
+ Need to link advapi32.lib for jsc.exe since wtf/OSRandomSource.cpp uses the Win32 Crypto API
+
+ * jsc.pro:
+
+2011-03-24 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Darin Adler.
+
+ Introduce WTF HexNumber.h
+ https://bugs.webkit.org/show_bug.cgi?id=56099
+
+ Introduce a set of functions that ease converting from a bye or a number to a hex string,
+ replacing several of these conversions and String::format("%x") usages all over WebCore.
+
+ * GNUmakefile.am: Add HexNumber.h to build.
+ * JavaScriptCore.exp: Export StringBuilder::reserveCapacity.
+ * JavaScriptCore.gypi: Add HexNumber.h to build.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export StringBuilder::reserveCapacity.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add HexNumber.h to build.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * wtf/CMakeLists.txt: Ditto.
+ * wtf/HexNumber.h: Added.
+ (WTF::Internal::hexDigitsForMode): Internal helper.
+ (WTF::appendByteAsHex): Free function, that appends a byte as hex string into a destination.
+ (WTF::placeByteAsHex): Ditto, but places the result using *foo++ = '..' or foo[index++] = '..'
+ (WTF::appendUnsignedAsHex): Free function, that appends a number as hex string into a destination.
+
+2011-03-24 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix take 2: Add new symobl.
+
+ (I should have used the EWS bots for this!)
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2011-03-24 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix take 1: Removed old symobl.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2011-03-24 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Ensure that all compilation takes place within a dynamic global object scope
+ https://bugs.webkit.org/show_bug.cgi?id=57054
+ <rdar://problem/9083011>
+
+ Otherwise, entry to the global object scope might throw away the code
+ we just compiled, causing a crash.
+
+ * JavaScriptCore.exp: Updated for signature change.
+
+ * debugger/Debugger.cpp:
+ (JSC::evaluateInGlobalCallFrame):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate): Removed explicit compilation calls
+ here because (a) they took place outside a dynamic global object scope
+ and (b) they were redundant.
+
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::CachedCall): Updated for signature change.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct): Declare our dynamic global object
+ scope earlier, to ensure that compilation takes place within it.
+
+ * runtime/Completion.cpp:
+ (JSC::evaluate): Removed explicit compilation calls here because (a)
+ they took place outside a dynamic global object scope and (b) they were
+ redundant.
+
+ * runtime/Executable.h:
+ (JSC::EvalExecutable::compile):
+ (JSC::ProgramExecutable::compile):
+ (JSC::FunctionExecutable::compileForCall):
+ (JSC::FunctionExecutable::compileForConstruct): Added an ASSERT to
+ verify our new invariant that all compilation takes place within a
+ dynamic global object scope.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+ * runtime/JSGlobalObject.h: Changed the signature of DynamicGlobalObjectScope
+ to require a JSGlobalData instead of an ExecState* since it is often
+ easier to provide the former, and the latter was not necessary.
+
+2011-03-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ REGRESSION (r79987-r80210): Crash in JSWeakObjectMapClear
+ https://bugs.webkit.org/show_bug.cgi?id=55671
+
+ This is no longer necessary, and it seems that with the new weakmap
+ model it's simply unsafe, so this reduces it to a no-op.
+
+ * API/JSWeakObjectMapRefPrivate.cpp:
+
+2011-03-24 Ben Taylor <bentaylor.solx86@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20302
+ Correct implementation of signbit on Solaris
+
+ * wtf/MathExtras.h:
+ (signbit):
+
+2011-03-23 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/7959320> Threads that use APIs above the BSD layer must be registered with the Obj-C GC.
+
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::initializeCurrentThreadInternal):
+
+2011-03-23 Mark Rowe <mrowe@apple.com>
+
+ Stop setting OTHER_OPTIONS in JavaScriptCore's Makefile.
+
+ It's not necessary to pass "-target All" as xcodebuild always builds the
+ first target in the project unless otherwise specified. The presence of
+ that option also breaks "make clean" since that results in both the
+ -target and -alltargets options being passed to xcodebuild.
+
+ * Makefile:
+
+2011-03-23 Pavel Feldman <pfeldman@chromium.org>
+
+ Not reviewed: bring back Vector::contains that was removed as a part of roll back.
+
+ * wtf/Vector.h:
+ (WTF::::contains):
+
+2011-03-23 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r81686.
+ http://trac.webkit.org/changeset/81686
+ https://bugs.webkit.org/show_bug.cgi?id=56914
+
+ Breaks webkit_tests in Chromium again. (Requested by pfeldman
+ on #webkit).
+
+ * wtf/Vector.h:
+
+2011-03-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ JavaScriptCore GYP build should work on a case-sensitive file system
+ https://bugs.webkit.org/show_bug.cgi?id=56911
+
+ The issue is that there are two UString.h headers, one named UString.h
+ and one named ustring.h. This patch excludes ustring.h from the header
+ map to avoid confusion. While I was editing this part of the GYP file,
+ I cleaned up the exclude rules to be more modern.
+
+ * gyp/JavaScriptCore.gyp:
+
+2011-03-22 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ REGRESSION (r78382): No scripts appear in the Web Inspector's Scripts
+ panel on Windows, and many inspector regression tests are failing
+ https://bugs.webkit.org/show_bug.cgi?id=54490
+
+ The bug was caused by two different classes using the same name (Recompiler).
+
+ * debugger/Debugger.cpp:
+ * runtime/JSGlobalData.cpp:
+ (WTF::Recompiler::operator()): Put Recompiler in an anonymous namespace,
+ so our two recompilers' inline functions don't stomp each other at
+ link time.
+
+2011-03-22 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Remove USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER.
+ <rdar://problem/8944718>
+
+ * DerivedSources.make:
+ Remove generation of USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER.
+
+2011-03-22 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Csaba Osztrogonác.
+
+ [Qt] Add DFG module to build system (disabled by default).
+ https://bugs.webkit.org/show_bug.cgi?id=56845
+
+ * JavaScriptCore.pri:
+ * JavaScriptCore.pro:
+
+2011-03-22 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Add support to build-webkit for building with gyp-generated project files
+ https://bugs.webkit.org/show_bug.cgi?id=56877
+
+ Found a couple missing Private headers while trying to make WebCore build.
+
+ * JavaScriptCore.gypi:
+
+2011-03-22 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Make it possible to build JavaScriptCore and WebCore gyp builds outside of Source
+ https://bugs.webkit.org/show_bug.cgi?id=56867
+
+ This should make it possible to build the gyp-generated JavaScriptCore.xcodeproj
+ from a JavaScriptCore directory outside of Source.
+
+ * gyp/JavaScriptCore.gyp:
+ * gyp/run-if-exists.sh: Added.
+ * gyp/update-info-plist.sh: Added.
+
+2011-03-22 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Add Profiling Configuration to JavaScriptCore gyp build
+ https://bugs.webkit.org/show_bug.cgi?id=56862
+
+ It appears this is identical to Release, but I suspect
+ there is someone/thing who uses the Profiling target
+ so we're adding it for completeness.
+
+ * gyp/JavaScriptCore.gyp:
+
+2011-03-22 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Remove os_win32_files variable from the GYP build
+ https://bugs.webkit.org/show_bug.cgi?id=56804
+
+ Now that our understanding of GYP is sufficiently advanced, we don't
+ need os_win32_files any more. (Turns out Eric was right, as he always
+ is.)
+
+ * JavaScriptCore.gypi:
+
+2011-03-22 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ GYP build of JavaScriptCore should be able to link from an empty WebKitBuild directory
+ https://bugs.webkit.org/show_bug.cgi?id=56803
+
+ Previously, we thought we should generate the derived source files in
+ the shared intermediate build products directory, but there are
+ assumptions built into other parts of the Mac build system that the
+ derived source files will be generated in a particular subdirectory of
+ the build products directory.
+
+ This patch is a partial revert of the change that moved the derived
+ source files to the shared intermediate directory. After this patch,
+ the GYP build can build JavaScriptCore without help from the main
+ normal build system.
+
+ * JavaScriptCore.gypi:
+ * gyp/JavaScriptCore.gyp:
+ * gyp/generate-derived-sources.sh:
+ * gyp/generate-dtrace-header.sh:
+
+2011-03-22 Jay Civelli <jcivelli@chromium.org>
+
+ Reviewed by David Levin.
+
+ Adding a contains method to Vector.
+ https://bugs.webkit.org/show_bug.cgi?id=55859
+
+ * wtf/Vector.h:
+ (WTF::Vector::contains):
+
+2011-03-22 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fix a bunch of typos in DFG.
+ https://bugs.webkit.org/show_bug.cgi?id=56813
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::parse):
+ * dfg/DFGGenerationInfo.h:
+ (JSC::DFG::GenerationInfo::setSpilled):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGGraph.h:
+ * dfg/DFGJITCodeGenerator.h:
+ (JSC::DFG::JITCodeGenerator::setupStubArguments):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ * dfg/DFGNode.h:
+ * dfg/DFGNonSpeculativeJIT.h:
+ * dfg/DFGOperations.h:
+ * dfg/DFGRegisterBank.h:
+ (JSC::DFG::RegisterBank::allocate):
+ * dfg/DFGScoreBoard.h:
+ (JSC::DFG::ScoreBoard::~ScoreBoard):
+ (JSC::DFG::ScoreBoard::allocate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+
+2011-03-22 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Production configuration in GYP isn&apos;t set up correctly
+ https://bugs.webkit.org/show_bug.cgi?id=56786
+
+ Update JavaScriptCore.gyp with information mined from
+ JavaScriptCore.xcodeproj.
+
+ * JavaScriptCore.gypi:
+ * gyp/JavaScriptCore.gyp:
+
+2011-03-22 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ REGRESSION(r80096): Number type input unexpectedly rounds fractional values
+ https://bugs.webkit.org/show_bug.cgi?id=56367
+
+ Introduce clampToInteger(unsigned).
+
+ * wtf/MathExtras.h:
+ (clampToInteger): Added.
+
+2011-03-21 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ GYP build should not have include paths that point within the source tree
+ https://bugs.webkit.org/show_bug.cgi?id=56788
+
+ Turns out we don't need these include paths anymore now that we have
+ header maps working properly.
+
+ * gyp/JavaScriptCore.gyp:
+ - Also, remove jsc.cpp from the excluded list because it's not part
+ of the jsc_files variable instead of the javascriptcore_files
+ variable.
+
+2011-03-21 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Solve the Assertions.cpp / -Wno-missing-format-attribute mystery
+ https://bugs.webkit.org/show_bug.cgi?id=56780
+
+ The reason we couldn't resolve this warning in the GYP build was that
+ the normal build disables this warning specifically for this file.
+ This patch takes the same approach as the previous patch to
+ WebCoreObjCExtras.mm in that it uses a pragma to suppress the warning
+ (rather than a build system configuration).
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ - Remove the special-case for this file.
+ * gyp/JavaScriptCore.gyp:
+ - Remove the work-around for this issue.
+ * wtf/Assertions.cpp:
+ - Add a pragma disabling this warning for this file.
+
+2011-03-21 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ WebCore GYP build shouldn't crash on startup
+ https://bugs.webkit.org/show_bug.cgi?id=56776
+
+ Debug builds shouldn't define NDEBUG. This same logic exists in the
+ project.pbxproj file.
+
+ * gyp/JavaScriptCore.gyp:
+
+2011-03-21 Robert Kroeger <rjkroege@chromium.org>
+
+ Reviewed by Antonio Gomes.
+
+ Flag to enable/disable a GestureReocognizer framework
+
+ https://bugs.webkit.org/show_bug.cgi?id=49345
+
+ * wtf/Platform.h:
+
+2011-03-21 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Add new files to JavaScriptCore.gypi
+ https://bugs.webkit.org/show_bug.cgi?id=56766
+
+ * JavaScriptCore.gypi:
+
+2011-03-21 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r81377.
+ http://trac.webkit.org/changeset/81377
+ https://bugs.webkit.org/show_bug.cgi?id=56765
+
+ WebPageSerializerTest.MultipleFrames is broken (Requested by
+ simonjam on #webkit).
+
+ * wtf/Vector.h:
+
+2011-03-21 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Csaba Osztrogonác.
+
+ Extend constant pool to be able to store 16 bit instructions with a constant
+ https://bugs.webkit.org/show_bug.cgi?id=46796
+
+ The putShortWithConstantInt function inserts a 16 bit instruction which
+ refers a 32 bits constant or literal. This is a vital function for those
+ target which loads a PC relative value with a 16 bit instruction (like
+ Thumb-2 instruction set and SH4 architecture).
+
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::putIntegral):
+ (JSC::AssemblerBuffer::putIntegralUnchecked):
+ * assembler/AssemblerBufferWithConstantPool.h:
+
+2011-03-21 Philippe Normand <pnormand@igalia.com>
+
+ Unreviewed, GTK distcheck build fix.
+
+ * GNUmakefile.am:
+
+2011-03-20 Bill Budge <bbudge@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Rename ThreadSafeShared to ThreadSafeRefCounted
+ https://bugs.webkit.org/show_bug.cgi?id=56714
+
+ No new tests. Exposes no new functionality.
+
+ * API/JSClassRef.h:
+ * API/OpaqueJSString.h:
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/Atomics.h:
+ * wtf/CMakeLists.txt:
+ * wtf/CrossThreadRefCounted.h:
+ (WTF::CrossThreadRefCounted::CrossThreadRefCounted):
+ (WTF::::crossThreadCopy):
+ * wtf/ThreadSafeRefCounted.h: Copied from wtf/ThreadSafeShared.h.
+ (WTF::ThreadSafeRefCountedBase::ThreadSafeRefCountedBase):
+ (WTF::ThreadSafeRefCountedBase::ref):
+ (WTF::ThreadSafeRefCountedBase::refCount):
+ (WTF::ThreadSafeRefCountedBase::derefBase):
+ (WTF::ThreadSafeRefCounted::ThreadSafeRefCounted):
+ * wtf/ThreadSafeShared.h: Removed.
+ * wtf/Threading.h:
+
+2011-03-19 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Remove StringImpl::computeHash()
+ https://bugs.webkit.org/show_bug.cgi?id=49894
+
+ Replace remainig StringImpl::computeHash with StringImpl::computeHashStringHasher.
+
+ * wtf/text/AtomicString.cpp:
+ (WTF::CStringTranslator::hash):
+ (WTF::UCharBufferTranslator::hash):
+ (WTF::HashAndCharactersTranslator::hash):
+ * wtf/text/StringImpl.h:
+ (WTF::StringImpl::setHash):
+ (WTF::StringImpl::hash):
+
+2011-03-19 Patrick Gansterer <paroga@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Rename WTF::StringHasher methods
+ https://bugs.webkit.org/show_bug.cgi?id=53532
+
+ Rename createHash to computeHash and createBlobHash to hashMemory.
+ Also add a using WTF::StringHasher in the header file.
+
+ * profiler/CallIdentifier.h:
+ (JSC::CallIdentifier::Hash::hash):
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierCStringTranslator::hash):
+ (JSC::IdentifierUCharBufferTranslator::hash):
+ * wtf/StringHasher.h:
+ (WTF::StringHasher::computeHash):
+ (WTF::StringHasher::hashMemory):
+ * wtf/text/StringHash.h:
+ (WTF::CaseFoldingHash::hash):
+ * wtf/text/StringImpl.h:
+ (WTF::StringImpl::computeHash):
+ * wtf/unicode/UTF8.cpp:
+ (WTF::Unicode::calculateStringHashAndLengthFromUTF8Internal):
+
+2011-03-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ [GTK] JSC crashes in 32bit Release bots after r80743
+ https://bugs.webkit.org/show_bug.cgi?id=56180
+
+ The crash was caused by referencing GC memory from a GC destructor. This
+ is not safe because destruction time / order is not guaranteed.
+
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::create):
+ (JSC::ProfileGenerator::ProfileGenerator):
+ (JSC::ProfileGenerator::willExecute):
+ (JSC::ProfileGenerator::didExecute):
+ * profiler/ProfileGenerator.h:
+ (JSC::ProfileGenerator::origin): Made ExecState* the first argument,
+ to match the rest of this class and JSC.
+
+ Use a JSGlobalObject* instead of an ExecState* with an indirect reference
+ to a JSGlobalObject* to track our origin. This is simpler and more
+ efficient, and it removes the destruction order dependency that was causing
+ our crash.
+
+ * profiler/Profiler.cpp:
+ (JSC::Profiler::startProfiling): Updated for change to JSGlobalObject*.
+ (JSC::Profiler::stopProfiling): New function for stopping all profiles
+ for a given global object. This is more straight-forward than multiplexing
+ through the old function.
+
+ (JSC::dispatchFunctionToProfiles): Updated for change to JSGlobalObject*.
+ * profiler/Profiler.h: Ditto.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::~JSGlobalObject): Ditto.
+
+2011-03-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ 1 Structure leaked beneath JSGlobalData::storeVPtrs()
+ https://bugs.webkit.org/show_bug.cgi?id=56595
+
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::EvalExecutable):
+ (JSC::ProgramExecutable::ProgramExecutable):
+ (JSC::FunctionExecutable::FunctionExecutable):
+ * runtime/Executable.h:
+ (JSC::ExecutableBase::ExecutableBase):
+ (JSC::NativeExecutable::NativeExecutable):
+ (JSC::VPtrHackExecutable::VPtrHackExecutable):
+ (JSC::ScriptExecutable::ScriptExecutable): Use a raw pointer instead of
+ PassRefPtr, like JSString does, since JSGlobalData owns the singleton
+ exectuable structure.
+
+2011-03-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Fixed some string leaks seen on the buildbot
+ https://bugs.webkit.org/show_bug.cgi?id=56619
+
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyTable::~PropertyTable): DEref!
+
+2011-03-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Crash in JSC::MarkStack::drain Under Stress
+ https://bugs.webkit.org/show_bug.cgi?id=56470
+
+ We perform a number of gc allocations while when
+ we are setting up new globals in a piece of global
+ code. We do this by adding new properties to the
+ symbol table, and then expanding the storage to fit
+ at the end.
+
+ If a GC happens during this time we will report an
+ incorrect size for the global object's symbol table
+ storage.
+
+ This patch corrects this by growing the storage size
+ before we starting adding entries to the symbol table.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::resizeRegisters):
+
+2011-03-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ 1 Structure leaked beneath JSGlobalData::storeVPtrs()
+ https://bugs.webkit.org/show_bug.cgi?id=56595
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::storeVPtrs): Take local ownership of the Structure
+ we're using, since the Executable is not designed to own the Structure.
+
+2011-03-17 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Sam Weinig.
+
+ Add missing register-register branchTest8 to MacroAssemblerX86Common/X86Assembler.
+
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::branchTest8):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::testb_rr):
+
+2011-03-17 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 56603 - DFG JIT related cleanup
+ Move node generation out to separate function, move binarySearch algorithm out
+ to StdLibExtras, fix Graph::dump() to print comma between non-node children,
+ even if there are no node children.
+
+ * bytecode/CodeBlock.h:
+ (JSC::getCallReturnOffset):
+ (JSC::CodeBlock::getStubInfo):
+ (JSC::CodeBlock::getCallLinkInfo):
+ (JSC::CodeBlock::getMethodCallLinkInfo):
+ (JSC::CodeBlock::bytecodeOffset):
+ - Move binaryChop to binarySearch in StdLibExtras
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::parse):
+ (JSC::DFG::parse):
+ - Make m_noArithmetic a member, initialize m_currentIndex in the constructor.
+ * dfg/DFGByteCodeParser.h:
+ - Change parse() to not take a start index (always 0).
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ - Fix Graph::dump() to print comma between non-node children, even if there are no node children.
+ * dfg/DFGJITCodeGenerator.h:
+ (JSC::DFG::JITCodeGenerator::JITCodeGenerator):
+ - Initialize m_compileIndex in constructor.
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGNonSpeculativeJIT.h:
+ - Spilt out compilation of individual node.
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::operationConvertThis):
+ * dfg/DFGOperations.h:
+ - Cleanup parameter name.
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ - Spilt out compilation of individual node.
+ * runtime/Executable.cpp:
+ (JSC::tryDFGCompile):
+ - Change parse() to not take a start index (always 0).
+ * wtf/StdLibExtras.h:
+ (WTF::binarySearch):
+ - Move binaryChop to binarySearch in StdLibExtras
+
+2011-03-17 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix clang build.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::storeVPtrs):
+
+2011-03-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ 1 Structure leaked beneath JSGlobalData::storeVPtrs()
+ https://bugs.webkit.org/show_bug.cgi?id=56595
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::storeVPtrs): Now that we have an executable, we need
+ to explicitly run its destructor.
+
+2011-03-17 Jeff Miller <jeffm@apple.com>
+
+ Use a consistent set of file patterns in the svn:ignore property for all .xcodeproj directories, specifically:
+
+ *.mode*
+ *.pbxuser
+ *.perspective*
+ project.xcworkspace
+ xcuserdata
+
+ * JavaScriptCore.xcodeproj: Modified property svn:ignore.
+
+2011-03-17 Gavin Barraclough <barraclough@apple.com>
+
+ Reverting r81197, breaks JIT + INTERPRETER build.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset):
+ (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addPropertyAccessInstruction):
+ (JSC::CodeBlock::addGlobalResolveInstruction):
+ (JSC::CodeBlock::addStructureStubInfo):
+ * bytecode/Opcode.h:
+ * bytecode/StructureStubInfo.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveWithBase):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitDirectPutById):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitConstruct):
+ (JSC::BytecodeGenerator::emitCatch):
+
+2011-03-17 Ben Taylor <bentaylor.solx86@gmail.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add a COMPILER(SUNCC) define for Sun Studio 12.
+ https://bugs.webkit.org/show_bug.cgi?56444
+ derived from patch 1 of 16 originally from https://bugs.webkit.org/show_bug.cgi?id=24932
+
+ * wtf/Platform.h:
+
+2011-03-17 Jay Civelli <jcivelli@chromium.org>
+
+ Reviewed by David Levin.
+
+ Adding a contains method to Vector.
+ https://bugs.webkit.org/show_bug.cgi?id=55859
+
+ * wtf/Vector.h:
+ (WTF::::operator):
+ (WTF::::contains):
+
+2011-03-17 Patrick Gansterer <paroga@webkit.org>
+
+ Fix the interpreter build.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute): Added globalData to inheritorID().
+
+2011-03-16 Sam Weinig <sam@webkit.org>
+
+ Fix the interpreter build.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolve):
+ (JSC::Interpreter::resolveSkip):
+ (JSC::Interpreter::resolveGlobal):
+ (JSC::Interpreter::resolveGlobalDynamic):
+ (JSC::Interpreter::resolveBaseAndProperty):
+ (JSC::Interpreter::privateExecute):
+ Remove .get()s.
+
+2011-03-16 Adam Barth <abarth@webkit.org>
+
+ Reviewed by James Robinson.
+
+ Remove USE(BUILTIN_UTF8_CODEC)
+ https://bugs.webkit.org/show_bug.cgi?id=56508
+
+ We added this recently when we were unsure about the stability of the
+ built-in UTF-8 codec. However, the codec seems to be stable, so we
+ don't need the macro.
+
+ * wtf/Platform.h:
+
+2011-03-16 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Darin Adler.
+
+ Make JIT build for ARM Thumb-2 with RVCT
+ https://bugs.webkit.org/show_bug.cgi?id=56440
+
+ Derived from a patch by Dave Tapuska.
+
+ Also, modify the RVCT stub template to indicate that it preserves 8 byte stack alignment.
+
+ * jit/JITStubs.cpp:
+
+2011-03-16 Chao-ying Fu <fu@mips.com>
+
+ Reviewed by Darin Adler.
+
+ Fix MIPS build with const *void
+ https://bugs.webkit.org/show_bug.cgi?id=56513
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::load32):
+ (JSC::MacroAssemblerMIPS::store32):
+
+2011-03-16 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Remove unnecessary caller tracking shenanigans from CodeBlock
+ https://bugs.webkit.org/show_bug.cgi?id=56483
+
+ This removes some leftover cruft from when we made CodeBlock
+ mark its callees. Removing it gives us a 0.7% progression,
+ reducing the overall regression to ~1.3%.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CallLinkInfo::CallLinkInfo):
+ * jit/JIT.cpp:
+ (JSC::JIT::linkCall):
+ (JSC::JIT::linkConstruct):
+
+2011-03-15 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Make Structure creation require a JSGlobalData
+ https://bugs.webkit.org/show_bug.cgi?id=56438
+
+ Mechanical change to make Structure::create require JSGlobalData&, and
+ require all users to provide the globalData.
+
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.h:
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * API/JSContextRef.cpp:
+ * JavaScriptCore.exp:
+ * debugger/DebuggerActivation.cpp:
+ (JSC::DebuggerActivation::DebuggerActivation):
+ * debugger/DebuggerActivation.h:
+ (JSC::DebuggerActivation::createStructure):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jsc.cpp:
+ (GlobalObject::GlobalObject):
+ (functionRun):
+ (jscmain):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ * runtime/ArrayPrototype.h:
+ (JSC::ArrayPrototype::createStructure):
+ * runtime/BooleanObject.h:
+ (JSC::BooleanObject::createStructure):
+ * runtime/DateInstance.h:
+ (JSC::DateInstance::createStructure):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/ErrorInstance.h:
+ (JSC::ErrorInstance::createStructure):
+ * runtime/Executable.h:
+ (JSC::ExecutableBase::createStructure):
+ (JSC::EvalExecutable::createStructure):
+ (JSC::ProgramExecutable::createStructure):
+ (JSC::FunctionExecutable::createStructure):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GetterSetter.h:
+ (JSC::GetterSetter::createStructure):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ * runtime/JSAPIValueWrapper.h:
+ (JSC::JSAPIValueWrapper::createStructure):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::createStructure):
+ * runtime/JSByteArray.h:
+ (JSC::JSByteArray::JSByteArray):
+ * runtime/JSCell.h:
+ (JSC::JSCell::JSCell::createDummyStructure):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::storeVPtrs):
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ (JSC::JSGlobalObject::createStructure):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::createStructure):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::createInheritorID):
+ * runtime/JSObject.h:
+ (JSC::JSObject::createStructure):
+ (JSC::JSNonFinalObject::createStructure):
+ (JSC::JSFinalObject::createStructure):
+ (JSC::createEmptyObjectStructure):
+ (JSC::JSObject::inheritorID):
+ * runtime/JSObjectWithGlobalObject.h:
+ (JSC::JSObjectWithGlobalObject::createStructure):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::createStructure):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSString.h:
+ (JSC::RopeBuilder::createStructure):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::createStructure):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::createStructure):
+ * runtime/JSZombie.h:
+ (JSC::JSZombie::createStructure):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NativeErrorConstructor.cpp:
+ (JSC::NativeErrorConstructor::NativeErrorConstructor):
+ * runtime/NativeErrorConstructor.h:
+ (JSC::NativeErrorConstructor::createStructure):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.h:
+ (JSC::NumberObject::createStructure):
+ * runtime/ObjectConstructor.h:
+ (JSC::ObjectConstructor::createStructure):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ * runtime/ScopeChain.h:
+ (JSC::ScopeChainNode::createStructure):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+ * runtime/StringPrototype.h:
+ (JSC::StringPrototype::createStructure):
+ * runtime/Structure.h:
+ (JSC::Structure::create):
+
+2011-03-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Some conservative root gathering cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=56447
+
+ SunSpider says 0.5% - 1.8% faster.
+
+ * interpreter/RegisterFile.cpp:
+ (JSC::RegisterFile::gatherConservativeRoots):
+ * interpreter/RegisterFile.h: New helper function for doing the
+ conservative gathering of the register file. It's still conservative,
+ since the register file may contain uninitialized values, but it's
+ moving-safe, because it only visits values tagged as pointers, so there's
+ no risk of mistaking an integer for a pointer and accidentally changing it.
+
+ * runtime/ConservativeSet.cpp:
+ (JSC::ConservativeRoots::add):
+ * runtime/ConservativeSet.h: Added a single-value add function, used above.
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::markRoots): Separated machine stack conservative roots from
+ register file conservative roots because machine stack roots must be
+ pinned, but register file roots need not be pinned.
+
+ Adopted new interface for passing the current stack extent to the machine
+ stack root gathering routine. This allows us to exclude marking-related
+ data structures on the stack, and thus avoid double-marking the set of
+ machine roots.
+
+ * runtime/MachineStackMarker.cpp:
+ (JSC::MachineThreads::gatherFromCurrentThread):
+ (JSC::MachineThreads::gatherConservativeRoots):
+ * runtime/MachineStackMarker.h: Added new interface, described above.
+
+ * runtime/MarkedBlock.h:
+ (JSC::MarkedBlock::firstAtom):
+ * wtf/StdLibExtras.h:
+ (WTF::roundUpToMultipleOf): Moved roundUpToMultipleOf so it could be used
+ by MachineStacks.
+
+2011-03-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ A little bit of MarkStack cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=56443
+
+ Moved MarkStack functions into MarkStack.h/.cpp.
+
+ SunSpider reports no change.
+
+ * runtime/JSArray.h:
+ * runtime/JSCell.h: Moved from here...
+ * runtime/MarkStack.cpp:
+ (JSC::MarkStack::markChildren):
+ (JSC::MarkStack::drain): ...to here. Also, no need to inline drain. It's
+ a huge function, and not called many times.
+
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::~MarkStack): Moved near constructor, per style guide.
+ (JSC::MarkStack::append):
+ (JSC::MarkStack::deprecatedAppend):
+ (JSC::MarkStack::internalAppend): Moved to here.
+
+2011-03-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed another deprecatedAppend
+ https://bugs.webkit.org/show_bug.cgi?id=56429
+
+ * collector/handles/HandleHeap.cpp:
+ (JSC::HandleHeap::markStrongHandles):
+ * collector/handles/HandleHeap.h: Use HeapRootMarker, since handles are
+ marked directly by the Heap.
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::markRoots): Ditto.
+
+2011-03-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed some more deprecated / unsafe append
+ https://bugs.webkit.org/show_bug.cgi?id=56428
+
+ * collector/handles/HandleStack.cpp:
+ (JSC::HandleStack::mark):
+ * collector/handles/HandleStack.h: Mark the handle stack using a HeapRoot
+ marker, since it's a heap root.
+
+ * runtime/ArgList.cpp:
+ (JSC::MarkedArgumentBuffer::markLists):
+ (JSC::MarkedArgumentBuffer::slowAppend):
+ * runtime/ArgList.h: Ditto.
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::markRoots): Added a mark call for marking the handle stack.
+ It seems like Oliver forgot this in his last patch. (!)
+
+ * runtime/MarkStack.h: Removed appendSlots, since it would allow an
+ object to embed JSValues directly instead of using WriteBarrier.
+
+ (JSC::MarkStack::append): Added a private append for a list of values.
+
+ (JSC::HeapRootMarker::mark): Access to the above.
+
+2011-03-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed a few more deprecatedAppends, and removed HeapRoot<T>
+ https://bugs.webkit.org/show_bug.cgi?id=56422
+
+ Added HeapRootMarker, a privileged class for marking direct heap roots
+ that are iterated during each garbage collection. This is easier to use
+ and more reliable than HeapRoot<T>, so I've removed HeapRoot<T>.
+
+ * debugger/Debugger.cpp:
+ (JSC::evaluateInGlobalCallFrame):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::exception):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Completion.cpp:
+ (JSC::evaluate): exception is no longer a HeapRoot<T>, so no need to
+ call .get() on it.
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::markProtectedObjects):
+ (JSC::Heap::markTempSortVectors):
+ (JSC::Heap::markRoots):
+ * runtime/Heap.h: Updated to use HeapRootMarker.
+
+ * runtime/JSCell.h:
+ (JSC::JSCell::MarkStack::append): Added private functions for
+ HeapRootMarker to use.
+
+ * runtime/JSGlobalData.h: exception is no longer a HeapRoot<T>.
+
+ * runtime/MarkStack.h:
+ (JSC::HeapRootMarker::HeapRootMarker):
+ (JSC::HeapRootMarker::mark): Added private functions for
+ HeapRootMarker to use.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStrings::markChildren): Updated to use HeapRootMarker.
+
+ * runtime/SmallStrings.h:
+ (JSC::SmallStrings::emptyString):
+ (JSC::SmallStrings::singleCharacterString):
+ (JSC::SmallStrings::singleCharacterStrings): Updated to use HeapRootMarker.
+
+ * runtime/WriteBarrier.h: Removed HeapRoot<T>.
+
+2011-03-14 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Made the global object moving-GC-safe
+ https://bugs.webkit.org/show_bug.cgi?id=56348
+
+ SunSpider reports no change.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::markChildren): Removed a dubious comment that
+ suggested we do not need to visit all our references during GC, since
+ that is not true in a moving GC.
+
+ Re-sorted data members by type, removed one duplicate, and added back
+ the one missing mark I found.
+
+ * runtime/JSGlobalObject.h: Re-sorted data members by type.
+
+2011-03-15 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Introduce Local<T> to allow us to start moving to precise marking of locals
+ https://bugs.webkit.org/show_bug.cgi?id=56394
+
+ Introduce a new handle type, Local<T> and a scoping mechanism
+ LocalScope to allow us to start moving towards precise marking
+ of temporaries and local variables.
+
+ We also start to use the new Local<> type in the JSON stringifier
+ so that we can have some coverage of their behaviour in the initial
+ checkin.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * collector/handles/Handle.h:
+ (JSC::::asObject):
+ * collector/handles/HandleStack.cpp: Added.
+ (JSC::HandleStack::HandleStack):
+ (JSC::HandleStack::mark):
+ (JSC::HandleStack::grow):
+ * collector/handles/HandleStack.h: Added.
+ (JSC::HandleStack::enterScope):
+ (JSC::HandleStack::zapTo):
+ (JSC::HandleStack::leaveScope):
+ (JSC::HandleStack::push):
+ * collector/handles/Local.h: Added.
+ (JSC::Local::internalSet):
+ (JSC::::Local):
+ (JSC::::operator):
+ (JSC::LocalStack::LocalStack):
+ (JSC::LocalStack::peek):
+ (JSC::LocalStack::pop):
+ (JSC::LocalStack::push):
+ (JSC::LocalStack::isEmpty):
+ (JSC::LocalStack::size):
+ * collector/handles/LocalScope.h: Added.
+ (JSC::LocalScope::LocalScope):
+ (JSC::LocalScope::~LocalScope):
+ (JSC::LocalScope::release):
+ * runtime/Heap.cpp:
+ (JSC::Heap::markRoots):
+ * runtime/Heap.h:
+ (JSC::Heap::allocateLocalHandle):
+ (JSC::Heap::handleStack):
+ * runtime/JSCell.h:
+ (JSC::JSCell::::getString):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSC::JSGlobalData::allocateLocalHandle):
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Stringifier):
+ (JSC::Stringifier::stringify):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Walker::Walker):
+ (JSC::Walker::walk):
+ (JSC::JSONProtoFuncParse):
+ (JSC::JSONProtoFuncStringify):
+ (JSC::JSONStringify):
+ * runtime/JSONObject.h:
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::appendValues):
+ (JSC::MarkStack::appendSlots):
+
+2011-03-15 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Sam Weinig.
+
+ Bug 56420 - Remove ENABLE(JIT) code from ByteCompiler
+ Some methods have unnecessary differences in name/arguments for interpreter/JIT.
+
+ * bytecode/CodeBlock.cpp:
+ * bytecode/CodeBlock.h:
+ (JSC::HandlerInfo::HandlerInfo):
+ (JSC::CodeBlock::addPropertyAccessInfo):
+ (JSC::CodeBlock::addGlobalResolveInfo):
+ (JSC::CodeBlock::addCallLinkInfo):
+ (JSC::CodeBlock::globalResolveInfo):
+ * bytecode/Opcode.h:
+ * bytecode/StructureStubInfo.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveWithBase):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitDirectPutById):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitConstruct):
+ (JSC::BytecodeGenerator::emitCatch):
+
+2011-03-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix broken assert in new code.
+
+ * dfg/DFGAliasTracker.h:
+ (JSC::DFG::AliasTracker::recordPutByVal):
+ - recordPutByVal is called for both PutByVal & PutByValAlias.
+
+2011-03-15 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Sam Weinig.
+
+ Removed redundant code from BytecodeGenerator.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ * bytecompiler/BytecodeGenerator.h:
+ - delete uncalled code missed when reparsing was removed.
+
+2011-03-15 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Darin Adler.
+
+ Introduce WTF_USE_EXPORT_MACROS, which will allow us to put shared library import/export
+ info into the headers rather than in export symbol definition files, but disable it on
+ all platforms initially so we can deal with port build issues one port at a time.
+
+ https://bugs.webkit.org/show_bug.cgi?id=27551
+
+ * API/JSBase.h:
+ * config.h:
+ * wtf/Assertions.h:
+ * wtf/ExportMacros.h: Added.
+ * wtf/Platform.h:
+
+2011-03-14 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed build fix.
+
+ Buildfix when JIT is not enabled after r81079
+ https://bugs.webkit.org/show_bug.cgi?id=56361
+
+ * runtime/Executable.cpp:
+
+2011-03-14 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Made the global object moving-GC-safe
+ https://bugs.webkit.org/show_bug.cgi?id=56348
+
+ SunSpider reports no change.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::markChildren): Removed a dubious comment that
+ suggested we do not need to visit all our references during GC, since
+ that is not true in a moving GC.
+
+ Re-sorted data members by type, removed one duplicate, and added back
+ the one missing mark I found.
+
+ * runtime/JSGlobalObject.h: Re-sorted data members by type.
+
+2011-03-14 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Made JSWrapperObject and subclasses moving-GC-safe
+ https://bugs.webkit.org/show_bug.cgi?id=56346
+
+ SunSpider reports no change.
+
+ * runtime/BooleanObject.cpp:
+ (JSC::BooleanObject::BooleanObject):
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::DateInstance): No more need for JSGlobalData, since
+ we don't initialize the wrapped value in our constructor.
+
+ * runtime/DateInstance.h: Don't set the OverridesMarkChildren flag because
+ we do not in fact override markChildren.
+
+ * runtime/DatePrototype.h: Declare an anonymous slot, since wrapper object
+ no longer does so for us. Also added an ASSERT to catch a latent bug,
+ where DatePrototype stomped on its base class's anonymous slot. Hard-coded
+ anonymous slots are a plague on our code. This doesn't cause any problems
+ in our existing code since the base class never reads the anonymous slot
+ it declares, but it caused crashes when I tried to start using the slot
+ in an initial version of this patch.
+
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::JSWrapperObject):
+ (JSC::JSWrapperObject::internalValue):
+ (JSC::JSWrapperObject::setInternalValue): Resolved a problem where
+ our internal value was stored in two places: an anonymous slot, and a
+ data member which was not always visited during GC. Now, we only use the
+ data member, and we always visit it. (Instead of relying on certain
+ subclasses to set the OverridesMarkChildren bit, we set it ourselves.)
+
+ * runtime/NumberObject.cpp:
+ (JSC::NumberObject::NumberObject): No more need for JSGlobalData, since
+ we don't initialize the wrapped value in our constructor.
+
+ * runtime/NumberObject.h: Removed meaningless declaration.
+
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::StringObject): No more need for JSGlobalData, since
+ we don't initialize the wrapped value in our constructor.
+
+ * runtime/StringObject.h: Don't set the OverridesMarkChildren flag because
+ we do not in fact override markChildren.
+
+ * runtime/StringPrototype.h: Declare an anonymous slot, since wrapper object
+ no longer does so for us. Also added an ASSERT to catch a latent bug,
+ where DatePrototype stomped on its base class's anonymous slot. Hard-coded
+ anonymous slots are a plague on our code.
+
+2011-03-14 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Look-ahead assertions with back references don’t work as expected
+ https://bugs.webkit.org/show_bug.cgi?id=56082
+
+ Changed parentheses assertion processing to temporarily back out the
+ number of known characters after the assertion while processing the
+ assertion. This was done so that assertions don't fail due to
+ checking the number of required characters as additional to the
+ rest of the express since assertions don't "consume" input.
+ Added a byte code to uncheck characters to support the change.
+
+ * yarr/YarrInterpreter.cpp:
+ (JSC::Yarr::Interpreter::matchDisjunction):
+ (JSC::Yarr::ByteCompiler::uncheckInput):
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+ * yarr/YarrInterpreter.h:
+ (JSC::Yarr::ByteTerm::UncheckInput):
+
+2011-03-14 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] Warning that round/roundf functions are already defined when compiled with RVCT 4 on symbian.
+ https://bugs.webkit.org/show_bug.cgi?id=56133
+
+ Add condition to not compile webkit internal math round functions on RVCT compiler versions
+ from 3.0.0 because they are already defined in compiler math library.
+
+ * wtf/MathExtras.h:
+
+2011-03-14 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoffrey Garen & Oliver Hunt.
+
+ Bug 56284 - Add a dataflow intermediate representation for use in JIT generation.
+
+ The JSC JIT presently generates code directly from the bytecode used by the interpreter.
+ This is not an optimal intermediate representation for JIT code generation, since it does
+ not capture liveness information of values, and provides little opportunity to perform
+ any static analysis for even primitive types. The JIT currently generates two code paths,
+ a fast path handling common cases, and a slower path handling less common operand types.
+ However the slow path jumps back into the fast path, meaning that information arising
+ from the earlier type checks cannot be propagated to later operations.
+
+ This patch adds:
+ * a dataflow intermediate representation capable of describing a single basic block
+ of operations,
+ * a mechanism to convert a simple, single-block bytecode functions to the new IR,
+ * and a JIT code generator capable of generating code from this representation.
+
+ The JIT generates two code paths, with the slower path not reentering the fast path
+ mid-block, allowing speculative optimizations to be made on the hot path, with type
+ information arising from these speculative decisions able to be propagated through the
+ dataflow. Code generation of both speculative and non-speculative paths exploits the type
+ and liveness information represented in the dataflow graph to attempt to avoid redundant
+ boxing and type-checking of values, and to remove unnecessary spills of temporary values
+ to the RegisterFile.
+
+ The dataflow JIT currently can only support a subset of bytecode operations, limited to
+ arithmetic, bit-ops, and basic property access. Functions that cannot be compiled by the
+ dataflow JIT will be run using the existing JIT. The coverage of the dataflow JIT will be
+ expanded to include, control-flow, function calls, and then the long-tail of remaining
+ bytecode instructions. The JIT presently only support JSVALUE64, and as a consequence of
+ this only supports x86-64.
+
+ The status of the dataflow JIT is currently work-in-progress. Limitations of the present
+ JIT code generation may cause performance regressions, particularly:
+ * the policy to only generate arithmetic code on the speculative path using integer
+ instructions, never using floating point.
+ * the policy to only generate arithmetic code on the non-speculative path using
+ floating point instructions, never using integer.
+ * always generating JSValue adds on the non-speculative path as a call out to a
+ C-function, never handling this in JIT code.
+ * always assuming by-Value property accesses on the speculative path to be array
+ accesses.
+ * generating all by-Value property accesses from the non-speculative path as a call
+ out to a C-function.
+ * generating all by-Indentifer property accesses as a call out to a C-function.
+ Due to these regressions, the code is landed in a state where it is disabled in most
+ cases by the ENABLE_DFG_JIT_RESTRICTIONS guard in Platform.h. As these regressions are
+ addressed, the JIT will be allowed to trigger in more cases.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ - Added new files to Xcode project.
+ * dfg: Added.
+ - Added directory for new code.
+ * dfg/DFGByteCodeParser.cpp: Added.
+ * dfg/DFGByteCodeParser.h: Added.
+ - Contruct a DFG::Graph representation from a bytecode CodeBlock.
+ * dfg/DFGGenerationInfo.h: Added.
+ - Track type & register information for VirtualRegisters during JIT code generation.
+ * dfg/DFGGraph.cpp: Added.
+ * dfg/DFGGraph.h: Added.
+ - Dataflow graph intermediate representation for code generation.
+ * dfg/DFGJITCodeGenerator.cpp: Added.
+ * dfg/DFGJITCodeGenerator.h: Added.
+ - Base class for SpeculativeJIT & NonSpeculativeJIT to share common functionality.
+ * dfg/DFGJITCompiler.cpp: Added.
+ * dfg/DFGJITCompiler.h: Added.
+ - Class responsible for driving code generation of speculativeJIT & non-speculative
+ code paths from the dataflow graph.
+ * dfg/DFGNonSpeculativeJIT.cpp: Added.
+ * dfg/DFGNonSpeculativeJIT.h: Added.
+ - Used to generate the non-speculative code path, this make no assumptions
+ about operand types.
+ * dfg/DFGOperations.cpp: Added.
+ * dfg/DFGOperations.h: Added.
+ - Helper functions called from the JIT generated code.
+ * dfg/DFGRegisterBank.h: Added.
+ - Used to track contents of physical registers during JIT code generation.
+ * dfg/DFGSpeculativeJIT.cpp: Added.
+ * dfg/DFGSpeculativeJIT.h: Added.
+ - Used to generate the speculative code path, this make assumptions about
+ operand types to enable optimization.
+ * runtime/Executable.cpp:
+ - Add code to attempt to use the DFG JIT to compile a function, with fallback
+ to the existing JIT.
+ * wtf/Platform.h:
+ - Added compile guards to enable the DFG JIT.
+
+2011-03-14 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed more cases of DeprecatedPtr (exception, SmallStrings)
+ https://bugs.webkit.org/show_bug.cgi?id=56332
+
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ (JSC::Identifier::addSlowCase): Use a variable instead of a hard-coded
+ constant, to make this code less brittle.
+
+ * runtime/JSGlobalData.h: Use HeapRoot instead of DeprecatedPtr because
+ this reference is owned and managed directly by the heap.
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::substringFromRope):
+ * runtime/JSString.h:
+ (JSC::jsSingleCharacterString):
+ (JSC::jsSingleCharacterSubstring):
+ (JSC::jsString):
+ (JSC::jsStringWithFinalizer):
+ (JSC::jsSubstring):
+ (JSC::jsOwnedString): Use a variable instead of a hard-coded
+ constant, to make this code less brittle.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStringsStorage::rep):
+ (JSC::SmallStringsStorage::SmallStringsStorage):
+ (JSC::SmallStrings::SmallStrings):
+ (JSC::SmallStrings::markChildren):
+ (JSC::SmallStrings::clear):
+ (JSC::SmallStrings::count): Use a variable instead of a hard-coded
+ constant, to make this code less brittle.
+
+ * runtime/SmallStrings.h:
+ (JSC::SmallStrings::singleCharacterString): Use HeapRoot instead of
+ DeprecatedPtr because these references are owned and managed directly by
+ the heap.
+
+ Stop using FixedArray because we only want a very limited set
+ of classes to be able to use HeapRoot. (Replaced with manual ASSERTs.)
+
+ * runtime/WriteBarrier.h:
+ (JSC::operator==):
+ (JSC::WriteBarrier::WriteBarrier):
+ (JSC::HeapRoot::HeapRoot):
+ (JSC::HeapRoot::operator=): Added HeapRoot, which is allowed to set
+ without write barrier because we assume all HeapRoots are scanned during
+ all GC passes.
+
+2011-03-14 Brian Weinstein <bweinstein@apple.com>
+
+ Reviewed by Adam Roben and Gavin Barraclough.
+
+ FileSystemWin.cpp needs listDirectory() implementation
+ https://bugs.webkit.org/show_bug.cgi?id=56331
+ <rdar://problem/9126635>
+
+ Give StringConcatenate the ability to deal with const UChar*'s as a String type to append.
+
+ * wtf/text/StringConcatenate.h:
+
+2011-03-14 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <http://webkit.org/b/56304> REGRESSION(r80892): 100,000+ leaks seen on the build bot
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::OpaqueJSClass): Don't leak any existing entry for the given name if
+ the class definition contains duplicates. This also removes what look to be leaks
+ of the StringImpl instances that are used as keys: the HashMap key type is a RefPtr
+ which retains / releases the instances at the appropriate time, so explicitly calling
+ ref is not necessary.
+
+2011-03-14 Oliver Hunt <oliver@apple.com>
+
+ Fix windows build
+
+ * jit/JSInterfaceJIT.h:
+ (JSC::JSInterfaceJIT::emitLoadInt32):
+ (JSC::JSInterfaceJIT::tagFor):
+ (JSC::JSInterfaceJIT::payloadFor):
+ (JSC::JSInterfaceJIT::intPayloadFor):
+ (JSC::JSInterfaceJIT::intTagFor):
+ (JSC::JSInterfaceJIT::addressFor):
+
+2011-03-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Ensure all values are correctly tagged in the registerfile
+ https://bugs.webkit.org/show_bug.cgi?id=56214
+
+ This patch makes sure that all JSCell pointers written to
+ the registerfile are correctly tagged as JSCells, and replaces
+ raw int usage with the immediate representation.
+
+ For performance, register pressure, and general saneness reasons
+ I've added abstractions for reading and writing the tag
+ and payload of integer registers directly for the JSVALUE64
+ encoding.
+
+ * interpreter/Register.h:
+ (JSC::Register::withInt):
+ (JSC::Register::withCallee):
+ (JSC::Register::operator=):
+ (JSC::Register::i):
+ (JSC::Register::activation):
+ (JSC::Register::function):
+ (JSC::Register::propertyNameIterator):
+ (JSC::Register::scopeChain):
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutToCallFrameHeader):
+ (JSC::JIT::emitPutCellToCallFrameHeader):
+ (JSC::JIT::emitPutIntToCallFrameHeader):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::emit_op_load_varargs):
+ (JSC::JIT::emitSlow_op_load_varargs):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ * jit/JSInterfaceJIT.h:
+ (JSC::JSInterfaceJIT::intPayloadFor):
+ (JSC::JSInterfaceJIT::intTagFor):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::returnJSValue):
+ (JSC::SpecializedThunkJIT::returnDouble):
+ (JSC::SpecializedThunkJIT::returnInt32):
+ (JSC::SpecializedThunkJIT::returnJSCell):
+
+2011-03-13 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A few Heap-related renames (sans file moves, which should come next)
+ https://bugs.webkit.org/show_bug.cgi?id=56283
+
+ ConservativeSet => ConservativeRoots. "Set" was misleading, since items
+ are not uniqued. Also, "Roots" is more specific about what's in the set.
+
+ MachineStackMarker => MachineThreads. "Threads" is more descriptive of
+ the fact that this class maintains a set of all threads using JSC.
+ "Stack" was misleading, since this class traverses stacks and registers.
+ "Mark" was misleading, since this class doesn't mark anything anymore.
+
+ registerThread => addCurrentThread. "Current" is more specific.
+ unregisterThread => removeCurrentThread. "Current" is more specific.
+
+ "currentThreadRegistrar" => threadSpecific. The only point of this data
+ structure is to register a thread-specific destructor with a pointer to
+ this.
+
+ "mark...Conservatively" => "gather". "Mark" is not true, since these
+ functions don't mark anything. "Conservatively" is redundant, since they
+ take "ConservativeRoots" as an argument.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ * JavaScriptCore.exp:
+ * runtime/ConservativeSet.cpp:
+ (JSC::ConservativeRoots::grow):
+ (JSC::ConservativeRoots::add):
+ * runtime/ConservativeSet.h:
+ (JSC::ConservativeRoots::ConservativeRoots):
+ (JSC::ConservativeRoots::~ConservativeRoots):
+ (JSC::ConservativeRoots::size):
+ (JSC::ConservativeRoots::roots):
+ * runtime/Heap.cpp:
+ (JSC::Heap::Heap):
+ (JSC::Heap::markRoots):
+ * runtime/Heap.h:
+ (JSC::Heap::machineThreads):
+ * runtime/JSGlobalData.h:
+ (JSC::JSGlobalData::makeUsableFromMultipleThreads):
+ * runtime/MachineStackMarker.cpp:
+ (JSC::MachineThreads::MachineThreads):
+ (JSC::MachineThreads::~MachineThreads):
+ (JSC::MachineThreads::makeUsableFromMultipleThreads):
+ (JSC::MachineThreads::addCurrentThread):
+ (JSC::MachineThreads::removeThread):
+ (JSC::MachineThreads::removeCurrentThread):
+ (JSC::MachineThreads::gatherFromCurrentThreadInternal):
+ (JSC::MachineThreads::gatherFromCurrentThread):
+ (JSC::MachineThreads::gatherFromOtherThread):
+ (JSC::MachineThreads::gatherConservativeRoots):
+ * runtime/MachineStackMarker.h:
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::append):
+
+2011-03-13 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX for armv7 after r80969
+
+ Bug 56270 - The JIT 'friend's many classes in JSC; start unwinding this.
+ <https://bugs.webkit.org/show_bug.cgi?id=56270>
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::load32): Made void* address argument
+ const.
+ (JSC::MacroAssemblerARMv7::store32): Ditto.
+
+2011-03-13 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix the Mac build.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Make sure to forward
+ ConervativeSet.h, since it's now visible when compiling other projects.
+
+2011-03-13 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed another case of DeprecatedPtr (ConservativeSet)
+ https://bugs.webkit.org/show_bug.cgi?id=56281
+
+ The ConservativeSet is an internal data structure used during marking,
+ so direct pointers are fine.
+
+ * runtime/ConservativeSet.cpp:
+ (JSC::ConservativeSet::grow):
+ * runtime/ConservativeSet.h: Added some accessors, for use by MarkStack::append.
+ (JSC::ConservativeSet::~ConservativeSet): Fixed a typo where we calculated
+ the size of the set based on sizeof(DeprecatedPtr<T>*) instead of
+ sizeof(DeprecatedPtr<T>). I'm not sure if this had real-world implications or not.
+ (JSC::ConservativeSet::size):
+ (JSC::ConservativeSet::set): Use direct pointers, as stated above.
+
+ * runtime/Heap.cpp:
+ (JSC::Heap::markRoots):
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::append): Created a special case of append for
+ ConservativeSet. I didn't want to add back a generic "append JSCell*"
+ function, since other class might start using that wrong. (In the end,
+ this function might go away, since the Heap will want to do something
+ slightly more interesting with the conservative set, but this is OK for
+ now.)
+
+2011-03-13 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed another case of DeprecatedPtr (PutPropertySlot)
+ https://bugs.webkit.org/show_bug.cgi?id=56278
+
+ * runtime/PutPropertySlot.h:
+ (JSC::PutPropertySlot::setExistingProperty):
+ (JSC::PutPropertySlot::setNewProperty):
+ (JSC::PutPropertySlot::base): Direct pointer is fine for PutPropertySlot,
+ since it's a stack-allocated temporary.
+
+2011-03-13 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed one case of DeprecatedPtr (ScopeChainIterator)
+ https://bugs.webkit.org/show_bug.cgi?id=56277
+
+ * runtime/ScopeChain.h: Direct pointer is fine for ScopeChainIterator,
+ since it's a stack-allocated temporary.
+
+2011-03-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 56273 - Add three operand forms to MacroAssember operations.
+
+ Adding for X86(_64) for now, should be rolled out to other backends as necessary.
+ These may allow more efficient code generation in some cases, avoiding the need
+ for unnecessary register-register move instructions.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Jump::link):
+ (JSC::AbstractMacroAssembler::Jump::linkTo):
+ - marked these methods const.
+ (JSC::AbstractMacroAssembler::Jump::isSet):
+ - add a method to check whether a Jump object has been set to
+ reference an instruction, or is in a null, unset state.
+ * assembler/MacroAssemblerCodeRef.h:
+ (JSC::FunctionPtr::FunctionPtr):
+ - add non-explicit constructor, for FunctionPtr's to C/C++ functions.
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::and32):
+ (JSC::MacroAssemblerX86Common::lshift32):
+ (JSC::MacroAssemblerX86Common::or32):
+ (JSC::MacroAssemblerX86Common::rshift32):
+ (JSC::MacroAssemblerX86Common::urshift32):
+ (JSC::MacroAssemblerX86Common::xor32):
+ (JSC::MacroAssemblerX86Common::moveDouble):
+ (JSC::MacroAssemblerX86Common::addDouble):
+ (JSC::MacroAssemblerX86Common::divDouble):
+ (JSC::MacroAssemblerX86Common::subDouble):
+ (JSC::MacroAssemblerX86Common::mulDouble):
+ (JSC::MacroAssemblerX86Common::branchTruncateDoubleToInt32):
+ (JSC::MacroAssemblerX86Common::branchTest32):
+ (JSC::MacroAssemblerX86Common::branchTest8):
+ (JSC::MacroAssemblerX86Common::branchAdd32):
+ (JSC::MacroAssemblerX86Common::branchMul32):
+ (JSC::MacroAssemblerX86Common::branchSub32):
+ - add three operand forms of these instructions.
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::addDouble):
+ (JSC::MacroAssemblerX86_64::convertInt32ToDouble):
+ (JSC::MacroAssemblerX86_64::loadPtr):
+ (JSC::MacroAssemblerX86_64::branchTestPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::JmpSrc::isSet):
+ - add a method to check whether a JmpSrc object has been set to
+ reference an instruction, or is in a null, unset state.
+ (JSC::X86Assembler::movsd_rr):
+ - added FP register-register move.
+ (JSC::X86Assembler::linkJump):
+ - Add an assert to check jumps aren't linked more than once.
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitLoadInt32ToDouble):
+ - load integers to the FPU via regsiters on x86-64.
+
+2011-03-13 Gavin Barraclough <barraclough@apple.com>
+
+ ARM build fix.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::load32):
+
+2011-03-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 56270 - The JIT 'friend's many classes in JSC; start unwinding this.
+
+ The JIT need to 'friend' other classes in order to be able to calculate offsets
+ of various properties, or the absolute addresses of members within specific objects,
+ in order to JIT generate code that will access members within the class when run.
+
+ Instead of using friends in these cases, switch to providing specific accessor
+ methods to provide this information. In the case of offsets, these can be static
+ functions, and in the case of pointers to members within a specific object these can
+ be const methods returning pointers to const values, to prevent clients from
+ modifying values otherwise encapsulated within classes.
+
+ * bytecode/SamplingTool.h:
+ * interpreter/Register.h:
+ * interpreter/RegisterFile.h:
+ * runtime/JSArray.h:
+ * runtime/JSCell.h:
+ * runtime/JSTypeInfo.h:
+ * runtime/JSVariableObject.h:
+ * runtime/Structure.h:
+ * wtf/RefCounted.h:
+ - Change these classes to no longer friend the JIT, add accessors for member offsets.
+ * jit/JIT.cpp:
+ * jit/JITCall32_64.cpp:
+ * jit/JITInlineMethods.h:
+ * jit/JITOpcodes.cpp:
+ * jit/JITOpcodes32_64.cpp:
+ * jit/JITPropertyAccess.cpp:
+ * jit/JITPropertyAccess32_64.cpp:
+ - Change the JIT to use class accessors, rather than taking object ofsets directly.
+ * assembler/AbstractMacroAssembler.h:
+ * assembler/MacroAssemblerX86_64.h:
+ * assembler/X86Assembler.h:
+ - Since the accessors for objects members return const pointers to retain encapsulation,
+ methods generating code with absolute addresses must be able to handle const pointers
+ (the JIT doesn't write to these values, do dies treat the pointer to value as const
+ from within the C++ code of the JIT, if not at runtime!).
+
+2011-03-12 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r80919.
+ http://trac.webkit.org/changeset/80919
+ https://bugs.webkit.org/show_bug.cgi?id=56251
+
+ all windows bots failed to compile this change (Requested by
+ loislo on #webkit).
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/StructureStubInfo.cpp:
+ * interpreter/Register.h:
+ (JSC::Register::withInt):
+ (JSC::Register::withCallee):
+ (JSC::Register::operator=):
+ (JSC::Register::i):
+ (JSC::Register::activation):
+ (JSC::Register::function):
+ (JSC::Register::propertyNameIterator):
+ (JSC::Register::scopeChain):
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutToCallFrameHeader):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::emit_op_load_varargs):
+ (JSC::JIT::emitSlow_op_load_varargs):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ * jit/JSInterfaceJIT.h:
+ (JSC::JSInterfaceJIT::payloadFor):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::returnJSValue):
+ (JSC::SpecializedThunkJIT::returnDouble):
+ (JSC::SpecializedThunkJIT::returnInt32):
+ (JSC::SpecializedThunkJIT::returnJSCell):
+ * runtime/ArgList.cpp:
+ * runtime/DateConversion.cpp:
+ * runtime/GCActivityCallbackCF.cpp:
+ * runtime/Identifier.cpp:
+ * runtime/JSActivation.h:
+ (JSC::asActivation):
+ * runtime/JSLock.cpp:
+ * runtime/JSNumberCell.cpp:
+ * runtime/JSObject.h:
+ * runtime/JSPropertyNameIterator.h:
+ * runtime/JSValue.h:
+ * runtime/JSZombie.cpp:
+ * runtime/MarkedBlock.cpp:
+ * runtime/MarkedSpace.cpp:
+ * runtime/PropertyNameArray.cpp:
+ * runtime/ScopeChain.h:
+ (JSC::ExecState::globalThisValue):
+ * wtf/DateMath.cpp:
+
+2011-03-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Ensure all values are correctly tagged in the registerfile
+ https://bugs.webkit.org/show_bug.cgi?id=56214
+
+ This patch makes sure that all JSCell pointers written to
+ the registerfile are correctly tagged as JSCells, and replaces
+ raw int usage with the immediate representation.
+
+ For performance, register pressure, and general saneness reasons
+ I've added abstractions for reading and writing the tag
+ and payload of integer registers directly for the JSVALUE64
+ encoding.
+
+ * interpreter/Register.h:
+ (JSC::Register::withInt):
+ (JSC::Register::withCallee):
+ (JSC::Register::operator=):
+ (JSC::Register::i):
+ (JSC::Register::activation):
+ (JSC::Register::function):
+ (JSC::Register::propertyNameIterator):
+ (JSC::Register::scopeChain):
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallVarargs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutToCallFrameHeader):
+ (JSC::JIT::emitPutCellToCallFrameHeader):
+ (JSC::JIT::emitPutIntToCallFrameHeader):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::emit_op_load_varargs):
+ (JSC::JIT::emitSlow_op_load_varargs):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ * jit/JSInterfaceJIT.h:
+ (JSC::JSInterfaceJIT::intPayloadFor):
+ (JSC::JSInterfaceJIT::intTagFor):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::returnJSValue):
+ (JSC::SpecializedThunkJIT::returnDouble):
+ (JSC::SpecializedThunkJIT::returnInt32):
+ (JSC::SpecializedThunkJIT::returnJSCell):
+
+2011-03-11 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Introduce project_dir variable and make paths a whole lot saner. Ok, a little bit saner.
+ https://bugs.webkit.org/show_bug.cgi?id=56231
+
+ * JavaScriptCore.gypi: Added project_dir variable.
+ * gyp/JavaScriptCore.gyp: Changed to use project_dir, rather than DEPTH/JavaScriptCore.
+ * gyp/generate-dtrace-header.sh: Changed to use project_dir.
+
+2011-03-11 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Start using derived sources correctly and link minidom with JavaScriptCore gyp project.
+ https://bugs.webkit.org/show_bug.cgi?id=56217
+
+ * gyp/JavaScriptCore.gyp: Added derived source files and passing of shared directory
+ to the scripts.
+ * gyp/generate-derived-sources.sh: Changed to use passed directory.
+ * gyp/generate-dtrace-header.sh: Ditto.
+
+2011-03-11 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ <rdar://problem/8955589> Adopt AVFoundation media back end on Lion.
+
+ No new tests, existing media tests cover this.
+
+ * JavaScriptCore.exp: Export cancelCallOnMainThread
+ * wtf/Platform.h: Define WTF_USE_AVFOUNDATION.
+
+2011-03-11 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Tweak dylib paths and add dtrace header generation action to JavaScriptCore gyp project.
+ https://bugs.webkit.org/show_bug.cgi?id=56207
+
+ * JavaScriptCore.gypi: Added Tracing.d to the sources.
+ * gyp/generate-dtrace-header.sh: Added.
+ * gyp/JavaScriptCore.gyp: Updated dylib paths (now the project can see them),
+ and added DTrace header generating step.
+
+2011-03-10 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix allocation of native function with a cached thunk
+ https://bugs.webkit.org/show_bug.cgi?id=56127
+
+ Fix this race condition found while fixing zombies.
+
+ * collector/handles/HandleHeap.cpp:
+ (JSC::HandleHeap::clearWeakPointers):
+ * runtime/Heap.cpp:
+ (JSC::Heap::reset):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::markChildren):
+ * runtime/JSValue.h:
+ (JSC::JSValue::decode):
+ * runtime/JSZombie.cpp:
+ (JSC::JSZombie::leakedZombieStructure):
+ * runtime/JSZombie.h:
+ (JSC::JSZombie::createStructure):
+ * runtime/MarkedBlock.cpp:
+
+2011-03-10 Luiz Agostini <luiz.agostini@openbossa.org>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] fast/workers/stress-js-execution.html is crashing on Qt bot (intermittently)
+ https://bugs.webkit.org/show_bug.cgi?id=33008
+
+ Defining WTF_USE_PTHREAD_BASED_QT=1 for platforms where QThread uses pthread internally.
+ Symbian is excluded because pthread_kill does not work on it. Mac is excluded because
+ it has its own ways to do JSC threading.
+
+ Defining WTF_USE_PTHREADS inside MachineStackMarker.cpp if USE(PTHREAD_BASED_QT) is true.
+
+ * runtime/MachineStackMarker.cpp:
+ * wtf/Platform.h:
+
+2011-03-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 56077 - ES5 conformance issues with RegExp.prototype
+
+ There are three issues causing test failures in sputnik.
+
+ (1) lastIndex should be converted at the point it is used, not the point it is set (this is visible if valueOf is overridden).
+ (2) The 'length' property of the test/exec functions should be 1.
+ (3) If no input is specified, the input to test()/exec() is "undefined" (i.e. ToString(undefined)) - not RegExp.input.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::markChildren):
+ - Added to mark lastIndex
+ (JSC::regExpObjectLastIndex):
+ (JSC::setRegExpObjectLastIndex):
+ - lastIndex is now stored as a JSValue.
+ (JSC::RegExpObject::match):
+ - Use accessor methods to get/set lastIndex, add fast case for isUInt32 (don't convert to double).
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::setLastIndex):
+ (JSC::RegExpObject::setLastIndex):
+ - Set lastIndex, either from a size_t or a JSValue.
+ (JSC::RegExpObject::getLastIndex):
+ - Get lastIndex.
+ (JSC::RegExpObject::RegExpObjectData::RegExpObjectData):
+ - Initialize as a JSValue.
+ * runtime/RegExpPrototype.cpp:
+ (JSC::RegExpPrototype::RegExpPrototype):
+ - Add test/exec properties with length 1.
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ - Do not read RegExp.input if none is provided.
+ * tests/mozilla/js1_2/regexp/RegExp_input.js:
+ * tests/mozilla/js1_2/regexp/RegExp_input_as_array.js:
+ - Update these tests (they relied on non-ES5 behaviour).
+
+2011-03-10 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Rolled back in 80277 and 80280 with event handler layout test failures fixed.
+ https://bugs.webkit.org/show_bug.cgi?id=55653
+
+ The failures were caused by a last minute typo: assigning to currentEvent
+ instead of m_currentEvent.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecompiler/BytecodeGenerator.cpp:
+ * jit/JITOpcodes.cpp:
+ * jit/JITOpcodes32_64.cpp:
+ * runtime/Arguments.h:
+ * runtime/JSActivation.cpp:
+ * runtime/JSActivation.h:
+ * runtime/JSCell.h:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObject.h:
+ * runtime/JSObject.cpp:
+ * runtime/JSStaticScopeObject.cpp:
+ * runtime/JSStaticScopeObject.h:
+ * runtime/JSVariableObject.h:
+ * runtime/MarkedSpace.cpp:
+ * runtime/MarkedSpace.h:
+
+2011-03-09 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ jquery/manipulation.html fails after r80598
+ https://bugs.webkit.org/show_bug.cgi?id=56019
+
+ When linking a call, codeblock now takes ownership of the linked function
+ This removes the need for unlinking, and thus the incorrectness that was
+ showing up in these tests.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::markAggregate):
+ * bytecode/CodeBlock.h:
+ (JSC::CallLinkInfo::CallLinkInfo):
+ (JSC::CallLinkInfo::setUnlinked):
+ (JSC::CodeBlock::addCaller):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::linkCall):
+ (JSC::JIT::linkConstruct):
+ * jit/JIT.h:
+ * runtime/Executable.cpp:
+ * runtime/Executable.h:
+
+2011-03-09 Daniel Bates <dbates@rim.com>
+
+ Attempt to fix the WinCE build after changeset 80684 <http://trac.webkit.org/changeset/80684>
+ (Bug #56041<https://bugs.webkit.org/show_bug.cgi?id=56041>).
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute): Substitute variable callFrame for exec in call to createSyntaxError().
+
+2011-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 56041 - RexExp constructor should only accept flags "gim"
+ Fix for issues introduced in r80667.
+
+ Invalid flags to a RegExp literal are a late syntax error!
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addRegExp):
+ - Pass a PassRefPtr<RegExp>
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::addRegExp):
+ (JSC::BytecodeGenerator::emitNewRegExp):
+ * bytecompiler/BytecodeGenerator.h:
+ - Pass a PassRefPtr<RegExp>
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ - Should not be ASSERTing that the flags are valid - this is a late(er) error.
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ - Need to check for error from RegExp constructor.
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ - Need to check for error from RegExp constructor.
+ * runtime/RegExp.h:
+ (JSC::RegExp::isValid):
+ - Make isValid check that the regexp was created with valid flags.
+ * runtime/RegExpKey.h:
+ - Since we'll not create RegExp objects with invalid flags, separate out the deleted value.
+
+2011-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix part 2.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2011-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix part 1.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2011-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 56041 - RexExp constructor should only accept flags "gim"
+ We also should be passing the flags around as a bitfield rather than a string,
+ and should not have redundant, incompatible code for converting the string to a bitfield!
+
+ * JavaScriptCore.exp:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ - Need to parse flags string to enum.
+ * runtime/RegExp.cpp:
+ (JSC::regExpFlags):
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::create):
+ - Add method to parse flags string to enum, change constructor/create args to take enum.
+ * runtime/RegExp.h:
+ (JSC::RegExp::global):
+ (JSC::RegExp::ignoreCase):
+ (JSC::RegExp::multiline):
+ - Change to use new enum values.
+ * runtime/RegExpCache.cpp:
+ (JSC::RegExpCache::lookupOrCreate):
+ (JSC::RegExpCache::create):
+ * runtime/RegExpCache.h:
+ - Changed to use regExpFlags enum instead of int/const UString&.
+ * runtime/RegExpConstructor.cpp:
+ (JSC::constructRegExp):
+ - Add use new enum parsing, check for error.
+ * runtime/RegExpKey.h:
+ (JSC::RegExpKey::RegExpKey):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::RegExpPrototype::RegExpPrototype):
+ - Pass NoFlags value instead of empty string.
+ (JSC::regExpProtoFuncCompile):
+ - Add use new enum parsing, check for error.
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ - Pass NoFlags value instead of empty string.
+
+2011-03-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig
+
+ Bug 55994 - Functions on Array.prototype should check length first.
+ These methods are designed to work on generic objects too, and if 'length'
+ is a getter that throws an exception, ensure this is correctly thrown
+ (even if other exceptions would be thrown, too).
+
+ Make the length check the first thing we do.
+ This change shows a progression on SunSpider on my machine, but this is likely bogus.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ (JSC::arrayProtoFuncPop):
+ (JSC::arrayProtoFuncPush):
+ (JSC::arrayProtoFuncReverse):
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSlice):
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ (JSC::arrayProtoFuncEvery):
+ (JSC::arrayProtoFuncForEach):
+ (JSC::arrayProtoFuncSome):
+ (JSC::arrayProtoFuncReduce):
+ (JSC::arrayProtoFuncReduceRight):
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+
+2011-03-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Make CodeBlock GC write barrier safe
+ https://bugs.webkit.org/show_bug.cgi?id=55910
+
+ In order to make CodeBlock WriteBarrier safe it was necessary
+ to make it have a single GC owner, and for that reason I have
+ made ExecutableBase a GC allocated object. This required
+ updating their creation routines as well as all sites that hold
+ a reference to them. GC objects that held Executable's have been
+ converted to WriteBarriers, and all other sites now use Global<>.
+
+ As an added benefit this gets rid of JSGlobalData's list of
+ GlobalCodeBlocks.
+
+ Perf testing shows a 0.5% progression on v8, vs. a 0.3% regression
+ on SunSpider. Given none of the tests that show regressions
+ demonstrate a regression on their own, and sampling shows up nothing.
+ I suspect we're just getting one or two additional gc passes at
+ the end of the run.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::EvalCodeCache::markAggregate):
+ (JSC::CodeBlock::markAggregate):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::ownerExecutable):
+ (JSC::CodeBlock::addConstant):
+ (JSC::CodeBlock::constantRegister):
+ (JSC::CodeBlock::getConstant):
+ (JSC::CodeBlock::addFunctionDecl):
+ (JSC::CodeBlock::addFunctionExpr):
+ (JSC::GlobalCodeBlock::GlobalCodeBlock):
+ (JSC::ExecState::r):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::get):
+ * bytecode/SamplingTool.h:
+ (JSC::ScriptSampleRecord::ScriptSampleRecord):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::addConstantValue):
+ (JSC::BytecodeGenerator::emitEqualityOp):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::makeFunction):
+ * debugger/Debugger.cpp:
+ (JSC::evaluateInGlobalCallFrame):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::callEval):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitLoadDouble):
+ (JSC::JIT::emitLoadInt32ToDouble):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks):
+ (JSC::JITThunks::hostFunctionStub):
+ (JSC::JITThunks::clearHostFunctionStubs):
+ * jit/JITStubs.h:
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::EvalExecutable):
+ (JSC::ProgramExecutable::ProgramExecutable):
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::FunctionExecutable::~FunctionExecutable):
+ (JSC::EvalExecutable::markChildren):
+ (JSC::ProgramExecutable::markChildren):
+ (JSC::FunctionExecutable::markChildren):
+ (JSC::FunctionExecutable::fromGlobalCode):
+ * runtime/Executable.h:
+ (JSC::ExecutableBase::ExecutableBase):
+ (JSC::ExecutableBase::createStructure):
+ (JSC::NativeExecutable::create):
+ (JSC::NativeExecutable::NativeExecutable):
+ (JSC::VPtrHackExecutable::VPtrHackExecutable):
+ (JSC::ScriptExecutable::ScriptExecutable):
+ (JSC::EvalExecutable::create):
+ (JSC::EvalExecutable::createStructure):
+ (JSC::ProgramExecutable::create):
+ (JSC::ProgramExecutable::createStructure):
+ (JSC::FunctionExecutable::create):
+ (JSC::FunctionExecutable::createStructure):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/Heap.cpp:
+ (JSC::Heap::destroy):
+ (JSC::Heap::markRoots):
+ * runtime/Heap.h:
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::JSActivation):
+ (JSC::JSActivation::markChildren):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::JSActivationData::JSActivationData):
+ * runtime/JSCell.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::~JSFunction):
+ (JSC::JSFunction::markChildren):
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::storeVPtrs):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::getHostFunction):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+ * runtime/JSObject.cpp:
+ * runtime/JSStaticScopeObject.cpp:
+ (JSC::JSStaticScopeObject::markChildren):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::JSStaticScopeObjectData::JSStaticScopeObjectData):
+ (JSC::JSStaticScopeObject::JSStaticScopeObject):
+ * runtime/JSZombie.cpp:
+ (JSC::JSZombie::leakedZombieStructure):
+ * runtime/JSZombie.h:
+ (JSC::JSZombie::createStructure):
+ * runtime/MarkedSpace.h:
+
+2011-03-07 Andy Estes <aestes@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ REGRESSION (r79060): Timestamp is missing from tweets in twitter.
+ https://bugs.webkit.org/show_bug.cgi?id=55228
+
+ A change to the date parser to handle the case where the year is
+ specified before the time zone inadvertently started accepting strings
+ such as '+0000' as valid years. Those strings actually represent time
+ zones in an offset of hours and minutes from UTC, not years.
+
+ * wtf/DateMath.cpp:
+ (WTF::parseDateFromNullTerminatedCharacters): If the current character
+ in dateString is '+' or '-', do not try to parse the next token as a
+ year.
+
2011-03-06 Yuta Kitamura <yutak@chromium.org>
Reviewed by Kent Tamura.
diff --git a/Source/JavaScriptCore/Configurations/Base.xcconfig b/Source/JavaScriptCore/Configurations/Base.xcconfig
index 8d91d70..12d0efd 100644
--- a/Source/JavaScriptCore/Configurations/Base.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Base.xcconfig
@@ -25,7 +25,6 @@ DEBUG_INFORMATION_FORMAT = dwarf;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DEBUGGING_SYMBOLS = default;
GCC_DYNAMIC_NO_PIC = NO;
-GCC_ENABLE_CPP_EXCEPTIONS = NO;
GCC_ENABLE_CPP_RTTI = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_ENABLE_OBJC_GC = $(GCC_ENABLE_OBJC_GC_$(REAL_PLATFORM_NAME));
@@ -118,12 +117,23 @@ TARGET_GCC_VERSION_macosx_1050_ = $(TARGET_GCC_VERSION_macosx_1050_$(XCODE_VERSI
TARGET_GCC_VERSION_macosx_1050_0310 = GCC_42;
TARGET_GCC_VERSION_macosx_1050_0320 = GCC_42;
TARGET_GCC_VERSION_macosx_1060 = GCC_42;
-TARGET_GCC_VERSION_macosx_1070 = LLVM_GCC_42;
+TARGET_GCC_VERSION_macosx_1070 = $(TARGET_GCC_VERSION_macosx_1070_$(CONFIGURATION));
+TARGET_GCC_VERSION_macosx_1070_Debug = LLVM_COMPILER;
+TARGET_GCC_VERSION_macosx_1070_Release = LLVM_GCC_42;
+TARGET_GCC_VERSION_macosx_1070_Production = LLVM_GCC_42;
GCC_VERSION = $(GCC_VERSION_$(TARGET_GCC_VERSION));
GCC_VERSION_GCC_40 = 4.0;
GCC_VERSION_GCC_42 = 4.2;
GCC_VERSION_LLVM_GCC_42 = com.apple.compilers.llvmgcc42;
+GCC_VERSION_LLVM_COMPILER = com.apple.compilers.llvm.clang.1_0;
+
+// FIXME: Disable C++ exceptions in the LLVM Compiler once it supports enabling Obj-C exceptions without C++ exceptions.
+GCC_ENABLE_CPP_EXCEPTIONS = $(GCC_ENABLE_CPP_EXCEPTIONS_$(TARGET_GCC_VERSION));
+GCC_ENABLE_CPP_EXCEPTIONS_GCC_40 = NO;
+GCC_ENABLE_CPP_EXCEPTIONS_GCC_42 = NO;
+GCC_ENABLE_CPP_EXCEPTIONS_LLVM_GCC = NO;
+GCC_ENABLE_CPP_EXCEPTIONS_LLVM_COMPILER = YES;
// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK.
SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index ae9167c..59988e3 100644
--- a/Source/JavaScriptCore/Configurations/Version.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 534;
-MINOR_VERSION = 24;
+MINOR_VERSION = 27;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make
index 8abb17c..9a8c2cc 100644
--- a/Source/JavaScriptCore/DerivedSources.make
+++ b/Source/JavaScriptCore/DerivedSources.make
@@ -84,7 +84,6 @@ HeaderDetection.h : DerivedSources.make /System/Library/CoreServices/SystemVersi
rm -f $@
echo "/* This is a generated file. Do not edit. */" > $@
if [ -f $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders/pthread_machdep.h ]; then echo "#define HAVE_PTHREAD_MACHDEP_H 1" >> $@; else echo >> $@; fi
- if [ -f $(SDKROOT)/System/Library/Frameworks/AppKit.framework/PrivateHeaders/NSScrollerImpPair_Private.h ]; then echo "#define USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER 1" >> $@; else echo >> $@; fi
else
diff --git a/Source/JavaScriptCore/GNUmakefile.am b/Source/JavaScriptCore/GNUmakefile.am
index 977cb18..31e70a0 100644
--- a/Source/JavaScriptCore/GNUmakefile.am
+++ b/Source/JavaScriptCore/GNUmakefile.am
@@ -115,6 +115,10 @@ javascriptcore_sources += \
Source/JavaScriptCore/collector/handles/Handle.h \
Source/JavaScriptCore/collector/handles/HandleHeap.cpp \
Source/JavaScriptCore/collector/handles/HandleHeap.h \
+ Source/JavaScriptCore/collector/handles/HandleStack.cpp \
+ Source/JavaScriptCore/collector/handles/HandleStack.h \
+ Source/JavaScriptCore/collector/handles/Local.h \
+ Source/JavaScriptCore/collector/handles/LocalScope.h \
Source/JavaScriptCore/config.h \
Source/JavaScriptCore/debugger/DebuggerActivation.cpp \
Source/JavaScriptCore/debugger/DebuggerActivation.h \
@@ -468,6 +472,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/wtf/HashTable.cpp \
Source/JavaScriptCore/wtf/HashTable.h \
Source/JavaScriptCore/wtf/HashTraits.h \
+ Source/JavaScriptCore/wtf/HexNumber.h \
Source/JavaScriptCore/wtf/ListHashSet.h \
Source/JavaScriptCore/wtf/ListRefPtr.h \
Source/JavaScriptCore/wtf/Locker.h \
@@ -549,7 +554,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/wtf/Threading.h \
Source/JavaScriptCore/wtf/ThreadingPrimitives.h \
Source/JavaScriptCore/wtf/ThreadingPthreads.cpp \
- Source/JavaScriptCore/wtf/ThreadSafeShared.h \
+ Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h \
Source/JavaScriptCore/wtf/ThreadSpecific.h \
Source/JavaScriptCore/wtf/TypeTraits.cpp \
Source/JavaScriptCore/wtf/TypeTraits.h \
diff --git a/Source/JavaScriptCore/JavaScriptCore.exp b/Source/JavaScriptCore/JavaScriptCore.exp
index 914c2ac..e2647d1 100644
--- a/Source/JavaScriptCore/JavaScriptCore.exp
+++ b/Source/JavaScriptCore/JavaScriptCore.exp
@@ -1,4 +1,3 @@
-__ZN3JSC22objectConstructorTableE
_JSCheckScriptSyntax
_JSClassCreate
_JSClassRelease
@@ -114,15 +113,15 @@ __ZN3JSC10JSFunction6s_infoE
__ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE
__ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE
__ZN3JSC11JSByteArray13s_defaultInfoE
-__ZN3JSC11JSByteArray15createStructureENS_7JSValueEPKNS_9ClassInfoE
+__ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataENS_7JSValueEPKNS_9ClassInfoE
__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayE
__ZN3JSC11MarkedSpace21allocateFromSizeClassERNS0_9SizeClassE
__ZN3JSC11ParserArena5resetEv
__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
__ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC11regExpFlagsERKNS_7UStringE
__ZN3JSC12DateInstance6s_infoE
__ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
-__ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
__ZN3JSC12JSGlobalData10ClientDataD2Ev
__ZN3JSC12JSGlobalData11jsArrayVPtrE
__ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeE
@@ -159,11 +158,11 @@ __ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSO
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
__ZN3JSC14JSGlobalObject12markChildrenERNS_9MarkStackE
__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
-__ZN3JSC14JSGlobalObject25destroyJSGlobalObjectDataEPv
__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
__ZN3JSC14JSGlobalObjectD2Ev
__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
+__ZN3JSC14MachineThreads16addCurrentThreadEv
__ZN3JSC14SamplingThread4stopEv
__ZN3JSC14SamplingThread5startEj
__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
@@ -182,10 +181,9 @@ __ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE
__ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
-__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3JSC17constructFunctionEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
__ZN3JSC17createSyntaxErrorEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC18DebuggerActivationC1ERNS_12JSGlobalDataEPNS_8JSObjectE
-__ZN3JSC18MachineStackMarker14registerThreadEv
__ZN3JSC18PropertyDescriptor11setWritableEb
__ZN3JSC18PropertyDescriptor12setUndefinedEv
__ZN3JSC18PropertyDescriptor13setDescriptorENS_7JSValueEj
@@ -201,13 +199,13 @@ __ZN3JSC19initializeThreadingEv
__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC22globalMemoryStatisticsEv
+__ZN3JSC22objectConstructorTableE
__ZN3JSC23AbstractSamplingCounter4dumpEv
__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC24DynamicGlobalObjectScopeC1EPNS_9ExecStateEPNS_14JSGlobalObjectE
+__ZN3JSC24DynamicGlobalObjectScopeC1ERNS_12JSGlobalDataEPNS_14JSGlobalObjectE
__ZN3JSC24JSObjectWithGlobalObjectC2EPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEE
__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
-__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
__ZN3JSC3NaNE
@@ -248,7 +246,7 @@ __ZN3JSC6JSLock4lockENS_14JSLockBehaviorE
__ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
__ZN3JSC6JSLock9lockCountEv
__ZN3JSC6JSLockC1EPNS_9ExecStateE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE
__ZN3JSC6RegExpD1Ev
__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
__ZN3JSC7JSArray15setSubclassDataEPv
@@ -287,7 +285,6 @@ __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
__ZN3JSC8JSObject15unwrappedObjectEv
__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3JSC8JSObject17createInheritorIDEv
__ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb
__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_10JSFunctionEj
__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
@@ -387,6 +384,7 @@ __ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
+__ZN3WTF13StringBuilder15reserveCapacityEj
__ZN3WTF13StringBuilder11reifyStringEv
__ZN3WTF13StringBuilder11shrinkToFitEv
__ZN3WTF13StringBuilder6appendEPKcj
@@ -431,6 +429,7 @@ __ZN3WTF21RefCountedLeakCounter9incrementEv
__ZN3WTF21RefCountedLeakCounterC1EPKc
__ZN3WTF21RefCountedLeakCounterD1Ev
__ZN3WTF21charactersToIntStrictEPKtmPbi
+__ZN3WTF22cancelCallOnMainThreadEPFvPvES0_
__ZN3WTF22charactersToUIntStrictEPKtmPbi
__ZN3WTF23callOnMainThreadAndWaitEPFvPvES0_
__ZN3WTF23dayInMonthFromDayInYearEib
@@ -446,10 +445,10 @@ __ZN3WTF39initializeMainThreadToProcessMainThreadEv
__ZN3WTF3MD58addBytesEPKhm
__ZN3WTF3MD58checksumERNS_6VectorIhLm16EEE
__ZN3WTF3MD5C1Ev
-__ZN3WTF4dtoaEPcdRbRiRj
__ZN3WTF4SHA111computeHashERNS_6VectorIhLm20EEE
__ZN3WTF4SHA18addBytesEPKhm
__ZN3WTF4SHA1C1Ev
+__ZN3WTF4dtoaEPcdRbRiRj
__ZN3WTF5Mutex4lockEv
__ZN3WTF5Mutex6unlockEv
__ZN3WTF5Mutex7tryLockEv
@@ -535,7 +534,7 @@ __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
__ZNK3JSC6JSCell14isGetterSetterEv
__ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE
-__ZNK3JSC6JSCell8toObjectEPNS_9ExecStateE
+__ZNK3JSC6JSCell8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE
__ZNK3JSC6JSCell8toStringEPNS_9ExecStateE
__ZNK3JSC6JSCell9getStringEPNS_9ExecStateE
__ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
@@ -543,7 +542,7 @@ __ZNK3JSC6JSCell9getUInt32ERj
__ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
__ZNK3JSC7ArgList8getSliceEiRS0_
__ZNK3JSC7JSArray12subclassDataEv
-__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
+__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateEPNS_14JSGlobalObjectE
__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
@@ -556,7 +555,7 @@ __ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject18toStrictThisObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
-__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
+__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE
__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
__ZNK3JSC8JSObject9classNameEv
__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
diff --git a/Source/JavaScriptCore/JavaScriptCore.gypi b/Source/JavaScriptCore/JavaScriptCore.gypi
index 292473c..cb93a29 100644
--- a/Source/JavaScriptCore/JavaScriptCore.gypi
+++ b/Source/JavaScriptCore/JavaScriptCore.gypi
@@ -1,5 +1,6 @@
{
'variables': {
+ 'project_dir': ['.'],
# These headers are part of JavaScriptCore's public API in the Apple Mac build.
'javascriptcore_publicheader_files': [
'API/JSBase.h',
@@ -29,6 +30,9 @@
'collector/handles/Global.h',
'collector/handles/Handle.h',
'collector/handles/HandleHeap.h',
+ 'collector/handles/HandleStack.h',
+ 'collector/handles/Local.h',
+ 'collector/handles/LocalScope.h',
'config.h',
'debugger/Debugger.h',
'debugger/DebuggerActivation.h',
@@ -64,6 +68,7 @@
'runtime/ExceptionHelpers.h',
'runtime/FunctionConstructor.h',
'runtime/FunctionPrototype.h',
+ 'runtime/GCActivityCallback.h',
'runtime/Heap.h',
'runtime/Identifier.h',
'runtime/InitializeThreading.h',
@@ -105,7 +110,9 @@
'runtime/Protect.h',
'runtime/PutPropertySlot.h',
'runtime/RegExp.h',
+ 'runtime/RegExpKey.h',
'runtime/RegExpCache.h',
+ 'runtime/RegExpObject.h',
'runtime/RopeImpl.h',
'runtime/ScopeChain.h',
'runtime/SmallStrings.h',
@@ -157,6 +164,7 @@
'wtf/HashSet.h',
'wtf/HashTable.h',
'wtf/HashTraits.h',
+ 'wtf/HexNumber.h',
'wtf/ListHashSet.h',
'wtf/ListRefPtr.h',
'wtf/Locker.h',
@@ -195,7 +203,7 @@
'wtf/StdLibExtras.h',
'wtf/StringExtras.h',
'wtf/StringHasher.h',
- 'wtf/ThreadSafeShared.h',
+ 'wtf/ThreadSafeRefCounted.h',
'wtf/ThreadSpecific.h',
'wtf/Threading.h',
'wtf/ThreadingPrimitives.h',
@@ -303,9 +311,29 @@
'bytecompiler/NodesCodegen.cpp',
'bytecompiler/RegisterID.h',
'collector/handles/HandleHeap.cpp',
+ 'collector/handles/HandleStack.cpp',
'debugger/Debugger.cpp',
'debugger/DebuggerActivation.cpp',
'debugger/DebuggerCallFrame.cpp',
+ 'dfg/DFGAliasTracker.h',
+ 'dfg/DFGByteCodeParser.cpp',
+ 'dfg/DFGByteCodeParser.h',
+ 'dfg/DFGGenerationInfo.h',
+ 'dfg/DFGGraph.cpp',
+ 'dfg/DFGGraph.h',
+ 'dfg/DFGJITCodeGenerator.cpp',
+ 'dfg/DFGJITCodeGenerator.h',
+ 'dfg/DFGJITCompiler.cpp',
+ 'dfg/DFGJITCompiler.h',
+ 'dfg/DFGNode.h',
+ 'dfg/DFGNonSpeculativeJIT.cpp',
+ 'dfg/DFGNonSpeculativeJIT.h',
+ 'dfg/DFGOperations.cpp',
+ 'dfg/DFGOperations.h',
+ 'dfg/DFGRegisterBank.h',
+ 'dfg/DFGScoreBoard.h',
+ 'dfg/DFGSpeculativeJIT.cpp',
+ 'dfg/DFGSpeculativeJIT.h',
'icu/unicode/parseerr.h',
'icu/unicode/platform.h',
'icu/unicode/putil.h',
@@ -351,6 +379,10 @@
'jit/JSInterfaceJIT.h',
'jit/SpecializedThunkJIT.h',
'jit/ThunkGenerators.cpp',
+ 'os-win32/WinMain.cpp',
+ 'os-win32/inttypes.h',
+ 'os-win32/stdbool.h',
+ 'os-win32/stdint.h',
'parser/ASTBuilder.h',
'parser/JSParser.cpp',
'parser/JSParser.h',
@@ -447,7 +479,6 @@
'runtime/FunctionConstructor.cpp',
'runtime/FunctionPrototype.cpp',
'runtime/GCActivityCallback.cpp',
- 'runtime/GCActivityCallback.h',
'runtime/GCActivityCallbackCF.cpp',
'runtime/GetterSetter.cpp',
'runtime/GetterSetter.h',
@@ -517,10 +548,8 @@
'runtime/RegExpCache.cpp',
'runtime/RegExpConstructor.cpp',
'runtime/RegExpConstructor.h',
- 'runtime/RegExpKey.h',
'runtime/RegExpMatchesArray.h',
'runtime/RegExpObject.cpp',
- 'runtime/RegExpObject.h',
'runtime/RegExpPrototype.cpp',
'runtime/RegExpPrototype.h',
'runtime/RopeImpl.cpp',
@@ -538,6 +567,7 @@
'runtime/Structure.cpp',
'runtime/StructureChain.cpp',
'runtime/TimeoutChecker.cpp',
+ 'runtime/Tracing.d',
'runtime/Tracing.h',
'runtime/UString.cpp',
'runtime/UStringConcatenate.h',
@@ -564,9 +594,9 @@
'wtf/RandomNumber.cpp',
'wtf/RandomNumberSeed.h',
'wtf/RefCountedLeakCounter.cpp',
- 'wtf/SegmentedVector.h',
'wtf/SHA1.cpp',
'wtf/SHA1.h',
+ 'wtf/SegmentedVector.h',
'wtf/SizeLimits.cpp',
'wtf/StackBounds.cpp',
'wtf/StringExtras.cpp',
@@ -656,13 +686,20 @@
'yarr/YarrSyntaxChecker.cpp',
'yarr/YarrSyntaxChecker.h',
],
- # These files are separate from javascriptcore_files so we can use a
- # header map in the Apple Mac Xcode build.
- 'os_win32_files': [
- 'os-win32/WinMain.cpp',
- 'os-win32/inttypes.h',
- 'os-win32/stdbool.h',
- 'os-win32/stdint.h',
+ 'javascriptcore_derived_source_files': [
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/ArrayPrototype.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/DatePrototype.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/HeaderDetection.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/JSONObject.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/Lexer.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/MathObject.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/NumberConstructor.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/RegExpConstructor.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/RegExpJitTables.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/RegExpObject.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/StringPrototype.lut.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/TracingDtrace.h',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/ObjectConstructor.lut.h',
],
'minidom_files': [
'API/tests/JSNode.c',
diff --git a/Source/JavaScriptCore/JavaScriptCore.pri b/Source/JavaScriptCore/JavaScriptCore.pri
index 391c74f..941a708 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pri
+++ b/Source/JavaScriptCore/JavaScriptCore.pri
@@ -26,6 +26,7 @@ JAVASCRIPTCORE_INCLUDEPATH = \
$$PWD/bytecode \
$$PWD/bytecompiler \
$$PWD/collector/handles \
+ $$PWD/dfg \
$$PWD/debugger \
$$PWD/interpreter \
$$PWD/jit \
diff --git a/Source/JavaScriptCore/JavaScriptCore.pro b/Source/JavaScriptCore/JavaScriptCore.pro
index e41f04d..80ad3e8 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pro
+++ b/Source/JavaScriptCore/JavaScriptCore.pro
@@ -69,10 +69,18 @@ SOURCES += \
bytecode/StructureStubInfo.cpp \
bytecompiler/BytecodeGenerator.cpp \
bytecompiler/NodesCodegen.cpp \
+ collector/handles/HandleHeap.cpp \
+ collector/handles/HandleStack.cpp \
debugger/DebuggerActivation.cpp \
debugger/DebuggerCallFrame.cpp \
debugger/Debugger.cpp \
- collector/handles/HandleHeap.cpp \
+ dfg/DFGByteCodeParser.cpp \
+ dfg/DFGGraph.cpp \
+ dfg/DFGJITCodeGenerator.cpp \
+ dfg/DFGJITCompiler.cpp \
+ dfg/DFGNonSpeculativeJIT.cpp \
+ dfg/DFGOperations.cpp \
+ dfg/DFGSpeculativeJIT.cpp \
interpreter/CallFrame.cpp \
interpreter/Interpreter.cpp \
interpreter/RegisterFile.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
index 68075f9..b5461e4 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
@@ -5,7 +5,6 @@ BUILDSTYLE=Release_PGO
!ENDIF
install:
- set PRODUCTION=1
set WebKitLibrariesDir=$(SRCROOT)\AppleInternal
set WebKitOutputDir=$(OBJROOT)
set ConfigurationBuildDir=$(OBJROOT)\$(BUILDSTYLE)
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
index a4832ed..0b610e2 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
@@ -22,7 +22,7 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_All|Win32 = Debug_All|Win32
Debug|Win32 = Debug|Win32
- Release_LTCG|Win32 = Release_LTCG|Win32
+ Production|Win32 = Production|Win32
Release_PGO_Optimize|Win32 = Release_PGO_Optimize|Win32
Release_PGO|Win32 = Release_PGO|Win32
Release|Win32 = Release|Win32
@@ -32,8 +32,8 @@ Global
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.Build.0 = Debug_All|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.ActiveCfg = Debug|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.Build.0 = Debug|Win32
- {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Production|Win32.ActiveCfg = Production|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Production|Win32.Build.0 = Production|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO_Optimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO_Optimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -44,8 +44,8 @@ Global
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.Build.0 = Debug_All|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.ActiveCfg = Debug|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.Build.0 = Debug|Win32
- {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Production|Win32.ActiveCfg = Production|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Production|Win32.Build.0 = Production|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -56,8 +56,8 @@ Global
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.Build.0 = Debug_All|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.Build.0 = Debug|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.Build.0 = Production|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -68,8 +68,8 @@ Global
{DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_All|Win32.Build.0 = Debug_All|Win32
{DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.ActiveCfg = Debug|Win32
{DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.Build.0 = Debug|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {DA31DA52-6675-48D4-89E0-333A7144397C}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Production|Win32.ActiveCfg = Production|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Production|Win32.Build.0 = Production|Win32
{DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{DA31DA52-6675-48D4-89E0-333A7144397C}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -80,8 +80,8 @@ Global
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.Build.0 = Debug_All|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = Debug|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = Debug|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Production|Win32.ActiveCfg = Production|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Production|Win32.Build.0 = Production|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 7a8be2a..d7cddf4 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -3,11 +3,10 @@ EXPORTS
??0CString@WTF@@QAE@PBD@Z
??0CString@WTF@@QAE@PBDI@Z
??0Collator@WTF@@QAE@PBD@Z
- ??0DateInstance@JSC@@QAE@PAVExecState@1@N@Z
??0DateInstance@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@N@Z
??0DefaultGCActivityCallback@JSC@@QAE@PAVHeap@1@@Z
??0DropAllLocks@JSLock@JSC@@QAE@W4JSLockBehavior@2@@Z
- ??0DynamicGlobalObjectScope@JSC@@QAE@PAVExecState@1@PAVJSGlobalObject@1@@Z
+ ??0DynamicGlobalObjectScope@JSC@@QAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@@Z
??0InternalFunction@JSC@@IAE@PAVJSGlobalData@1@PAVJSGlobalObject@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVIdentifier@1@@Z
??0JSArray@JSC@@QAE@AAVJSGlobalData@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVArgList@1@@Z
??0JSArray@JSC@@QAE@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@@Z
@@ -51,6 +50,7 @@ EXPORTS
?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WTF@@@Z
?addBytes@MD5@WTF@@QAEXPBEI@Z
?addBytes@SHA1@WTF@@QAEXPBEI@Z
+ ?addCurrentThread@MachineThreads@JSC@@QAEXXZ
?addPropertyTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z
?addPropertyTransitionToExistingStructure@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z
?addPropertyWithoutTransition@Structure@JSC@@QAEIABVIdentifier@2@IPAVJSCell@2@@Z
@@ -93,23 +93,22 @@ EXPORTS
?constructArray@JSC@@YAPAVJSArray@1@PAVExecState@1@ABVArgList@1@@Z
?constructEmptyArray@JSC@@YAPAVJSArray@1@PAVExecState@1@@Z
?constructEmptyObject@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?constructFunction@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVArgList@1@ABVIdentifier@1@ABVUString@1@H@Z
+ ?constructFunction@JSC@@YAPAVJSObject@1@PAVExecState@1@PAVJSGlobalObject@1@ABVArgList@1@ABVIdentifier@1@ABVUString@1@H@Z
?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z
?convertUTF8ToUTF16@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBDPBDPAPA_WPA_W_N@Z
?create@ByteArray@WTF@@SA?AV?$PassRefPtr@VByteArray@WTF@@@2@I@Z
?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4ThreadStackType@2@@Z
?create@OpaqueJSString@@SA?AV?$PassRefPtr@UOpaqueJSString@@@WTF@@ABVUString@JSC@@@Z
- ?create@RegExp@JSC@@SA?AV?$PassRefPtr@VRegExp@JSC@@@WTF@@PAVJSGlobalData@2@ABVUString@2@1@Z
+ ?create@RegExp@JSC@@SA?AV?$PassRefPtr@VRegExp@JSC@@@WTF@@PAVJSGlobalData@2@ABVUString@2@W4RegExpFlags@2@@Z
?createEmptyString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@@Z
?createError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVUString@1@@Z
- ?createInheritorID@JSObject@JSC@@AAEPAVStructure@2@XZ
?createInterruptedExecutionException@JSC@@YAPAVJSObject@1@PAVJSGlobalData@1@@Z
?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4ThreadStackType@2@@Z
?createRangeError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVUString@1@@Z
?createReferenceError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVUString@1@@Z
?createSingleCharacterString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@E@Z
?createStackOverflowError@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@VJSValue@2@PBUClassInfo@2@@Z
+ ?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@AAVJSGlobalData@2@VJSValue@2@PBUClassInfo@2@@Z
?createSyntaxError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVUString@1@@Z
?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z
?createThread@WTF@@YAIP6APAXPAX@Z0@Z
@@ -147,7 +146,6 @@ EXPORTS
?despecifyDictionaryFunction@Structure@JSC@@QAEXABVIdentifier@2@@Z
?despecifyFunctionTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@@Z
?destroy@Heap@JSC@@QAEXXZ
- ?destroyJSGlobalObjectData@JSGlobalObject@JSC@@CAXPAX@Z
?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXI@Z
?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
@@ -277,8 +275,9 @@ EXPORTS
?putWithAttributes@JSObject@JSC@@UAEXPAVJSGlobalData@2@IVJSValue@2@I@Z
?randomNumber@WTF@@YANXZ
?recompileAllJSFunctions@Debugger@JSC@@QAEXPAVJSGlobalData@2@@Z
- ?registerThread@MachineStackMarker@JSC@@QAEXXZ
+ ?regExpFlags@JSC@@YA?AW4RegExpFlags@1@ABVUString@1@@Z
?reifyString@StringBuilder@WTF@@AAEXXZ
+ ?reserveCapacity@StringBuilder@WTF@@QAEXI@Z
?releaseDecommitted@OSAllocator@WTF@@SAXPAXI@Z
?releaseStack@MarkStack@JSC@@CAXPAXI@Z
?reportExtraMemoryCostSlowCase@Heap@JSC@@AAEXI@Z
@@ -336,10 +335,9 @@ EXPORTS
?toNumber@JSCell@JSC@@UBENPAVExecState@2@@Z
?toNumber@JSObject@JSC@@UBENPAVExecState@2@@Z
?toNumber@JSString@JSC@@EBENPAVExecState@2@@Z
- ?toObject@JSCell@JSC@@UBEPAVJSObject@2@PAVExecState@2@@Z
- ?toObject@JSObject@JSC@@UBEPAV12@PAVExecState@2@@Z
- ?toObject@JSString@JSC@@EBEPAVJSObject@2@PAVExecState@2@@Z
- ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
+ ?toObject@JSCell@JSC@@UBEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
+ ?toObject@JSObject@JSC@@UBEPAV12@PAVExecState@2@PAVJSGlobalObject@2@@Z
+ ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
?toPrimitive@JSCell@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
?toPrimitive@JSString@JSC@@EBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
?toStrictThisObject@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@@Z
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 34a9902..30b014a 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -18,7 +18,7 @@
<Configuration
Name="Debug|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreDebug.vsprops"
CharacterSet="1"
>
<Tool
@@ -79,7 +79,7 @@
<Configuration
Name="Release|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreRelease.vsprops"
CharacterSet="1"
>
<Tool
@@ -140,7 +140,7 @@
<Configuration
Name="Release_PGO|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreReleasePGO.vsprops"
CharacterSet="1"
WholeProgramOptimization="2"
>
@@ -202,7 +202,7 @@
<Configuration
Name="Debug_Cairo_CFLite|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreDebugCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -263,7 +263,7 @@
<Configuration
Name="Release_Cairo_CFLite|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreReleaseCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -324,7 +324,7 @@
<Configuration
Name="Debug_All|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreDebugAll.vsprops"
CharacterSet="1"
>
<Tool
@@ -383,9 +383,9 @@
/>
</Configuration>
<Configuration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreProduction.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -447,7 +447,7 @@
<Configuration
Name="Release_PGO_Optimize|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;.\JavaScriptCorePGOOptimize.vsprops"
+ InheritedPropertySheets=".\JavaScriptCoreReleasePGOOptimize.vsprops"
CharacterSet="1"
WholeProgramOptimization="4"
>
@@ -1960,6 +1960,22 @@
RelativePath="..\..\collector\handles\HandleHeap.h"
>
</File>
+ <File
+ RelativePath="..\..\collector\handles\HandleStack.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\collector\handles\HandleStack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\collector\handles\Local.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\collector\handles\LocalScope.h"
+ >
+ </File>
</Filter>
</Filter>
<File
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops
new file mode 100644
index 0000000..0afe222
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreDebug"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops
new file mode 100644
index 0000000..8cd1130
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreDebugAll"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCF.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops
new file mode 100644
index 0000000..ea0806d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreDebugCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCFLite.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
index 2437071..ebff713 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
@@ -43,7 +43,7 @@
/>
</Configuration>
<Configuration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
ConfigurationType="0"
InheritedPropertySheets=".\JavaScriptCoreGeneratedCommon.vsprops"
>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops
new file mode 100644
index 0000000..1d8e82d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreProduction"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops
new file mode 100644
index 0000000..e4612c3
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreRelease"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops
new file mode 100644
index 0000000..64699b5
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreReleaseCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCFLite.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops
new file mode 100644
index 0000000..ada0b8e
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreReleasePGO"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops
new file mode 100644
index 0000000..3e207e7
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="JavaScriptCoreReleasePGOOptimize"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\JavaScriptCoreCommon.vsprops;
+ .\JavaScriptCoreCF.vsprops;
+ .\JavaScriptCorePGOOptimize.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
index 1109c33..1e24f28 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
@@ -22,7 +22,7 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_All|Win32 = Debug_All|Win32
Debug|Win32 = Debug|Win32
- Release_LTCG|Win32 = Release_LTCG|Win32
+ Production|Win32 = Production|Win32
Release_PGO_Optimize|Win32 = Release_PGO_Optimize|Win32
Release_PGO|Win32 = Release_PGO|Win32
Release|Win32 = Release|Win32
@@ -32,8 +32,8 @@ Global
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug_All|Win32.Build.0 = Debug_All|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.ActiveCfg = Debug|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Debug|Win32.Build.0 = Debug|Win32
- {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Production|Win32.ActiveCfg = Production|Win32
+ {011D10F1-B656-4A1B-A0C3-3842F02122C5}.Production|Win32.Build.0 = Production|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO_Optimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO_Optimize|Win32
{011D10F1-B656-4A1B-A0C3-3842F02122C5}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -44,8 +44,8 @@ Global
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug_All|Win32.Build.0 = Debug_All|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.Build.0 = Debug|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.ActiveCfg = Production|Win32
+ {AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Production|Win32.Build.0 = Production|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -56,8 +56,8 @@ Global
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug_All|Win32.Build.0 = Debug_All|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.ActiveCfg = Debug|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Debug|Win32.Build.0 = Debug|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Production|Win32.ActiveCfg = Production|Win32
+ {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Production|Win32.Build.0 = Production|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
@@ -68,8 +68,8 @@ Global
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug_All|Win32.Build.0 = Debug_All|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.ActiveCfg = Debug|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Debug|Win32.Build.0 = Debug|Win32
- {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_LTCG|Win32.ActiveCfg = Release_LTCG|Win32
- {C59E5129-B453-49B7-A52B-1E104715F76E}.Release_LTCG|Win32.Build.0 = Release_LTCG|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Production|Win32.ActiveCfg = Production|Win32
+ {C59E5129-B453-49B7-A52B-1E104715F76E}.Production|Win32.Build.0 = Production|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
{C59E5129-B453-49B7-A52B-1E104715F76E}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 8f0cfcb..aa337b3 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -18,7 +18,7 @@
<Configuration
Name="Debug|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets=".\WTFDebug.vsprops"
CharacterSet="1"
>
<Tool
@@ -70,7 +70,7 @@
<Configuration
Name="Release|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets=".\WTFRelease.vsprops"
CharacterSet="1"
>
<Tool
@@ -122,7 +122,7 @@
<Configuration
Name="Debug_All|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\WTFCommon.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets=".\WTFDebugAll.vsprops"
CharacterSet="1"
>
<Tool
@@ -172,9 +172,9 @@
/>
</Configuration>
<Configuration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets=".\WTFProduction.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -227,7 +227,7 @@
<Configuration
Name="Release_Cairo_CFLite|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets=".\WTFReleaseCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -279,7 +279,7 @@
<Configuration
Name="Debug_Cairo_CFLite|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets=".\WTFDebugCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -331,7 +331,7 @@
<Configuration
Name="Release_PGO|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets=".\WTFReleasePGO.vsprops"
CharacterSet="1"
>
<Tool
@@ -632,7 +632,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -705,6 +705,10 @@
>
</File>
<File
+ RelativePath="..\..\wtf\HexNumber.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\ListHashSet.h"
>
</File>
@@ -965,7 +969,7 @@
>
</File>
<File
- RelativePath="..\..\wtf\ThreadSafeShared.h"
+ RelativePath="..\..\wtf\ThreadSafeRefCounted.h"
>
</File>
<File
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebug.vsprops
new file mode 100644
index 0000000..132b5c7
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebug.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFDebug"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\WTFCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugAll.vsprops
new file mode 100644
index 0000000..061f2ed
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugAll.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFDebugAll"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\WTFCommon.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugCairoCFLite.vsprops
new file mode 100644
index 0000000..7965652
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFDebugCairoCFLite.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFDebugCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;
+ .\WTFCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFProduction.vsprops
new file mode 100644
index 0000000..3de342c
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFProduction.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFProduction"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\WTFCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFRelease.vsprops
new file mode 100644
index 0000000..3960f98
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFRelease.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFRelease"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ .\WTFCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleaseCairoCFLite.vsprops
new file mode 100644
index 0000000..3267d79
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleaseCairoCFLite.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFReleaseCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;
+ .\WTFCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops
new file mode 100644
index 0000000..ac4f8a5
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFReleasePGO.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WTFReleasePGO"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\WTFCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
index ebcfd8e..a650cd2 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
@@ -18,7 +18,7 @@
<Configuration
Name="Debug|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\jscCommon.vsprops"
+ InheritedPropertySheets=".\jscDebug.vsprops"
CharacterSet="1"
>
<Tool
@@ -79,7 +79,7 @@
<Configuration
Name="Release|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\jscCommon.vsprops"
+ InheritedPropertySheets=".\jscRelease.vsprops"
CharacterSet="1"
>
<Tool
@@ -140,7 +140,7 @@
<Configuration
Name="Debug_Cairo_CFLite|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\jscCommon.vsprops"
+ InheritedPropertySheets=".\jscDebugCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -201,7 +201,7 @@
<Configuration
Name="Debug_All|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\jscCommon.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets=".\jscDebugAll.vsprops"
CharacterSet="1"
>
<Tool
@@ -260,9 +260,9 @@
/>
</Configuration>
<Configuration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\jscCommon.vsprops"
+ InheritedPropertySheets=".\jscProduction.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -324,7 +324,7 @@
<Configuration
Name="Release_Cairo_CFLite|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;.\jscCommon.vsprops"
+ InheritedPropertySheets=".\jscReleaseCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -385,7 +385,7 @@
<Configuration
Name="Release_PGO|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\jscCommon.vsprops"
+ InheritedPropertySheets=".\jscReleasePGO.vsprops"
CharacterSet="1"
>
<Tool
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops
new file mode 100644
index 0000000..fa6dc68
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscDebug"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\jscCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops
new file mode 100644
index 0000000..6090c60
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscDebugAll"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\jscCommon.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops
new file mode 100644
index 0000000..c1868a8
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscDebugCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;
+ .\jscCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops
new file mode 100644
index 0000000..408871b
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscProduction"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\jscCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops
new file mode 100644
index 0000000..ba9b288
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscRelease"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ .\jscCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops
new file mode 100644
index 0000000..2104fe4
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscReleaseCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;
+ .\jscCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops
new file mode 100644
index 0000000..78f3672
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="jscReleasePGO"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\jscCommon.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
index 5b18032..1dfdd1e 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
@@ -18,7 +18,7 @@
<Configuration
Name="Debug|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\testapiDebug.vsprops"
CharacterSet="1"
>
<Tool
@@ -79,7 +79,7 @@
<Configuration
Name="Release|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\testapiRelease.vsprops"
CharacterSet="1"
>
<Tool
@@ -140,7 +140,7 @@
<Configuration
Name="Debug_Cairo_CFLite|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCFLite.vsprops"
+ InheritedPropertySheets=".\testapiDebugCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -201,7 +201,7 @@
<Configuration
Name="Release_Cairo_CFLite|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCFLite.vsprops"
+ InheritedPropertySheets=".\testapiReleaseCairoCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -262,7 +262,7 @@
<Configuration
Name="Debug_All|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets=".\testapiDebugAll.vsprops"
CharacterSet="1"
>
<Tool
@@ -321,9 +321,9 @@
/>
</Configuration>
<Configuration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets=".\testapiProduction.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -430,7 +430,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release_LTCG|Win32"
+ Name="Production|Win32"
>
<Tool
Name="VCCLCompilerTool"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops
new file mode 100644
index 0000000..ba5e31d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testapiDebug"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\testapiCommon.vsprops;
+ ..\JavaScriptCore\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops
new file mode 100644
index 0000000..cc139f8
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testapiDebugAll"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ .\testapiCommon.vsprops;
+ ..\JavaScriptCore\JavaScriptCoreCF.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops
new file mode 100644
index 0000000..4e1e11f
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testapiDebugCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;
+ .\testapiCommon.vsprops;
+ ..\JavaScriptCore\JavaScriptCoreCFLite.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops
new file mode 100644
index 0000000..03fceab
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testapiProduction"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;
+ .\testapiCommon.vsprops;
+ ..\JavaScriptCore\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops
new file mode 100644
index 0000000..1c041ff
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testapiRelease"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ .\testapiCommon.vsprops;
+ ..\JavaScriptCore\JavaScriptCoreCF.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops
new file mode 100644
index 0000000..c025283
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testapiReleaseCairoCFLite"
+ InheritedPropertySheets="
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;
+ $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;
+ .\testapiCommon.vsprops;
+ ..\JavaScriptCore\JavaScriptCoreCFLite.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 9f8d49a..44e108c 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -121,6 +121,7 @@
14469DEC107EC7E700650446 /* StringObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C20E16EE3300B34460 /* StringObject.cpp */; };
14469DED107EC7E700650446 /* StringPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */; };
14469DEE107EC7E700650446 /* UString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8850255597D01FF60F7 /* UString.cpp */; };
+ 144836E7132DA7BE005BE785 /* ConservativeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 149DAAF212EB559D0083B12B /* ConservativeSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146AAB370B66A94400E55F16 /* JSStringRefCF.cpp */; };
146B16D812EB5B59001BEC1B /* ConservativeSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146B14DB12EB5B12001BEC1B /* ConservativeSet.cpp */; };
146FE51211A710430087AE66 /* JITCall32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146FE51111A710430087AE66 /* JITCall32_64.cpp */; };
@@ -209,7 +210,8 @@
655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; };
65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DFC92D08EA173A00F7300B /* HashTable.cpp */; };
65E1A3DF122B894500B26097 /* NonCopyingSort.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E1A2F4122B880D00B26097 /* NonCopyingSort.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B808E7EECC0023E5F6 /* Assertions.cpp */; settings = {COMPILER_FLAGS = "-Wno-missing-format-attribute"; }; };
+ 65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B808E7EECC0023E5F6 /* Assertions.cpp */; };
+ 7186A6EC13100BA5004479E1 /* HexNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 7186A6E813100B57004479E1 /* HexNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
76FB9F0F12E851860051A2EB /* SHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = 76FB9F0E12E851860051A2EB /* SHA1.h */; settings = {ATTRIBUTES = (Private, ); }; };
76FB9F1112E851960051A2EB /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76FB9F1012E851960051A2EB /* SHA1.cpp */; };
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -280,6 +282,25 @@
86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; };
86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; };
86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
+ 86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */; };
+ 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */; };
+ 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */; };
+ 86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */; };
+ 86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */; };
+ 86EC9DC91328DF82002B2AD7 /* DFGJITCodeGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB91328DF82002B2AD7 /* DFGJITCodeGenerator.cpp */; };
+ 86EC9DCA1328DF82002B2AD7 /* DFGJITCodeGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DBA1328DF82002B2AD7 /* DFGJITCodeGenerator.h */; };
+ 86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DBB1328DF82002B2AD7 /* DFGJITCompiler.cpp */; };
+ 86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */; };
+ 86EC9DCD1328DF82002B2AD7 /* DFGNonSpeculativeJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DBD1328DF82002B2AD7 /* DFGNonSpeculativeJIT.cpp */; };
+ 86EC9DCE1328DF82002B2AD7 /* DFGNonSpeculativeJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DBE1328DF82002B2AD7 /* DFGNonSpeculativeJIT.h */; };
+ 86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */; };
+ 86EC9DD01328DF82002B2AD7 /* DFGOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */; };
+ 86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */; };
+ 86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */; };
+ 86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */; };
+ 86ECA3EA132DEF1C002B2AD7 /* DFGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */; };
+ 86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */; };
+ 86ECA4F1132EAA6D002B2AD7 /* DFGAliasTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA4F0132EAA6D002B2AD7 /* DFGAliasTracker.h */; };
86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F38858121130CA007A7CE3 /* AtomicStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */; };
90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 90213E3C123A40C200D422F3 /* MemoryStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -355,6 +376,10 @@
A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */; };
A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */; };
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A76BE39F132EEA7C008F7F0B /* HandleStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A76BE1B7132DAC68008F7F0B /* HandleStack.cpp */; };
+ A76BE3A0132EEA7C008F7F0B /* HandleStack.h in Headers */ = {isa = PBXBuildFile; fileRef = A76BE1B8132DAC68008F7F0B /* HandleStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A76BE3A1132EEA7C008F7F0B /* Local.h in Headers */ = {isa = PBXBuildFile; fileRef = A76BE1B5132DABF5008F7F0B /* Local.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A76BE3A2132EEA7C008F7F0B /* LocalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = A76BE1B6132DAC24008F7F0B /* LocalScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; };
A7795590101A74D500114E55 /* MarkStack.h in Headers */ = {isa = PBXBuildFile; fileRef = A779558F101A74D500114E55 /* MarkStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
A783A0D111A36DCA00563D20 /* JSObjectWithGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A783A0D011A36DCA00563D20 /* JSObjectWithGlobalObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -531,7 +556,7 @@
BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */; };
BC5F7BBE11823B590052C02C /* Atomics.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBB11823B590052C02C /* Atomics.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC5F7BBF11823B590052C02C /* ThreadingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC5F7BC011823B590052C02C /* ThreadSafeShared.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBD11823B590052C02C /* ThreadSafeShared.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC5F7BC011823B590052C02C /* ThreadSafeRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBD11823B590052C02C /* ThreadSafeRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
BC7F8FB90E19D1C3008632C0 /* JSNumberCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F8FB80E19D1C3008632C0 /* JSNumberCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -850,6 +875,7 @@
65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommonIdentifiers.cpp; sourceTree = "<group>"; };
65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
+ 7186A6E813100B57004479E1 /* HexNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexNumber.h; sourceTree = "<group>"; };
76FB9F0E12E851860051A2EB /* SHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHA1.h; sourceTree = "<group>"; };
76FB9F1012E851960051A2EB /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SHA1.cpp; sourceTree = "<group>"; };
7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeChainMark.h; sourceTree = "<group>"; };
@@ -922,6 +948,25 @@
86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; };
86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; };
86E85538111B9968001AF51E /* JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringBuilder.h; sourceTree = "<group>"; };
+ 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGByteCodeParser.cpp; path = dfg/DFGByteCodeParser.cpp; sourceTree = "<group>"; };
+ 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeParser.h; path = dfg/DFGByteCodeParser.h; sourceTree = "<group>"; };
+ 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGGenerationInfo.h; path = dfg/DFGGenerationInfo.h; sourceTree = "<group>"; };
+ 86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGGraph.cpp; path = dfg/DFGGraph.cpp; sourceTree = "<group>"; };
+ 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGGraph.h; path = dfg/DFGGraph.h; sourceTree = "<group>"; };
+ 86EC9DB91328DF82002B2AD7 /* DFGJITCodeGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCodeGenerator.cpp; path = dfg/DFGJITCodeGenerator.cpp; sourceTree = "<group>"; };
+ 86EC9DBA1328DF82002B2AD7 /* DFGJITCodeGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJITCodeGenerator.h; path = dfg/DFGJITCodeGenerator.h; sourceTree = "<group>"; };
+ 86EC9DBB1328DF82002B2AD7 /* DFGJITCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCompiler.cpp; path = dfg/DFGJITCompiler.cpp; sourceTree = "<group>"; };
+ 86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJITCompiler.h; path = dfg/DFGJITCompiler.h; sourceTree = "<group>"; };
+ 86EC9DBD1328DF82002B2AD7 /* DFGNonSpeculativeJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNonSpeculativeJIT.cpp; path = dfg/DFGNonSpeculativeJIT.cpp; sourceTree = "<group>"; };
+ 86EC9DBE1328DF82002B2AD7 /* DFGNonSpeculativeJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNonSpeculativeJIT.h; path = dfg/DFGNonSpeculativeJIT.h; sourceTree = "<group>"; };
+ 86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOperations.cpp; path = dfg/DFGOperations.cpp; sourceTree = "<group>"; };
+ 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOperations.h; path = dfg/DFGOperations.h; sourceTree = "<group>"; };
+ 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisterBank.h; path = dfg/DFGRegisterBank.h; sourceTree = "<group>"; };
+ 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT.cpp; path = dfg/DFGSpeculativeJIT.cpp; sourceTree = "<group>"; };
+ 86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSpeculativeJIT.h; path = dfg/DFGSpeculativeJIT.h; sourceTree = "<group>"; };
+ 86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNode.h; path = dfg/DFGNode.h; sourceTree = "<group>"; };
+ 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGScoreBoard.h; path = dfg/DFGScoreBoard.h; sourceTree = "<group>"; };
+ 86ECA4F0132EAA6D002B2AD7 /* DFGAliasTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAliasTracker.h; path = dfg/DFGAliasTracker.h; sourceTree = "<group>"; };
86F38858121130CA007A7CE3 /* AtomicStringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringHash.h; path = text/AtomicStringHash.h; sourceTree = "<group>"; };
90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStatistics.cpp; sourceTree = "<group>"; };
90213E3C123A40C200D422F3 /* MemoryStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryStatistics.h; sourceTree = "<group>"; };
@@ -1030,6 +1075,10 @@
A74B3498102A5F8E0032AB98 /* MarkStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkStack.cpp; sourceTree = "<group>"; };
A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMv7Assembler.cpp; sourceTree = "<group>"; };
A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic32_64.cpp; sourceTree = "<group>"; };
+ A76BE1B5132DABF5008F7F0B /* Local.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Local.h; path = collector/handles/Local.h; sourceTree = "<group>"; };
+ A76BE1B6132DAC24008F7F0B /* LocalScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LocalScope.h; path = collector/handles/LocalScope.h; sourceTree = "<group>"; };
+ A76BE1B7132DAC68008F7F0B /* HandleStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HandleStack.cpp; path = collector/handles/HandleStack.cpp; sourceTree = "<group>"; };
+ A76BE1B8132DAC68008F7F0B /* HandleStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HandleStack.h; path = collector/handles/HandleStack.h; sourceTree = "<group>"; };
A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; };
A779558F101A74D500114E55 /* MarkStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStack.h; sourceTree = "<group>"; };
A783A0D011A36DCA00563D20 /* JSObjectWithGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectWithGlobalObject.h; sourceTree = "<group>"; };
@@ -1125,7 +1174,7 @@
BC337BEA0E1B00CB0076918A /* Error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Error.cpp; sourceTree = "<group>"; };
BC5F7BBB11823B590052C02C /* Atomics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atomics.h; sourceTree = "<group>"; };
BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadingPrimitives.h; sourceTree = "<group>"; };
- BC5F7BBD11823B590052C02C /* ThreadSafeShared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadSafeShared.h; sourceTree = "<group>"; };
+ BC5F7BBD11823B590052C02C /* ThreadSafeRefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadSafeRefCounted.h; sourceTree = "<group>"; };
BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassInfo.h; sourceTree = "<group>"; };
BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectFunctions.cpp; sourceTree = "<group>"; };
BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectFunctions.h; sourceTree = "<group>"; };
@@ -1317,6 +1366,7 @@
7E39D81D0EC38EFA003AF11A /* bytecompiler */,
A7E4FC8312F8E4A300AF4CF4 /* collector */,
1480DB9A0DDC2231003CFDF2 /* debugger */,
+ 86EC9DB31328DF44002B2AD7 /* dfg */,
1429D77A0ED20D7300B89619 /* interpreter */,
1429D92C0ED22D7000B89619 /* jit */,
7E39D8370EC3A388003AF11A /* parser */,
@@ -1567,6 +1617,7 @@
65DFC92D08EA173A00F7300B /* HashTable.cpp */,
65DFC92E08EA173A00F7300B /* HashTable.h */,
65DFC92F08EA173A00F7300B /* HashTraits.h */,
+ 7186A6E813100B57004479E1 /* HexNumber.h */,
657EB7450B708F540063461B /* ListHashSet.h */,
148A1626095D16BB00666D0D /* ListRefPtr.h */,
E1EE79270D6C964500FEA3BA /* Locker.h */,
@@ -1634,7 +1685,7 @@
E1EE79220D6C95CD00FEA3BA /* Threading.h */,
BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */,
E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */,
- BC5F7BBD11823B590052C02C /* ThreadSafeShared.h */,
+ BC5F7BBD11823B590052C02C /* ThreadSafeRefCounted.h */,
E1B7C8BD0DA3A3360074B0DC /* ThreadSpecific.h */,
0B330C260F38C62300692DE3 /* TypeTraits.cpp */,
0B4D7E620F319AC800AD7E58 /* TypeTraits.h */,
@@ -1946,6 +1997,32 @@
name = yarr;
sourceTree = "<group>";
};
+ 86EC9DB31328DF44002B2AD7 /* dfg */ = {
+ isa = PBXGroup;
+ children = (
+ 86ECA4F0132EAA6D002B2AD7 /* DFGAliasTracker.h */,
+ 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */,
+ 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,
+ 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */,
+ 86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */,
+ 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */,
+ 86EC9DB91328DF82002B2AD7 /* DFGJITCodeGenerator.cpp */,
+ 86EC9DBA1328DF82002B2AD7 /* DFGJITCodeGenerator.h */,
+ 86EC9DBB1328DF82002B2AD7 /* DFGJITCompiler.cpp */,
+ 86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */,
+ 86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */,
+ 86EC9DBD1328DF82002B2AD7 /* DFGNonSpeculativeJIT.cpp */,
+ 86EC9DBE1328DF82002B2AD7 /* DFGNonSpeculativeJIT.h */,
+ 86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */,
+ 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */,
+ 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
+ 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */,
+ 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */,
+ 86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */,
+ );
+ name = dfg;
+ sourceTree = "<group>";
+ };
932FC3C20824BB70005B3C75 /* Resources */ = {
isa = PBXGroup;
children = (
@@ -2074,6 +2151,10 @@
A7E4FC8812F8E4CA00AF4CF4 /* Handle.h */,
A7E4FC8912F8E4CA00AF4CF4 /* HandleHeap.cpp */,
A7E4FC8A12F8E4CA00AF4CF4 /* HandleHeap.h */,
+ A76BE1B7132DAC68008F7F0B /* HandleStack.cpp */,
+ A76BE1B8132DAC68008F7F0B /* HandleStack.h */,
+ A76BE1B5132DABF5008F7F0B /* Local.h */,
+ A76BE1B6132DAC24008F7F0B /* LocalScope.h */,
);
name = handles;
sourceTree = "<group>";
@@ -2160,6 +2241,7 @@
BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
FDA15C1E12B0305C003A583A /* Complex.h in Headers */,
BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
+ 144836E7132DA7BE005BE785 /* ConservativeSet.h in Headers */,
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */,
0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */,
86565743115BE3DA00291F40 /* CString.h in Headers */,
@@ -2205,6 +2287,7 @@
BC18C40D0E16F5CD00B34460 /* HashTable.h in Headers */,
BC18C40E0E16F5CD00B34460 /* HashTraits.h in Headers */,
140CDE7112DE97B10013CFC5 /* Heap.h in Headers */,
+ 7186A6EC13100BA5004479E1 /* HexNumber.h in Headers */,
BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
@@ -2401,7 +2484,7 @@
18BAB55410DAE066000D945B /* ThreadIdentifierDataPthreads.h in Headers */,
BC18C4700E16F5CD00B34460 /* Threading.h in Headers */,
BC5F7BBF11823B590052C02C /* ThreadingPrimitives.h in Headers */,
- BC5F7BC011823B590052C02C /* ThreadSafeShared.h in Headers */,
+ BC5F7BC011823B590052C02C /* ThreadSafeRefCounted.h in Headers */,
BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */,
A7386556118697B400540279 /* ThunkGenerators.h in Headers */,
14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */,
@@ -2449,6 +2532,21 @@
A7C40C0A130B057D00D002A1 /* BlockStack.h in Headers */,
A7C40C0B130B057D00D002A1 /* SentinelLinkedList.h in Headers */,
A7C40C0C130B057D00D002A1 /* SinglyLinkedList.h in Headers */,
+ A76BE3A0132EEA7C008F7F0B /* HandleStack.h in Headers */,
+ A76BE3A1132EEA7C008F7F0B /* Local.h in Headers */,
+ A76BE3A2132EEA7C008F7F0B /* LocalScope.h in Headers */,
+ 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */,
+ 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,
+ 86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */,
+ 86EC9DCA1328DF82002B2AD7 /* DFGJITCodeGenerator.h in Headers */,
+ 86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */,
+ 86EC9DCE1328DF82002B2AD7 /* DFGNonSpeculativeJIT.h in Headers */,
+ 86EC9DD01328DF82002B2AD7 /* DFGOperations.h in Headers */,
+ 86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
+ 86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */,
+ 86ECA3EA132DEF1C002B2AD7 /* DFGNode.h in Headers */,
+ 86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */,
+ 86ECA4F1132EAA6D002B2AD7 /* DFGAliasTracker.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2888,6 +2986,14 @@
97941A7E1302A098004A3447 /* CryptographicallyRandomNumber.cpp in Sources */,
A7E4FC9112F8E4CA00AF4CF4 /* HandleHeap.cpp in Sources */,
A7AC25BD1304D146003396DE /* MarkedBlock.cpp in Sources */,
+ A76BE39F132EEA7C008F7F0B /* HandleStack.cpp in Sources */,
+ 86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
+ 86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */,
+ 86EC9DC91328DF82002B2AD7 /* DFGJITCodeGenerator.cpp in Sources */,
+ 86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
+ 86EC9DCD1328DF82002B2AD7 /* DFGNonSpeculativeJIT.cpp in Sources */,
+ 86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */,
+ 86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/JavaScriptCore/Makefile b/Source/JavaScriptCore/Makefile
index b9e2a72..cb4c11a 100644
--- a/Source/JavaScriptCore/Makefile
+++ b/Source/JavaScriptCore/Makefile
@@ -1,2 +1 @@
-OTHER_OPTIONS = -target All
include ../Makefile.shared
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 5ebc572..8e81784 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -145,21 +145,21 @@ public:
// Describes an memory operand given by a pointer. For regular load & store
// operations an unwrapped void* will be used, rather than using this.
struct AbsoluteAddress {
- explicit AbsoluteAddress(void* ptr)
+ explicit AbsoluteAddress(const void* ptr)
: m_ptr(ptr)
{
}
- void* m_ptr;
+ const void* m_ptr;
};
- // ImmPtr:
+ // TrustedImmPtr:
//
// A pointer sized immediate operand to an instruction - this is wrapped
// in a class requiring explicit construction in order to differentiate
// from pointers used as absolute addresses to memory operations
- struct ImmPtr {
- explicit ImmPtr(const void* value)
+ struct TrustedImmPtr {
+ explicit TrustedImmPtr(const void* value)
: m_value(value)
{
}
@@ -172,14 +172,21 @@ public:
const void* m_value;
};
- // Imm32:
+ struct ImmPtr : public TrustedImmPtr {
+ explicit ImmPtr(const void* value)
+ : TrustedImmPtr(value)
+ {
+ }
+ };
+
+ // TrustedImm32:
//
// A 32bit immediate operand to an instruction - this is wrapped in a
// class requiring explicit construction in order to prevent RegisterIDs
// (which are implemented as an enum) from accidentally being passed as
// immediate values.
- struct Imm32 {
- explicit Imm32(int32_t value)
+ struct TrustedImm32 {
+ explicit TrustedImm32(int32_t value)
: m_value(value)
#if CPU(ARM) || CPU(MIPS)
, m_isPointer(false)
@@ -188,7 +195,7 @@ public:
}
#if !CPU(X86_64)
- explicit Imm32(ImmPtr ptr)
+ explicit TrustedImm32(TrustedImmPtr ptr)
: m_value(ptr.asIntptr())
#if CPU(ARM) || CPU(MIPS)
, m_isPointer(true)
@@ -211,6 +218,19 @@ public:
};
+ struct Imm32 : public TrustedImm32 {
+ explicit Imm32(int32_t value)
+ : TrustedImm32(value)
+ {
+ }
+#if !CPU(X86_64)
+ explicit Imm32(TrustedImmPtr ptr)
+ : TrustedImm32(ptr)
+ {
+ }
+#endif
+ };
+
// Section 2: MacroAssembler code buffer handles
//
// The following types are used to reference items in the code buffer
@@ -358,16 +378,18 @@ public:
{
}
- void link(AbstractMacroAssembler<AssemblerType>* masm)
+ void link(AbstractMacroAssembler<AssemblerType>* masm) const
{
masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
}
- void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+ void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
{
masm->m_assembler.linkJump(m_jmp, label.m_label);
}
+ bool isSet() const { return m_jmp.isSet(); }
+
private:
JmpSrc m_jmp;
};
diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.h b/Source/JavaScriptCore/assembler/AssemblerBuffer.h
index 0454a99..a90efc6 100644
--- a/Source/JavaScriptCore/assembler/AssemblerBuffer.h
+++ b/Source/JavaScriptCore/assembler/AssemblerBuffer.h
@@ -114,6 +114,21 @@ namespace JSC {
putIntUnchecked(value);
}
+ template<typename IntegralType>
+ void putIntegral(IntegralType value)
+ {
+ if (m_size > m_capacity - sizeof(IntegralType))
+ grow();
+ putIntegralUnchecked(value);
+ }
+
+ template<typename IntegralType>
+ void putIntegralUnchecked(IntegralType value)
+ {
+ *reinterpret_cast_ptr<IntegralType*>(&m_buffer[m_size]) = value;
+ m_size += sizeof(IntegralType);
+ }
+
void* data() const
{
return m_buffer;
diff --git a/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h b/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
index 599be14..9a9618f 100644
--- a/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
+++ b/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
@@ -188,29 +188,14 @@ public:
return AssemblerBuffer::executableCopy(allocator);
}
- void putIntWithConstantInt(uint32_t insn, uint32_t constant, bool isReusable = false)
+ void putShortWithConstantInt(uint16_t insn, uint32_t constant, bool isReusable = false)
{
- if (!m_numConsts)
- m_maxDistance = maxPoolSize;
- flushIfNoSpaceFor(4, 4);
-
- m_loadOffsets.append(AssemblerBuffer::size());
- if (isReusable)
- for (int i = 0; i < m_numConsts; ++i) {
- if (m_mask[i] == ReusableConst && m_pool[i] == constant) {
- AssemblerBuffer::putInt(AssemblerType::patchConstantPoolLoad(insn, i));
- correctDeltas(4);
- return;
- }
- }
-
- m_pool[m_numConsts] = constant;
- m_mask[m_numConsts] = static_cast<char>(isReusable ? ReusableConst : UniqueConst);
-
- AssemblerBuffer::putInt(AssemblerType::patchConstantPoolLoad(insn, m_numConsts));
- ++m_numConsts;
+ putIntegralWithConstantInt(insn, constant, isReusable);
+ }
- correctDeltas(4, 4);
+ void putIntWithConstantInt(uint32_t insn, uint32_t constant, bool isReusable = false)
+ {
+ putIntegralWithConstantInt(insn, constant, isReusable);
}
// This flushing mechanism can be called after any unconditional jumps.
@@ -248,6 +233,33 @@ private:
m_lastConstDelta = constSize;
}
+ template<typename IntegralType>
+ void putIntegralWithConstantInt(IntegralType insn, uint32_t constant, bool isReusable)
+ {
+ if (!m_numConsts)
+ m_maxDistance = maxPoolSize;
+ flushIfNoSpaceFor(sizeof(IntegralType), 4);
+
+ m_loadOffsets.append(AssemblerBuffer::size());
+ if (isReusable) {
+ for (int i = 0; i < m_numConsts; ++i) {
+ if (m_mask[i] == ReusableConst && m_pool[i] == constant) {
+ putIntegral(static_cast<IntegralType>(AssemblerType::patchConstantPoolLoad(insn, i)));
+ correctDeltas(sizeof(IntegralType));
+ return;
+ }
+ }
+ }
+
+ m_pool[m_numConsts] = constant;
+ m_mask[m_numConsts] = static_cast<char>(isReusable ? ReusableConst : UniqueConst);
+
+ putIntegral(static_cast<IntegralType>(AssemblerType::patchConstantPoolLoad(insn, m_numConsts)));
+ ++m_numConsts;
+
+ correctDeltas(sizeof(IntegralType), 4);
+ }
+
void flushConstantPool(bool useBarrier = true)
{
if (m_numConsts == 0)
@@ -259,7 +271,7 @@ private:
// Callback to protect the constant pool from execution
if (useBarrier)
- AssemblerBuffer::putInt(AssemblerType::placeConstantPoolBarrier(m_numConsts * sizeof(uint32_t) + alignPool));
+ putIntegral(AssemblerType::placeConstantPoolBarrier(m_numConsts * sizeof(uint32_t) + alignPool));
if (alignPool) {
if (alignPool & 1)
diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
index fa165de..bb19a98 100644
--- a/Source/JavaScriptCore/assembler/MacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
@@ -74,7 +74,7 @@ public:
// described in terms of other macro assembly methods.
void pop()
{
- addPtr(Imm32(sizeof(void*)), stackPointerRegister);
+ addPtr(TrustedImm32(sizeof(void*)), stackPointerRegister);
}
void peek(RegisterID dest, int index = 0)
@@ -87,19 +87,19 @@ public:
storePtr(src, Address(stackPointerRegister, (index * sizeof(void*))));
}
- void poke(Imm32 value, int index = 0)
+ void poke(TrustedImm32 value, int index = 0)
{
store32(value, Address(stackPointerRegister, (index * sizeof(void*))));
}
- void poke(ImmPtr imm, int index = 0)
+ void poke(TrustedImmPtr imm, int index = 0)
{
storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*))));
}
// Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
- void branchPtr(Condition cond, RegisterID op1, ImmPtr imm, Label target)
+ void branchPtr(Condition cond, RegisterID op1, TrustedImmPtr imm, Label target)
{
branchPtr(cond, op1, imm).linkTo(target, this);
}
@@ -109,7 +109,7 @@ public:
branch32(cond, op1, op2).linkTo(target, this);
}
- void branch32(Condition cond, RegisterID op1, Imm32 imm, Label target)
+ void branch32(Condition cond, RegisterID op1, TrustedImm32 imm, Label target)
{
branch32(cond, op1, imm).linkTo(target, this);
}
@@ -144,17 +144,17 @@ public:
add32(src, dest);
}
- void addPtr(Imm32 imm, RegisterID srcDest)
+ void addPtr(TrustedImm32 imm, RegisterID srcDest)
{
add32(imm, srcDest);
}
- void addPtr(ImmPtr imm, RegisterID dest)
+ void addPtr(TrustedImmPtr imm, RegisterID dest)
{
- add32(Imm32(imm), dest);
+ add32(TrustedImm32(imm), dest);
}
- void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
+ void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
add32(imm, src, dest);
}
@@ -164,7 +164,7 @@ public:
and32(src, dest);
}
- void andPtr(Imm32 imm, RegisterID srcDest)
+ void andPtr(TrustedImm32 imm, RegisterID srcDest)
{
and32(imm, srcDest);
}
@@ -174,12 +174,12 @@ public:
or32(src, dest);
}
- void orPtr(ImmPtr imm, RegisterID dest)
+ void orPtr(TrustedImmPtr imm, RegisterID dest)
{
- or32(Imm32(imm), dest);
+ or32(TrustedImm32(imm), dest);
}
- void orPtr(Imm32 imm, RegisterID dest)
+ void orPtr(TrustedImm32 imm, RegisterID dest)
{
or32(imm, dest);
}
@@ -189,14 +189,14 @@ public:
sub32(src, dest);
}
- void subPtr(Imm32 imm, RegisterID dest)
+ void subPtr(TrustedImm32 imm, RegisterID dest)
{
sub32(imm, dest);
}
- void subPtr(ImmPtr imm, RegisterID dest)
+ void subPtr(TrustedImmPtr imm, RegisterID dest)
{
- sub32(Imm32(imm), dest);
+ sub32(TrustedImm32(imm), dest);
}
void xorPtr(RegisterID src, RegisterID dest)
@@ -204,7 +204,7 @@ public:
xor32(src, dest);
}
- void xorPtr(Imm32 imm, RegisterID srcDest)
+ void xorPtr(TrustedImm32 imm, RegisterID srcDest)
{
xor32(imm, srcDest);
}
@@ -230,7 +230,7 @@ public:
return load32WithAddressOffsetPatch(address, dest);
}
- void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void setPtr(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
set32Compare32(cond, left, right, dest);
}
@@ -250,14 +250,14 @@ public:
store32(src, address);
}
- void storePtr(ImmPtr imm, ImplicitAddress address)
+ void storePtr(TrustedImmPtr imm, ImplicitAddress address)
{
- store32(Imm32(imm), address);
+ store32(TrustedImm32(imm), address);
}
- void storePtr(ImmPtr imm, void* address)
+ void storePtr(TrustedImmPtr imm, void* address)
{
- store32(Imm32(imm), address);
+ store32(TrustedImm32(imm), address);
}
DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
@@ -271,9 +271,9 @@ public:
return branch32(cond, left, right);
}
- Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
+ Jump branchPtr(Condition cond, RegisterID left, TrustedImmPtr right)
{
- return branch32(cond, left, Imm32(right));
+ return branch32(cond, left, TrustedImm32(right));
}
Jump branchPtr(Condition cond, RegisterID left, Address right)
@@ -291,14 +291,14 @@ public:
return branch32(cond, left, right);
}
- Jump branchPtr(Condition cond, Address left, ImmPtr right)
+ Jump branchPtr(Condition cond, Address left, TrustedImmPtr right)
{
- return branch32(cond, left, Imm32(right));
+ return branch32(cond, left, TrustedImm32(right));
}
- Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right)
+ Jump branchPtr(Condition cond, AbsoluteAddress left, TrustedImmPtr right)
{
- return branch32(cond, left, Imm32(right));
+ return branch32(cond, left, TrustedImm32(right));
}
Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
@@ -306,17 +306,17 @@ public:
return branchTest32(cond, reg, mask);
}
- Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
return branchTest32(cond, reg, mask);
}
- Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
return branchTest32(cond, address, mask);
}
- Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
return branchTest32(cond, address, mask);
}
@@ -327,12 +327,12 @@ public:
return branchAdd32(cond, src, dest);
}
- Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchSubPtr(Condition cond, TrustedImm32 imm, RegisterID dest)
{
return branchSub32(cond, imm, dest);
}
using MacroAssemblerBase::branchTest8;
- Jump branchTest8(Condition cond, ExtendedAddress address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
{
return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
}
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index 66814b5..80f69bf 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -86,14 +86,14 @@ public:
m_assembler.adds_r(dest, dest, src);
}
- void add32(Imm32 imm, Address address)
+ void add32(TrustedImm32 imm, Address address)
{
load32(address, ARMRegisters::S1);
add32(imm, ARMRegisters::S1);
store32(ARMRegisters::S1, address);
}
- void add32(Imm32 imm, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.adds_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
@@ -109,7 +109,7 @@ public:
m_assembler.ands_r(dest, dest, src);
}
- void and32(Imm32 imm, RegisterID dest)
+ void and32(TrustedImm32 imm, RegisterID dest)
{
ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
if (w & ARMAssembler::OP2_INV_IMM)
@@ -127,7 +127,7 @@ public:
m_assembler.movs_r(dest, m_assembler.lsl_r(dest, ARMRegisters::S0));
}
- void lshift32(Imm32 imm, RegisterID dest)
+ void lshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
}
@@ -141,7 +141,7 @@ public:
m_assembler.muls_r(dest, dest, src);
}
- void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+ void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
move(imm, ARMRegisters::S0);
m_assembler.muls_r(dest, src, ARMRegisters::S0);
@@ -162,7 +162,7 @@ public:
m_assembler.orrs_r(dest, dest, src);
}
- void or32(Imm32 imm, RegisterID dest)
+ void or32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.orrs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
@@ -176,7 +176,7 @@ public:
m_assembler.movs_r(dest, m_assembler.asr_r(dest, ARMRegisters::S0));
}
- void rshift32(Imm32 imm, RegisterID dest)
+ void rshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.movs_r(dest, m_assembler.asr(dest, imm.m_value & 0x1f));
}
@@ -190,7 +190,7 @@ public:
m_assembler.movs_r(dest, m_assembler.lsr_r(dest, ARMRegisters::S0));
}
- void urshift32(Imm32 imm, RegisterID dest)
+ void urshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.movs_r(dest, m_assembler.lsr(dest, imm.m_value & 0x1f));
}
@@ -200,12 +200,12 @@ public:
m_assembler.subs_r(dest, dest, src);
}
- void sub32(Imm32 imm, RegisterID dest)
+ void sub32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.subs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
- void sub32(Imm32 imm, Address address)
+ void sub32(TrustedImm32 imm, Address address)
{
load32(address, ARMRegisters::S1);
sub32(imm, ARMRegisters::S1);
@@ -223,7 +223,7 @@ public:
m_assembler.eors_r(dest, dest, src);
}
- void xor32(Imm32 imm, RegisterID dest)
+ void xor32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
@@ -303,7 +303,7 @@ public:
m_assembler.baseIndexTransfer32(false, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
}
- void store32(Imm32 imm, ImplicitAddress address)
+ void store32(TrustedImm32 imm, ImplicitAddress address)
{
if (imm.m_isPointer)
m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value);
@@ -318,7 +318,7 @@ public:
m_assembler.dtr_u(false, src, ARMRegisters::S0, 0);
}
- void store32(Imm32 imm, void* address)
+ void store32(TrustedImm32 imm, void* address)
{
m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
if (imm.m_isPointer)
@@ -344,13 +344,13 @@ public:
push(ARMRegisters::S1);
}
- void push(Imm32 imm)
+ void push(TrustedImm32 imm)
{
move(imm, ARMRegisters::S0);
push(ARMRegisters::S0);
}
- void move(Imm32 imm, RegisterID dest)
+ void move(TrustedImm32 imm, RegisterID dest)
{
if (imm.m_isPointer)
m_assembler.ldr_un_imm(dest, imm.m_value);
@@ -363,9 +363,9 @@ public:
m_assembler.mov_r(dest, src);
}
- void move(ImmPtr imm, RegisterID dest)
+ void move(TrustedImmPtr imm, RegisterID dest)
{
- move(Imm32(imm), dest);
+ move(TrustedImm32(imm), dest);
}
void swap(RegisterID reg1, RegisterID reg2)
@@ -387,7 +387,7 @@ public:
move(src, dest);
}
- Jump branch8(Condition cond, Address left, Imm32 right)
+ Jump branch8(Condition cond, Address left, TrustedImm32 right)
{
load8(left, ARMRegisters::S1);
return branch32(cond, ARMRegisters::S1, right);
@@ -399,7 +399,7 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
}
- Jump branch32(Condition cond, RegisterID left, Imm32 right, int useConstantPool = 0)
+ Jump branch32(Condition cond, RegisterID left, TrustedImm32 right, int useConstantPool = 0)
{
if (right.m_isPointer) {
m_assembler.ldr_un_imm(ARMRegisters::S0, right.m_value);
@@ -426,19 +426,19 @@ public:
return branch32(cond, ARMRegisters::S1, right);
}
- Jump branch32(Condition cond, Address left, Imm32 right)
+ Jump branch32(Condition cond, Address left, TrustedImm32 right)
{
load32(left, ARMRegisters::S1);
return branch32(cond, ARMRegisters::S1, right);
}
- Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right)
{
load32(left, ARMRegisters::S1);
return branch32(cond, ARMRegisters::S1, right);
}
- Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right)
{
load32WithUnalignedHalfWords(left, ARMRegisters::S1);
return branch32(cond, ARMRegisters::S1, right);
@@ -453,7 +453,7 @@ public:
return jump();
}
- Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch16(Condition cond, BaseIndex left, TrustedImm32 right)
{
load16(left, ARMRegisters::S0);
move(right, ARMRegisters::S1);
@@ -461,7 +461,7 @@ public:
return m_assembler.jmp(ARMCondition(cond));
}
- Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
load8(address, ARMRegisters::S1);
return branchTest32(cond, ARMRegisters::S1, mask);
@@ -474,7 +474,7 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
- Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
ARMWord w = m_assembler.getImm(mask.m_value, ARMRegisters::S0, true);
@@ -485,13 +485,13 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
- Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
load32(address, ARMRegisters::S1);
return branchTest32(cond, ARMRegisters::S1, mask);
}
- Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
load32(address, ARMRegisters::S1);
return branchTest32(cond, ARMRegisters::S1, mask);
@@ -519,7 +519,7 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
- Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchAdd32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
add32(imm, dest);
@@ -548,7 +548,7 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
- Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+ Jump branchMul32(Condition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
if (cond == Overflow) {
@@ -568,7 +568,7 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
- Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchSub32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
sub32(imm, dest);
@@ -628,7 +628,7 @@ public:
m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
}
- void set32Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set32Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
m_assembler.mov_r(dest, ARMAssembler::getOp2(0));
@@ -648,13 +648,13 @@ public:
set32Compare32(cond, ARMRegisters::S1, right, dest);
}
- void set8Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set8Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
// ARM doesn't have byte registers
set32Compare32(cond, left, right, dest);
}
- void set32Test32(Condition cond, RegisterID reg, Imm32 mask, RegisterID dest)
+ void set32Test32(Condition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
{
if (mask.m_value == -1)
m_assembler.cmp_r(0, reg);
@@ -664,24 +664,24 @@ public:
m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
}
- void set32Test32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test32(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
load32(address, ARMRegisters::S1);
set32Test32(cond, ARMRegisters::S1, mask, dest);
}
- void set32Test8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test8(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
load8(address, ARMRegisters::S1);
set32Test32(cond, ARMRegisters::S1, mask, dest);
}
- void add32(Imm32 imm, RegisterID src, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
m_assembler.add_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
- void add32(Imm32 imm, AbsoluteAddress address)
+ void add32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
@@ -690,7 +690,7 @@ public:
m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
}
- void sub32(Imm32 imm, AbsoluteAddress address)
+ void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
@@ -699,7 +699,7 @@ public:
m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
}
- void load32(void* address, RegisterID dest)
+ void load32(const void* address, RegisterID dest)
{
m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
m_assembler.dtr_u(true, dest, ARMRegisters::S0, 0);
@@ -711,7 +711,7 @@ public:
return branch32(cond, ARMRegisters::S1, right);
}
- Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+ Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right)
{
load32(left.m_ptr, ARMRegisters::S1);
return branch32(cond, ARMRegisters::S1, right);
@@ -748,21 +748,21 @@ public:
return Call::fromTailJump(oldJump);
}
- DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+ DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
{
DataLabelPtr dataLabel(this);
m_assembler.ldr_un_imm(dest, reinterpret_cast<ARMWord>(initialValue.m_value));
return dataLabel;
}
- Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S1);
Jump jump = branch32(cond, left, ARMRegisters::S1, true);
return jump;
}
- Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
load32(left, ARMRegisters::S1);
dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S0);
@@ -770,7 +770,7 @@ public:
return jump;
}
- DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+ DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
{
DataLabelPtr dataLabel = moveWithPatch(initialValue, ARMRegisters::S1);
store32(ARMRegisters::S1, address);
@@ -779,7 +779,7 @@ public:
DataLabelPtr storePtrWithPatch(ImplicitAddress address)
{
- return storePtrWithPatch(ImmPtr(0), address);
+ return storePtrWithPatch(TrustedImmPtr(0), address);
}
// Floating point operators
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 450a34c..84e0a5e 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -139,7 +139,7 @@ public:
// Integer arithmetic operations:
//
// Operations are typically two operand - operation(source, srcDst)
- // For many operations the source may be an Imm32, the srcDst operand
+ // For many operations the source may be an TrustedImm32, the srcDst operand
// may often be a memory location (explictly described using an Address
// object).
@@ -148,12 +148,12 @@ public:
m_assembler.add(dest, dest, src);
}
- void add32(Imm32 imm, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID dest)
{
add32(imm, dest, dest);
}
- void add32(Imm32 imm, RegisterID src, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
if (armImm.isValid())
@@ -164,7 +164,7 @@ public:
}
}
- void add32(Imm32 imm, Address address)
+ void add32(TrustedImm32 imm, Address address)
{
load32(address, dataTempRegister);
@@ -187,7 +187,7 @@ public:
add32(dataTempRegister, dest);
}
- void add32(Imm32 imm, AbsoluteAddress address)
+ void add32(TrustedImm32 imm, AbsoluteAddress address)
{
load32(address.m_ptr, dataTempRegister);
@@ -209,7 +209,7 @@ public:
m_assembler.ARM_and(dest, dest, src);
}
- void and32(Imm32 imm, RegisterID dest)
+ void and32(TrustedImm32 imm, RegisterID dest)
{
ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
if (armImm.isValid())
@@ -235,7 +235,7 @@ public:
m_assembler.lsl(dest, dest, dataTempRegister);
}
- void lshift32(Imm32 imm, RegisterID dest)
+ void lshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.lsl(dest, dest, imm.m_value & 0x1f);
}
@@ -245,7 +245,7 @@ public:
m_assembler.smull(dest, dataTempRegister, dest, src);
}
- void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+ void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
move(imm, dataTempRegister);
m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
@@ -266,7 +266,7 @@ public:
m_assembler.orr(dest, dest, src);
}
- void or32(Imm32 imm, RegisterID dest)
+ void or32(TrustedImm32 imm, RegisterID dest)
{
ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
if (armImm.isValid())
@@ -287,7 +287,7 @@ public:
m_assembler.asr(dest, dest, dataTempRegister);
}
- void rshift32(Imm32 imm, RegisterID dest)
+ void rshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.asr(dest, dest, imm.m_value & 0x1f);
}
@@ -302,7 +302,7 @@ public:
m_assembler.lsr(dest, dest, dataTempRegister);
}
- void urshift32(Imm32 imm, RegisterID dest)
+ void urshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.lsr(dest, dest, imm.m_value & 0x1f);
}
@@ -312,7 +312,7 @@ public:
m_assembler.sub(dest, dest, src);
}
- void sub32(Imm32 imm, RegisterID dest)
+ void sub32(TrustedImm32 imm, RegisterID dest)
{
ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
if (armImm.isValid())
@@ -323,7 +323,7 @@ public:
}
}
- void sub32(Imm32 imm, Address address)
+ void sub32(TrustedImm32 imm, Address address)
{
load32(address, dataTempRegister);
@@ -346,7 +346,7 @@ public:
sub32(dataTempRegister, dest);
}
- void sub32(Imm32 imm, AbsoluteAddress address)
+ void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
load32(address.m_ptr, dataTempRegister);
@@ -368,7 +368,7 @@ public:
m_assembler.eor(dest, dest, src);
}
- void xor32(Imm32 imm, RegisterID dest)
+ void xor32(TrustedImm32 imm, RegisterID dest)
{
ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
if (armImm.isValid())
@@ -383,7 +383,7 @@ public:
// Memory access operations:
//
// Loads are of the form load(address, destination) and stores of the form
- // store(source, address). The source for a store may be an Imm32. Address
+ // store(source, address). The source for a store may be an TrustedImm32. Address
// operand objects to loads and store will be implicitly constructed if a
// register is passed.
@@ -460,9 +460,9 @@ public:
load32(setupArmAddress(address), dest);
}
- void load32(void* address, RegisterID dest)
+ void load32(const void* address, RegisterID dest)
{
- move(ImmPtr(address), addressTempRegister);
+ move(TrustedImmPtr(address), addressTempRegister);
m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
}
@@ -473,7 +473,7 @@ public:
DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
{
- DataLabel32 label = moveWithPatch(Imm32(address.offset), dataTempRegister);
+ DataLabel32 label = moveWithPatch(TrustedImm32(address.offset), dataTempRegister);
load32(ArmAddress(address.base, dataTempRegister), dest);
return label;
}
@@ -489,14 +489,14 @@ public:
if (armImm.isValid())
m_assembler.ldrh(dest, address.base, armImm);
else {
- move(Imm32(address.offset), dataTempRegister);
+ move(TrustedImm32(address.offset), dataTempRegister);
m_assembler.ldrh(dest, address.base, dataTempRegister);
}
}
DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
{
- DataLabel32 label = moveWithPatch(Imm32(address.offset), dataTempRegister);
+ DataLabel32 label = moveWithPatch(TrustedImm32(address.offset), dataTempRegister);
store32(src, ArmAddress(address.base, dataTempRegister));
return label;
}
@@ -511,19 +511,19 @@ public:
store32(src, setupArmAddress(address));
}
- void store32(Imm32 imm, ImplicitAddress address)
+ void store32(TrustedImm32 imm, ImplicitAddress address)
{
move(imm, dataTempRegister);
store32(dataTempRegister, setupArmAddress(address));
}
- void store32(RegisterID src, void* address)
+ void store32(RegisterID src, const void* address)
{
- move(ImmPtr(address), addressTempRegister);
+ move(TrustedImmPtr(address), addressTempRegister);
m_assembler.str(src, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
}
- void store32(Imm32 imm, void* address)
+ void store32(TrustedImm32 imm, const void* address)
{
move(imm, dataTempRegister);
store32(dataTempRegister, address);
@@ -558,7 +558,7 @@ public:
// Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
- add32(Imm32(offset), base, addressTempRegister);
+ add32(TrustedImm32(offset), base, addressTempRegister);
base = addressTempRegister;
offset = 0;
}
@@ -568,7 +568,7 @@ public:
void loadDouble(const void* address, FPRegisterID dest)
{
- move(ImmPtr(address), addressTempRegister);
+ move(TrustedImmPtr(address), addressTempRegister);
m_assembler.vldr(dest, addressTempRegister, 0);
}
@@ -579,7 +579,7 @@ public:
// Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
- add32(Imm32(offset), base, addressTempRegister);
+ add32(TrustedImm32(offset), base, addressTempRegister);
base = addressTempRegister;
offset = 0;
}
@@ -748,7 +748,7 @@ public:
push(dataTempRegister);
}
- void push(Imm32 imm)
+ void push(TrustedImm32 imm)
{
move(imm, dataTempRegister);
push(dataTempRegister);
@@ -758,7 +758,7 @@ public:
//
// Move values in registers.
- void move(Imm32 imm, RegisterID dest)
+ void move(TrustedImm32 imm, RegisterID dest)
{
uint32_t value = imm.m_value;
@@ -784,9 +784,9 @@ public:
m_assembler.mov(dest, src);
}
- void move(ImmPtr imm, RegisterID dest)
+ void move(TrustedImmPtr imm, RegisterID dest)
{
- move(Imm32(imm), dest);
+ move(TrustedImm32(imm), dest);
}
void swap(RegisterID reg1, RegisterID reg2)
@@ -821,7 +821,7 @@ public:
// used (representing the names 'below' and 'above').
//
// Operands to the comparision are provided in the expected order, e.g.
- // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+ // jle32(reg1, TrustedImm32(5)) will branch if the value held in reg1, when
// treated as a signed 32bit value, is less than or equal to 5.
//
// jz and jnz test whether the first operand is equal to zero, and take
@@ -829,7 +829,7 @@ public:
private:
// Should we be using TEQ for equal/not-equal?
- void compare32(RegisterID left, Imm32 right)
+ void compare32(RegisterID left, TrustedImm32 right)
{
int32_t imm = right.m_value;
if (!imm)
@@ -841,13 +841,13 @@ private:
else if ((armImm = ARMThumbImmediate::makeEncodedImm(-imm)).isValid())
m_assembler.cmn(left, armImm);
else {
- move(Imm32(imm), dataTempRegister);
+ move(TrustedImm32(imm), dataTempRegister);
m_assembler.cmp(left, dataTempRegister);
}
}
}
- void test32(RegisterID reg, Imm32 mask)
+ void test32(RegisterID reg, TrustedImm32 mask)
{
int32_t imm = mask.m_value;
@@ -871,7 +871,7 @@ public:
return Jump(makeBranch(cond));
}
- Jump branch32(Condition cond, RegisterID left, Imm32 right)
+ Jump branch32(Condition cond, RegisterID left, TrustedImm32 right)
{
compare32(left, right);
return Jump(makeBranch(cond));
@@ -889,21 +889,21 @@ public:
return branch32(cond, dataTempRegister, right);
}
- Jump branch32(Condition cond, Address left, Imm32 right)
+ Jump branch32(Condition cond, Address left, TrustedImm32 right)
{
// use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
load32(left, addressTempRegister);
return branch32(cond, addressTempRegister, right);
}
- Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right)
{
// use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
load32(left, addressTempRegister);
return branch32(cond, addressTempRegister, right);
}
- Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right)
{
// use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
load32WithUnalignedHalfWords(left, addressTempRegister);
@@ -916,7 +916,7 @@ public:
return branch32(cond, dataTempRegister, right);
}
- Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+ Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right)
{
// use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
load32(left.m_ptr, addressTempRegister);
@@ -931,21 +931,21 @@ public:
return branch32(cond, dataTempRegister, addressTempRegister);
}
- Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch16(Condition cond, BaseIndex left, TrustedImm32 right)
{
// use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
load16(left, addressTempRegister);
m_assembler.lsl(addressTempRegister, addressTempRegister, 16);
- return branch32(cond, addressTempRegister, Imm32(right.m_value << 16));
+ return branch32(cond, addressTempRegister, TrustedImm32(right.m_value << 16));
}
- Jump branch8(Condition cond, RegisterID left, Imm32 right)
+ Jump branch8(Condition cond, RegisterID left, TrustedImm32 right)
{
compare32(left, right);
return Jump(makeBranch(cond));
}
- Jump branch8(Condition cond, Address left, Imm32 right)
+ Jump branch8(Condition cond, Address left, TrustedImm32 right)
{
// use addressTempRegister incase the branch8 we call uses dataTempRegister. :-/
load8(left, addressTempRegister);
@@ -959,14 +959,14 @@ public:
return Jump(makeBranch(cond));
}
- Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
test32(reg, mask);
return Jump(makeBranch(cond));
}
- Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
// use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
@@ -974,7 +974,7 @@ public:
return branchTest32(cond, addressTempRegister, mask);
}
- Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
// use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
@@ -982,14 +982,14 @@ public:
return branchTest32(cond, addressTempRegister, mask);
}
- Jump branchTest8(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
test32(reg, mask);
return Jump(makeBranch(cond));
}
- Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
// use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/
@@ -1032,7 +1032,7 @@ public:
return Jump(makeBranch(cond));
}
- Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchAdd32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
@@ -1053,7 +1053,7 @@ public:
return branch32(NotEqual, addressTempRegister, dataTempRegister);
}
- Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+ Jump branchMul32(Condition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
{
ASSERT_UNUSED(cond, cond == Overflow);
move(imm, dataTempRegister);
@@ -1076,7 +1076,7 @@ public:
return Jump(makeBranch(cond));
}
- Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchSub32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
@@ -1111,13 +1111,13 @@ public:
Call nearCall()
{
- moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::LinkableNear);
}
Call call()
{
- moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable);
}
@@ -1151,7 +1151,7 @@ public:
set32Compare32(cond, dataTempRegister, right, dest);
}
- void set32Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set32Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
compare32(left, right);
m_assembler.it(armV7Condition(cond), false);
@@ -1169,7 +1169,7 @@ public:
set32Compare32(cond, left, right, dest);
}
- void set8Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set8Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
set32Compare32(cond, left, right, dest);
}
@@ -1178,7 +1178,7 @@ public:
// The mask should be optional... paerhaps the argument order should be
// dest-src, operations always have a dest? ... possibly not true, considering
// asm ops like test, or pseudo ops like pop().
- void set32Test32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test32(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
load32(address, dataTempRegister);
test32(dataTempRegister, mask);
@@ -1187,7 +1187,7 @@ public:
m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
}
- void set32Test8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test8(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
load8(address, dataTempRegister);
test32(dataTempRegister, mask);
@@ -1196,44 +1196,44 @@ public:
m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
}
- DataLabel32 moveWithPatch(Imm32 imm, RegisterID dst)
+ DataLabel32 moveWithPatch(TrustedImm32 imm, RegisterID dst)
{
moveFixedWidthEncoding(imm, dst);
return DataLabel32(this);
}
- DataLabelPtr moveWithPatch(ImmPtr imm, RegisterID dst)
+ DataLabelPtr moveWithPatch(TrustedImmPtr imm, RegisterID dst)
{
- moveFixedWidthEncoding(Imm32(imm), dst);
+ moveFixedWidthEncoding(TrustedImm32(imm), dst);
return DataLabelPtr(this);
}
- Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
return branch32(cond, left, dataTempRegister);
}
- Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
load32(left, addressTempRegister);
dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
return branch32(cond, addressTempRegister, dataTempRegister);
}
- DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+ DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
{
DataLabelPtr label = moveWithPatch(initialValue, dataTempRegister);
store32(dataTempRegister, address);
return label;
}
- DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(ImmPtr(0), address); }
+ DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(TrustedImmPtr(0), address); }
Call tailRecursiveCall()
{
// Like a normal call, but don't link.
- moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable);
}
@@ -1257,14 +1257,14 @@ protected:
ARMv7Assembler::JmpSrc makeJump()
{
- moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition);
}
ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond)
{
m_assembler.it(cond, true, true);
- moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond);
}
ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); }
@@ -1277,7 +1277,7 @@ protected:
if (imm.isValid())
m_assembler.add(addressTempRegister, address.base, imm);
else {
- move(Imm32(address.offset), addressTempRegister);
+ move(TrustedImm32(address.offset), addressTempRegister);
m_assembler.add(addressTempRegister, addressTempRegister, address.base);
}
@@ -1291,7 +1291,7 @@ protected:
if ((address.offset >= -0xff) && (address.offset <= 0xfff))
return ArmAddress(address.base, address.offset);
- move(Imm32(address.offset), addressTempRegister);
+ move(TrustedImm32(address.offset), addressTempRegister);
return ArmAddress(address.base, addressTempRegister);
}
@@ -1300,7 +1300,7 @@ protected:
if ((address.offset >= -0xff) && (address.offset <= 0xfff))
return ArmAddress(address.base, address.offset);
- move(Imm32(address.offset), addressTempRegister);
+ move(TrustedImm32(address.offset), addressTempRegister);
return ArmAddress(address.base, addressTempRegister);
}
@@ -1313,14 +1313,14 @@ protected:
if (imm.isValid())
m_assembler.add(addressTempRegister, address.base, imm);
else {
- move(Imm32(address.offset), addressTempRegister);
+ move(TrustedImm32(address.offset), addressTempRegister);
m_assembler.add(addressTempRegister, addressTempRegister, address.base);
}
return addressTempRegister;
}
- void moveFixedWidthEncoding(Imm32 imm, RegisterID dst)
+ void moveFixedWidthEncoding(TrustedImm32 imm, RegisterID dst)
{
uint32_t value = imm.m_value;
m_assembler.movT3(dst, ARMThumbImmediate::makeUInt16(value & 0xffff));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
index 543b0fa..2183b22 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
@@ -65,15 +65,47 @@ public:
{
}
+ template<typename returnType>
+ FunctionPtr(returnType(*value)())
+ : m_value((void*)value)
+ {
+ ASSERT_VALID_CODE_POINTER(m_value);
+ }
+
+ template<typename returnType, typename argType1>
+ FunctionPtr(returnType(*value)(argType1))
+ : m_value((void*)value)
+ {
+ ASSERT_VALID_CODE_POINTER(m_value);
+ }
+
+ template<typename returnType, typename argType1, typename argType2>
+ FunctionPtr(returnType(*value)(argType1, argType2))
+ : m_value((void*)value)
+ {
+ ASSERT_VALID_CODE_POINTER(m_value);
+ }
+
+ template<typename returnType, typename argType1, typename argType2, typename argType3>
+ FunctionPtr(returnType(*value)(argType1, argType2, argType3))
+ : m_value((void*)value)
+ {
+ ASSERT_VALID_CODE_POINTER(m_value);
+ }
+
+ template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
+ FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4))
+ : m_value((void*)value)
+ {
+ ASSERT_VALID_CODE_POINTER(m_value);
+ }
+
template<typename FunctionType>
explicit FunctionPtr(FunctionType* value)
-#if COMPILER(RVCT)
- // RVTC compiler needs C-style cast as it fails with the following error
- // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers
- : m_value((void*)(value))
-#else
- : m_value(reinterpret_cast<void*>(value))
-#endif
+ // Using a C-ctyle cast here to avoid compiler error on RVTC:
+ // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers
+ // (I guess on RVTC function pointers have a different constness to GCC/MSVC?)
+ : m_value((void*)value)
{
ASSERT_VALID_CODE_POINTER(m_value);
}
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 4697dfc..1bcec38 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -95,7 +95,7 @@ public:
// Integer arithmetic operations:
//
// Operations are typically two operand - operation(source, srcDst)
- // For many operations the source may be an Imm32, the srcDst operand
+ // For many operations the source may be an TrustedImm32, the srcDst operand
// may often be a memory location (explictly described using an Address
// object).
@@ -104,12 +104,12 @@ public:
m_assembler.addu(dest, dest, src);
}
- void add32(Imm32 imm, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID dest)
{
add32(imm, dest, dest);
}
- void add32(Imm32 imm, RegisterID src, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
&& !m_fixedWidth) {
@@ -127,7 +127,7 @@ public:
}
}
- void add32(Imm32 imm, Address address)
+ void add32(TrustedImm32 imm, Address address)
{
if (address.offset >= -32768 && address.offset <= 32767
&& !m_fixedWidth) {
@@ -207,7 +207,7 @@ public:
}
}
- void add32(Imm32 imm, AbsoluteAddress address)
+ void add32(TrustedImm32 imm, AbsoluteAddress address)
{
/*
li addrTemp, address
@@ -216,7 +216,7 @@ public:
addu dataTemp, dataTemp, immTemp
sw dataTemp, 0(addrTemp)
*/
- move(ImmPtr(address.m_ptr), addrTempRegister);
+ move(TrustedImmPtr(address.m_ptr), addrTempRegister);
m_assembler.lw(dataTempRegister, addrTempRegister, 0);
if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
&& !m_fixedWidth)
@@ -233,7 +233,7 @@ public:
m_assembler.andInsn(dest, dest, src);
}
- void and32(Imm32 imm, RegisterID dest)
+ void and32(TrustedImm32 imm, RegisterID dest)
{
if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
move(MIPSRegisters::zero, dest);
@@ -250,7 +250,7 @@ public:
}
}
- void lshift32(Imm32 imm, RegisterID dest)
+ void lshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.sll(dest, dest, imm.m_value);
}
@@ -265,7 +265,7 @@ public:
m_assembler.mul(dest, dest, src);
}
- void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+ void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
move(MIPSRegisters::zero, dest);
@@ -296,7 +296,7 @@ public:
m_assembler.orInsn(dest, dest, src);
}
- void or32(Imm32 imm, RegisterID dest)
+ void or32(TrustedImm32 imm, RegisterID dest)
{
if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
return;
@@ -320,7 +320,7 @@ public:
m_assembler.srav(dest, dest, shiftAmount);
}
- void rshift32(Imm32 imm, RegisterID dest)
+ void rshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.sra(dest, dest, imm.m_value);
}
@@ -330,7 +330,7 @@ public:
m_assembler.srlv(dest, dest, shiftAmount);
}
- void urshift32(Imm32 imm, RegisterID dest)
+ void urshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.srl(dest, dest, imm.m_value);
}
@@ -340,7 +340,7 @@ public:
m_assembler.subu(dest, dest, src);
}
- void sub32(Imm32 imm, RegisterID dest)
+ void sub32(TrustedImm32 imm, RegisterID dest)
{
if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
&& !m_fixedWidth) {
@@ -358,7 +358,7 @@ public:
}
}
- void sub32(Imm32 imm, Address address)
+ void sub32(TrustedImm32 imm, Address address)
{
if (address.offset >= -32768 && address.offset <= 32767
&& !m_fixedWidth) {
@@ -413,7 +413,7 @@ public:
sub32(dataTempRegister, dest);
}
- void sub32(Imm32 imm, AbsoluteAddress address)
+ void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
/*
li addrTemp, address
@@ -422,7 +422,7 @@ public:
subu dataTemp, dataTemp, immTemp
sw dataTemp, 0(addrTemp)
*/
- move(ImmPtr(address.m_ptr), addrTempRegister);
+ move(TrustedImmPtr(address.m_ptr), addrTempRegister);
m_assembler.lw(dataTempRegister, addrTempRegister, 0);
if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
@@ -441,7 +441,7 @@ public:
m_assembler.xorInsn(dest, dest, src);
}
- void xor32(Imm32 imm, RegisterID dest)
+ void xor32(TrustedImm32 imm, RegisterID dest)
{
/*
li immTemp, imm
@@ -459,7 +459,7 @@ public:
// Memory access operations:
//
// Loads are of the form load(address, destination) and stores of the form
- // store(source, address). The source for a store may be an Imm32. Address
+ // store(source, address). The source for a store may be an TrustedImm32. Address
// operand objects to loads and store will be implicitly constructed if a
// register is passed.
@@ -581,13 +581,13 @@ public:
}
}
- void load32(void* address, RegisterID dest)
+ void load32(const void* address, RegisterID dest)
{
/*
li addrTemp, address
lw dest, 0(addrTemp)
*/
- move(ImmPtr(address), addrTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
m_assembler.lw(dest, addrTempRegister, 0);
}
@@ -601,7 +601,7 @@ public:
lw dest, 0(addrTemp)
*/
DataLabel32 dataLabel(this);
- move(Imm32(address.offset), addrTempRegister);
+ move(TrustedImm32(address.offset), addrTempRegister);
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
m_assembler.lw(dest, addrTempRegister, 0);
m_fixedWidth = false;
@@ -666,7 +666,7 @@ public:
sw src, 0(addrTemp)
*/
DataLabel32 dataLabel(this);
- move(Imm32(address.offset), addrTempRegister);
+ move(TrustedImm32(address.offset), addrTempRegister);
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
m_assembler.sw(src, addrTempRegister, 0);
m_fixedWidth = false;
@@ -719,7 +719,7 @@ public:
}
}
- void store32(Imm32 imm, ImplicitAddress address)
+ void store32(TrustedImm32 imm, ImplicitAddress address)
{
if (address.offset >= -32768 && address.offset <= 32767
&& !m_fixedWidth) {
@@ -749,17 +749,17 @@ public:
}
}
- void store32(RegisterID src, void* address)
+ void store32(RegisterID src, const void* address)
{
/*
li addrTemp, address
sw src, 0(addrTemp)
*/
- move(ImmPtr(address), addrTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
m_assembler.sw(src, addrTempRegister, 0);
}
- void store32(Imm32 imm, void* address)
+ void store32(TrustedImm32 imm, const void* address)
{
/*
li immTemp, imm
@@ -767,11 +767,11 @@ public:
sw src, 0(addrTemp)
*/
if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth) {
- move(ImmPtr(address), addrTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
m_assembler.sw(MIPSRegisters::zero, addrTempRegister, 0);
} else {
move(imm, immTempRegister);
- move(ImmPtr(address), addrTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
m_assembler.sw(immTempRegister, addrTempRegister, 0);
}
}
@@ -831,7 +831,7 @@ public:
push(dataTempRegister);
}
- void push(Imm32 imm)
+ void push(TrustedImm32 imm)
{
move(imm, immTempRegister);
push(immTempRegister);
@@ -841,7 +841,7 @@ public:
//
// Move values in registers.
- void move(Imm32 imm, RegisterID dest)
+ void move(TrustedImm32 imm, RegisterID dest)
{
if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
move(MIPSRegisters::zero, dest);
@@ -858,9 +858,9 @@ public:
m_assembler.move(dest, src);
}
- void move(ImmPtr imm, RegisterID dest)
+ void move(TrustedImmPtr imm, RegisterID dest)
{
- move(Imm32(imm), dest);
+ move(TrustedImm32(imm), dest);
}
void swap(RegisterID reg1, RegisterID reg2)
@@ -894,13 +894,13 @@ public:
// used (representing the names 'below' and 'above').
//
// Operands to the comparision are provided in the expected order, e.g.
- // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+ // jle32(reg1, TrustedImm32(5)) will branch if the value held in reg1, when
// treated as a signed 32bit value, is less than or equal to 5.
//
// jz and jnz test whether the first operand is equal to zero, and take
// an optional second operand of a mask under which to perform the test.
- Jump branch8(Condition cond, Address left, Imm32 right)
+ Jump branch8(Condition cond, Address left, TrustedImm32 right)
{
// Make sure the immediate value is unsigned 8 bits.
ASSERT(!(right.m_value & 0xFFFFFF00));
@@ -985,7 +985,7 @@ public:
return Jump();
}
- Jump branch32(Condition cond, RegisterID left, Imm32 right)
+ Jump branch32(Condition cond, RegisterID left, TrustedImm32 right)
{
move(right, immTempRegister);
return branch32(cond, left, immTempRegister);
@@ -1003,14 +1003,14 @@ public:
return branch32(cond, dataTempRegister, right);
}
- Jump branch32(Condition cond, Address left, Imm32 right)
+ Jump branch32(Condition cond, Address left, TrustedImm32 right)
{
load32(left, dataTempRegister);
move(right, immTempRegister);
return branch32(cond, dataTempRegister, immTempRegister);
}
- Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right)
{
load32(left, dataTempRegister);
// Be careful that the previous load32() uses immTempRegister.
@@ -1019,7 +1019,7 @@ public:
return branch32(cond, dataTempRegister, immTempRegister);
}
- Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right)
{
load32WithUnalignedHalfWords(left, dataTempRegister);
// Be careful that the previous load32WithUnalignedHalfWords()
@@ -1035,7 +1035,7 @@ public:
return branch32(cond, dataTempRegister, right);
}
- Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+ Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right)
{
load32(left.m_ptr, dataTempRegister);
move(right, immTempRegister);
@@ -1048,7 +1048,7 @@ public:
return branch32(cond, dataTempRegister, right);
}
- Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch16(Condition cond, BaseIndex left, TrustedImm32 right)
{
ASSERT(!(right.m_value & 0xFFFF0000));
load16(left, dataTempRegister);
@@ -1067,7 +1067,7 @@ public:
return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
}
- Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
ASSERT((cond == Zero) || (cond == NonZero));
if (mask.m_value == -1 && !m_fixedWidth) {
@@ -1079,19 +1079,19 @@ public:
return branchTest32(cond, reg, immTempRegister);
}
- Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
load32(address, dataTempRegister);
return branchTest32(cond, dataTempRegister, mask);
}
- Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
load32(address, dataTempRegister);
return branchTest32(cond, dataTempRegister, mask);
}
- Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
load8(address, dataTempRegister);
return branchTest32(cond, dataTempRegister, mask);
@@ -1174,7 +1174,7 @@ public:
return Jump();
}
- Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchAdd32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
move(imm, immTempRegister);
return branchAdd32(cond, immTempRegister, dest);
@@ -1225,7 +1225,7 @@ public:
return Jump();
}
- Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+ Jump branchMul32(Condition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
{
move(imm, immTempRegister);
move(src, dest);
@@ -1279,7 +1279,7 @@ public:
return Jump();
}
- Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchSub32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
move(imm, immTempRegister);
return branchSub32(cond, immTempRegister, dest);
@@ -1360,7 +1360,7 @@ public:
set32Compare32(cond, left, right, dest);
}
- void set8Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set8Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
move(right, immTempRegister);
set32Compare32(cond, left, immTempRegister, dest);
@@ -1417,13 +1417,13 @@ public:
}
}
- void set32Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set32Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
move(right, immTempRegister);
set32Compare32(cond, left, immTempRegister, dest);
}
- void set32Test8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test8(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
ASSERT((cond == Zero) || (cond == NonZero));
load8(address, dataTempRegister);
@@ -1443,7 +1443,7 @@ public:
}
}
- void set32Test32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test32(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
ASSERT((cond == Zero) || (cond == NonZero));
load32(address, dataTempRegister);
@@ -1463,7 +1463,7 @@ public:
}
}
- DataLabel32 moveWithPatch(Imm32 imm, RegisterID dest)
+ DataLabel32 moveWithPatch(TrustedImm32 imm, RegisterID dest)
{
m_fixedWidth = true;
DataLabel32 label(this);
@@ -1472,7 +1472,7 @@ public:
return label;
}
- DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+ DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
{
m_fixedWidth = true;
DataLabelPtr label(this);
@@ -1481,7 +1481,7 @@ public:
return label;
}
- Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
m_fixedWidth = true;
dataLabel = moveWithPatch(initialRightValue, immTempRegister);
@@ -1490,7 +1490,7 @@ public:
return temp;
}
- Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
m_fixedWidth = true;
load32(left, dataTempRegister);
@@ -1500,7 +1500,7 @@ public:
return temp;
}
- DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+ DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
{
m_fixedWidth = true;
DataLabelPtr dataLabel = moveWithPatch(initialValue, dataTempRegister);
@@ -1511,14 +1511,14 @@ public:
DataLabelPtr storePtrWithPatch(ImplicitAddress address)
{
- return storePtrWithPatch(ImmPtr(0), address);
+ return storePtrWithPatch(TrustedImmPtr(0), address);
}
Call tailRecursiveCall()
{
// Like a normal call, but don't update the returned address register
m_fixedWidth = true;
- move(Imm32(0), MIPSRegisters::t9);
+ move(TrustedImm32(0), MIPSRegisters::t9);
m_assembler.jr(MIPSRegisters::t9);
m_assembler.nop();
m_fixedWidth = false;
@@ -1540,7 +1540,7 @@ public:
lwc1 dest, 0(addrTemp)
lwc1 dest+1, 4(addrTemp)
*/
- move(Imm32(address.offset), addrTempRegister);
+ move(TrustedImm32(address.offset), addrTempRegister);
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
m_assembler.lwc1(dest, addrTempRegister, 0);
m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, 4);
@@ -1569,7 +1569,7 @@ public:
lwc1 dest, 0(addrTemp)
lwc1 dest+1, 4(addrTemp)
*/
- move(ImmPtr(address), addrTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
m_assembler.lwc1(dest, addrTempRegister, 0);
m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, 4);
#else
@@ -1577,7 +1577,7 @@ public:
li addrTemp, address
ldc1 dest, 0(addrTemp)
*/
- move(ImmPtr(address), addrTempRegister);
+ move(TrustedImmPtr(address), addrTempRegister);
m_assembler.ldc1(dest, addrTempRegister, 0);
#endif
}
@@ -1592,7 +1592,7 @@ public:
swc1 dest, 0(addrTemp)
swc1 dest+1, 4(addrTemp)
*/
- move(Imm32(address.offset), addrTempRegister);
+ move(TrustedImm32(address.offset), addrTempRegister);
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
m_assembler.swc1(src, addrTempRegister, 0);
m_assembler.swc1(FPRegisterID(src + 1), addrTempRegister, 4);
@@ -1779,7 +1779,7 @@ public:
{
m_assembler.truncwd(fpTempRegister, src);
m_assembler.mfc1(dest, fpTempRegister);
- return branch32(Equal, dest, Imm32(0x7fffffff));
+ return branch32(Equal, dest, TrustedImm32(0x7fffffff));
}
// Convert 'src' to an integer, and places the resulting 'dest'.
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
index 92da5f0..b180e2b 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -52,32 +52,32 @@ public:
using MacroAssemblerX86Common::loadDouble;
using MacroAssemblerX86Common::convertInt32ToDouble;
- void add32(Imm32 imm, RegisterID src, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
m_assembler.leal_mr(imm.m_value, src, dest);
}
- void add32(Imm32 imm, AbsoluteAddress address)
+ void add32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.addl_im(imm.m_value, address.m_ptr);
}
- void addWithCarry32(Imm32 imm, AbsoluteAddress address)
+ void addWithCarry32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.adcl_im(imm.m_value, address.m_ptr);
}
- void and32(Imm32 imm, AbsoluteAddress address)
+ void and32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.andl_im(imm.m_value, address.m_ptr);
}
- void or32(Imm32 imm, AbsoluteAddress address)
+ void or32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.orl_im(imm.m_value, address.m_ptr);
}
- void sub32(Imm32 imm, AbsoluteAddress address)
+ void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.subl_im(imm.m_value, address.m_ptr);
}
@@ -98,7 +98,7 @@ public:
m_assembler.cvtsi2sd_mr(src.m_ptr, dest);
}
- void store32(Imm32 imm, void* address)
+ void store32(TrustedImm32 imm, void* address)
{
m_assembler.movl_i32m(imm.m_value, address);
}
@@ -114,7 +114,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+ Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right)
{
m_assembler.cmpl_im(right.m_value, left.m_ptr);
return Jump(m_assembler.jCC(x86Condition(cond)));
@@ -136,27 +136,27 @@ public:
}
- DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+ DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
{
m_assembler.movl_i32r(initialValue.asIntptr(), dest);
return DataLabelPtr(this);
}
- Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left);
dataLabel = DataLabelPtr(this);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base);
dataLabel = DataLabelPtr(this);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+ DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
{
m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base);
return DataLabelPtr(this);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index a02074c..f5829dd 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -83,7 +83,7 @@ public:
// Integer arithmetic operations:
//
// Operations are typically two operand - operation(source, srcDst)
- // For many operations the source may be an Imm32, the srcDst operand
+ // For many operations the source may be an TrustedImm32, the srcDst operand
// may often be a memory location (explictly described using an Address
// object).
@@ -92,12 +92,12 @@ public:
m_assembler.addl_rr(src, dest);
}
- void add32(Imm32 imm, Address address)
+ void add32(TrustedImm32 imm, Address address)
{
m_assembler.addl_im(imm.m_value, address.offset, address.base);
}
- void add32(Imm32 imm, RegisterID dest)
+ void add32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.addl_ir(imm.m_value, dest);
}
@@ -117,7 +117,7 @@ public:
m_assembler.andl_rr(src, dest);
}
- void and32(Imm32 imm, RegisterID dest)
+ void and32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.andl_ir(imm.m_value, dest);
}
@@ -132,36 +132,64 @@ public:
m_assembler.andl_mr(src.offset, src.base, dest);
}
- void and32(Imm32 imm, Address address)
+ void and32(TrustedImm32 imm, Address address)
{
m_assembler.andl_im(imm.m_value, address.offset, address.base);
}
- void lshift32(Imm32 imm, RegisterID dest)
+ void and32(RegisterID op1, RegisterID op2, RegisterID dest)
{
- m_assembler.shll_i8r(imm.m_value, dest);
+ if (op1 == op2)
+ zeroExtend32ToPtr(op1, dest);
+ else if (op1 == dest)
+ and32(op2, dest);
+ else {
+ move(op2, dest);
+ and32(op1, dest);
+ }
}
-
+
+ void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ and32(imm, dest);
+ }
+
void lshift32(RegisterID shift_amount, RegisterID dest)
{
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86Registers::ecx) {
- swap(shift_amount, X86Registers::ecx);
+ ASSERT(shift_amount != dest);
- // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.shll_CLr(X86Registers::ecx);
- // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86Registers::ecx)
- m_assembler.shll_CLr(shift_amount);
- // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
- else
- m_assembler.shll_CLr(dest);
-
- swap(shift_amount, X86Registers::ecx);
- } else
+ if (shift_amount == X86Registers::ecx)
m_assembler.shll_CLr(dest);
+ else {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ // If we dest is ecx, then shift the swapped register!
+ swap(shift_amount, X86Registers::ecx);
+ m_assembler.shll_CLr(dest == X86Registers::ecx ? shift_amount : dest);
+ swap(shift_amount, X86Registers::ecx);
+ }
+ }
+
+ void lshift32(RegisterID src, RegisterID shift_amount, RegisterID dest)
+ {
+ ASSERT(shift_amount != dest);
+
+ if (src != dest)
+ move(src, dest);
+ lshift32(shift_amount, dest);
+ }
+
+ void lshift32(TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.shll_i8r(imm.m_value, dest);
+ }
+
+ void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ lshift32(imm, dest);
}
void mul32(RegisterID src, RegisterID dest)
@@ -174,7 +202,7 @@ public:
m_assembler.imull_mr(src.offset, src.base, dest);
}
- void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+ void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
m_assembler.imull_i32r(src, imm.m_value, dest);
}
@@ -204,7 +232,7 @@ public:
m_assembler.orl_rr(src, dest);
}
- void or32(Imm32 imm, RegisterID dest)
+ void or32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.orl_ir(imm.m_value, dest);
}
@@ -219,76 +247,114 @@ public:
m_assembler.orl_mr(src.offset, src.base, dest);
}
- void or32(Imm32 imm, Address address)
+ void or32(TrustedImm32 imm, Address address)
{
m_assembler.orl_im(imm.m_value, address.offset, address.base);
}
+ void or32(RegisterID op1, RegisterID op2, RegisterID dest)
+ {
+ if (op1 == op2)
+ zeroExtend32ToPtr(op1, dest);
+ else if (op1 == dest)
+ or32(op2, dest);
+ else {
+ move(op2, dest);
+ or32(op1, dest);
+ }
+ }
+
+ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ or32(imm, dest);
+ }
+
void rshift32(RegisterID shift_amount, RegisterID dest)
{
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86Registers::ecx) {
- swap(shift_amount, X86Registers::ecx);
+ ASSERT(shift_amount != dest);
- // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.sarl_CLr(X86Registers::ecx);
- // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86Registers::ecx)
- m_assembler.sarl_CLr(shift_amount);
- // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
- else
- m_assembler.sarl_CLr(dest);
-
- swap(shift_amount, X86Registers::ecx);
- } else
+ if (shift_amount == X86Registers::ecx)
m_assembler.sarl_CLr(dest);
+ else {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ // If we dest is ecx, then shift the swapped register!
+ swap(shift_amount, X86Registers::ecx);
+ m_assembler.sarl_CLr(dest == X86Registers::ecx ? shift_amount : dest);
+ swap(shift_amount, X86Registers::ecx);
+ }
+ }
+
+ void rshift32(RegisterID src, RegisterID shift_amount, RegisterID dest)
+ {
+ ASSERT(shift_amount != dest);
+
+ if (src != dest)
+ move(src, dest);
+ rshift32(shift_amount, dest);
}
- void rshift32(Imm32 imm, RegisterID dest)
+ void rshift32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.sarl_i8r(imm.m_value, dest);
}
+ void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ rshift32(imm, dest);
+ }
+
void urshift32(RegisterID shift_amount, RegisterID dest)
{
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86Registers::ecx) {
+ ASSERT(shift_amount != dest);
+
+ if (shift_amount == X86Registers::ecx)
+ m_assembler.shrl_CLr(dest);
+ else {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ // If we dest is ecx, then shift the swapped register!
swap(shift_amount, X86Registers::ecx);
-
- // E.g. transform "shrl %eax, %eax" -> "xchgl %eax, %ecx; shrl %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.shrl_CLr(X86Registers::ecx);
- // E.g. transform "shrl %eax, %ecx" -> "xchgl %eax, %ecx; shrl %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86Registers::ecx)
- m_assembler.shrl_CLr(shift_amount);
- // E.g. transform "shrl %eax, %ebx" -> "xchgl %eax, %ecx; shrl %ecx, %ebx; xchgl %eax, %ecx"
- else
- m_assembler.shrl_CLr(dest);
-
+ m_assembler.shrl_CLr(dest == X86Registers::ecx ? shift_amount : dest);
swap(shift_amount, X86Registers::ecx);
- } else
- m_assembler.shrl_CLr(dest);
+ }
}
-
- void urshift32(Imm32 imm, RegisterID dest)
+
+ void urshift32(RegisterID src, RegisterID shift_amount, RegisterID dest)
{
- m_assembler.shrl_i8r(imm.m_value, dest);
+ ASSERT(shift_amount != dest);
+
+ if (src != dest)
+ move(src, dest);
+ urshift32(shift_amount, dest);
}
+ void urshift32(TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.shrl_i8r(imm.m_value, dest);
+ }
+
+ void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ urshift32(imm, dest);
+ }
+
void sub32(RegisterID src, RegisterID dest)
{
m_assembler.subl_rr(src, dest);
}
- void sub32(Imm32 imm, RegisterID dest)
+ void sub32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.subl_ir(imm.m_value, dest);
}
- void sub32(Imm32 imm, Address address)
+ void sub32(TrustedImm32 imm, Address address)
{
m_assembler.subl_im(imm.m_value, address.offset, address.base);
}
@@ -309,12 +375,12 @@ public:
m_assembler.xorl_rr(src, dest);
}
- void xor32(Imm32 imm, Address dest)
+ void xor32(TrustedImm32 imm, Address dest)
{
m_assembler.xorl_im(imm.m_value, dest.offset, dest.base);
}
- void xor32(Imm32 imm, RegisterID dest)
+ void xor32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.xorl_ir(imm.m_value, dest);
}
@@ -329,6 +395,24 @@ public:
m_assembler.xorl_mr(src.offset, src.base, dest);
}
+ void xor32(RegisterID op1, RegisterID op2, RegisterID dest)
+ {
+ if (op1 == op2)
+ move(TrustedImm32(0), dest);
+ else if (op1 == dest)
+ xor32(op2, dest);
+ else {
+ move(op2, dest);
+ xor32(op1, dest);
+ }
+ }
+
+ void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ xor32(imm, dest);
+ }
+
void sqrtDouble(FPRegisterID src, FPRegisterID dst)
{
m_assembler.sqrtsd_rr(src, dst);
@@ -337,7 +421,7 @@ public:
// Memory access operations:
//
// Loads are of the form load(address, destination) and stores of the form
- // store(source, address). The source for a store may be an Imm32. Address
+ // store(source, address). The source for a store may be an TrustedImm32. Address
// operand objects to loads and store will be implicitly constructed if a
// register is passed.
@@ -388,7 +472,7 @@ public:
m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale);
}
- void store32(Imm32 imm, ImplicitAddress address)
+ void store32(TrustedImm32 imm, ImplicitAddress address)
{
m_assembler.movl_i32m(imm.m_value, address.offset, address.base);
}
@@ -398,6 +482,13 @@ public:
//
// Presently only supports SSE, not x87 floating point.
+ void moveDouble(FPRegisterID src, FPRegisterID dest)
+ {
+ ASSERT(isSSE2Present());
+ if (src != dest)
+ m_assembler.movsd_rr(src, dest);
+ }
+
void loadDouble(ImplicitAddress address, FPRegisterID dest)
{
ASSERT(isSSE2Present());
@@ -416,6 +507,17 @@ public:
m_assembler.addsd_rr(src, dest);
}
+ void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ ASSERT(isSSE2Present());
+ if (op1 == dest)
+ addDouble(op2, dest);
+ else {
+ moveDouble(op2, dest);
+ addDouble(op1, dest);
+ }
+ }
+
void addDouble(Address src, FPRegisterID dest)
{
ASSERT(isSSE2Present());
@@ -428,6 +530,15 @@ public:
m_assembler.divsd_rr(src, dest);
}
+ void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ // B := A / B is invalid.
+ ASSERT(op1 == dest || op2 != dest);
+
+ moveDouble(op1, dest);
+ divDouble(op2, dest);
+ }
+
void divDouble(Address src, FPRegisterID dest)
{
ASSERT(isSSE2Present());
@@ -440,6 +551,15 @@ public:
m_assembler.subsd_rr(src, dest);
}
+ void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ // B := A - B is invalid.
+ ASSERT(op1 == dest || op2 != dest);
+
+ moveDouble(op1, dest);
+ subDouble(op2, dest);
+ }
+
void subDouble(Address src, FPRegisterID dest)
{
ASSERT(isSSE2Present());
@@ -452,6 +572,17 @@ public:
m_assembler.mulsd_rr(src, dest);
}
+ void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ ASSERT(isSSE2Present());
+ if (op1 == dest)
+ mulDouble(op2, dest);
+ else {
+ moveDouble(op2, dest);
+ mulDouble(op1, dest);
+ }
+ }
+
void mulDouble(Address src, FPRegisterID dest)
{
ASSERT(isSSE2Present());
@@ -501,11 +632,12 @@ public:
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
// (specifically, in this case, INT_MIN).
- Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
+ enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
+ Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
{
ASSERT(isSSE2Present());
m_assembler.cvttsd2si_rr(src, dest);
- return branch32(Equal, dest, Imm32(0x80000000));
+ return branch32(branchType ? NotEqual : Equal, dest, TrustedImm32(0x80000000));
}
// Convert 'src' to an integer, and places the resulting 'dest'.
@@ -564,7 +696,7 @@ public:
m_assembler.push_m(address.offset, address.base);
}
- void push(Imm32 imm)
+ void push(TrustedImm32 imm)
{
m_assembler.push_i32(imm.m_value);
}
@@ -574,9 +706,9 @@ public:
//
// Move values in registers.
- void move(Imm32 imm, RegisterID dest)
+ void move(TrustedImm32 imm, RegisterID dest)
{
- // Note: on 64-bit the Imm32 value is zero extended into the register, it
+ // Note: on 64-bit the TrustedImm32 value is zero extended into the register, it
// may be useful to have a separate version that sign extends the value?
if (!imm.m_value)
m_assembler.xorl_rr(dest, dest);
@@ -593,7 +725,7 @@ public:
m_assembler.movq_rr(src, dest);
}
- void move(ImmPtr imm, RegisterID dest)
+ void move(TrustedImmPtr imm, RegisterID dest)
{
m_assembler.movq_i64r(imm.asIntptr(), dest);
}
@@ -620,7 +752,7 @@ public:
m_assembler.movl_rr(src, dest);
}
- void move(ImmPtr imm, RegisterID dest)
+ void move(TrustedImmPtr imm, RegisterID dest)
{
m_assembler.movl_i32r(imm.asIntptr(), dest);
}
@@ -655,14 +787,14 @@ public:
// used (representing the names 'below' and 'above').
//
// Operands to the comparision are provided in the expected order, e.g.
- // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+ // jle32(reg1, TrustedImm32(5)) will branch if the value held in reg1, when
// treated as a signed 32bit value, is less than or equal to 5.
//
// jz and jnz test whether the first operand is equal to zero, and take
// an optional second operand of a mask under which to perform the test.
public:
- Jump branch8(Condition cond, Address left, Imm32 right)
+ Jump branch8(Condition cond, Address left, TrustedImm32 right)
{
m_assembler.cmpb_im(right.m_value, left.offset, left.base);
return Jump(m_assembler.jCC(x86Condition(cond)));
@@ -674,7 +806,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branch32(Condition cond, RegisterID left, Imm32 right)
+ Jump branch32(Condition cond, RegisterID left, TrustedImm32 right)
{
if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
m_assembler.testl_rr(left, left);
@@ -695,19 +827,19 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branch32(Condition cond, Address left, Imm32 right)
+ Jump branch32(Condition cond, Address left, TrustedImm32 right)
{
m_assembler.cmpl_im(right.m_value, left.offset, left.base);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right)
{
m_assembler.cmpl_im(right.m_value, left.offset, left.base, left.index, left.scale);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right)
{
return branch32(cond, left, right);
}
@@ -718,7 +850,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+ Jump branch16(Condition cond, BaseIndex left, TrustedImm32 right)
{
ASSERT(!(right.m_value & 0xFFFF0000));
@@ -728,14 +860,14 @@ public:
Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
{
- ASSERT((cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
m_assembler.testl_rr(reg, mask);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
- ASSERT((cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
// if we are only interested in the low seven bits, this can be tested with a testb
if (mask.m_value == -1)
m_assembler.testl_rr(reg, reg);
@@ -746,9 +878,9 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
- ASSERT((cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
if (mask.m_value == -1)
m_assembler.cmpl_im(0, address.offset, address.base);
else
@@ -756,9 +888,9 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTest32(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
- ASSERT((cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
if (mask.m_value == -1)
m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale);
else
@@ -766,9 +898,23 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
+ {
+ // Byte in TrustedImm32 is not well defined, so be a little permisive here, but don't accept nonsense values.
+ ASSERT(mask.m_value >= -128 && mask.m_value <= 255);
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
+ if (mask.m_value == -1)
+ m_assembler.testb_rr(reg, reg);
+ else
+ m_assembler.testb_i8r(mask.m_value, reg);
+ return Jump(m_assembler.jCC(x86Condition(cond)));
+ }
+
+ Jump branchTest8(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
- ASSERT((cond == Zero) || (cond == NonZero));
+ // Byte in TrustedImm32 is not well defined, so be a little permisive here, but don't accept nonsense values.
+ ASSERT(mask.m_value >= -128 && mask.m_value <= 255);
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
if (mask.m_value == -1)
m_assembler.cmpb_im(0, address.offset, address.base);
else
@@ -776,9 +922,11 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTest8(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
- ASSERT((cond == Zero) || (cond == NonZero));
+ // Byte in TrustedImm32 is not well defined, so be a little permisive here, but don't accept nonsense values.
+ ASSERT(mask.m_value >= -128 && mask.m_value <= 255);
+ ASSERT((cond == Zero) || (cond == NonZero) || (cond == Signed));
if (mask.m_value == -1)
m_assembler.cmpb_im(0, address.offset, address.base, address.index, address.scale);
else
@@ -820,14 +968,14 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchAdd32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
add32(imm, dest);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchAdd32(Condition cond, Imm32 src, Address dest)
+ Jump branchAdd32(Condition cond, TrustedImm32 src, Address dest)
{
ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
add32(src, dest);
@@ -848,6 +996,20 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
+ Jump branchAdd32(Condition cond, RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ if (src1 == dest)
+ return branchAdd32(cond, src2, dest);
+ move(src2, dest);
+ return branchAdd32(cond, src1, dest);
+ }
+
+ Jump branchAdd32(Condition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ return branchAdd32(cond, imm, dest);
+ }
+
Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
{
ASSERT(cond == Overflow);
@@ -862,13 +1024,21 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+ Jump branchMul32(Condition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
{
ASSERT(cond == Overflow);
mul32(imm, src, dest);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
+ Jump branchMul32(Condition cond, RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ if (src1 == dest)
+ return branchMul32(cond, src2, dest);
+ move(src2, dest);
+ return branchMul32(cond, src1, dest);
+ }
+
Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -876,14 +1046,14 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchSub32(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
sub32(imm, dest);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchSub32(Condition cond, Imm32 imm, Address dest)
+ Jump branchSub32(Condition cond, TrustedImm32 imm, Address dest)
{
ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
sub32(imm, dest);
@@ -904,6 +1074,15 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
+ Jump branchSub32(Condition cond, RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ // B := A - B is invalid.
+ ASSERT(src1 == dest || src2 != dest);
+
+ move(src1, dest);
+ return branchSub32(cond, src2, dest);
+ }
+
Jump branchNeg32(Condition cond, RegisterID srcDest)
{
ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
@@ -958,7 +1137,7 @@ public:
m_assembler.setCC_r(x86Condition(cond), dest);
}
- void set8Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set8Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
m_assembler.testl_rr(left, left);
@@ -974,7 +1153,7 @@ public:
m_assembler.movzbl_rr(dest, dest);
}
- void set32Compare32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void set32Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
m_assembler.testl_rr(left, left);
@@ -989,7 +1168,7 @@ public:
// dest-src, operations always have a dest? ... possibly not true, considering
// asm ops like test, or pseudo ops like pop().
- void set32Test8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test8(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
if (mask.m_value == -1)
m_assembler.cmpb_im(0, address.offset, address.base);
@@ -999,7 +1178,7 @@ public:
m_assembler.movzbl_rr(dest, dest);
}
- void set32Test32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ void set32Test32(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
{
if (mask.m_value == -1)
m_assembler.cmpl_im(0, address.offset, address.base);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index ebbe0bd..bd417aa 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -48,30 +48,31 @@ public:
using MacroAssemblerX86Common::load32;
using MacroAssemblerX86Common::store32;
using MacroAssemblerX86Common::call;
+ using MacroAssemblerX86Common::addDouble;
using MacroAssemblerX86Common::loadDouble;
using MacroAssemblerX86Common::convertInt32ToDouble;
- void add32(Imm32 imm, AbsoluteAddress address)
+ void add32(TrustedImm32 imm, AbsoluteAddress address)
{
- move(ImmPtr(address.m_ptr), scratchRegister);
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
add32(imm, Address(scratchRegister));
}
- void and32(Imm32 imm, AbsoluteAddress address)
+ void and32(TrustedImm32 imm, AbsoluteAddress address)
{
- move(ImmPtr(address.m_ptr), scratchRegister);
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
and32(imm, Address(scratchRegister));
}
- void or32(Imm32 imm, AbsoluteAddress address)
+ void or32(TrustedImm32 imm, AbsoluteAddress address)
{
- move(ImmPtr(address.m_ptr), scratchRegister);
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
or32(imm, Address(scratchRegister));
}
- void sub32(Imm32 imm, AbsoluteAddress address)
+ void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
- move(ImmPtr(address.m_ptr), scratchRegister);
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
sub32(imm, Address(scratchRegister));
}
@@ -88,17 +89,23 @@ public:
void loadDouble(const void* address, FPRegisterID dest)
{
- move(ImmPtr(address), scratchRegister);
+ move(TrustedImmPtr(address), scratchRegister);
loadDouble(scratchRegister, dest);
}
- void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
+ void addDouble(AbsoluteAddress address, FPRegisterID dest)
{
- move(Imm32(*static_cast<int32_t*>(src.m_ptr)), scratchRegister);
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
+ m_assembler.addsd_mr(0, scratchRegister, dest);
+ }
+
+ void convertInt32ToDouble(TrustedImm32 imm, FPRegisterID dest)
+ {
+ move(imm, scratchRegister);
m_assembler.cvtsi2sd_rr(scratchRegister, dest);
}
- void store32(Imm32 imm, void* address)
+ void store32(TrustedImm32 imm, void* address)
{
move(X86Registers::eax, scratchRegister);
move(imm, X86Registers::eax);
@@ -108,7 +115,7 @@ public:
Call call()
{
- DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister);
Call result = Call(m_assembler.call(scratchRegister), Call::Linkable);
ASSERT(differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11);
return result;
@@ -116,7 +123,7 @@ public:
Call tailRecursiveCall()
{
- DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister);
Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
return Call::fromTailJump(newJump);
@@ -125,7 +132,7 @@ public:
Call makeTailRecursiveCall(Jump oldJump)
{
oldJump.link(this);
- DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister);
Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
return Call::fromTailJump(newJump);
@@ -137,30 +144,30 @@ public:
m_assembler.addq_rr(src, dest);
}
- void addPtr(Imm32 imm, RegisterID srcDest)
+ void addPtr(TrustedImm32 imm, RegisterID srcDest)
{
m_assembler.addq_ir(imm.m_value, srcDest);
}
- void addPtr(ImmPtr imm, RegisterID dest)
+ void addPtr(TrustedImmPtr imm, RegisterID dest)
{
move(imm, scratchRegister);
m_assembler.addq_rr(scratchRegister, dest);
}
- void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
+ void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
m_assembler.leaq_mr(imm.m_value, src, dest);
}
- void addPtr(Imm32 imm, Address address)
+ void addPtr(TrustedImm32 imm, Address address)
{
m_assembler.addq_im(imm.m_value, address.offset, address.base);
}
- void addPtr(Imm32 imm, AbsoluteAddress address)
+ void addPtr(TrustedImm32 imm, AbsoluteAddress address)
{
- move(ImmPtr(address.m_ptr), scratchRegister);
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
addPtr(imm, Address(scratchRegister));
}
@@ -169,7 +176,7 @@ public:
m_assembler.andq_rr(src, dest);
}
- void andPtr(Imm32 imm, RegisterID srcDest)
+ void andPtr(TrustedImm32 imm, RegisterID srcDest)
{
m_assembler.andq_ir(imm.m_value, srcDest);
}
@@ -179,13 +186,13 @@ public:
m_assembler.orq_rr(src, dest);
}
- void orPtr(ImmPtr imm, RegisterID dest)
+ void orPtr(TrustedImmPtr imm, RegisterID dest)
{
move(imm, scratchRegister);
m_assembler.orq_rr(scratchRegister, dest);
}
- void orPtr(Imm32 imm, RegisterID dest)
+ void orPtr(TrustedImm32 imm, RegisterID dest)
{
m_assembler.orq_ir(imm.m_value, dest);
}
@@ -195,12 +202,12 @@ public:
m_assembler.subq_rr(src, dest);
}
- void subPtr(Imm32 imm, RegisterID dest)
+ void subPtr(TrustedImm32 imm, RegisterID dest)
{
m_assembler.subq_ir(imm.m_value, dest);
}
- void subPtr(ImmPtr imm, RegisterID dest)
+ void subPtr(TrustedImmPtr imm, RegisterID dest)
{
move(imm, scratchRegister);
m_assembler.subq_rr(scratchRegister, dest);
@@ -211,7 +218,7 @@ public:
m_assembler.xorq_rr(src, dest);
}
- void xorPtr(Imm32 imm, RegisterID srcDest)
+ void xorPtr(TrustedImm32 imm, RegisterID srcDest)
{
m_assembler.xorq_ir(imm.m_value, srcDest);
}
@@ -227,7 +234,7 @@ public:
m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
}
- void loadPtr(void* address, RegisterID dest)
+ void loadPtr(const void* address, RegisterID dest)
{
if (dest == X86Registers::eax)
m_assembler.movq_mEAX(address);
@@ -265,7 +272,7 @@ public:
}
}
- void storePtr(ImmPtr imm, ImplicitAddress address)
+ void storePtr(TrustedImmPtr imm, ImplicitAddress address)
{
move(imm, scratchRegister);
storePtr(scratchRegister, address);
@@ -287,7 +294,7 @@ public:
m_assembler.movq_rr(src, dest);
}
- void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ void setPtr(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
m_assembler.testq_rr(left, left);
@@ -303,7 +310,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
+ Jump branchPtr(Condition cond, RegisterID left, TrustedImmPtr right)
{
move(right, scratchRegister);
return branchPtr(cond, left, scratchRegister);
@@ -317,7 +324,7 @@ public:
Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
{
- move(ImmPtr(left.m_ptr), scratchRegister);
+ move(TrustedImmPtr(left.m_ptr), scratchRegister);
return branchPtr(cond, Address(scratchRegister), right);
}
@@ -327,7 +334,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchPtr(Condition cond, Address left, ImmPtr right)
+ Jump branchPtr(Condition cond, Address left, TrustedImmPtr right)
{
move(right, scratchRegister);
return branchPtr(cond, left, scratchRegister);
@@ -339,7 +346,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
// if we are only interested in the low seven bits, this can be tested with a testb
if (mask.m_value == -1)
@@ -351,7 +358,13 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
+ {
+ loadPtr(address.m_ptr, scratchRegister);
+ return branchTestPtr(cond, scratchRegister, mask);
+ }
+
+ Jump branchTestPtr(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
{
if (mask.m_value == -1)
m_assembler.cmpq_im(0, address.offset, address.base);
@@ -360,7 +373,7 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
if (mask.m_value == -1)
m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
@@ -377,32 +390,32 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
+ Jump branchSubPtr(Condition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
subPtr(imm, dest);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
- DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+ DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
{
m_assembler.movq_i64r(initialValue.asIntptr(), dest);
return DataLabelPtr(this);
}
- Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
dataLabel = moveWithPatch(initialRightValue, scratchRegister);
return branchPtr(cond, left, scratchRegister);
}
- Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
dataLabel = moveWithPatch(initialRightValue, scratchRegister);
return branchPtr(cond, left, scratchRegister);
}
- DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+ DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
{
DataLabelPtr label = moveWithPatch(initialValue, scratchRegister);
storePtr(scratchRegister, address);
@@ -410,9 +423,9 @@ public:
}
using MacroAssemblerX86Common::branchTest8;
- Jump branchTest8(Condition cond, ExtendedAddress address, Imm32 mask = Imm32(-1))
+ Jump branchTest8(Condition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
{
- ImmPtr addr(reinterpret_cast<void*>(address.offset));
+ TrustedImmPtr addr(reinterpret_cast<void*>(address.offset));
MacroAssemblerX86Common::move(addr, scratchRegister);
return MacroAssemblerX86Common::branchTest8(cond, BaseIndex(scratchRegister, address.base, TimesOne), mask);
}
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index 587d900..4851c1e 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -131,6 +131,7 @@ private:
OP_GROUP1_EbIb = 0x80,
OP_GROUP1_EvIz = 0x81,
OP_GROUP1_EvIb = 0x83,
+ OP_TEST_EbGb = 0x84,
OP_TEST_EvGv = 0x85,
OP_XCHG_EvGv = 0x87,
OP_MOV_EvGv = 0x89,
@@ -228,6 +229,8 @@ public:
{
}
+ bool isSet() const { return (m_offset != -1); }
+
private:
JmpSrc(int offset)
: m_offset(offset)
@@ -299,7 +302,7 @@ public:
// Arithmetic operations:
#if !CPU(X86_64)
- void adcl_im(int imm, void* addr)
+ void adcl_im(int imm, const void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
@@ -376,7 +379,7 @@ public:
}
}
#else
- void addl_im(int imm, void* addr)
+ void addl_im(int imm, const void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
@@ -442,7 +445,7 @@ public:
}
}
#else
- void andl_im(int imm, void* addr)
+ void andl_im(int imm, const void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
@@ -528,7 +531,7 @@ public:
}
}
#else
- void orl_im(int imm, void* addr)
+ void orl_im(int imm, const void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
@@ -594,7 +597,7 @@ public:
}
}
#else
- void subl_im(int imm, void* addr)
+ void subl_im(int imm, const void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
@@ -867,12 +870,12 @@ public:
}
}
#else
- void cmpl_rm(RegisterID reg, void* addr)
+ void cmpl_rm(RegisterID reg, const void* addr)
{
m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
}
- void cmpl_im(int imm, void* addr)
+ void cmpl_im(int imm, const void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
@@ -919,7 +922,12 @@ public:
m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
m_formatter.immediate32(imm);
}
-
+
+ void testb_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_TEST_EbGb, src, dst);
+ }
+
void testb_im(int imm, int offset, RegisterID base)
{
m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
@@ -1039,7 +1047,7 @@ public:
m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
}
- void movl_mEAX(void* addr)
+ void movl_mEAX(const void* addr)
{
m_formatter.oneByteOp(OP_MOV_EAXOv);
#if CPU(X86_64)
@@ -1076,7 +1084,7 @@ public:
m_formatter.immediate32(imm);
}
- void movl_EAXm(void* addr)
+ void movl_EAXm(const void* addr)
{
m_formatter.oneByteOp(OP_MOV_OvEAX);
#if CPU(X86_64)
@@ -1107,13 +1115,13 @@ public:
m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
}
- void movq_mEAX(void* addr)
+ void movq_mEAX(const void* addr)
{
m_formatter.oneByteOp64(OP_MOV_EAXOv);
m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
}
- void movq_EAXm(void* addr)
+ void movq_EAXm(const void* addr)
{
m_formatter.oneByteOp64(OP_MOV_OvEAX);
m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
@@ -1153,7 +1161,7 @@ public:
#else
- void movl_rm(RegisterID src, void* addr)
+ void movl_rm(RegisterID src, const void* addr)
{
if (src == X86Registers::eax)
movl_EAXm(addr);
@@ -1161,7 +1169,7 @@ public:
m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
}
- void movl_mr(void* addr, RegisterID dst)
+ void movl_mr(const void* addr, RegisterID dst)
{
if (dst == X86Registers::eax)
movl_mEAX(addr);
@@ -1169,7 +1177,7 @@ public:
m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
}
- void movl_i32m(int imm, void* addr)
+ void movl_i32m(int imm, const void* addr)
{
m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
m_formatter.immediate32(imm);
@@ -1365,7 +1373,7 @@ public:
}
#if !CPU(X86_64)
- void cvtsi2sd_mr(void* address, XMMRegisterID dst)
+ void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
@@ -1398,6 +1406,12 @@ public:
}
#endif
+ void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+ }
+
void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
{
m_formatter.prefix(PRE_SSE_F2);
@@ -1536,6 +1550,7 @@ public:
ASSERT(to.m_offset != -1);
char* code = reinterpret_cast<char*>(m_formatter.data());
+ ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]);
setRel32(code + from.m_offset, code + to.m_offset);
}
@@ -1717,7 +1732,7 @@ private:
}
#if !CPU(X86_64)
- void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
+ void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
{
m_buffer.ensureSpace(maxInstructionSize);
m_buffer.putByteUnchecked(opcode);
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 2d235df..98bbb3c 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -364,7 +364,7 @@ void CodeBlock::dump(ExecState* exec) const
unsigned registerIndex = m_numVars;
size_t i = 0;
do {
- printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).utf8().data());
+ printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data());
++i;
++registerIndex;
} while (i < m_constantRegisters.size());
@@ -731,7 +731,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
case op_resolve_global_dynamic: {
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
- JSValue scope = JSValue((++it)->u.jsCell);
+ JSValue scope = JSValue((++it)->u.jsCell.get());
++it;
int depth = (++it)->u.operand;
printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
@@ -1360,13 +1360,13 @@ void CodeBlock::dumpStatistics()
}
CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor)
- : m_globalObject(globalObject)
+ : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject)
, m_heap(&m_globalObject->globalData().heap)
, m_numCalleeRegisters(0)
, m_numVars(0)
, m_numParameters(0)
, m_isConstructor(isConstructor)
- , m_ownerExecutable(ownerExecutable)
+ , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
, m_globalData(0)
#ifndef NDEBUG
, m_instructionCount(0)
@@ -1406,12 +1406,6 @@ CodeBlock::~CodeBlock()
for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i)
m_structureStubInfos[i].deref();
- for (size_t size = m_callLinkInfos.size(), i = 0; i < size; ++i) {
- CallLinkInfo* callLinkInfo = &m_callLinkInfos[i];
- if (callLinkInfo->isLinked())
- callLinkInfo->callee->removeCaller(callLinkInfo);
- }
-
for (size_t size = m_methodCallLinkInfos.size(), i = 0; i < size; ++i) {
if (Structure* structure = m_methodCallLinkInfos[i].cachedStructure) {
structure->deref();
@@ -1421,10 +1415,6 @@ CodeBlock::~CodeBlock()
}
}
-#if ENABLE(JIT_OPTIMIZE_CALL)
- unlinkCallers();
-#endif
-
#endif // ENABLE(JIT)
#if DUMP_CODE_BLOCK_STATISTICS
@@ -1432,19 +1422,6 @@ CodeBlock::~CodeBlock()
#endif
}
-#if ENABLE(JIT_OPTIMIZE_CALL)
-void CodeBlock::unlinkCallers()
-{
- size_t size = m_linkedCallerList.size();
- for (size_t i = 0; i < size; ++i) {
- CallLinkInfo* currentCaller = m_linkedCallerList[i];
- JIT::unlinkCallOrConstruct(currentCaller);
- currentCaller->setUnlinked();
- }
- m_linkedCallerList.clear();
-}
-#endif
-
void CodeBlock::derefStructures(Instruction* vPC) const
{
Interpreter* interpreter = m_globalData->interpreter;
@@ -1460,13 +1437,11 @@ void CodeBlock::derefStructures(Instruction* vPC) const
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
vPC[4].u.structure->deref();
- vPC[5].u.structureChain->deref();
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
vPC[4].u.structure->deref();
vPC[5].u.structure->deref();
- vPC[6].u.structureChain->deref();
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
@@ -1509,13 +1484,11 @@ void CodeBlock::refStructures(Instruction* vPC) const
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
vPC[4].u.structure->ref();
- vPC[5].u.structureChain->ref();
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
vPC[4].u.structure->ref();
vPC[5].u.structure->ref();
- vPC[6].u.structureChain->ref();
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
@@ -1527,14 +1500,43 @@ void CodeBlock::refStructures(Instruction* vPC) const
ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic));
}
+void EvalCodeCache::markAggregate(MarkStack& markStack)
+{
+ EvalCacheMap::iterator end = m_cacheMap.end();
+ for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
+ markStack.append(&ptr->second);
+}
+
void CodeBlock::markAggregate(MarkStack& markStack)
{
- for (size_t i = 0; i < m_constantRegisters.size(); ++i)
- markStack.deprecatedAppend(&m_constantRegisters[i]);
+ markStack.append(&m_globalObject);
+ markStack.append(&m_ownerExecutable);
+ if (m_rareData)
+ m_rareData->m_evalCodeCache.markAggregate(markStack);
+ markStack.appendValues(m_constantRegisters.data(), m_constantRegisters.size());
for (size_t i = 0; i < m_functionExprs.size(); ++i)
- m_functionExprs[i]->markAggregate(markStack);
+ markStack.append(&m_functionExprs[i]);
for (size_t i = 0; i < m_functionDecls.size(); ++i)
- m_functionDecls[i]->markAggregate(markStack);
+ markStack.append(&m_functionDecls[i]);
+#if ENABLE(JIT_OPTIMIZE_CALL)
+ for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i)
+ if (callLinkInfo(i).isLinked())
+ markStack.append(&callLinkInfo(i).callee);
+#endif
+#if ENABLE(INTERPRETER)
+ Interpreter* interpreter = m_globalData->interpreter;
+ for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
+ Instruction* vPC = &m_instructions[m_propertyAccessInstructions[i]];
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain))
+ markStack.append(&vPC[5].u.structureChain);
+ else if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition))
+ markStack.append(&vPC[6].u.structureChain);
+ }
+#endif
+#if ENABLE(JIT)
+ for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i)
+ m_structureStubInfos[i].markAggregate(markStack);
+#endif
}
HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
@@ -1671,7 +1673,6 @@ void CodeBlock::shrinkToFit()
m_structureStubInfos.shrinkToFit();
m_globalResolveInfos.shrinkToFit();
m_callLinkInfos.shrinkToFit();
- m_linkedCallerList.shrinkToFit();
#endif
m_identifiers.shrinkToFit();
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index bef4561..25e65f4 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -96,21 +96,17 @@ namespace JSC {
#if ENABLE(JIT)
struct CallLinkInfo {
CallLinkInfo()
- : callee(0)
- , position(0)
- , hasSeenShouldRepatch(0)
+ : hasSeenShouldRepatch(false)
{
}
CodeLocationNearCall callReturnLocation;
CodeLocationDataLabelPtr hotPathBegin;
CodeLocationNearCall hotPathOther;
- CodeBlock* ownerCodeBlock;
- CodeBlock* callee;
- unsigned position : 31;
- unsigned hasSeenShouldRepatch : 1;
+ WriteBarrier<JSFunction> callee;
+ bool hasSeenShouldRepatch;
- void setUnlinked() { callee = 0; }
+ void setUnlinked() { callee.clear(); }
bool isLinked() { return callee; }
bool seenOnce()
@@ -183,7 +179,7 @@ namespace JSC {
unsigned bytecodeOffset;
};
- // valueAtPosition helpers for the binaryChop algorithm below.
+ // valueAtPosition helpers for the binarySearch algorithm.
inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
{
@@ -204,42 +200,6 @@ namespace JSC {
{
return pc->callReturnOffset;
}
-
- // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
- // compares result with key (KeyTypes should be comparable with '--', '<', '>').
- // Optimized for cases where the array contains the key, checked by assertions.
- template<typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)>
- inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key)
- {
- // The array must contain at least one element (pre-condition, array does conatin key).
- // If the array only contains one element, no need to do the comparison.
- while (size > 1) {
- // Pick an element to check, half way through the array, and read the value.
- int pos = (size - 1) >> 1;
- KeyType val = valueAtPosition(&array[pos]);
-
- // If the key matches, success!
- if (val == key)
- return &array[pos];
- // The item we are looking for is smaller than the item being check; reduce the value of 'size',
- // chopping off the right hand half of the array.
- else if (key < val)
- size = pos;
- // Discard all values in the left hand half of the array, up to and including the item at pos.
- else {
- size -= (pos + 1);
- array += (pos + 1);
- }
-
- // 'size' should never reach zero.
- ASSERT(size);
- }
-
- // If we reach this point we've chopped down to one element, no need to check it matches
- ASSERT(size == 1);
- ASSERT(key == valueAtPosition(&array[0]));
- return &array[0];
- }
#endif
class CodeBlock {
@@ -248,7 +208,7 @@ namespace JSC {
protected:
CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable* symbolTable, bool isConstructor);
- DeprecatedPtr<JSGlobalObject> m_globalObject;
+ WriteBarrier<JSGlobalObject> m_globalObject;
Heap* m_heap;
public:
@@ -257,9 +217,6 @@ namespace JSC {
void markAggregate(MarkStack&);
void refStructures(Instruction* vPC) const;
void derefStructures(Instruction* vPC) const;
-#if ENABLE(JIT_OPTIMIZE_CALL)
- void unlinkCallers();
-#endif
static void dumpStatistics();
@@ -292,38 +249,20 @@ namespace JSC {
void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
#if ENABLE(JIT)
- void addCaller(CallLinkInfo* caller)
- {
- caller->callee = this;
- caller->position = m_linkedCallerList.size();
- m_linkedCallerList.append(caller);
- }
-
- void removeCaller(CallLinkInfo* caller)
- {
- unsigned pos = caller->position;
- unsigned lastPos = m_linkedCallerList.size() - 1;
-
- if (pos != lastPos) {
- m_linkedCallerList[pos] = m_linkedCallerList[lastPos];
- m_linkedCallerList[pos]->position = pos;
- }
- m_linkedCallerList.shrink(lastPos);
- }
StructureStubInfo& getStubInfo(ReturnAddressPtr returnAddress)
{
- return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value()));
+ return *(binarySearch<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value()));
}
CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress)
{
- return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value()));
+ return *(binarySearch<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value()));
}
MethodCallLinkInfo& getMethodCallLinkInfo(ReturnAddressPtr returnAddress)
{
- return *(binaryChop<MethodCallLinkInfo, void*, getMethodCallLinkInfoReturnLocation>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value()));
+ return *(binarySearch<MethodCallLinkInfo, void*, getMethodCallLinkInfoReturnLocation>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value()));
}
unsigned bytecodeOffset(ReturnAddressPtr returnAddress)
@@ -333,7 +272,7 @@ namespace JSC {
Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
if (!callIndices.size())
return 1;
- return binaryChop<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
+ return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
}
#endif
#if ENABLE(INTERPRETER)
@@ -359,7 +298,7 @@ namespace JSC {
ExecutablePool* executablePool() { return getJITCode().getExecutablePool(); }
#endif
- ScriptExecutable* ownerExecutable() const { return m_ownerExecutable; }
+ ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
@@ -451,6 +390,8 @@ namespace JSC {
bool hasExpressionInfo() { return m_rareData && m_rareData->m_expressionInfo.size(); }
bool hasLineInfo() { return m_rareData && m_rareData->m_lineInfo.size(); }
+ // We only generate exception handling info if the user is debugging
+ // (and may want line number info), or if the function contains exception handler.
bool needsCallReturnIndices()
{
return m_rareData &&
@@ -472,18 +413,34 @@ namespace JSC {
Identifier& identifier(int index) { return m_identifiers[index]; }
size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
- void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
- Register& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
+ void addConstant(JSValue v)
+ {
+ m_constantRegisters.append(WriteBarrier<Unknown>());
+ m_constantRegisters.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), v);
+ }
+ WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
- ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
+ ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
- unsigned addFunctionDecl(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; }
+ unsigned addFunctionDecl(FunctionExecutable* n)
+ {
+ unsigned size = m_functionDecls.size();
+ m_functionDecls.append(WriteBarrier<FunctionExecutable>());
+ m_functionDecls.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), n);
+ return size;
+ }
FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
int numberOfFunctionDecls() { return m_functionDecls.size(); }
- unsigned addFunctionExpr(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
+ unsigned addFunctionExpr(FunctionExecutable* n)
+ {
+ unsigned size = m_functionExprs.size();
+ m_functionExprs.append(WriteBarrier<FunctionExecutable>());
+ m_functionExprs.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), n);
+ return size;
+ }
FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
- unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
+ unsigned addRegExp(PassRefPtr<RegExp> r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
JSGlobalObject* globalObject() { return m_globalObject.get(); }
@@ -536,7 +493,7 @@ namespace JSC {
m_rareData = adoptPtr(new RareData);
}
- ScriptExecutable* m_ownerExecutable;
+ WriteBarrier<ScriptExecutable> m_ownerExecutable;
JSGlobalData* m_globalData;
Vector<Instruction> m_instructions;
@@ -567,16 +524,16 @@ namespace JSC {
Vector<GlobalResolveInfo> m_globalResolveInfos;
Vector<CallLinkInfo> m_callLinkInfos;
Vector<MethodCallLinkInfo> m_methodCallLinkInfos;
- Vector<CallLinkInfo*> m_linkedCallerList;
#endif
Vector<unsigned> m_jumpTargets;
// Constant Pool
Vector<Identifier> m_identifiers;
- Vector<Register> m_constantRegisters;
- Vector<RefPtr<FunctionExecutable> > m_functionDecls;
- Vector<RefPtr<FunctionExecutable> > m_functionExprs;
+ COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
+ Vector<WriteBarrier<Unknown> > m_constantRegisters;
+ Vector<WriteBarrier<FunctionExecutable> > m_functionDecls;
+ Vector<WriteBarrier<FunctionExecutable> > m_functionExprs;
SymbolTable* m_symbolTable;
@@ -617,12 +574,6 @@ namespace JSC {
GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
: CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false)
{
- m_heap->codeBlocks().add(this);
- }
-
- ~GlobalCodeBlock()
- {
- m_heap->codeBlocks().remove(this);
}
private:
@@ -680,7 +631,7 @@ namespace JSC {
{
CodeBlock* codeBlock = this->codeBlock();
if (codeBlock->isConstantRegisterIndex(index))
- return codeBlock->constantRegister(index);
+ return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
return this[index];
}
diff --git a/Source/JavaScriptCore/bytecode/EvalCodeCache.h b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
index edd575f..3e450b1 100644
--- a/Source/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -41,14 +41,16 @@
namespace JSC {
+ class MarkStack;
+
class EvalCodeCache {
public:
- PassRefPtr<EvalExecutable> get(ExecState* exec, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
+ EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
{
- RefPtr<EvalExecutable> evalExecutable;
+ EvalExecutable* evalExecutable = 0;
if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
- evalExecutable = m_cacheMap.get(evalSource.impl());
+ evalExecutable = m_cacheMap.get(evalSource.impl()).get();
if (!evalExecutable) {
evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
@@ -57,19 +59,21 @@ namespace JSC {
return 0;
if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
- m_cacheMap.set(evalSource.impl(), evalExecutable);
+ m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable));
}
- return evalExecutable.release();
+ return evalExecutable;
}
bool isEmpty() const { return m_cacheMap.isEmpty(); }
+ void markAggregate(MarkStack&);
+
private:
static const unsigned maxCacheableSourceLength = 256;
static const int maxCacheEntries = 64;
- typedef HashMap<RefPtr<StringImpl>, RefPtr<EvalExecutable> > EvalCacheMap;
+ typedef HashMap<RefPtr<StringImpl>, WriteBarrier<EvalExecutable> > EvalCacheMap;
EvalCacheMap m_cacheMap;
};
diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h
index f077cbf..da0821d 100644
--- a/Source/JavaScriptCore/bytecode/Instruction.h
+++ b/Source/JavaScriptCore/bytecode/Instruction.h
@@ -63,7 +63,7 @@ namespace JSC {
Structure* base;
union {
Structure* proto;
- StructureChain* chain;
+ WriteBarrierBase<StructureChain> chain;
} u;
void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base)
@@ -82,11 +82,11 @@ namespace JSC {
isChain = false;
}
- void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
+ void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
{
stubRoutine = _stubRoutine;
base = _base;
- u.chain = _chain;
+ u.chain.set(globalData, owner, _chain);
isChain = true;
}
} list[POLYMORPHIC_LIST_CACHE_SIZE];
@@ -101,9 +101,9 @@ namespace JSC {
list[0].set(stubRoutine, firstBase, firstProto);
}
- PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
+ PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
{
- list[0].set(stubRoutine, firstBase, firstChain);
+ list[0].set(globalData, owner, stubRoutine, firstBase, firstChain);
}
void derefStructures(int count)
@@ -115,13 +115,22 @@ namespace JSC {
info.base->deref();
if (info.u.proto) {
- if (info.isChain)
- info.u.chain->deref();
- else
+ if (!info.isChain)
info.u.proto->deref();
}
}
}
+
+ void markAggregate(MarkStack& markStack, int count)
+ {
+ for (int i = 0; i < count; ++i) {
+ PolymorphicStubInfo& info = list[i];
+ ASSERT(info.base);
+
+ if (info.u.proto && info.isChain)
+ markStack.append(&info.u.chain);
+ }
+ }
};
struct Instruction {
@@ -130,7 +139,7 @@ namespace JSC {
#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
// We have to initialize one of the pointer members to ensure that
// the entire struct is initialized, when opcode is not a pointer.
- u.jsCell = 0;
+ u.jsCell.clear();
#endif
u.opcode = opcode;
}
@@ -139,13 +148,21 @@ namespace JSC {
{
// We have to initialize one of the pointer members to ensure that
// the entire struct is initialized in 64-bit.
- u.jsCell = 0;
+ u.jsCell.clear();
u.operand = operand;
}
Instruction(Structure* structure) { u.structure = structure; }
- Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
- Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
+ Instruction(JSGlobalData& globalData, JSCell* owner, StructureChain* structureChain)
+ {
+ u.structureChain.clear();
+ u.structureChain.set(globalData, owner, structureChain);
+ }
+ Instruction(JSGlobalData& globalData, JSCell* owner, JSCell* jsCell)
+ {
+ u.jsCell.clear();
+ u.jsCell.set(globalData, owner, jsCell);
+ }
Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
@@ -153,8 +170,8 @@ namespace JSC {
Opcode opcode;
int operand;
Structure* structure;
- StructureChain* structureChain;
- JSCell* jsCell;
+ WriteBarrierBase<StructureChain> structureChain;
+ WriteBarrierBase<JSCell> jsCell;
PolymorphicAccessStructureList* polymorphicStructures;
PropertySlot::GetValueFunc getterFunc;
} u;
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.h b/Source/JavaScriptCore/bytecode/SamplingTool.h
index 9ca54da..a0696b1 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.h
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.h
@@ -95,8 +95,8 @@ namespace JSC {
struct Instruction;
struct ScriptSampleRecord {
- ScriptSampleRecord(ScriptExecutable* executable)
- : m_executable(executable)
+ ScriptSampleRecord(JSGlobalData& globalData, ScriptExecutable* executable)
+ : m_executable(globalData, executable)
, m_codeBlock(0)
, m_sampleCount(0)
, m_opcodeSampleCount(0)
@@ -113,7 +113,7 @@ namespace JSC {
void sample(CodeBlock*, Instruction*);
- RefPtr<ScriptExecutable> m_executable;
+ Global<ScriptExecutable> m_executable;
CodeBlock* m_codeBlock;
int m_sampleCount;
int m_opcodeSampleCount;
@@ -280,7 +280,6 @@ namespace JSC {
// Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
// See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
class AbstractSamplingCounter {
- friend class JIT;
friend class DeletableSamplingCounter;
public:
void count(uint32_t count = 1)
@@ -290,6 +289,8 @@ namespace JSC {
static void dump();
+ int64_t* addressOfCounter() { return &m_counter; }
+
protected:
// Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
void init(const char* name)
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
index 5ec2a3f..4d59ac1 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "StructureStubInfo.h"
+#include "JSObject.h"
#include "ScopeChain.h"
namespace JSC {
@@ -43,7 +44,6 @@ void StructureStubInfo::deref()
return;
case access_get_by_id_chain:
u.getByIdChain.baseObjectStructure->deref();
- u.getByIdChain.chain->deref();
return;
case access_get_by_id_self_list: {
PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
@@ -60,7 +60,6 @@ void StructureStubInfo::deref()
case access_put_by_id_transition:
u.putByIdTransition.previousStructure->deref();
u.putByIdTransition.structure->deref();
- u.putByIdTransition.chain->deref();
return;
case access_put_by_id_replace:
u.putByIdReplace.baseObjectStructure->deref();
@@ -77,6 +76,42 @@ void StructureStubInfo::deref()
ASSERT_NOT_REACHED();
}
}
+
+void StructureStubInfo::markAggregate(MarkStack& markStack)
+{
+ switch (accessType) {
+ case access_get_by_id_self:
+ return;
+ case access_get_by_id_proto:
+ return;
+ case access_get_by_id_chain:
+ return;
+ case access_get_by_id_self_list: {
+ PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
+ polymorphicStructures->markAggregate(markStack, u.getByIdSelfList.listSize);
+ return;
+ }
+ case access_get_by_id_proto_list: {
+ PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
+ polymorphicStructures->markAggregate(markStack, u.getByIdProtoList.listSize);
+ return;
+ }
+ case access_put_by_id_transition:
+ return;
+ case access_put_by_id_replace:
+ return;
+ case access_get_by_id:
+ case access_put_by_id:
+ case access_get_by_id_generic:
+ case access_put_by_id_generic:
+ case access_get_array_length:
+ case access_get_string_length:
+ // These instructions don't ref their Structures.
+ return;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
#endif
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
index 8e2c489..28202f9 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -85,7 +85,6 @@ namespace JSC {
baseObjectStructure->ref();
u.getByIdChain.chain = chain;
- chain->ref();
}
void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
@@ -117,7 +116,6 @@ namespace JSC {
structure->ref();
u.putByIdTransition.chain = chain;
- chain->ref();
}
void initPutByIdReplace(Structure* baseObjectStructure)
@@ -129,6 +127,7 @@ namespace JSC {
}
void deref();
+ void markAggregate(MarkStack&);
bool seenOnce()
{
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 08f4bd4..5af3420 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -224,8 +224,6 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* s
#endif
, m_stack(m_globalData->stack())
, m_usesExceptions(false)
- , m_regeneratingForExceptionInfo(false)
- , m_codeBlockBeingRegeneratedFrom(0)
, m_expressionTooDeep(false)
{
if (m_shouldEmitDebugHooks)
@@ -250,7 +248,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* s
SymbolTable::iterator end = symbolTable->end();
for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it)
registerFor(it->second.getIndex()).setIndex(it->second.getIndex() + m_globalVarStorageOffset);
-
+
BatchedTransitionOptimizer optimizer(*m_globalData, globalObject);
const VarStack& varStack = programNode->varStack();
@@ -260,27 +258,49 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* s
// Shift new symbols so they get stored prior to existing symbols.
m_nextGlobalIndex -= symbolTable->size();
- size_t oldSymbolTableSize = symbolTable->size();
-
+ HashSet<StringImpl*, IdentifierRepHash> newGlobals;
+ Vector<std::pair<int, bool>, 16> functionInfo(functionStack.size());
for (size_t i = 0; i < functionStack.size(); ++i) {
FunctionBodyNode* function = functionStack[i];
globalObject->removeDirect(function->ident()); // Make sure our new function is not shadowed by an old property.
- emitNewFunction(addGlobalVar(function->ident(), false), function);
+ SymbolTableEntry entry = symbolTable->inlineGet(function->ident().impl());
+
+ if (entry.isNull())
+ newGlobals.add(function->ident().impl());
+ functionInfo[i] = make_pair(entry.getIndex(), entry.isReadOnly());
}
-
- Vector<RegisterID*, 32> newVars;
+
+ Vector<bool, 16> shouldCreateVar(varStack.size());
for (size_t i = 0; i < varStack.size(); ++i) {
- if (globalObject->symbolTableHasProperty(*varStack[i].first) || globalObject->hasProperty(exec, *varStack[i].first))
+ if (newGlobals.contains(varStack[i].first->impl()) || globalObject->hasProperty(exec, *varStack[i].first)) {
+ shouldCreateVar[i] = false;
continue;
- newVars.append(addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant));
+ }
+ shouldCreateVar[i] = true;
+ newGlobals.add(varStack[i].first->impl());
}
- globalObject->resizeRegisters(oldSymbolTableSize, symbolTable->size());
+ int expectedSize = symbolTable->size() + newGlobals.size();
+ globalObject->resizeRegisters(symbolTable->size(), expectedSize);
+
+ for (size_t i = 0; i < functionStack.size(); ++i) {
+ FunctionBodyNode* function = functionStack[i];
+ if (functionInfo[i].second)
+ continue;
+ RegisterID* dst = addGlobalVar(function->ident(), false);
+ JSValue value = new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain);
+ globalObject->registerAt(dst->index() - m_globalVarStorageOffset).set(*m_globalData, globalObject, value);
+ }
- preserveLastVar();
+ for (size_t i = 0; i < varStack.size(); ++i) {
+ if (!shouldCreateVar[i])
+ continue;
+ addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
+ }
+ if (symbolTable->size() != expectedSize)
+ CRASH();
- for (size_t i = 0; i < newVars.size(); ++i)
- emitLoad(newVars[i], jsUndefined());
+ preserveLastVar();
} else {
for (size_t i = 0; i < functionStack.size(); ++i) {
FunctionBodyNode* function = functionStack[i];
@@ -325,8 +345,6 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainN
#endif
, m_stack(m_globalData->stack())
, m_usesExceptions(false)
- , m_regeneratingForExceptionInfo(false)
- , m_codeBlockBeingRegeneratedFrom(0)
, m_expressionTooDeep(false)
{
if (m_shouldEmitDebugHooks)
@@ -491,8 +509,6 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeCh
#endif
, m_stack(m_globalData->stack())
, m_usesExceptions(false)
- , m_regeneratingForExceptionInfo(false)
- , m_codeBlockBeingRegeneratedFrom(0)
, m_expressionTooDeep(false)
{
if (m_shouldEmitDebugHooks || m_baseScopeDepth)
@@ -909,7 +925,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond,
emitOpcode(op_jneq_ptr);
instructions().append(cond->index());
- instructions().append(m_scopeChain->globalObject->d()->callFunction.get());
+ instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->callFunction()));
instructions().append(target->bind(begin, instructions().size()));
return target;
}
@@ -920,7 +936,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond
emitOpcode(op_jneq_ptr);
instructions().append(cond->index());
- instructions().append(m_scopeChain->globalObject->d()->applyFunction.get());
+ instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->applyFunction()));
instructions().append(target->bind(begin, instructions().size()));
return target;
}
@@ -943,14 +959,14 @@ RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
if (result.second) {
m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
++m_nextConstantOffset;
- m_codeBlock->addConstantRegister(JSValue(v));
+ m_codeBlock->addConstant(JSValue(v));
} else
index = result.first->second;
return &m_constantPoolRegisters[index];
}
-unsigned BytecodeGenerator::addRegExp(RegExp* r)
+unsigned BytecodeGenerator::addRegExp(PassRefPtr<RegExp> r)
{
return m_codeBlock->addRegExp(r);
}
@@ -1026,8 +1042,8 @@ RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst
if (src1->index() == dstIndex
&& src1->isTemporary()
&& m_codeBlock->isConstantRegisterIndex(src2->index())
- && m_codeBlock->constantRegister(src2->index()).jsValue().isString()) {
- const UString& value = asString(m_codeBlock->constantRegister(src2->index()).jsValue())->tryGetValue();
+ && m_codeBlock->constantRegister(src2->index()).get().isString()) {
+ const UString& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
if (value == "undefined") {
rewindUnaryOp();
emitOpcode(op_is_undefined);
@@ -1201,13 +1217,6 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
if (globalObject) {
bool forceGlobalResolve = false;
- if (m_regeneratingForExceptionInfo) {
-#if ENABLE(JIT)
- forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInfoAtBytecodeOffset(instructions().size());
-#else
- forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInstructionAtBytecodeOffset(instructions().size());
-#endif
- }
if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) {
// Directly index the property lookup across multiple scopes.
@@ -1344,13 +1353,6 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register
}
bool forceGlobalResolve = false;
- if (m_regeneratingForExceptionInfo) {
-#if ENABLE(JIT)
- forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInfoAtBytecodeOffset(instructions().size());
-#else
- forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInstructionAtBytecodeOffset(instructions().size());
-#endif
- }
// Global object is the base
emitLoad(baseDst, JSValue(globalObject));
@@ -1584,7 +1586,7 @@ RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned
return dst;
}
-RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
+RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, PassRefPtr<RegExp> regExp)
{
emitOpcode(op_new_regexp);
instructions().append(dst->index());
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index b3851c7..3a40390 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -291,7 +291,7 @@ namespace JSC {
RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
- RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp);
+ RegisterID* emitNewRegExp(RegisterID* dst, PassRefPtr<RegExp> regExp);
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
@@ -396,12 +396,6 @@ namespace JSC {
CodeType codeType() const { return m_codeType; }
- void setRegeneratingForExceptionInfo(CodeBlock* originalCodeBlock)
- {
- m_regeneratingForExceptionInfo = true;
- m_codeBlockBeingRegeneratedFrom = originalCodeBlock;
- }
-
bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; }
bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
@@ -481,14 +475,14 @@ namespace JSC {
unsigned addConstant(const Identifier&);
RegisterID* addConstantValue(JSValue);
- unsigned addRegExp(RegExp*);
+ unsigned addRegExp(PassRefPtr<RegExp>);
- PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body)
+ FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)
{
return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
- PassRefPtr<FunctionExecutable> makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)
+ FunctionExecutable* makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)
{
return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
@@ -577,8 +571,6 @@ namespace JSC {
StackBounds m_stack;
bool m_usesExceptions;
- bool m_regeneratingForExceptionInfo;
- CodeBlock* m_codeBlockBeingRegeneratedFrom;
bool m_expressionTooDeep;
};
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 2875434..03578cf 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -125,9 +125,8 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
{
if (dst == generator.ignoredResult())
return 0;
- RefPtr<RegExp> regExp = generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), m_flags.ustring());
- ASSERT(regExp->isValid());
- return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
+ return generator.emitNewRegExp(generator.finalDestination(dst),
+ generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), regExpFlags(m_flags.ustring())));
}
// ------------------------------ ThisNode -------------------------------------
diff --git a/Source/JavaScriptCore/collector/handles/Handle.h b/Source/JavaScriptCore/collector/handles/Handle.h
index 98c60ec..d4e38c0 100644
--- a/Source/JavaScriptCore/collector/handles/Handle.h
+++ b/Source/JavaScriptCore/collector/handles/Handle.h
@@ -111,10 +111,19 @@ template <typename Base, typename T> struct HandleConverter {
};
template <typename Base> struct HandleConverter<Base, Unknown> {
+ Handle<JSObject> asObject() const;
+ bool isObject() const { return jsValue().isObject(); }
+ bool getNumber(double number) const { return jsValue().getNumber(number); }
+ UString getString(ExecState*) const;
+ bool isUndefinedOrNull() const { return jsValue().isUndefinedOrNull(); }
+
+private:
+ JSValue jsValue() const { return static_cast<const Base*>(this)->get(); }
};
template <typename T> class Handle : public HandleBase, public HandleConverter<Handle<T>, T> {
public:
+ template <typename A, typename B> friend class HandleConverter;
typedef typename HandleTypes<T>::ExternalType ExternalType;
template <typename U> Handle(Handle<U> o)
{
@@ -144,6 +153,11 @@ private:
}
};
+template <typename Base> Handle<JSObject> HandleConverter<Base, Unknown>::asObject() const
+{
+ return Handle<JSObject>::wrapSlot(static_cast<const Base*>(this)->slot());
+}
+
template <typename T, typename U> inline bool operator==(const Handle<T>& a, const Handle<U>& b)
{
return a.get() == b.get();
diff --git a/Source/JavaScriptCore/collector/handles/HandleHeap.cpp b/Source/JavaScriptCore/collector/handles/HandleHeap.cpp
index 32fa42d..1beb407 100644
--- a/Source/JavaScriptCore/collector/handles/HandleHeap.cpp
+++ b/Source/JavaScriptCore/collector/handles/HandleHeap.cpp
@@ -51,11 +51,11 @@ void HandleHeap::grow()
}
}
-void HandleHeap::markStrongHandles(MarkStack& markStack)
+void HandleHeap::markStrongHandles(HeapRootMarker& heapRootMarker)
{
Node* end = m_strongList.end();
for (Node* node = m_strongList.begin(); node != end; node = node->next())
- markStack.deprecatedAppend(node->slot());
+ heapRootMarker.mark(node->slot());
}
void HandleHeap::updateAfterMark()
@@ -79,7 +79,10 @@ void HandleHeap::clearWeakPointers()
JSCell* cell = value.asCell();
ASSERT(!cell || cell->structure());
-
+
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!cell->isZombie());
+#endif
if (Heap::isMarked(cell))
continue;
diff --git a/Source/JavaScriptCore/collector/handles/HandleHeap.h b/Source/JavaScriptCore/collector/handles/HandleHeap.h
index 4bb9b00..ed462d4 100644
--- a/Source/JavaScriptCore/collector/handles/HandleHeap.h
+++ b/Source/JavaScriptCore/collector/handles/HandleHeap.h
@@ -36,7 +36,7 @@ namespace JSC {
class HandleHeap;
class JSGlobalData;
class JSValue;
-class MarkStack;
+class HeapRootMarker;
class Finalizer {
public:
@@ -56,7 +56,7 @@ public:
void makeWeak(HandleSlot, Finalizer*, void* context);
void makeSelfDestroying(HandleSlot, Finalizer*, void* context);
- void markStrongHandles(MarkStack&);
+ void markStrongHandles(HeapRootMarker&);
void updateAfterMark();
// Should only be called during teardown.
diff --git a/Source/JavaScriptCore/collector/handles/HandleStack.cpp b/Source/JavaScriptCore/collector/handles/HandleStack.cpp
new file mode 100644
index 0000000..1c151af
--- /dev/null
+++ b/Source/JavaScriptCore/collector/handles/HandleStack.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "HandleStack.h"
+
+#include "MarkStack.h"
+
+namespace JSC {
+
+HandleStack::HandleStack()
+#ifndef NDEBUG
+ : m_scopeDepth(0)
+#endif
+{
+ grow();
+}
+
+void HandleStack::mark(HeapRootMarker& heapRootMarker)
+{
+ const Vector<HandleSlot>& blocks = m_blockStack.blocks();
+ size_t blockLength = m_blockStack.blockLength;
+
+ int end = blocks.size() - 1;
+ for (int i = 0; i < end; ++i) {
+ HandleSlot block = blocks[i];
+ heapRootMarker.mark(block, blockLength);
+ }
+ HandleSlot block = blocks[end];
+ heapRootMarker.mark(block, m_frame.m_next - block);
+}
+
+void HandleStack::grow()
+{
+ HandleSlot block = m_blockStack.grow();
+ m_frame.m_next = block;
+ m_frame.m_end = block + m_blockStack.blockLength;
+}
+
+}
diff --git a/Source/JavaScriptCore/collector/handles/HandleStack.h b/Source/JavaScriptCore/collector/handles/HandleStack.h
new file mode 100644
index 0000000..54e6c60
--- /dev/null
+++ b/Source/JavaScriptCore/collector/handles/HandleStack.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HandleStack_h
+#define HandleStack_h
+
+#include "Assertions.h"
+#include "BlockStack.h"
+#include "Handle.h"
+
+#include <wtf/UnusedParam.h>
+
+namespace JSC {
+
+class LocalScope;
+class HeapRootMarker;
+
+class HandleStack {
+public:
+ class Frame {
+ public:
+ HandleSlot m_next;
+ HandleSlot m_end;
+ };
+
+ HandleStack();
+
+ void enterScope(Frame&);
+ void leaveScope(Frame&);
+
+ HandleSlot push();
+
+ void mark(HeapRootMarker&);
+
+private:
+ void grow();
+ void zapTo(Frame&);
+ HandleSlot findFirstAfter(HandleSlot);
+
+#ifndef NDEBUG
+ size_t m_scopeDepth;
+#endif
+ BlockStack<JSValue> m_blockStack;
+ Frame m_frame;
+};
+
+inline void HandleStack::enterScope(Frame& lastFrame)
+{
+#ifndef NDEBUG
+ ++m_scopeDepth;
+#endif
+
+ lastFrame = m_frame;
+}
+
+
+
+inline void HandleStack::zapTo(Frame& lastFrame)
+{
+#ifdef NDEBUG
+ UNUSED_PARAM(lastFrame);
+#else
+ const Vector<HandleSlot>& blocks = m_blockStack.blocks();
+
+ if (lastFrame.m_end != m_frame.m_end) { // Zapping to a frame in a different block.
+ int i = blocks.size() - 1;
+ for ( ; blocks[i] + m_blockStack.blockLength != lastFrame.m_end; --i) {
+ for (int j = m_blockStack.blockLength - 1; j >= 0; --j)
+ blocks[i][j] = JSValue();
+ }
+
+ for (HandleSlot it = blocks[i] + m_blockStack.blockLength - 1; it != lastFrame.m_next - 1; --it)
+ *it = JSValue();
+
+ return;
+ }
+
+ for (HandleSlot it = m_frame.m_next - 1; it != lastFrame.m_next - 1; --it)
+ *it = JSValue();
+#endif
+}
+
+inline void HandleStack::leaveScope(Frame& lastFrame)
+{
+#ifndef NDEBUG
+ --m_scopeDepth;
+#endif
+
+ zapTo(lastFrame);
+
+ if (lastFrame.m_end != m_frame.m_end) // Popping to a frame in a different block.
+ m_blockStack.shrink(lastFrame.m_end);
+
+ m_frame = lastFrame;
+}
+
+inline HandleSlot HandleStack::push()
+{
+ ASSERT(m_scopeDepth); // Creating a Local outside of a LocalScope is a memory leak.
+ if (m_frame.m_next == m_frame.m_end)
+ grow();
+ return m_frame.m_next++;
+}
+
+}
+
+#endif
diff --git a/Source/JavaScriptCore/collector/handles/Local.h b/Source/JavaScriptCore/collector/handles/Local.h
new file mode 100644
index 0000000..035e9e9
--- /dev/null
+++ b/Source/JavaScriptCore/collector/handles/Local.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Local_h
+#define Local_h
+
+#include "Handle.h"
+#include "JSGlobalData.h"
+
+/*
+ A Local is a temporary handle whose lifetime is tied to a given LocalScope.
+ Use Locals for local values on the stack. It is an error to create a Local
+ outside of any LocalScope.
+*/
+
+namespace JSC {
+template <typename T> class Local;
+}
+
+namespace WTF {
+
+template<typename T> struct VectorTraits<JSC::Local<T> > {
+ static const bool needsDestruction = false;
+ static const bool needsInitialization = true;
+ static const bool canInitializeWithMemset = false;
+ static const bool canMoveWithMemcpy = true;
+ static const bool canCopyWithMemcpy = false;
+ static const bool canFillWithMemset = false;
+ static const bool canCompareWithMemcmp = true;
+};
+
+}
+
+namespace JSC {
+
+template <typename T> class Local : public Handle<T> {
+ friend class LocalScope;
+public:
+ typedef typename Handle<T>::ExternalType ExternalType;
+ Local(JSGlobalData&, ExternalType = ExternalType());
+ Local(JSGlobalData&, Handle<T>);
+ Local(const Local<T>&); // Adopting constructor. Used to return a Local to a calling function.
+
+ Local& operator=(ExternalType);
+ Local& operator=(Handle<T>);
+
+ using Handle<T>::slot;
+
+private:
+ Local(HandleSlot, ExternalType); // Used by LocalScope::release() to move a Local to a containing scope.
+ void internalSet(ExternalType value)
+ {
+ JSValue newValue(HandleTypes<T>::toJSValue(value));
+ HandleSlot slot = this->slot();
+ *slot = newValue;
+ }
+};
+
+template <typename T> inline Local<T>::Local(JSGlobalData& globalData, ExternalType value)
+ : Handle<T>(globalData.allocateLocalHandle())
+{
+ internalSet(value);
+}
+
+template <typename T> inline Local<T>::Local(JSGlobalData& globalData, Handle<T> handle)
+ : Handle<T>(globalData.allocateLocalHandle())
+{
+ internalSet(handle.get());
+}
+
+template <typename T> inline Local<T>::Local(const Local<T>& o)
+ : Handle<T>(o.slot())
+{
+ const_cast<Local<T>&>(o).invalidate(); // Prevent accidental sharing.
+}
+
+template <typename T> inline Local<T>::Local(HandleSlot slot, ExternalType value)
+ : Handle<T>(slot, value)
+{
+}
+
+template <typename T> inline Local<T>& Local<T>::operator=(ExternalType value)
+{
+ internalSet(value);
+ return *this;
+}
+
+template <typename T> inline Local<T>& Local<T>::operator=(Handle<T> handle)
+{
+ internalSet(handle.get());
+ return *this;
+}
+
+template <typename T, unsigned inlineCapacity = 0> class LocalStack {
+ typedef typename Handle<T>::ExternalType ExternalType;
+public:
+ LocalStack(JSGlobalData& globalData)
+ : m_globalData(&globalData)
+ , m_count(0)
+ {
+ }
+
+ ExternalType peek() const
+ {
+ ASSERT(m_count > 0);
+ return m_stack[m_count - 1].get();
+ }
+
+ ExternalType pop()
+ {
+ ASSERT(m_count > 0);
+ return m_stack[--m_count].get();
+ }
+
+ void push(ExternalType value)
+ {
+ if (m_count == m_stack.size())
+ m_stack.append(Local<T>(*m_globalData, value));
+ else
+ m_stack[m_count] = value;
+ m_count++;
+ }
+
+ bool isEmpty() const { return !m_count; }
+ unsigned size() const { return m_count; }
+
+private:
+ RefPtr<JSGlobalData> m_globalData;
+ Vector<Local<T>, inlineCapacity> m_stack;
+ unsigned m_count;
+};
+
+}
+
+#endif
diff --git a/Source/JavaScriptCore/collector/handles/LocalScope.h b/Source/JavaScriptCore/collector/handles/LocalScope.h
new file mode 100644
index 0000000..cd27b32
--- /dev/null
+++ b/Source/JavaScriptCore/collector/handles/LocalScope.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LocalScope_h
+#define LocalScope_h
+
+#include "HandleStack.h"
+#include "Local.h"
+
+namespace JSC {
+/*
+ A LocalScope is a temporary scope in which Locals are allocated. When a
+ LocalScope goes out of scope, all the Locals created in it are destroyed.
+
+ LocalScope is similar in concept to NSAutoreleasePool.
+*/
+
+class JSGlobalData;
+
+class LocalScope {
+public:
+ explicit LocalScope(JSGlobalData&);
+ ~LocalScope();
+
+ template <typename T> Local<T> release(Local<T>); // Destroys all other locals in the scope.
+
+private:
+ HandleStack* m_handleStack;
+ HandleStack::Frame m_lastFrame;
+};
+
+inline LocalScope::LocalScope(JSGlobalData& globalData)
+ : m_handleStack(globalData.heap.handleStack())
+{
+ m_handleStack->enterScope(m_lastFrame);
+}
+
+inline LocalScope::~LocalScope()
+{
+ m_handleStack->leaveScope(m_lastFrame);
+}
+
+template <typename T> Local<T> LocalScope::release(Local<T> local)
+{
+ typename Local<T>::ExternalType ptr = local.get();
+
+ m_handleStack->leaveScope(m_lastFrame);
+ HandleSlot slot = m_handleStack->push();
+ m_handleStack->enterScope(m_lastFrame);
+
+ return Local<T>(slot, ptr);
+}
+
+}
+
+#endif
diff --git a/Source/JavaScriptCore/config.h b/Source/JavaScriptCore/config.h
index 1c14917..ea10e77 100644
--- a/Source/JavaScriptCore/config.h
+++ b/Source/JavaScriptCore/config.h
@@ -29,6 +29,24 @@
#include <wtf/Platform.h>
+/* See note in wtf/Platform.h for more info on EXPORT_MACROS. */
+#if USE(EXPORT_MACROS)
+
+#include <wtf/ExportMacros.h>
+
+#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
+#define WTF_EXPORT_PRIVATE WTF_EXPORT
+#define JS_EXPORT_PRIVATE WTF_EXPORT
+#else
+#define WTF_EXPORT_PRIVATE WTF_IMPORT
+#define JS_EXPORT_PRIVATE WTF_IMPORT
+#endif
+
+#define JS_EXPORTDATA JS_EXPORT_PRIVATE
+#define JS_EXPORTCLASS JS_EXPORT_PRIVATE
+
+#else /* !USE(EXPORT_MACROS) */
+
#if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
#define JS_EXPORTDATA __declspec(dllexport)
@@ -41,6 +59,11 @@
#define JS_EXPORTCLASS
#endif
+#define WTF_EXPORT_PRIVATE JS_EXPORTDATA
+#define JS_EXPORT_PRIVATE JS_EXPORTDATA
+
+#endif /* USE(EXPORT_MACROS) */
+
#if OS(WINDOWS)
// If we don't define these, they get defined in windef.h.
diff --git a/Source/JavaScriptCore/debugger/Debugger.cpp b/Source/JavaScriptCore/debugger/Debugger.cpp
index b999446..64f6002 100644
--- a/Source/JavaScriptCore/debugger/Debugger.cpp
+++ b/Source/JavaScriptCore/debugger/Debugger.cpp
@@ -29,7 +29,9 @@
#include "Parser.h"
#include "Protect.h"
-namespace JSC {
+namespace {
+
+using namespace JSC;
class Recompiler {
public:
@@ -82,6 +84,10 @@ inline void Recompiler::operator()(JSCell* cell)
m_sourceProviders.add(executable->source().provider(), exec);
}
+} // namespace
+
+namespace JSC {
+
Debugger::~Debugger()
{
HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end();
@@ -118,16 +124,18 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
{
CallFrame* globalCallFrame = globalObject->globalExec();
+ JSGlobalData& globalData = globalObject->globalData();
- RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
- JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain());
- if (error)
- return error;
+ EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
+ if (!eval) {
+ exception = globalData.exception;
+ globalData.exception = JSValue();
+ return exception;
+ }
- JSGlobalData& globalData = globalObject->globalData();
- JSValue result = globalData.interpreter->execute(eval.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain());
+ JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scopeChain());
if (globalData.exception) {
- exception = globalData.exception.get();
+ exception = globalData.exception;
globalData.exception = JSValue();
}
ASSERT(result);
diff --git a/Source/JavaScriptCore/debugger/DebuggerActivation.cpp b/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
index 62a2e54..50ba746 100644
--- a/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
@@ -31,7 +31,7 @@
namespace JSC {
DebuggerActivation::DebuggerActivation(JSGlobalData& globalData, JSObject* activation)
- : JSNonFinalObject(DebuggerActivation::createStructure(jsNull()))
+ : JSNonFinalObject(DebuggerActivation::createStructure(globalData, jsNull()))
{
ASSERT(activation);
ASSERT(activation->isActivationObject());
diff --git a/Source/JavaScriptCore/debugger/DebuggerActivation.h b/Source/JavaScriptCore/debugger/DebuggerActivation.h
index 01a4907..f22d2ff 100644
--- a/Source/JavaScriptCore/debugger/DebuggerActivation.h
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.h
@@ -49,9 +49,9 @@ namespace JSC {
virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName);
virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index d778bd5..08fba4a 100644
--- a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -87,16 +87,17 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c
{
if (!m_callFrame->codeBlock())
return JSValue();
-
- RefPtr<EvalExecutable> eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
- JSObject* error = eval->compile(m_callFrame, m_callFrame->scopeChain());
- if (error)
- return error;
-
+
JSGlobalData& globalData = m_callFrame->globalData();
- JSValue result = globalData.interpreter->execute(eval.get(), m_callFrame, thisObject(), m_callFrame->scopeChain());
+ EvalExecutable* eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
+ if (globalData.exception) {
+ exception = globalData.exception;
+ globalData.exception = JSValue();
+ }
+
+ JSValue result = globalData.interpreter->execute(eval, m_callFrame, thisObject(), m_callFrame->scopeChain());
if (globalData.exception) {
- exception = globalData.exception.get();
+ exception = globalData.exception;
globalData.exception = JSValue();
}
ASSERT(result);
diff --git a/Source/JavaScriptCore/dfg/DFGAliasTracker.h b/Source/JavaScriptCore/dfg/DFGAliasTracker.h
new file mode 100644
index 0000000..8710169
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGAliasTracker.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGAliasTracker_h
+#define DFGAliasTracker_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGGraph.h>
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+// === AliasTracker ===
+//
+// This class id used to detect aliasing property accesses, which we may
+// be able to speculatively optimize (for example removing redundant loads
+// where we know a getter will not be called, or optimizing puts to arrays
+// where we know the value being written to in within length and is not a
+// hole value). In time, this should be more than a 1-deep buffer!
+class AliasTracker {
+public:
+ AliasTracker(Graph& graph)
+ : m_graph(graph)
+ , m_candidateAliasGetByVal(NoNode)
+ {
+ }
+
+ NodeIndex lookupGetByVal(NodeIndex base, NodeIndex property)
+ {
+ // Try to detect situations where a GetByVal follows another GetByVal to the same
+ // property; in these cases, we may be able to omit the subsequent get on the
+ // speculative path, where we know conditions hold to make this safe (for example,
+ // on the speculative path we will not have allowed getter access).
+ if (m_candidateAliasGetByVal != NoNode) {
+ Node& possibleAlias = m_graph[m_candidateAliasGetByVal];
+ ASSERT(possibleAlias.op == GetByVal);
+ // This check ensures the accesses alias, provided that the subscript is an
+ // integer index (this is good enough; the speculative path will only generate
+ // optimized accesses to handle integer subscripts).
+ if (possibleAlias.child1 == base && equalIgnoringLaterNumericConversion(possibleAlias.child2, property))
+ return m_candidateAliasGetByVal;
+ }
+ return NoNode;
+ }
+
+ void recordGetByVal(NodeIndex getByVal)
+ {
+ m_candidateAliasGetByVal = getByVal;
+ }
+
+ void recordPutByVal(NodeIndex putByVal)
+ {
+ ASSERT_UNUSED(putByVal, m_graph[putByVal].op == PutByVal || m_graph[putByVal].op == PutByValAlias);
+ m_candidateAliasGetByVal = NoNode;
+ }
+
+ void recordGetById(NodeIndex getById)
+ {
+ ASSERT_UNUSED(getById, m_graph[getById].op == GetById);
+ m_candidateAliasGetByVal = NoNode;
+ }
+
+ void recordPutById(NodeIndex putById)
+ {
+ ASSERT_UNUSED(putById, m_graph[putById].op == PutById);
+ m_candidateAliasGetByVal = NoNode;
+ }
+
+ void recordPutByIdDirect(NodeIndex putByVal)
+ {
+ ASSERT_UNUSED(putByVal, m_graph[putByVal].op == PutByIdDirect);
+ m_candidateAliasGetByVal = NoNode;
+ }
+
+private:
+ // This method returns true for arguments:
+ // - (X, X)
+ // - (X, ValueToNumber(X))
+ // - (X, ValueToInt32(X))
+ // - (X, NumberToInt32(X))
+ bool equalIgnoringLaterNumericConversion(NodeIndex op1, NodeIndex op2)
+ {
+ if (op1 == op2)
+ return true;
+ Node& node2 = m_graph[op2];
+ return (node2.op == ValueToNumber || node2.op == ValueToInt32 || node2.op == NumberToInt32) && op1 == node2.child1;
+ }
+
+ // The graph, to look up potentially aliasing nodes.
+ Graph& m_graph;
+ // Currently a 1-deep buffer!
+ NodeIndex m_candidateAliasGetByVal;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
new file mode 100644
index 0000000..03f5d4f
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGByteCodeParser.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAliasTracker.h"
+#include "DFGScoreBoard.h"
+#include "CodeBlock.h"
+
+namespace JSC { namespace DFG {
+
+// === ByteCodeParser ===
+//
+// This class is used to compile the dataflow graph from a CodeBlock.
+class ByteCodeParser {
+public:
+ ByteCodeParser(JSGlobalData* globalData, CodeBlock* codeBlock, Graph& graph)
+ : m_globalData(globalData)
+ , m_codeBlock(codeBlock)
+ , m_graph(graph)
+ , m_currentIndex(0)
+ , m_noArithmetic(true)
+ , m_constantUndefined(UINT_MAX)
+ , m_constant1(UINT_MAX)
+ {
+ unsigned numberOfConstants = codeBlock->numberOfConstantRegisters();
+ m_constantRecords.grow(numberOfConstants);
+
+ unsigned numberOfParameters = codeBlock->m_numParameters;
+ m_arguments.grow(numberOfParameters);
+ for (unsigned i = 0; i < numberOfParameters; ++i)
+ m_arguments[i] = NoNode;
+
+ unsigned numberOfRegisters = codeBlock->m_numCalleeRegisters;
+ m_calleeRegisters.grow(numberOfRegisters);
+ for (unsigned i = 0; i < numberOfRegisters; ++i)
+ m_calleeRegisters[i] = NoNode;
+ }
+
+ bool parse();
+
+private:
+ // Get/Set the operands/result of a bytecode instruction.
+ NodeIndex get(int operand)
+ {
+ // Is this a constant?
+ if (operand >= FirstConstantRegisterIndex) {
+ unsigned constant = operand - FirstConstantRegisterIndex;
+ ASSERT(constant < m_constantRecords.size());
+ return getJSConstant(constant);
+ }
+
+ // Is this an argument?
+ if (operand < 0) {
+ unsigned argument = operand + m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize;
+ ASSERT(argument < m_arguments.size());
+ return getArgument(argument);
+ }
+
+ // Must be a local or temporary.
+ ASSERT((unsigned)operand < m_calleeRegisters.size());
+ return getRegister((unsigned)operand);
+ }
+ void set(int operand, NodeIndex value)
+ {
+ // Is this an argument?
+ if (operand < 0) {
+ unsigned argument = operand + m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize;
+ ASSERT(argument < m_arguments.size());
+ return setArgument(argument, value);
+ }
+
+ // Must be a local or temporary.
+ ASSERT((unsigned)operand < m_calleeRegisters.size());
+ return setRegister((unsigned)operand, value);
+ }
+
+ // Used in implementing get/set, above, where the operand is a local or temporary.
+ NodeIndex getRegister(unsigned operand)
+ {
+ NodeIndex index = m_calleeRegisters[operand];
+ if (index != NoNode)
+ return index;
+ // We have not yet seen a definition for this value in this block.
+ // For now, since we are only generating single block functions,
+ // this value must be undefined.
+ // For example:
+ // function f() { var x; return x; }
+ return constantUndefined();
+ }
+ void setRegister(int operand, NodeIndex value)
+ {
+ m_calleeRegisters[operand] = value;
+ }
+
+ // Used in implementing get/set, above, where the operand is an argument.
+ NodeIndex getArgument(unsigned argument)
+ {
+ NodeIndex index = m_arguments[argument];
+ if (index != NoNode)
+ return index;
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(Argument, m_currentIndex, OpInfo(argument)));
+ return m_arguments[argument] = resultIndex;
+ }
+ void setArgument(int operand, NodeIndex value)
+ {
+ m_arguments[operand] = value;
+ }
+
+ // Get an operand, and perform a ToInt32/ToNumber conversion on it.
+ NodeIndex getToInt32(int operand)
+ {
+ // Avoid wastefully adding a JSConstant node to the graph, only to
+ // replace it with a Int32Constant (which is what would happen if
+ // we called 'toInt32(get(operand))' in this case).
+ if (operand >= FirstConstantRegisterIndex) {
+ JSValue v = m_codeBlock->getConstant(operand);
+ if (v.isInt32())
+ return getInt32Constant(v.asInt32(), operand - FirstConstantRegisterIndex);
+ }
+ return toInt32(get(operand));
+ }
+ NodeIndex getToNumber(int operand)
+ {
+ // Avoid wastefully adding a JSConstant node to the graph, only to
+ // replace it with a DoubleConstant (which is what would happen if
+ // we called 'toNumber(get(operand))' in this case).
+ if (operand >= FirstConstantRegisterIndex) {
+ JSValue v = m_codeBlock->getConstant(operand);
+ if (v.isNumber())
+ return getDoubleConstant(v.uncheckedGetNumber(), operand - FirstConstantRegisterIndex);
+ }
+ return toNumber(get(operand));
+ }
+
+ // Perform an ES5 ToInt32 operation - returns a node of type NodeResultInt32.
+ NodeIndex toInt32(NodeIndex index)
+ {
+ Node& node = m_graph[index];
+
+ if (node.hasInt32Result())
+ return index;
+
+ if (node.hasDoubleResult()) {
+ if (node.op == DoubleConstant)
+ return getInt32Constant(JSC::toInt32(valueOfDoubleConstant(index)), node.constantNumber());
+ // 'NumberToInt32(Int32ToNumber(X))' == X, and 'NumberToInt32(UInt32ToNumber(X)) == X'
+ if (node.op == Int32ToNumber || node.op == UInt32ToNumber)
+ return node.child1;
+
+ // We unique NumberToInt32 nodes in a map to prevent duplicate conversions.
+ pair<UnaryOpMap::iterator, bool> result = m_numberToInt32Nodes.add(index, NoNode);
+ // Either we added a new value, or the existing value in the map is non-zero.
+ ASSERT(result.second == (result.first->second == NoNode));
+ if (result.second)
+ result.first->second = addToGraph(NumberToInt32, index);
+ return result.first->second;
+ }
+
+ // Check for numeric constants boxed as JSValues.
+ if (node.op == JSConstant) {
+ JSValue v = valueOfJSConstant(index);
+ if (v.isInt32())
+ return getInt32Constant(v.asInt32(), node.constantNumber());
+ if (v.isNumber())
+ return getInt32Constant(JSC::toInt32(v.uncheckedGetNumber()), node.constantNumber());
+ }
+
+ return addToGraph(ValueToInt32, index);
+ }
+
+ // Perform an ES5 ToNumber operation - returns a node of type NodeResultDouble.
+ NodeIndex toNumber(NodeIndex index)
+ {
+ Node& node = m_graph[index];
+
+ if (node.hasDoubleResult())
+ return index;
+
+ if (node.hasInt32Result()) {
+ if (node.op == Int32Constant)
+ return getDoubleConstant(valueOfInt32Constant(index), node.constantNumber());
+
+ // We unique Int32ToNumber nodes in a map to prevent duplicate conversions.
+ pair<UnaryOpMap::iterator, bool> result = m_int32ToNumberNodes.add(index, NoNode);
+ // Either we added a new value, or the existing value in the map is non-zero.
+ ASSERT(result.second == (result.first->second == NoNode));
+ if (result.second)
+ result.first->second = addToGraph(Int32ToNumber, index);
+ return result.first->second;
+ }
+
+ if (node.op == JSConstant) {
+ JSValue v = valueOfJSConstant(index);
+ if (v.isNumber())
+ return getDoubleConstant(v.uncheckedGetNumber(), node.constantNumber());
+ }
+
+ return addToGraph(ValueToNumber, index);
+ }
+
+
+ // Used in implementing get, above, where the operand is a constant.
+ NodeIndex getInt32Constant(int32_t value, unsigned constant)
+ {
+ NodeIndex index = m_constantRecords[constant].asInt32;
+ if (index != NoNode)
+ return index;
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(Int32Constant, m_currentIndex, OpInfo(constant)));
+ m_graph[resultIndex].setInt32Constant(value);
+ m_constantRecords[constant].asInt32 = resultIndex;
+ return resultIndex;
+ }
+ NodeIndex getDoubleConstant(double value, unsigned constant)
+ {
+ NodeIndex index = m_constantRecords[constant].asNumeric;
+ if (index != NoNode)
+ return index;
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(DoubleConstant, m_currentIndex, OpInfo(constant)));
+ m_graph[resultIndex].setDoubleConstant(value);
+ m_constantRecords[constant].asNumeric = resultIndex;
+ return resultIndex;
+ }
+ NodeIndex getJSConstant(unsigned constant)
+ {
+ NodeIndex index = m_constantRecords[constant].asJSValue;
+ if (index != NoNode)
+ return index;
+
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(JSConstant, m_currentIndex, OpInfo(constant)));
+ m_constantRecords[constant].asJSValue = resultIndex;
+ return resultIndex;
+ }
+
+ // Helper functions to get/set the this value.
+ NodeIndex getThis()
+ {
+ return getArgument(0);
+ }
+ void setThis(NodeIndex value)
+ {
+ setArgument(0, value);
+ }
+
+ // Convenience methods for checking nodes for constants.
+ bool isInt32Constant(NodeIndex index)
+ {
+ return m_graph[index].op == Int32Constant;
+ }
+ bool isDoubleConstant(NodeIndex index)
+ {
+ return m_graph[index].op == DoubleConstant;
+ }
+ bool isJSConstant(NodeIndex index)
+ {
+ return m_graph[index].op == JSConstant;
+ }
+
+ // Convenience methods for getting constant values.
+ int32_t valueOfInt32Constant(NodeIndex index)
+ {
+ ASSERT(isInt32Constant(index));
+ return m_graph[index].int32Constant();
+ }
+ double valueOfDoubleConstant(NodeIndex index)
+ {
+ ASSERT(isDoubleConstant(index));
+ return m_graph[index].numericConstant();
+ }
+ JSValue valueOfJSConstant(NodeIndex index)
+ {
+ ASSERT(isJSConstant(index));
+ return m_codeBlock->getConstant(FirstConstantRegisterIndex + m_graph[index].constantNumber());
+ }
+
+ // This method returns a JSConstant with the value 'undefined'.
+ NodeIndex constantUndefined()
+ {
+ // Has m_constantUndefined been set up yet?
+ if (m_constantUndefined == UINT_MAX) {
+ // Search the constant pool for undefined, if we find it, we can just reuse this!
+ unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
+ for (m_constantUndefined = 0; m_constantUndefined < numberOfConstants; ++m_constantUndefined) {
+ JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantUndefined);
+ if (testMe.isUndefined())
+ return getJSConstant(m_constantUndefined);
+ }
+
+ // Add undefined to the CodeBlock's constants, and add a corresponding slot in m_constantRecords.
+ ASSERT(m_constantRecords.size() == numberOfConstants);
+ m_codeBlock->addConstant(jsUndefined());
+ m_constantRecords.append(ConstantRecord());
+ ASSERT(m_constantRecords.size() == m_codeBlock->numberOfConstantRegisters());
+ }
+
+ // m_constantUndefined must refer to an entry in the CodeBlock's constant pool that has the value 'undefined'.
+ ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantUndefined).isUndefined());
+ return getJSConstant(m_constantUndefined);
+ }
+
+ // This method returns a DoubleConstant with the value 1.
+ NodeIndex one()
+ {
+ // Has m_constant1 been set up yet?
+ if (m_constant1 == UINT_MAX) {
+ // Search the constant pool for the value 1, if we find it, we can just reuse this!
+ unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
+ for (m_constant1 = 0; m_constant1 < numberOfConstants; ++m_constant1) {
+ JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1);
+ if (testMe.isInt32() && testMe.asInt32() == 1)
+ return getDoubleConstant(1, m_constant1);
+ }
+
+ // Add the value 1 to the CodeBlock's constants, and add a corresponding slot in m_constantRecords.
+ ASSERT(m_constantRecords.size() == numberOfConstants);
+ m_codeBlock->addConstant(jsNumber(1));
+ m_constantRecords.append(ConstantRecord());
+ ASSERT(m_constantRecords.size() == m_codeBlock->numberOfConstantRegisters());
+ }
+
+ // m_constant1 must refer to an entry in the CodeBlock's constant pool that has the integer value 1.
+ ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).isInt32());
+ ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).asInt32() == 1);
+ return getDoubleConstant(1, m_constant1);
+ }
+
+
+ // These methods create a node and add it to the graph. If nodes of this type are
+ // 'mustGenerate' then the node will implicitly be ref'ed to ensure generation.
+ NodeIndex addToGraph(NodeType op, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ {
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(op, m_currentIndex, child1, child2, child3));
+
+ if (op & NodeMustGenerate)
+ m_graph.ref(resultIndex);
+ return resultIndex;
+ }
+ NodeIndex addToGraph(NodeType op, OpInfo info, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ {
+ NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ m_graph.append(Node(op, m_currentIndex, info, child1, child2, child3));
+
+ if (op & NodeMustGenerate)
+ m_graph.ref(resultIndex);
+ return resultIndex;
+ }
+
+ JSGlobalData* m_globalData;
+ CodeBlock* m_codeBlock;
+ Graph& m_graph;
+
+ // The bytecode index of the current instruction being generated.
+ unsigned m_currentIndex;
+
+ // FIXME: used to temporarily disable arithmetic, until we fix associated performance regressions.
+ bool m_noArithmetic;
+
+ // We use these values during code generation, and to avoid the need for
+ // special handling we make sure they are available as constants in the
+ // CodeBlock's constant pool. These variables are initialized to
+ // UINT_MAX, and lazily updated to hold an index into the CodeBlock's
+ // constant pool, as necessary.
+ unsigned m_constantUndefined;
+ unsigned m_constant1;
+
+ // A constant in the constant pool may be represented by more than one
+ // node in the graph, depending on the context in which it is being used.
+ struct ConstantRecord {
+ ConstantRecord()
+ : asInt32(NoNode)
+ , asNumeric(NoNode)
+ , asJSValue(NoNode)
+ {
+ }
+
+ NodeIndex asInt32;
+ NodeIndex asNumeric;
+ NodeIndex asJSValue;
+ };
+ Vector <ConstantRecord, 32> m_constantRecords;
+
+ // Track the index of the node whose result is the current value for every
+ // register value in the bytecode - argument, local, and temporary.
+ Vector <NodeIndex, 32> m_arguments;
+ Vector <NodeIndex, 32> m_calleeRegisters;
+
+ // These maps are used to unique ToNumber and ToInt32 operations.
+ typedef HashMap<NodeIndex, NodeIndex> UnaryOpMap;
+ UnaryOpMap m_int32ToNumberNodes;
+ UnaryOpMap m_numberToInt32Nodes;
+};
+
+#define NEXT_OPCODE(name) \
+ m_currentIndex += OPCODE_LENGTH(name); \
+ continue;
+
+bool ByteCodeParser::parse()
+{
+ AliasTracker aliases(m_graph);
+
+ Interpreter* interpreter = m_globalData->interpreter;
+ Instruction* instructionsBegin = m_codeBlock->instructions().begin();
+ while (true) {
+ // Switch on the current bytecode opcode.
+ Instruction* currentInstruction = instructionsBegin + m_currentIndex;
+ switch (interpreter->getOpcodeID(currentInstruction->u.opcode)) {
+
+ // === Function entry opcodes ===
+
+ case op_enter:
+ // This is a no-op for now - may need to initialize locals, if
+ // DCE analysis cannot determine that the values are never read.
+ NEXT_OPCODE(op_enter);
+
+ case op_convert_this: {
+ NodeIndex op1 = getThis();
+ setThis(addToGraph(ConvertThis, op1));
+ NEXT_OPCODE(op_convert_this);
+ }
+
+ // === Bitwise operations ===
+
+ case op_bitand: {
+ NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2));
+ NEXT_OPCODE(op_bitand);
+ }
+
+ case op_bitor: {
+ NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2));
+ NEXT_OPCODE(op_bitor);
+ }
+
+ case op_bitxor: {
+ NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2));
+ NEXT_OPCODE(op_bitxor);
+ }
+
+ case op_rshift: {
+ NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ NodeIndex result;
+ // Optimize out shifts by zero.
+ if (isInt32Constant(op2) && !(valueOfInt32Constant(op2) & 0x1f))
+ result = op1;
+ else
+ result = addToGraph(BitRShift, op1, op2);
+ set(currentInstruction[1].u.operand, result);
+ NEXT_OPCODE(op_rshift);
+ }
+
+ case op_lshift: {
+ NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ NodeIndex result;
+ // Optimize out shifts by zero.
+ if (isInt32Constant(op2) && !(valueOfInt32Constant(op2) & 0x1f))
+ result = op1;
+ else
+ result = addToGraph(BitLShift, op1, op2);
+ set(currentInstruction[1].u.operand, result);
+ NEXT_OPCODE(op_lshift);
+ }
+
+ case op_urshift: {
+ NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ NodeIndex result;
+ // The result of a zero-extending right shift is treated as an unsigned value.
+ // This means that if the top bit is set, the result is not in the int32 range,
+ // and as such must be stored as a double. If the shift amount is a constant,
+ // we may be able to optimize.
+ if (isInt32Constant(op2)) {
+ // If we know we are shifting by a non-zero amount, then since the operation
+ // zero fills we know the top bit of the result must be zero, and as such the
+ // result must be within the int32 range. Conversely, if this is a shift by
+ // zero, then the result may be changed by the conversion to unsigned, but it
+ // is not necessary to perform the shift!
+ if (valueOfInt32Constant(op2) & 0x1f)
+ result = addToGraph(BitURShift, op1, op2);
+ else
+ result = addToGraph(UInt32ToNumber, op1);
+ } else {
+ // Cannot optimize at this stage; shift & potentially rebox as a double.
+ result = addToGraph(BitURShift, op1, op2);
+ result = addToGraph(UInt32ToNumber, result);
+ }
+ set(currentInstruction[1].u.operand, result);
+ NEXT_OPCODE(op_urshift);
+ }
+
+ // === Increment/Decrement opcodes ===
+
+ case op_pre_inc: {
+ unsigned srcDst = currentInstruction[1].u.operand;
+ NodeIndex op = getToNumber(srcDst);
+ set(srcDst, addToGraph(ArithAdd, op, one()));
+ NEXT_OPCODE(op_pre_inc);
+ }
+
+ case op_post_inc: {
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned srcDst = currentInstruction[2].u.operand;
+ NodeIndex op = getToNumber(srcDst);
+ set(result, op);
+ set(srcDst, addToGraph(ArithAdd, op, one()));
+ NEXT_OPCODE(op_post_inc);
+ }
+
+ case op_pre_dec: {
+ unsigned srcDst = currentInstruction[1].u.operand;
+ NodeIndex op = getToNumber(srcDst);
+ set(srcDst, addToGraph(ArithSub, op, one()));
+ NEXT_OPCODE(op_pre_dec);
+ }
+
+ case op_post_dec: {
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned srcDst = currentInstruction[2].u.operand;
+ NodeIndex op = getToNumber(srcDst);
+ set(result, op);
+ set(srcDst, addToGraph(ArithSub, op, one()));
+ NEXT_OPCODE(op_post_dec);
+ }
+
+ // === Arithmetic operations ===
+
+ case op_add: {
+ m_noArithmetic = false;
+ NodeIndex op1 = get(currentInstruction[2].u.operand);
+ NodeIndex op2 = get(currentInstruction[3].u.operand);
+ // If both operands can statically be determined to the numbers, then this is an arithmetic add.
+ // Otherwise, we must assume this may be performing a concatenation to a string.
+ if (m_graph[op1].hasNumericResult() && m_graph[op2].hasNumericResult())
+ set(currentInstruction[1].u.operand, addToGraph(ArithAdd, toNumber(op1), toNumber(op2)));
+ else
+ set(currentInstruction[1].u.operand, addToGraph(ValueAdd, op1, op2));
+ NEXT_OPCODE(op_add);
+ }
+
+ case op_sub: {
+ m_noArithmetic = false;
+ NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(ArithSub, op1, op2));
+ NEXT_OPCODE(op_sub);
+ }
+
+ case op_mul: {
+ m_noArithmetic = false;
+ NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(ArithMul, op1, op2));
+ NEXT_OPCODE(op_mul);
+ }
+
+ case op_mod: {
+ m_noArithmetic = false;
+ NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(ArithMod, op1, op2));
+ NEXT_OPCODE(op_mod);
+ }
+
+ case op_div: {
+ m_noArithmetic = false;
+ NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
+ NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(ArithDiv, op1, op2));
+ NEXT_OPCODE(op_div);
+ }
+
+ // === Misc operations ===
+
+ case op_mov: {
+ NodeIndex op = get(currentInstruction[2].u.operand);
+ set(currentInstruction[1].u.operand, op);
+ NEXT_OPCODE(op_mov);
+ }
+
+ // === Property access operations ===
+
+ case op_get_by_val: {
+ NodeIndex base = get(currentInstruction[2].u.operand);
+ NodeIndex property = get(currentInstruction[3].u.operand);
+
+ NodeIndex getByVal = addToGraph(GetByVal, base, property, aliases.lookupGetByVal(base, property));
+ set(currentInstruction[1].u.operand, getByVal);
+ aliases.recordGetByVal(getByVal);
+
+ NEXT_OPCODE(op_get_by_val);
+ };
+
+ case op_put_by_val: {
+ NodeIndex base = get(currentInstruction[1].u.operand);
+ NodeIndex property = get(currentInstruction[2].u.operand);
+ NodeIndex value = get(currentInstruction[3].u.operand);
+
+ NodeIndex aliasedGet = aliases.lookupGetByVal(base, property);
+ NodeIndex putByVal = addToGraph(aliasedGet != NoNode ? PutByValAlias : PutByVal, base, property, value);
+ aliases.recordPutByVal(putByVal);
+
+ NEXT_OPCODE(op_put_by_val);
+ };
+
+ case op_get_by_id: {
+ NodeIndex base = get(currentInstruction[2].u.operand);
+ unsigned identifier = currentInstruction[3].u.operand;
+
+ NodeIndex getById = addToGraph(GetById, OpInfo(identifier), base);
+ set(currentInstruction[1].u.operand, getById);
+ aliases.recordGetById(getById);
+
+ NEXT_OPCODE(op_get_by_id);
+ }
+
+ case op_put_by_id: {
+ NodeIndex value = get(currentInstruction[3].u.operand);
+ NodeIndex base = get(currentInstruction[1].u.operand);
+ unsigned identifier = currentInstruction[2].u.operand;
+ bool direct = currentInstruction[8].u.operand;
+
+ if (direct) {
+ NodeIndex putByIdDirect = addToGraph(PutByIdDirect, OpInfo(identifier), base, value);
+ aliases.recordPutByIdDirect(putByIdDirect);
+ } else {
+ NodeIndex putById = addToGraph(PutById, OpInfo(identifier), base, value);
+ aliases.recordPutById(putById);
+ }
+
+ NEXT_OPCODE(op_put_by_id);
+ }
+
+ case op_get_global_var: {
+ NodeIndex getGlobalVar = addToGraph(GetGlobalVar, OpInfo(currentInstruction[2].u.operand));
+ set(currentInstruction[1].u.operand, getGlobalVar);
+ NEXT_OPCODE(op_get_global_var);
+ }
+
+ case op_put_global_var: {
+ NodeIndex value = get(currentInstruction[2].u.operand);
+ addToGraph(PutGlobalVar, OpInfo(currentInstruction[1].u.operand), value);
+ NEXT_OPCODE(op_put_global_var);
+ }
+
+ // === Block terminators. ===
+
+ case op_ret: {
+ addToGraph(Return, get(currentInstruction[1].u.operand));
+ m_currentIndex += OPCODE_LENGTH(op_ret);
+#if ENABLE(DFG_JIT_RESTRICTIONS)
+ // FIXME: temporarily disabling the DFG JIT for functions containing arithmetic.
+ return m_noArithmetic;
+#else
+ return true;
+#endif
+ }
+
+ default:
+ // parse failed!
+ return false;
+ }
+ }
+}
+
+bool parse(Graph& graph, JSGlobalData* globalData, CodeBlock* codeBlock)
+{
+ // Call ByteCodeParser::parse to build the dataflow for the basic block at 'startIndex'.
+ ByteCodeParser state(globalData, codeBlock, graph);
+ if (!state.parse())
+ return false;
+
+ // Assign VirtualRegisters.
+ ScoreBoard scoreBoard(graph);
+ Node* nodes = graph.begin();
+ size_t size = graph.size();
+ for (size_t i = 0; i < size; ++i) {
+ Node& node = nodes[i];
+ if (node.refCount) {
+ // First, call use on all of the current node's children, then
+ // allocate a VirtualRegister for this node. We do so in this
+ // order so that if a child is on its last use, and a
+ // VirtualRegister is freed, then it may be reused for node.
+ scoreBoard.use(node.child1);
+ scoreBoard.use(node.child2);
+ scoreBoard.use(node.child3);
+ node.virtualRegister = scoreBoard.allocate();
+ // 'mustGenerate' nodes have their useCount artificially elevated,
+ // call use now to account for this.
+ if (node.mustGenerate())
+ scoreBoard.use(i);
+ }
+ }
+
+ // 'm_numCalleeRegisters' is the number of locals and temporaries allocated
+ // for the function (and checked for on entry). Since we perform a new and
+ // different allocation of temporaries, more registers may now be required.
+ if ((unsigned)codeBlock->m_numCalleeRegisters < scoreBoard.allocatedCount())
+ codeBlock->m_numCalleeRegisters = scoreBoard.allocatedCount();
+
+#if DFG_DEBUG_VERBOSE
+ graph.dump(codeBlock);
+#endif
+ return true;
+}
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.h b/Source/JavaScriptCore/dfg/DFGByteCodeParser.h
new file mode 100644
index 0000000..d4efe61
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGByteCodeParser_h
+#define DFGByteCodeParser_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGGraph.h>
+
+namespace JSC {
+
+class CodeBlock;
+class JSGlobalData;
+
+namespace DFG {
+
+// Populate the Graph with a basic block of code from the CodeBlock,
+// starting at the provided bytecode index.
+bool parse(Graph&, JSGlobalData*, CodeBlock*);
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGGenerationInfo.h b/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
new file mode 100644
index 0000000..b3aa0cd
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGGenerationInfo_h
+#define DFGGenerationInfo_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGJITCompiler.h>
+
+namespace JSC { namespace DFG {
+
+// === DataFormat ===
+//
+// This enum tracks the current representation in which a value is being held.
+// Values may be unboxed primitives (int32, double, or cell), or boxed as a JSValue.
+// For boxed values, we may know the type of boxing that has taken place.
+// (May also need bool, array, object, string types!)
+enum DataFormat {
+ DataFormatNone = 0,
+ DataFormatInteger = 1,
+ DataFormatDouble = 2,
+ DataFormatCell = 3,
+ DataFormatJS = 8,
+ DataFormatJSInteger = DataFormatJS | DataFormatInteger,
+ DataFormatJSDouble = DataFormatJS | DataFormatDouble,
+ DataFormatJSCell = DataFormatJS | DataFormatCell,
+};
+
+// === GenerationInfo ===
+//
+// This class is used to track the current status of a live values during code generation.
+// Can provide information as to whether a value is in machine registers, and if so which,
+// whether a value has been spilled to the RegsiterFile, and if so may be able to provide
+// details of the format in memory (all values are spilled in a boxed form, but we may be
+// able to track the type of box), and tracks how many outstanding uses of a value remain,
+// so that we know when the value is dead and the machine registers associated with it
+// may be released.
+class GenerationInfo {
+public:
+ GenerationInfo()
+ : m_nodeIndex(NoNode)
+ , m_useCount(0)
+ , m_registerFormat(DataFormatNone)
+ , m_spillFormat(DataFormatNone)
+ , m_canFill(false)
+ {
+ }
+
+ // Used to set the generation info according the the result
+ // of various operations.
+ void initArgument(NodeIndex nodeIndex, uint32_t useCount)
+ {
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = DataFormatNone;
+ m_spillFormat = DataFormatNone;
+ m_canFill = true;
+ }
+ void initConstant(NodeIndex nodeIndex, uint32_t useCount)
+ {
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = DataFormatNone;
+ m_spillFormat = DataFormatNone;
+ m_canFill = true;
+ }
+ void initInteger(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
+ {
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = DataFormatInteger;
+ m_spillFormat = DataFormatNone;
+ m_canFill = false;
+ u.gpr = gpr;
+ }
+ void initJSValue(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS)
+ {
+ ASSERT(format & DataFormatJS);
+
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = format;
+ m_spillFormat = DataFormatNone;
+ m_canFill = false;
+ u.gpr = gpr;
+ }
+ void initCell(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
+ {
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = DataFormatCell;
+ m_spillFormat = DataFormatNone;
+ m_canFill = false;
+ u.gpr = gpr;
+ }
+ void initDouble(NodeIndex nodeIndex, uint32_t useCount, FPRReg fpr)
+ {
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = DataFormatDouble;
+ m_spillFormat = DataFormatNone;
+ m_canFill = false;
+ u.fpr = fpr;
+ }
+ void initNone(NodeIndex nodeIndex, uint32_t useCount)
+ {
+ m_nodeIndex = nodeIndex;
+ m_useCount = useCount;
+ m_registerFormat = DataFormatNone;
+ m_spillFormat = DataFormatNone;
+ m_canFill = false;
+ }
+
+ // Get the index of the node that produced this value.
+ NodeIndex nodeIndex() { return m_nodeIndex; }
+
+ // Mark the value as having been used (decrement the useCount).
+ // Returns true if this was the last use of the value, and any
+ // associated machine registers may be freed.
+ bool use()
+ {
+ return !--m_useCount;
+ }
+
+ // Used to check the operands of operations to see if they are on
+ // their last use; in some cases it may be safe to reuse the same
+ // machine register for the result of the operation.
+ bool canReuse()
+ {
+ ASSERT(m_useCount);
+ return m_useCount == 1;
+ }
+
+ // Get the format of the value in machine registers (or 'none').
+ DataFormat registerFormat() { return m_registerFormat; }
+ // Get the format of the value as it is spilled in the RegisterFile (or 'none').
+ DataFormat spillFormat() { return m_spillFormat; }
+
+ // Get the machine resister currently holding the value.
+ GPRReg gpr() { ASSERT(m_registerFormat && m_registerFormat != DataFormatDouble); return u.gpr; }
+ FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble); return u.fpr; }
+
+ // Check whether a value needs spilling in order to free up any associated machine registers.
+ bool needsSpill()
+ {
+ // This should only be called on values that are currently in a register.
+ ASSERT(m_registerFormat != DataFormatNone);
+ // Constants and arguments do not need spilling, nor do values
+ // that have already been spilled to the RegisterFile.
+ return !m_canFill;
+ }
+
+ // Called when a VirtualRegister is being spilled †o the RegisterFile for the first time.
+ void spill(DataFormat spillFormat)
+ {
+ // We shouldn't be spill values that don't need spilling.
+ ASSERT(!m_canFill);
+ ASSERT(m_spillFormat == DataFormatNone);
+ // We should only be spilling values that are currently in machine registers.
+ ASSERT(m_registerFormat != DataFormatNone);
+ // We only spill values that have been boxed as a JSValue; otherwise the GC
+ // would need a way to distinguish cell pointers from numeric primitives.
+ ASSERT(spillFormat & DataFormatJS);
+
+ m_registerFormat = DataFormatNone;
+ m_spillFormat = spillFormat;
+ m_canFill = true;
+ }
+
+ // Called on values that don't need spilling (constants, arguments,
+ // values that have already been spilled), to mark them as no longer
+ // being in machine registers.
+ void setSpilled()
+ {
+ // Should only be called on values that don't need spilling, and are currently in registers.
+ ASSERT(m_canFill && m_registerFormat != DataFormatNone);
+ m_registerFormat = DataFormatNone;
+ }
+
+ // Record that this value is filled into machine registers,
+ // tracking which registers, and what format the value has.
+ void fillJSValue(GPRReg gpr, DataFormat format = DataFormatJS)
+ {
+ ASSERT(format & DataFormatJS);
+ m_registerFormat = format;
+ u.gpr = gpr;
+ }
+ void fillInteger(GPRReg gpr)
+ {
+ m_registerFormat = DataFormatInteger;
+ u.gpr = gpr;
+ }
+ void fillDouble(FPRReg fpr)
+ {
+ m_registerFormat = DataFormatDouble;
+ u.fpr = fpr;
+ }
+
+#ifndef NDEBUG
+ bool alive()
+ {
+ return m_useCount;
+ }
+#endif
+
+private:
+ // The index of the node whose result is stored in this virtual register.
+ // FIXME: Can we remove this? - this is currently only used when collecting
+ // snapshots of the RegisterBank for SpeculationCheck/EntryLocation. Could
+ // investigate storing NodeIndex as the name in RegsiterBank, instead of
+ // VirtualRegister.
+ NodeIndex m_nodeIndex;
+ uint32_t m_useCount;
+ DataFormat m_registerFormat;
+ DataFormat m_spillFormat;
+ bool m_canFill;
+ union {
+ GPRReg gpr;
+ FPRReg fpr;
+ } u;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
new file mode 100644
index 0000000..be3beec
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGGraph.h"
+
+#include "CodeBlock.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+#ifndef NDEBUG
+void Graph::dump(CodeBlock* codeBlock)
+{
+ // Creates an array of stringized names.
+#define STRINGIZE_DFG_OP_ENUM(opcode, flags) #opcode ,
+ const char* dfgOpNames[] = {
+ FOR_EACH_DFG_OP(STRINGIZE_DFG_OP_ENUM)
+ };
+#undef STRINGIZE_DFG_OP_ENUM
+
+ Node* nodes = this->begin();
+
+ for (size_t i = 0; i < size(); ++i) {
+ Node& node = nodes[i];
+ NodeType op = node.op;
+
+ unsigned refCount = node.refCount;
+ if (!refCount)
+ continue;
+ bool mustGenerate = node.mustGenerate();
+ if (mustGenerate)
+ --refCount;
+
+ // Example/explanation of dataflow dump output
+ //
+ // 14: <!2:7> GetByVal(@3, @13)
+ // ^1 ^2 ^3 ^4 ^5
+ //
+ // (1) The nodeIndex of this operation.
+ // (2) The reference count. The number printed is the 'real' count,
+ // not including the 'mustGenerate' ref. If the node is
+ // 'mustGenerate' then the count it prefixed with '!'.
+ // (3) The virtual register slot assigned to this node.
+ // (4) The name of the operation.
+ // (5) The arguments to the operation. The may be of the form:
+ // @# - a NodeIndex referencing a prior node in the graph.
+ // arg# - an argument number.
+ // $# - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }.
+ // id# - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
+ // var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
+ printf("% 4d:\t<%c%u:%u>\t%s(", (int)i, mustGenerate ? '!' : ' ', refCount, node.virtualRegister, dfgOpNames[op & NodeIdMask]);
+ if (node.child1 != NoNode)
+ printf("@%u", node.child1);
+ if (node.child2 != NoNode)
+ printf(", @%u", node.child2);
+ if (node.child3 != NoNode)
+ printf(", @%u", node.child3);
+ bool hasPrinted = node.child1 != NoNode;
+
+ if (node.hasVarNumber()) {
+ printf("%svar%u", hasPrinted ? ", " : "", node.varNumber());
+ hasPrinted = true;
+ }
+ if (node.hasIdentifier()) {
+ if (codeBlock)
+ printf("%sid%u{%s}", hasPrinted ? ", " : "", node.identifierNumber(), codeBlock->identifier(node.identifierNumber()).ustring().utf8().data());
+ else
+ printf("%sid%u", hasPrinted ? ", " : "", node.identifierNumber());
+ hasPrinted = true;
+ }
+ if (node.isArgument()) {
+ printf("%sarg%u", hasPrinted ? ", " : "", node.argumentNumber());
+ hasPrinted = true;
+ }
+ if (op == Int32Constant) {
+ printf("%s$%u{%d|0x%08x}", hasPrinted ? ", " : "", node.constantNumber(), node.int32Constant(), node.int32Constant());
+ hasPrinted = true;
+ }
+ if (op == DoubleConstant) {
+ printf("%s$%u{%f})", hasPrinted ? ", " : "", node.constantNumber(), node.numericConstant());
+ hasPrinted = true;
+ }
+ if (op == JSConstant) {
+ printf("%s$%u", hasPrinted ? ", " : "", node.constantNumber());
+ hasPrinted = true;
+ }
+
+ printf(")\n");
+ }
+}
+#endif
+
+// FIXME: Convert this method to be iterative, not recursive.
+void Graph::refChildren(NodeIndex op)
+{
+ Node& node = at(op);
+
+ if (node.child1 == NoNode) {
+ ASSERT(node.child2 == NoNode && node.child3 == NoNode);
+ return;
+ }
+ ref(node.child1);
+
+ if (node.child2 == NoNode) {
+ ASSERT(node.child3 == NoNode);
+ return;
+ }
+ ref(node.child2);
+
+ if (node.child3 == NoNode)
+ return;
+ ref(node.child3);
+}
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
new file mode 100644
index 0000000..c02110e
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGGraph_h
+#define DFGGraph_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGNode.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+namespace DFG {
+
+//
+// === Graph ===
+//
+// The dataflow graph is an ordered vector of nodes.
+// The order may be significant for nodes with side-effects (property accesses, value conversions).
+// Nodes that are 'dead' remain in the vector with refCount 0.
+class Graph : public Vector<Node, 64> {
+public:
+ // Mark a node as being referenced.
+ void ref(NodeIndex nodeIndex)
+ {
+ // If the value (before incrementing) was at reCount zero then we need to ref its children.
+ if (!at(nodeIndex).refCount++)
+ refChildren(nodeIndex);
+ }
+
+#ifndef NDEBUG
+ // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
+ void dump(CodeBlock* = 0);
+#endif
+
+private:
+ // When a node's refCount goes from 0 to 1, it must (logically) recursively ref all of its children.
+ void refChildren(NodeIndex);
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp b/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
new file mode 100644
index 0000000..b945b5a
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGJITCodeGenerator.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNonSpeculativeJIT.h"
+#include "DFGSpeculativeJIT.h"
+#include "LinkBuffer.h"
+
+namespace JSC { namespace DFG {
+
+GPRReg JITCodeGenerator::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
+{
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ if (info.registerFormat() == DataFormatNone) {
+ GPRReg gpr = allocate();
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+
+ if (node.isConstant()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ if (isInt32Constant(nodeIndex)) {
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), reg);
+ info.fillInteger(gpr);
+ returnFormat = DataFormatInteger;
+ return gpr;
+ }
+ if (isDoubleConstant(nodeIndex)) {
+ JSValue jsValue = jsNumber(valueOfDoubleConstant(nodeIndex));
+ m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), reg);
+ } else {
+ ASSERT(isJSConstant(nodeIndex));
+ JSValue jsValue = valueOfJSConstant(nodeIndex);
+ m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), reg);
+ }
+ } else if (node.isArgument()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderArgument);
+ m_jit.loadPtr(m_jit.addressForArgument(m_jit.graph()[nodeIndex].argumentNumber()), reg);
+ } else {
+ ASSERT(info.spillFormat() == DataFormatJS || info.spillFormat() == DataFormatJSInteger);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
+ m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), reg);
+ }
+
+ // Since we statically know that we're filling an integer, and values
+ // in the RegisterFile are boxed, this must be DataFormatJSInteger.
+ // We will check this with a jitAssert below.
+ info.fillJSValue(gpr, DataFormatJSInteger);
+ unlock(gpr);
+ }
+
+ switch (info.registerFormat()) {
+ case DataFormatNone:
+ // Should have filled, above.
+ case DataFormatJSDouble:
+ case DataFormatDouble:
+ case DataFormatJS:
+ case DataFormatCell:
+ case DataFormatJSCell:
+ // Should only be calling this function if we know this operand to be integer.
+ ASSERT_NOT_REACHED();
+
+ case DataFormatJSInteger: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ m_jit.jitAssertIsJSInt32(gpr);
+ returnFormat = DataFormatJSInteger;
+ return gpr;
+ }
+
+ case DataFormatInteger: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ m_jit.jitAssertIsInt32(gpr);
+ returnFormat = DataFormatInteger;
+ return gpr;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return InvalidGPRReg;
+}
+
+FPRReg JITCodeGenerator::fillDouble(NodeIndex nodeIndex)
+{
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ if (info.registerFormat() == DataFormatNone) {
+ GPRReg gpr = allocate();
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+
+ if (node.isConstant()) {
+ if (isInt32Constant(nodeIndex)) {
+ // FIXME: should not be reachable?
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), reg);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ info.fillInteger(gpr);
+ unlock(gpr);
+ } else if (isDoubleConstant(nodeIndex)) {
+ FPRReg fpr = fprAllocate();
+ m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(nodeIndex)))), reg);
+ m_jit.movePtrToDouble(reg, JITCompiler::fprToRegisterID(fpr));
+ unlock(gpr);
+
+ m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
+ info.fillDouble(fpr);
+ return fpr;
+ } else {
+ // FIXME: should not be reachable?
+ ASSERT(isJSConstant(nodeIndex));
+ JSValue jsValue = valueOfJSConstant(nodeIndex);
+ m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), reg);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ info.fillJSValue(gpr, DataFormatJS);
+ unlock(gpr);
+ }
+ } else if (node.isArgument()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderArgument);
+ m_jit.loadPtr(m_jit.addressForArgument(m_jit.graph()[nodeIndex].argumentNumber()), reg);
+ info.fillJSValue(gpr, DataFormatJS);
+ unlock(gpr);
+ } else {
+ DataFormat spillFormat = info.spillFormat();
+ ASSERT(spillFormat & DataFormatJS);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
+ m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), reg);
+ info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
+ unlock(gpr);
+ }
+ }
+
+ switch (info.registerFormat()) {
+ case DataFormatNone:
+ // Should have filled, above.
+ case DataFormatCell:
+ case DataFormatJSCell:
+ // Should only be calling this function if we know this operand to be numeric.
+ ASSERT_NOT_REACHED();
+
+ case DataFormatJS: {
+ GPRReg jsValueGpr = info.gpr();
+ m_gprs.lock(jsValueGpr);
+ FPRReg fpr = fprAllocate();
+ GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?
+
+ JITCompiler::RegisterID jsValueReg = JITCompiler::gprToRegisterID(jsValueGpr);
+ JITCompiler::FPRegisterID fpReg = JITCompiler::fprToRegisterID(fpr);
+ JITCompiler::RegisterID tempReg = JITCompiler::gprToRegisterID(tempGpr);
+
+ JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueReg, JITCompiler::tagTypeNumberRegister);
+
+ m_jit.jitAssertIsJSDouble(jsValueGpr);
+
+ // First, if we get here we have a double encoded as a JSValue
+ m_jit.move(jsValueReg, tempReg);
+ m_jit.addPtr(JITCompiler::tagTypeNumberRegister, tempReg);
+ m_jit.movePtrToDouble(tempReg, fpReg);
+ JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
+
+ // Finally, handle integers.
+ isInteger.link(&m_jit);
+ m_jit.convertInt32ToDouble(jsValueReg, fpReg);
+ hasUnboxedDouble.link(&m_jit);
+
+ m_gprs.release(jsValueGpr);
+ m_gprs.unlock(jsValueGpr);
+ m_gprs.unlock(tempGpr);
+ m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
+ info.fillDouble(fpr);
+ return fpr;
+ }
+
+ case DataFormatJSInteger:
+ case DataFormatInteger: {
+ FPRReg fpr = fprAllocate();
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+ JITCompiler::FPRegisterID fpReg = JITCompiler::fprToRegisterID(fpr);
+
+ m_jit.convertInt32ToDouble(reg, fpReg);
+
+ m_gprs.release(gpr);
+ m_gprs.unlock(gpr);
+ m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
+ info.fillDouble(fpr);
+ return fpr;
+ }
+
+ // Unbox the double
+ case DataFormatJSDouble: {
+ GPRReg gpr = info.gpr();
+ FPRReg fpr = unboxDouble(gpr);
+
+ m_gprs.release(gpr);
+ m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
+
+ info.fillDouble(fpr);
+ return fpr;
+ }
+
+ case DataFormatDouble: {
+ FPRReg fpr = info.fpr();
+ m_fprs.lock(fpr);
+ return fpr;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return InvalidFPRReg;
+}
+
+GPRReg JITCodeGenerator::fillJSValue(NodeIndex nodeIndex)
+{
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ switch (info.registerFormat()) {
+ case DataFormatNone: {
+ GPRReg gpr = allocate();
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+
+ if (node.isConstant()) {
+ if (isInt32Constant(nodeIndex)) {
+ info.fillJSValue(gpr, DataFormatJSInteger);
+ JSValue jsValue = jsNumber(valueOfInt32Constant(nodeIndex));
+ m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), reg);
+ } else if (isDoubleConstant(nodeIndex)) {
+ info.fillJSValue(gpr, DataFormatJSDouble);
+ JSValue jsValue(JSValue::EncodeAsDouble, valueOfDoubleConstant(nodeIndex));
+ m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), reg);
+ } else {
+ ASSERT(isJSConstant(nodeIndex));
+ JSValue jsValue = valueOfJSConstant(nodeIndex);
+ m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), reg);
+ info.fillJSValue(gpr, DataFormatJS);
+ }
+
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ } else if (node.isArgument()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderArgument);
+ m_jit.loadPtr(m_jit.addressForArgument(m_jit.graph()[nodeIndex].argumentNumber()), reg);
+ info.fillJSValue(gpr, DataFormatJS);
+ } else {
+ DataFormat spillFormat = info.spillFormat();
+ ASSERT(spillFormat & DataFormatJS);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
+ m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), reg);
+ info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
+ }
+ return gpr;
+ }
+
+ case DataFormatInteger: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ m_jit.orPtr(JITCompiler::tagTypeNumberRegister, JITCompiler::gprToRegisterID(gpr));
+ info.fillJSValue(gpr, DataFormatJSInteger);
+ return gpr;
+ }
+
+ case DataFormatDouble: {
+ FPRReg fpr = info.fpr();
+ GPRReg gpr = boxDouble(fpr);
+
+ // Update all info
+ info.fillJSValue(gpr, DataFormatJSDouble);
+ m_fprs.release(fpr);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderJS);
+
+ return gpr;
+ }
+
+ case DataFormatCell:
+ // No retag required on JSVALUE64!
+ case DataFormatJS:
+ case DataFormatJSInteger:
+ case DataFormatJSDouble:
+ case DataFormatJSCell: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ return gpr;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return InvalidGPRReg;
+}
+
+void JITCodeGenerator::useChildren(Node& node)
+{
+ NodeIndex child1 = node.child1;
+ if (child1 == NoNode) {
+ ASSERT(node.child2 == NoNode && node.child3 == NoNode);
+ return;
+ }
+ use(child1);
+
+ NodeIndex child2 = node.child2;
+ if (child2 == NoNode) {
+ ASSERT(node.child3 == NoNode);
+ return;
+ }
+ use(child2);
+
+ NodeIndex child3 = node.child3;
+ if (child3 == NoNode)
+ return;
+ use(child3);
+}
+
+#ifndef NDEBUG
+static const char* dataFormatString(DataFormat format)
+{
+ // These values correspond to the DataFormat enum.
+ const char* strings[] = {
+ "[ ]",
+ "[ i]",
+ "[ d]",
+ "[ c]",
+ "Err!",
+ "Err!",
+ "Err!",
+ "Err!",
+ "[J ]",
+ "[Ji]",
+ "[Jd]",
+ "[Jc]",
+ "Err!",
+ "Err!",
+ "Err!",
+ "Err!",
+ };
+ return strings[format];
+}
+
+void JITCodeGenerator::dump(const char* label)
+{
+ if (label)
+ fprintf(stderr, "<%s>\n", label);
+
+ fprintf(stderr, " gprs:\n");
+ m_gprs.dump();
+ fprintf(stderr, " fprs:\n");
+ m_fprs.dump();
+ fprintf(stderr, " VirtualRegisters:\n");
+ for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
+ GenerationInfo& info = m_generationInfo[i];
+ if (info.alive())
+ fprintf(stderr, " % 3d:%s%s\n", i, dataFormatString(info.registerFormat()), dataFormatString(info.spillFormat()));
+ else
+ fprintf(stderr, " % 3d:[__][__]\n", i);
+ }
+ if (label)
+ fprintf(stderr, "</%s>\n", label);
+}
+#endif
+
+
+#if DFG_CONSISTENCY_CHECK
+void JITCodeGenerator::checkConsistency()
+{
+ VirtualRegister grpContents[numberOfGPRs];
+ VirtualRegister frpContents[numberOfFPRs];
+
+ for (unsigned i = 0; i < numberOfGPRs; ++i)
+ grpContents[i] = InvalidVirtualRegister;
+ for (unsigned i = 0; i < numberOfFPRs; ++i)
+ frpContents[i] = InvalidVirtualRegister;
+ for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
+ GenerationInfo& info = m_generationInfo[i];
+ if (!info.alive())
+ continue;
+ switch (info.registerFormat()) {
+ case DataFormatNone:
+ break;
+ case DataFormatInteger:
+ case DataFormatCell:
+ case DataFormatJS:
+ case DataFormatJSInteger:
+ case DataFormatJSDouble:
+ case DataFormatJSCell: {
+ GPRReg gpr = info.gpr();
+ ASSERT(gpr != InvalidGPRReg);
+ grpContents[gpr] = (VirtualRegister)i;
+ break;
+ }
+ case DataFormatDouble: {
+ FPRReg fpr = info.fpr();
+ ASSERT(fpr != InvalidFPRReg);
+ frpContents[fpr] = (VirtualRegister)i;
+ break;
+ }
+ }
+ }
+
+ for (GPRReg i = gpr0; i < numberOfGPRs; next(i)) {
+ if (m_gprs.isLocked(i) || m_gprs.name(i) != grpContents[i]) {
+ dump();
+ CRASH();
+ }
+ }
+ for (FPRReg i = fpr0; i < numberOfFPRs; next(i)) {
+ if (m_fprs.isLocked(i) || m_fprs.name(i) != frpContents[i]) {
+ dump();
+ CRASH();
+ }
+ }
+}
+#endif
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ m_gpr = m_jit->allocate();
+}
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.gpr();
+ if (m_jit->canReuse(op1.index()))
+ m_gpr = m_jit->reuse(op1.gpr());
+ else
+ m_gpr = m_jit->allocate();
+}
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1, SpeculateIntegerOperand& op2)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.gpr();
+ op2.gpr();
+ if (m_jit->canReuse(op1.index()))
+ m_gpr = m_jit->reuse(op1.gpr());
+ else if (m_jit->canReuse(op2.index()))
+ m_gpr = m_jit->reuse(op2.gpr());
+ else
+ m_gpr = m_jit->allocate();
+}
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.gpr();
+ if (m_jit->canReuse(op1.index()))
+ m_gpr = m_jit->reuse(op1.gpr());
+ else
+ m_gpr = m_jit->allocate();
+}
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1, IntegerOperand& op2)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.gpr();
+ op2.gpr();
+ if (m_jit->canReuse(op1.index()))
+ m_gpr = m_jit->reuse(op1.gpr());
+ else if (m_jit->canReuse(op2.index()))
+ m_gpr = m_jit->reuse(op2.gpr());
+ else
+ m_gpr = m_jit->allocate();
+}
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateCellOperand& op1)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.gpr();
+ if (m_jit->canReuse(op1.index()))
+ m_gpr = m_jit->reuse(op1.gpr());
+ else
+ m_gpr = m_jit->allocate();
+}
+
+GPRTemporary::GPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1)
+ : m_jit(jit)
+ , m_gpr(InvalidGPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.gpr();
+ if (m_jit->canReuse(op1.index()))
+ m_gpr = m_jit->reuse(op1.gpr());
+ else
+ m_gpr = m_jit->allocate();
+}
+
+FPRTemporary::FPRTemporary(JITCodeGenerator* jit)
+ : m_jit(jit)
+ , m_fpr(InvalidFPRReg)
+{
+ m_fpr = m_jit->fprAllocate();
+}
+
+FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1)
+ : m_jit(jit)
+ , m_fpr(InvalidFPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.fpr();
+ if (m_jit->canReuse(op1.index()))
+ m_fpr = m_jit->reuse(op1.fpr());
+ else
+ m_fpr = m_jit->fprAllocate();
+}
+
+FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1, DoubleOperand& op2)
+ : m_jit(jit)
+ , m_fpr(InvalidFPRReg)
+{
+ // locking into a register may free for reuse!
+ op1.fpr();
+ op2.fpr();
+ if (m_jit->canReuse(op1.index()))
+ m_fpr = m_jit->reuse(op1.fpr());
+ else if (m_jit->canReuse(op2.index()))
+ m_fpr = m_jit->reuse(op2.fpr());
+ else
+ m_fpr = m_jit->fprAllocate();
+}
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h b/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
new file mode 100644
index 0000000..a84cdc6
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
@@ -0,0 +1,955 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGJITCodeGenerator_h
+#define DFGJITCodeGenerator_h
+
+#if ENABLE(DFG_JIT)
+
+#include "CodeBlock.h"
+#include <dfg/DFGGenerationInfo.h>
+#include <dfg/DFGGraph.h>
+#include <dfg/DFGJITCompiler.h>
+#include <dfg/DFGOperations.h>
+#include <dfg/DFGRegisterBank.h>
+
+namespace JSC { namespace DFG {
+
+class SpeculateIntegerOperand;
+class SpeculateStrictInt32Operand;
+class SpeculateCellOperand;
+
+
+// === JITCodeGenerator ===
+//
+// This class provides common infrastructure used by the speculative &
+// non-speculative JITs. Provides common mechanisms for virtual and
+// physical register management, calls out from JIT code to helper
+// functions, etc.
+class JITCodeGenerator {
+protected:
+ typedef MacroAssembler::TrustedImm32 TrustedImm32;
+ typedef MacroAssembler::Imm32 Imm32;
+
+ // These constants are used to set priorities for spill order for
+ // the register allocator.
+ enum SpillOrder {
+ SpillOrderNone,
+ SpillOrderConstant = 1, // no spill, and cheap fill
+ SpillOrderSpilled = 2, // no spill
+ SpillOrderArgument = 3, // no spill, but we may lose typeinfo
+ SpillOrderJS = 4, // needs spill
+ SpillOrderCell = 4, // needs spill
+ SpillOrderInteger = 5, // needs spill and box
+ SpillOrderDouble = 6, // needs spill and convert
+ SpillOrderMax
+ };
+
+
+public:
+ GPRReg fillInteger(NodeIndex, DataFormat& returnFormat);
+ FPRReg fillDouble(NodeIndex);
+ GPRReg fillJSValue(NodeIndex);
+
+ // lock and unlock GPR & FPR registers.
+ void lock(GPRReg reg)
+ {
+ m_gprs.lock(reg);
+ }
+ void lock(FPRReg reg)
+ {
+ m_fprs.lock(reg);
+ }
+ void unlock(GPRReg reg)
+ {
+ m_gprs.unlock(reg);
+ }
+ void unlock(FPRReg reg)
+ {
+ m_fprs.unlock(reg);
+ }
+
+ // Used to check whether a child node is on its last use,
+ // and its machine registers may be reused.
+ bool canReuse(NodeIndex nodeIndex)
+ {
+ VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ return info.canReuse();
+ }
+ GPRReg reuse(GPRReg reg)
+ {
+ m_gprs.lock(reg);
+ return reg;
+ }
+ FPRReg reuse(FPRReg reg)
+ {
+ m_fprs.lock(reg);
+ return reg;
+ }
+
+ // Allocate a gpr/fpr.
+ GPRReg allocate()
+ {
+ VirtualRegister spillMe;
+ GPRReg gpr = m_gprs.allocate(spillMe);
+ if (spillMe != InvalidVirtualRegister)
+ spill(spillMe);
+ return gpr;
+ }
+ FPRReg fprAllocate()
+ {
+ VirtualRegister spillMe;
+ FPRReg fpr = m_fprs.allocate(spillMe);
+ if (spillMe != InvalidVirtualRegister)
+ spill(spillMe);
+ return fpr;
+ }
+
+ // Check whether a VirtualRegsiter is currently in a machine register.
+ // We use this when filling operands to fill those that are already in
+ // machine registers first (by locking VirtualRegsiters that are already
+ // in machine register before filling those that are not we attempt to
+ // avoid spilling values we will need immediately).
+ bool isFilled(NodeIndex nodeIndex)
+ {
+ VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ return info.registerFormat() != DataFormatNone;
+ }
+ bool isFilledDouble(NodeIndex nodeIndex)
+ {
+ VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ return info.registerFormat() == DataFormatDouble;
+ }
+
+protected:
+ JITCodeGenerator(JITCompiler& jit, bool isSpeculative)
+ : m_jit(jit)
+ , m_isSpeculative(isSpeculative)
+ , m_compileIndex(0)
+ , m_generationInfo(m_jit.codeBlock()->m_numCalleeRegisters)
+ {
+ }
+
+ // These methods convert between doubles, and doubles boxed and JSValues.
+ GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
+ {
+ JITCompiler::FPRegisterID fpReg = JITCompiler::fprToRegisterID(fpr);
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+ m_jit.moveDoubleToPtr(fpReg, reg);
+ m_jit.subPtr(JITCompiler::tagTypeNumberRegister, reg);
+ return gpr;
+ }
+ FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
+ {
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+ JITCompiler::FPRegisterID fpReg = JITCompiler::fprToRegisterID(fpr);
+ m_jit.addPtr(JITCompiler::tagTypeNumberRegister, reg);
+ m_jit.movePtrToDouble(reg, fpReg);
+ return fpr;
+ }
+ GPRReg boxDouble(FPRReg fpr)
+ {
+ return boxDouble(fpr, allocate());
+ }
+ FPRReg unboxDouble(GPRReg gpr)
+ {
+ return unboxDouble(gpr, fprAllocate());
+ }
+
+ // Called on an operand once it has been consumed by a parent node.
+ void use(NodeIndex nodeIndex)
+ {
+ VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ // use() returns true when the value becomes dead, and any
+ // associated resources may be freed.
+ if (!info.use())
+ return;
+
+ // Release the associated machine registers.
+ DataFormat registerFormat = info.registerFormat();
+ if (registerFormat == DataFormatDouble)
+ m_fprs.release(info.fpr());
+ else if (registerFormat != DataFormatNone)
+ m_gprs.release(info.gpr());
+ }
+
+ // Spill a VirtualRegister to the RegisterFile.
+ void spill(VirtualRegister spillMe)
+ {
+ GenerationInfo& info = m_generationInfo[spillMe];
+
+ // Check the GenerationInfo to see if this value need writing
+ // to the RegisterFile - if not, mark it as spilled & return.
+ if (!info.needsSpill()) {
+ info.setSpilled();
+ return;
+ }
+
+ DataFormat spillFormat = info.registerFormat();
+ if (spillFormat == DataFormatDouble) {
+ // All values are spilled as JSValues, so box the double via a temporary gpr.
+ GPRReg gpr = boxDouble(info.fpr());
+ m_jit.storePtr(JITCompiler::gprToRegisterID(gpr), JITCompiler::addressFor(spillMe));
+ unlock(gpr);
+ info.spill(DataFormatJSDouble);
+ return;
+ }
+
+ // The following code handles JSValues, int32s, and cells.
+ ASSERT(spillFormat == DataFormatInteger || spillFormat == DataFormatCell || spillFormat & DataFormatJS);
+
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(info.gpr());
+ // We need to box int32 and cell values ...
+ // but on JSVALUE64 boxing a cell is a no-op!
+ if (spillFormat == DataFormatInteger)
+ m_jit.orPtr(JITCompiler::tagTypeNumberRegister, reg);
+
+ // Spill the value, and record it as spilled in its boxed form.
+ m_jit.storePtr(reg, JITCompiler::addressFor(spillMe));
+ info.spill((DataFormat)(spillFormat | DataFormatJS));
+ }
+
+ // Checks/accessors for constant values.
+ bool isInt32Constant(NodeIndex nodeIndex) { return m_jit.isInt32Constant(nodeIndex); }
+ bool isDoubleConstant(NodeIndex nodeIndex) { return m_jit.isDoubleConstant(nodeIndex); }
+ bool isJSConstant(NodeIndex nodeIndex) { return m_jit.isJSConstant(nodeIndex); }
+ int32_t valueOfInt32Constant(NodeIndex nodeIndex) { return m_jit.valueOfInt32Constant(nodeIndex); }
+ double valueOfDoubleConstant(NodeIndex nodeIndex) { return m_jit.valueOfDoubleConstant(nodeIndex); }
+ JSValue valueOfJSConstant(NodeIndex nodeIndex) { return m_jit.valueOfJSConstant(nodeIndex); }
+
+ Identifier* identifier(unsigned index)
+ {
+ return &m_jit.codeBlock()->identifier(index);
+ }
+
+ // Spill all VirtualRegisters back to the RegisterFile.
+ void flushRegisters()
+ {
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister name = m_gprs.name(gpr);
+ if (name != InvalidVirtualRegister) {
+ spill(name);
+ m_gprs.release(gpr);
+ }
+ }
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister name = m_fprs.name(fpr);
+ if (name != InvalidVirtualRegister) {
+ spill(name);
+ m_fprs.release(fpr);
+ }
+ }
+ }
+
+#ifndef NDEBUG
+ // Used to ASSERT flushRegisters() has been called prior to
+ // calling out from JIT code to a C helper function.
+ bool isFlushed()
+ {
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister name = m_gprs.name(gpr);
+ if (name != InvalidVirtualRegister)
+ return false;
+ }
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister name = m_fprs.name(fpr);
+ if (name != InvalidVirtualRegister)
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ // Get the JSValue representation of a constant.
+ JSValue constantAsJSValue(NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ if (isInt32Constant(nodeIndex))
+ return jsNumber(node.int32Constant());
+ if (isDoubleConstant(nodeIndex))
+ return JSValue(JSValue::EncodeAsDouble, node.numericConstant());
+ ASSERT(isJSConstant(nodeIndex));
+ return valueOfJSConstant(nodeIndex);
+ }
+ MacroAssembler::ImmPtr constantAsJSValueAsImmPtr(NodeIndex nodeIndex)
+ {
+ return MacroAssembler::ImmPtr(JSValue::encode(constantAsJSValue(nodeIndex)));
+ }
+
+ // Helper functions to enable code sharing in implementations of bit/shift ops.
+ void bitOp(NodeType op, int32_t imm, MacroAssembler::RegisterID op1, MacroAssembler::RegisterID result)
+ {
+ switch (op) {
+ case BitAnd:
+ m_jit.and32(Imm32(imm), op1, result);
+ break;
+ case BitOr:
+ m_jit.or32(Imm32(imm), op1, result);
+ break;
+ case BitXor:
+ m_jit.xor32(Imm32(imm), op1, result);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+ void bitOp(NodeType op, MacroAssembler::RegisterID op1, MacroAssembler::RegisterID op2, MacroAssembler::RegisterID result)
+ {
+ switch (op) {
+ case BitAnd:
+ m_jit.and32(op1, op2, result);
+ break;
+ case BitOr:
+ m_jit.or32(op1, op2, result);
+ break;
+ case BitXor:
+ m_jit.xor32(op1, op2, result);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+ void shiftOp(NodeType op, MacroAssembler::RegisterID op1, int32_t shiftAmount, MacroAssembler::RegisterID result)
+ {
+ switch (op) {
+ case BitRShift:
+ m_jit.rshift32(op1, Imm32(shiftAmount), result);
+ break;
+ case BitLShift:
+ m_jit.lshift32(op1, Imm32(shiftAmount), result);
+ break;
+ case BitURShift:
+ m_jit.urshift32(op1, Imm32(shiftAmount), result);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+ void shiftOp(NodeType op, MacroAssembler::RegisterID op1, MacroAssembler::RegisterID shiftAmount, MacroAssembler::RegisterID result)
+ {
+ switch (op) {
+ case BitRShift:
+ m_jit.rshift32(op1, shiftAmount, result);
+ break;
+ case BitLShift:
+ m_jit.lshift32(op1, shiftAmount, result);
+ break;
+ case BitURShift:
+ m_jit.urshift32(op1, shiftAmount, result);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ // Called once a node has completed code generation but prior to setting
+ // its result, to free up its children. (This must happen prior to setting
+ // the nodes result, since the node may have the same VirtualRegister as
+ // a child, and as such will use the same GeneratioInfo).
+ void useChildren(Node&);
+
+ // These method called to initialize the the GenerationInfo
+ // to describe the result of an operation.
+ void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ useChildren(node);
+
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ if (format == DataFormatInteger) {
+ m_jit.jitAssertIsInt32(reg);
+ m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
+ info.initInteger(nodeIndex, node.refCount, reg);
+ } else {
+ ASSERT(format == DataFormatJSInteger);
+ m_jit.jitAssertIsJSInt32(reg);
+ m_gprs.retain(reg, virtualRegister, SpillOrderJS);
+ info.initJSValue(nodeIndex, node.refCount, reg, format);
+ }
+ }
+ void noResult(NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ useChildren(node);
+
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ info.initNone(nodeIndex, node.refCount);
+ }
+ void cellResult(GPRReg reg, NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ useChildren(node);
+
+ VirtualRegister virtualRegister = node.virtualRegister;
+ m_gprs.retain(reg, virtualRegister, SpillOrderCell);
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ info.initCell(nodeIndex, node.refCount, reg);
+ }
+ void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS)
+ {
+ if (format == DataFormatJSInteger)
+ m_jit.jitAssertIsJSInt32(reg);
+
+ Node& node = m_jit.graph()[nodeIndex];
+ useChildren(node);
+
+ VirtualRegister virtualRegister = node.virtualRegister;
+ m_gprs.retain(reg, virtualRegister, SpillOrderJS);
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ info.initJSValue(nodeIndex, node.refCount, reg, format);
+ }
+ void doubleResult(FPRReg reg, NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ useChildren(node);
+
+ VirtualRegister virtualRegister = node.virtualRegister;
+ m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+ info.initDouble(nodeIndex, node.refCount, reg);
+ }
+ void initConstantInfo(NodeIndex nodeIndex)
+ {
+ ASSERT(isInt32Constant(nodeIndex) || isDoubleConstant(nodeIndex) || isJSConstant(nodeIndex));
+ Node& node = m_jit.graph()[nodeIndex];
+ m_generationInfo[node.virtualRegister].initConstant(nodeIndex, node.refCount);
+ }
+ void initArgumentInfo(NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ m_generationInfo[node.virtualRegister].initArgument(nodeIndex, node.refCount);
+ }
+
+ // These methods used to sort arguments into the correct registers.
+ template<GPRReg destA, GPRReg destB>
+ void setupTwoStubArgs(GPRReg srcA, GPRReg srcB)
+ {
+ // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
+ // (1) both are already in arg regs, the right way around.
+ // (2) both are already in arg regs, the wrong way around.
+ // (3) neither are currently in arg registers.
+ // (4) srcA in in its correct reg.
+ // (5) srcA in in the incorrect reg.
+ // (6) srcB in in its correct reg.
+ // (7) srcB in in the incorrect reg.
+ //
+ // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
+ // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
+ // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
+ // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
+
+ if (srcB != destA) {
+ // Handle the easy cases - two simple moves.
+ m_jit.move(JITCompiler::gprToRegisterID(srcA), JITCompiler::gprToRegisterID(destA));
+ m_jit.move(JITCompiler::gprToRegisterID(srcB), JITCompiler::gprToRegisterID(destB));
+ } else if (srcA != destB) {
+ // Handle the non-swap case - just put srcB in place first.
+ m_jit.move(JITCompiler::gprToRegisterID(srcB), JITCompiler::gprToRegisterID(destB));
+ m_jit.move(JITCompiler::gprToRegisterID(srcA), JITCompiler::gprToRegisterID(destA));
+ } else
+ m_jit.swap(JITCompiler::gprToRegisterID(destB), JITCompiler::gprToRegisterID(destB));
+ }
+ template<FPRReg destA, FPRReg destB>
+ void setupTwoStubArgs(FPRReg srcA, FPRReg srcB)
+ {
+ // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
+ // (1) both are already in arg regs, the right way around.
+ // (2) both are already in arg regs, the wrong way around.
+ // (3) neither are currently in arg registers.
+ // (4) srcA in in its correct reg.
+ // (5) srcA in in the incorrect reg.
+ // (6) srcB in in its correct reg.
+ // (7) srcB in in the incorrect reg.
+ //
+ // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
+ // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
+ // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
+ // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
+
+ if (srcB != destA) {
+ // Handle the easy cases - two simple moves.
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(srcA), JITCompiler::fprToRegisterID(destA));
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(srcB), JITCompiler::fprToRegisterID(destB));
+ return;
+ }
+
+ if (srcA != destB) {
+ // Handle the non-swap case - just put srcB in place first.
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(srcB), JITCompiler::fprToRegisterID(destB));
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(srcA), JITCompiler::fprToRegisterID(destA));
+ return;
+ }
+
+ ASSERT(srcB == destA && srcA == destB);
+ // Need to swap; pick a temporary register.
+ FPRReg temp;
+ if (destA != JITCompiler::argumentFPR3 && destA != JITCompiler::argumentFPR3)
+ temp = JITCompiler::argumentFPR3;
+ else if (destA != JITCompiler::argumentFPR2 && destA != JITCompiler::argumentFPR2)
+ temp = JITCompiler::argumentFPR2;
+ else {
+ ASSERT(destA != JITCompiler::argumentFPR1 && destA != JITCompiler::argumentFPR1);
+ temp = JITCompiler::argumentFPR1;
+ }
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(destA), JITCompiler::fprToRegisterID(temp));
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(destB), JITCompiler::fprToRegisterID(destA));
+ m_jit.moveDouble(JITCompiler::fprToRegisterID(temp), JITCompiler::fprToRegisterID(destB));
+ }
+ void setupStubArguments(GPRReg arg1, GPRReg arg2)
+ {
+ setupTwoStubArgs<JITCompiler::argumentGPR1, JITCompiler::argumentGPR2>(arg1, arg2);
+ }
+ void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ // If neither of arg2/arg3 are in our way, then we can move arg1 into place.
+ // Then we can use setupTwoStubArgs to fix arg2/arg3.
+ if (arg2 != JITCompiler::argumentGPR1 && arg3 != JITCompiler::argumentGPR1) {
+ m_jit.move(JITCompiler::gprToRegisterID(arg1), JITCompiler::argumentRegister1);
+ setupTwoStubArgs<JITCompiler::argumentGPR2, JITCompiler::argumentGPR3>(arg2, arg3);
+ return;
+ }
+
+ // If neither of arg1/arg3 are in our way, then we can move arg2 into place.
+ // Then we can use setupTwoStubArgs to fix arg1/arg3.
+ if (arg1 != JITCompiler::argumentGPR2 && arg3 != JITCompiler::argumentGPR2) {
+ m_jit.move(JITCompiler::gprToRegisterID(arg2), JITCompiler::argumentRegister2);
+ setupTwoStubArgs<JITCompiler::argumentGPR1, JITCompiler::argumentGPR3>(arg1, arg3);
+ return;
+ }
+
+ // If neither of arg1/arg2 are in our way, then we can move arg3 into place.
+ // Then we can use setupTwoStubArgs to fix arg1/arg2.
+ if (arg1 != JITCompiler::argumentGPR3 && arg2 != JITCompiler::argumentGPR3) {
+ m_jit.move(JITCompiler::gprToRegisterID(arg3), JITCompiler::argumentRegister3);
+ setupTwoStubArgs<JITCompiler::argumentGPR1, JITCompiler::argumentGPR2>(arg1, arg2);
+ return;
+ }
+
+ // If we get here, we haven't been able to move any of arg1/arg2/arg3.
+ // Since all three are blocked, then all three must already be in the argument register.
+ // But are they in the right ones?
+
+ // First, ensure arg1 is in place.
+ if (arg1 != JITCompiler::argumentGPR1) {
+ m_jit.swap(JITCompiler::gprToRegisterID(arg1), JITCompiler::argumentRegister1);
+
+ // If arg1 wasn't in argumentGPR1, one of arg2/arg3 must be.
+ ASSERT(arg2 == JITCompiler::argumentGPR1 || arg3 == JITCompiler::argumentGPR1);
+ // If arg2 was in argumentGPR1 it no longer is (due to the swap).
+ // Otherwise arg3 must have been. Mark him as moved.
+ if (arg2 == JITCompiler::argumentGPR1)
+ arg2 = arg1;
+ else
+ arg3 = arg1;
+ }
+
+ // Either arg2 & arg3 need swapping, or we're all done.
+ ASSERT((arg2 == JITCompiler::argumentGPR2 || arg3 == JITCompiler::argumentGPR3)
+ || (arg2 == JITCompiler::argumentGPR3 || arg3 == JITCompiler::argumentGPR2));
+
+ if (arg2 != JITCompiler::argumentGPR2)
+ m_jit.swap(JITCompiler::argumentRegister2, JITCompiler::argumentRegister3);
+ }
+
+ // These methods add calls to C++ helper functions.
+ void callOperation(J_DFGOperation_EJP operation, GPRReg result, GPRReg arg1, void* pointer)
+ {
+ ASSERT(isFlushed());
+
+ m_jit.move(JITCompiler::gprToRegisterID(arg1), JITCompiler::argumentRegister1);
+ m_jit.move(JITCompiler::TrustedImmPtr(pointer), JITCompiler::argumentRegister2);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+
+ appendCallWithExceptionCheck(operation);
+ m_jit.move(JITCompiler::returnValueRegister, JITCompiler::gprToRegisterID(result));
+ }
+ void callOperation(J_DFGOperation_EJI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
+ {
+ callOperation((J_DFGOperation_EJP)operation, result, arg1, identifier);
+ }
+ void callOperation(J_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
+ {
+ ASSERT(isFlushed());
+
+ m_jit.move(JITCompiler::gprToRegisterID(arg1), JITCompiler::argumentRegister1);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+
+ appendCallWithExceptionCheck(operation);
+ m_jit.move(JITCompiler::returnValueRegister, JITCompiler::gprToRegisterID(result));
+ }
+ void callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ {
+ ASSERT(isFlushed());
+
+ setupStubArguments(arg1, arg2);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+
+ appendCallWithExceptionCheck(operation);
+ m_jit.move(JITCompiler::returnValueRegister, JITCompiler::gprToRegisterID(result));
+ }
+ void callOperation(V_DFGOperation_EJJP operation, GPRReg arg1, GPRReg arg2, void* pointer)
+ {
+ ASSERT(isFlushed());
+
+ setupStubArguments(arg1, arg2);
+ m_jit.move(JITCompiler::TrustedImmPtr(pointer), JITCompiler::argumentRegister3);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+
+ appendCallWithExceptionCheck(operation);
+ }
+ void callOperation(V_DFGOperation_EJJI operation, GPRReg arg1, GPRReg arg2, Identifier* identifier)
+ {
+ callOperation((V_DFGOperation_EJJP)operation, arg1, arg2, identifier);
+ }
+ void callOperation(V_DFGOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ ASSERT(isFlushed());
+
+ setupStubArguments(arg1, arg2, arg3);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+
+ appendCallWithExceptionCheck(operation);
+ }
+ void callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
+ {
+ ASSERT(isFlushed());
+
+ setupTwoStubArgs<JITCompiler::argumentFPR0, JITCompiler::argumentFPR1>(arg1, arg2);
+
+ m_jit.appendCall(operation);
+ m_jit.moveDouble(JITCompiler::fpReturnValueRegister, JITCompiler::fprToRegisterID(result));
+ }
+
+ void appendCallWithExceptionCheck(const FunctionPtr& function)
+ {
+ m_jit.appendCallWithExceptionCheck(function, m_jit.graph()[m_compileIndex].exceptionInfo);
+ }
+
+#ifndef NDEBUG
+ void dump(const char* label = 0);
+#endif
+
+#if DFG_CONSISTENCY_CHECK
+ void checkConsistency();
+#else
+ void checkConsistency() {}
+#endif
+
+ // The JIT, while also provides MacroAssembler functionality.
+ JITCompiler& m_jit;
+ // This flag is used to distinguish speculative and non-speculative
+ // code generation. This is significant when filling spilled values
+ // from the RegisterFile. When spilling we attempt to store information
+ // as to the type of boxed value being stored (int32, double, cell), and
+ // when filling on the speculative path we will retrieve this type info
+ // where available. On the non-speculative path, however, we cannot rely
+ // on the spill format info, since the a value being loaded might have
+ // been spilled by either the speculative or non-speculative paths (where
+ // we entered the non-speculative path on an intervening bail-out), and
+ // the value may have been boxed differently on the two paths.
+ bool m_isSpeculative;
+ // The current node being generated.
+ NodeIndex m_compileIndex;
+ // Virtual and physical register maps.
+ Vector<GenerationInfo, 32> m_generationInfo;
+ RegisterBank<GPRReg, numberOfGPRs, SpillOrder, SpillOrderNone, SpillOrderMax> m_gprs;
+ RegisterBank<FPRReg, numberOfFPRs, SpillOrder, SpillOrderNone, SpillOrderMax> m_fprs;
+};
+
+// === Operand types ===
+//
+// IntegerOperand, DoubleOperand and JSValueOperand.
+//
+// These classes are used to lock the operands to a node into machine
+// registers. These classes implement of pattern of locking a value
+// into register at the point of construction only if it is already in
+// registers, and otherwise loading it lazily at the point it is first
+// used. We do so in order to attempt to avoid spilling one operand
+// in order to make space available for another.
+
+class IntegerOperand {
+public:
+ explicit IntegerOperand(JITCodeGenerator* jit, NodeIndex index)
+ : m_jit(jit)
+ , m_index(index)
+ , m_gprOrInvalid(InvalidGPRReg)
+#ifndef NDEBUG
+ , m_format(DataFormatNone)
+#endif
+ {
+ ASSERT(m_jit);
+ if (jit->isFilled(index))
+ gpr();
+ }
+
+ ~IntegerOperand()
+ {
+ ASSERT(m_gprOrInvalid != InvalidGPRReg);
+ m_jit->unlock(m_gprOrInvalid);
+ }
+
+ NodeIndex index() const
+ {
+ return m_index;
+ }
+
+ GPRReg gpr()
+ {
+ if (m_gprOrInvalid == InvalidGPRReg)
+ m_gprOrInvalid = m_jit->fillInteger(index(), m_format);
+ return m_gprOrInvalid;
+ }
+
+ DataFormat format()
+ {
+ gpr(); // m_format is set when m_gpr is locked.
+ ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
+ return m_format;
+ }
+
+ MacroAssembler::RegisterID registerID()
+ {
+ return JITCompiler::gprToRegisterID(gpr());
+ }
+
+private:
+ JITCodeGenerator* m_jit;
+ NodeIndex m_index;
+ GPRReg m_gprOrInvalid;
+ DataFormat m_format;
+};
+
+class DoubleOperand {
+public:
+ explicit DoubleOperand(JITCodeGenerator* jit, NodeIndex index)
+ : m_jit(jit)
+ , m_index(index)
+ , m_fprOrInvalid(InvalidFPRReg)
+ {
+ ASSERT(m_jit);
+ if (jit->isFilledDouble(index))
+ fpr();
+ }
+
+ ~DoubleOperand()
+ {
+ ASSERT(m_fprOrInvalid != InvalidFPRReg);
+ m_jit->unlock(m_fprOrInvalid);
+ }
+
+ NodeIndex index() const
+ {
+ return m_index;
+ }
+
+ FPRReg fpr()
+ {
+ if (m_fprOrInvalid == InvalidFPRReg)
+ m_fprOrInvalid = m_jit->fillDouble(index());
+ return m_fprOrInvalid;
+ }
+
+ MacroAssembler::FPRegisterID registerID()
+ {
+ return JITCompiler::fprToRegisterID(fpr());
+ }
+
+private:
+ JITCodeGenerator* m_jit;
+ NodeIndex m_index;
+ FPRReg m_fprOrInvalid;
+};
+
+class JSValueOperand {
+public:
+ explicit JSValueOperand(JITCodeGenerator* jit, NodeIndex index)
+ : m_jit(jit)
+ , m_index(index)
+ , m_gprOrInvalid(InvalidGPRReg)
+ {
+ ASSERT(m_jit);
+ if (jit->isFilled(index))
+ gpr();
+ }
+
+ ~JSValueOperand()
+ {
+ ASSERT(m_gprOrInvalid != InvalidGPRReg);
+ m_jit->unlock(m_gprOrInvalid);
+ }
+
+ NodeIndex index() const
+ {
+ return m_index;
+ }
+
+ GPRReg gpr()
+ {
+ if (m_gprOrInvalid == InvalidGPRReg)
+ m_gprOrInvalid = m_jit->fillJSValue(index());
+ return m_gprOrInvalid;
+ }
+
+ MacroAssembler::RegisterID registerID()
+ {
+ return JITCompiler::gprToRegisterID(gpr());
+ }
+
+private:
+ JITCodeGenerator* m_jit;
+ NodeIndex m_index;
+ GPRReg m_gprOrInvalid;
+};
+
+
+// === Temporaries ===
+//
+// These classes are used to allocate temporary registers.
+// A mechanism is provided to attempt to reuse the registers
+// currently allocated to child nodes whose value is consumed
+// by, and not live after, this operation.
+
+class GPRTemporary {
+public:
+ GPRTemporary(JITCodeGenerator*);
+ GPRTemporary(JITCodeGenerator*, SpeculateIntegerOperand&);
+ GPRTemporary(JITCodeGenerator*, SpeculateIntegerOperand&, SpeculateIntegerOperand&);
+ GPRTemporary(JITCodeGenerator*, IntegerOperand&);
+ GPRTemporary(JITCodeGenerator*, IntegerOperand&, IntegerOperand&);
+ GPRTemporary(JITCodeGenerator*, SpeculateCellOperand&);
+ GPRTemporary(JITCodeGenerator*, JSValueOperand&);
+
+ ~GPRTemporary()
+ {
+ m_jit->unlock(gpr());
+ }
+
+ GPRReg gpr() const
+ {
+ ASSERT(m_gpr != InvalidGPRReg);
+ return m_gpr;
+ }
+
+ MacroAssembler::RegisterID registerID()
+ {
+ ASSERT(m_gpr != InvalidGPRReg);
+ return JITCompiler::gprToRegisterID(m_gpr);
+ }
+
+protected:
+ GPRTemporary(JITCodeGenerator* jit, GPRReg lockedGPR)
+ : m_jit(jit)
+ , m_gpr(lockedGPR)
+ {
+ }
+
+private:
+ JITCodeGenerator* m_jit;
+ GPRReg m_gpr;
+};
+
+class FPRTemporary {
+public:
+ FPRTemporary(JITCodeGenerator*);
+ FPRTemporary(JITCodeGenerator*, DoubleOperand&);
+ FPRTemporary(JITCodeGenerator*, DoubleOperand&, DoubleOperand&);
+
+ ~FPRTemporary()
+ {
+ m_jit->unlock(fpr());
+ }
+
+ FPRReg fpr() const
+ {
+ ASSERT(m_fpr != InvalidFPRReg);
+ return m_fpr;
+ }
+
+ MacroAssembler::FPRegisterID registerID()
+ {
+ ASSERT(m_fpr != InvalidFPRReg);
+ return JITCompiler::fprToRegisterID(m_fpr);
+ }
+
+protected:
+ FPRTemporary(JITCodeGenerator* jit, FPRReg lockedFPR)
+ : m_jit(jit)
+ , m_fpr(lockedFPR)
+ {
+ }
+
+private:
+ JITCodeGenerator* m_jit;
+ FPRReg m_fpr;
+};
+
+
+// === Results ===
+//
+// These classes lock the result of a call to a C++ helper function.
+
+class GPRResult : public GPRTemporary {
+public:
+ GPRResult(JITCodeGenerator* jit)
+ : GPRTemporary(jit, lockedResult(jit))
+ {
+ }
+
+private:
+ static GPRReg lockedResult(JITCodeGenerator* jit)
+ {
+ jit->lock(JITCompiler::returnValueGPR);
+ return JITCompiler::returnValueGPR;
+ }
+};
+
+class FPRResult : public FPRTemporary {
+public:
+ FPRResult(JITCodeGenerator* jit)
+ : FPRTemporary(jit, lockedResult(jit))
+ {
+ }
+
+private:
+ static FPRReg lockedResult(JITCodeGenerator* jit)
+ {
+ jit->lock(JITCompiler::returnValueFPR);
+ return JITCompiler::returnValueFPR;
+ }
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
+
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
new file mode 100644
index 0000000..5c5d5fe
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGJITCompiler.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "CodeBlock.h"
+#include "DFGJITCodeGenerator.h"
+#include "DFGNonSpeculativeJIT.h"
+#include "DFGOperations.h"
+#include "DFGRegisterBank.h"
+#include "DFGSpeculativeJIT.h"
+#include "JSGlobalData.h"
+#include "LinkBuffer.h"
+
+namespace JSC { namespace DFG {
+
+// This method used to fill a numeric value to a FPR when linking speculative -> non-speculative.
+void JITCompiler::fillNumericToDouble(NodeIndex nodeIndex, FPRReg fpr, GPRReg temporary)
+{
+ Node& node = graph()[nodeIndex];
+ MacroAssembler::RegisterID tempReg = gprToRegisterID(temporary);
+
+ // Arguments can't be know to be double, would need to have been a ValueToNumber node in the way!
+ ASSERT(!node.isArgument());
+
+ if (node.isConstant()) {
+ ASSERT(node.op == DoubleConstant);
+ move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(nodeIndex)))), tempReg);
+ movePtrToDouble(tempReg, fprToRegisterID(fpr));
+ } else {
+ loadPtr(addressFor(node.virtualRegister), tempReg);
+ Jump isInteger = branchPtr(MacroAssembler::AboveOrEqual, tempReg, tagTypeNumberRegister);
+ jitAssertIsJSDouble(gpr0);
+ addPtr(tagTypeNumberRegister, tempReg);
+ movePtrToDouble(tempReg, fprToRegisterID(fpr));
+ Jump hasUnboxedDouble = jump();
+ isInteger.link(this);
+ convertInt32ToDouble(tempReg, fprToRegisterID(fpr));
+ hasUnboxedDouble.link(this);
+ }
+}
+
+// This method used to fill an integer value to a GPR when linking speculative -> non-speculative.
+void JITCompiler::fillInt32ToInteger(NodeIndex nodeIndex, GPRReg gpr)
+{
+ Node& node = graph()[nodeIndex];
+
+ // Arguments can't be know to be int32, would need to have been a ValueToInt32 node in the way!
+ ASSERT(!node.isArgument());
+
+ if (node.isConstant()) {
+ ASSERT(node.op == Int32Constant);
+ move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gprToRegisterID(gpr));
+ } else {
+#if DFG_JIT_ASSERT
+ // Redundant load, just so we can check the tag!
+ loadPtr(addressFor(node.virtualRegister), gprToRegisterID(gpr));
+ jitAssertIsJSInt32(gpr);
+#endif
+ load32(addressFor(node.virtualRegister), gprToRegisterID(gpr));
+ }
+}
+
+// This method used to fill a JSValue to a GPR when linking speculative -> non-speculative.
+void JITCompiler::fillToJS(NodeIndex nodeIndex, GPRReg gpr)
+{
+ Node& node = graph()[nodeIndex];
+
+ if (node.isArgument()) {
+ loadPtr(addressForArgument(node.argumentNumber()), gprToRegisterID(gpr));
+ return;
+ }
+
+ if (node.isConstant()) {
+ if (isInt32Constant(nodeIndex)) {
+ JSValue jsValue = jsNumber(valueOfInt32Constant(nodeIndex));
+ move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gprToRegisterID(gpr));
+ } else if (isDoubleConstant(nodeIndex)) {
+ JSValue jsValue(JSValue::EncodeAsDouble, valueOfDoubleConstant(nodeIndex));
+ move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gprToRegisterID(gpr));
+ } else {
+ ASSERT(isJSConstant(nodeIndex));
+ JSValue jsValue = valueOfJSConstant(nodeIndex);
+ move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gprToRegisterID(gpr));
+ }
+ return;
+ }
+
+ loadPtr(addressFor(node.virtualRegister), gprToRegisterID(gpr));
+}
+
+void JITCompiler::jumpFromSpeculativeToNonSpeculative(const SpeculationCheck& check, const EntryLocation& entry, SpeculationRecovery* recovery)
+{
+ ASSERT(check.m_nodeIndex == entry.m_nodeIndex);
+
+ // Link the jump from the Speculative path to here.
+ check.m_check.link(this);
+
+ // Does this speculation check require any additional recovery to be performed,
+ // to restore any state that has been overwritten before we enter back in to the
+ // non-speculative path.
+ if (recovery) {
+ // The only additional recovery we currently support is for integer add operation
+ ASSERT(recovery->type() == SpeculativeAdd);
+ // Revert the add.
+ sub32(gprToRegisterID(recovery->src()), gprToRegisterID(recovery->dest()));
+ }
+
+ // FIXME: - This is hideously inefficient!
+ // Where a value is live in a register in the speculative path, and is required in a register
+ // on the non-speculative path, we should not need to be spilling it and reloading (we may
+ // need to spill anyway, if the value is marked as spilled on the non-speculative path).
+ // This may also be spilling values that don't need spilling, e.g. are already spilled,
+ // are constants, or are arguments.
+
+ // Spill all GPRs in use by the speculative path.
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ NodeIndex nodeIndex = check.m_gprInfo[gpr].nodeIndex;
+ if (nodeIndex == NoNode)
+ continue;
+
+ DataFormat dataFormat = check.m_gprInfo[gpr].format;
+ VirtualRegister virtualRegister = graph()[nodeIndex].virtualRegister;
+
+ ASSERT(dataFormat == DataFormatInteger || DataFormatCell || dataFormat & DataFormatJS);
+ if (dataFormat == DataFormatInteger)
+ orPtr(tagTypeNumberRegister, gprToRegisterID(gpr));
+ storePtr(gprToRegisterID(gpr), addressFor(virtualRegister));
+ }
+
+ // Spill all FPRs in use by the speculative path.
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ NodeIndex nodeIndex = check.m_fprInfo[fpr];
+ if (nodeIndex == NoNode)
+ continue;
+
+ VirtualRegister virtualRegister = graph()[nodeIndex].virtualRegister;
+
+ moveDoubleToPtr(fprToRegisterID(fpr), regT0);
+ subPtr(tagTypeNumberRegister, regT0);
+ storePtr(regT0, addressFor(virtualRegister));
+ }
+
+ // Fill all FPRs in use by the non-speculative path.
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ NodeIndex nodeIndex = entry.m_fprInfo[fpr];
+ if (nodeIndex == NoNode)
+ continue;
+
+ fillNumericToDouble(nodeIndex, fpr, gpr0);
+ }
+
+ // Fill all GPRs in use by the non-speculative path.
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ NodeIndex nodeIndex = entry.m_gprInfo[gpr].nodeIndex;
+ if (nodeIndex == NoNode)
+ continue;
+
+ DataFormat dataFormat = entry.m_gprInfo[gpr].format;
+ if (dataFormat == DataFormatInteger)
+ fillInt32ToInteger(nodeIndex, gpr);
+ else {
+ ASSERT(dataFormat & DataFormatJS || dataFormat == DataFormatCell); // Treat cell as JSValue for now!
+ fillToJS(nodeIndex, gpr);
+ // FIXME: For subtypes of DataFormatJS, should jitAssert the subtype?
+ }
+ }
+
+ // Jump into the non-speculative path.
+ jump(entry.m_entry);
+}
+
+void JITCompiler::linkSpeculationChecks(SpeculativeJIT& speculative, NonSpeculativeJIT& nonSpeculative)
+{
+ // Iterators to walk over the set of bail outs & corresponding entry points.
+ SpeculativeJIT::SpeculationCheckVector::Iterator checksIter = speculative.speculationChecks().begin();
+ SpeculativeJIT::SpeculationCheckVector::Iterator checksEnd = speculative.speculationChecks().end();
+ NonSpeculativeJIT::EntryLocationVector::Iterator entriesIter = nonSpeculative.entryLocations().begin();
+ NonSpeculativeJIT::EntryLocationVector::Iterator entriesEnd = nonSpeculative.entryLocations().end();
+
+ // Iterate over the speculation checks.
+ while (checksIter != checksEnd) {
+ // For every bail out from the speculative path, we must have provided an entry point
+ // into the non-speculative one.
+ ASSERT(checksIter->m_nodeIndex == entriesIter->m_nodeIndex);
+
+ // There may be multiple bail outs that map to the same entry point!
+ do {
+ ASSERT(checksIter != checksEnd);
+ ASSERT(entriesIter != entriesEnd);
+
+ // Plant code to link this speculation failure.
+ const SpeculationCheck& check = *checksIter;
+ const EntryLocation& entry = *entriesIter;
+ jumpFromSpeculativeToNonSpeculative(check, entry, speculative.speculationRecovery(check.m_recoveryIndex));
+ ++checksIter;
+ } while (checksIter != checksEnd && checksIter->m_nodeIndex == entriesIter->m_nodeIndex);
+ ++entriesIter;
+ }
+
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=56289
+ ASSERT(!(checksIter != checksEnd));
+ ASSERT(!(entriesIter != entriesEnd));
+}
+
+void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck)
+{
+ // === Stage 1 - Function header code generation ===
+ //
+ // This code currently matches the old JIT. In the function header we need to
+ // pop the return address (since we do not allow any recursion on the machine
+ // stack), and perform a fast register file check.
+
+ // This is the main entry point, without performing an arity check.
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=56292
+ // We'll need to convert the remaining cti_ style calls (specifically the register file
+ // check) which will be dependent on stack layout. (We'd need to account for this in
+ // both normal return code and when jumping to an exception handler).
+ preserveReturnAddressAfterCall(regT2);
+ emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
+ // If we needed to perform an arity check we will already have moved the return address,
+ // so enter after this.
+ Label fromArityCheck(this);
+
+ // Setup a pointer to the codeblock in the CallFrameHeader.
+ emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
+
+ // Plant a check that sufficient space is available in the RegisterFile.
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=56291
+ addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
+ Jump registerFileCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1);
+ // Return here after register file check.
+ Label fromRegisterFileCheck = label();
+
+
+ // === Stage 2 - Function body code generation ===
+ //
+ // We generate the speculative code path, followed by the non-speculative
+ // code for the function. Next we need to link the two together, making
+ // bail-outs from the speculative path jump to the corresponding point on
+ // the non-speculative one (and generating any code necessary to juggle
+ // register values around, rebox values, and ensure spilled, to match the
+ // non-speculative path's requirements).
+
+#if DFG_JIT_BREAK_ON_ENTRY
+ // Handy debug tool!
+ breakpoint();
+#endif
+
+ // First generate the speculative path.
+ SpeculativeJIT speculative(*this);
+ speculative.compile();
+
+ // Next, generate the non-speculative path. We pass this a SpeculationCheckIndexIterator
+ // to allow it to check which nodes in the graph may bail out, and may need to reenter the
+ // non-speculative path.
+ SpeculationCheckIndexIterator checkIterator(speculative);
+ NonSpeculativeJIT nonSpeculative(*this);
+ nonSpeculative.compile(checkIterator);
+
+ // Link the bail-outs from the speculative path to the corresponding entry points into the non-speculative one.
+ linkSpeculationChecks(speculative, nonSpeculative);
+
+
+ // === Stage 3 - Function footer code generation ===
+ //
+ // Generate code to lookup and jump to exception handlers, to perform the slow
+ // register file check (if the fast one in the function header fails), and
+ // generate the entry point with arity check.
+
+ // Iterate over the m_calls vector, checking for exception checks,
+ // and linking them to here.
+ unsigned exceptionCheckCount = 0;
+ for (unsigned i = 0; i < m_calls.size(); ++i) {
+ Jump& exceptionCheck = m_calls[i].m_exceptionCheck;
+ if (exceptionCheck.isSet()) {
+ exceptionCheck.link(this);
+ ++exceptionCheckCount;
+ }
+ }
+ // If any exception checks were linked, generate code to lookup a handler.
+ if (exceptionCheckCount) {
+ // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and
+ // an identifier for the operation that threw the exception, which we can use
+ // to look up handler information. The identifier we use is the return address
+ // of the call out from JIT code that threw the exception; this is still
+ // available on the stack, just below the stack pointer!
+ move(callFrameRegister, argumentRegister0);
+ peek(argumentRegister1, -1);
+ m_calls.append(CallRecord(call(), lookupExceptionHandler));
+ // lookupExceptionHandler leaves the handler CallFrame* in the returnValueRegister,
+ // and the address of the handler in returnValueRegister2.
+ jump(returnValueRegister2);
+ }
+
+ // Generate the register file check; if the fast check in the function head fails,
+ // we need to call out to a helper function to check whether more space is available.
+ // FIXME: change this from a cti call to a DFG style operation (normal C calling conventions).
+ registerFileCheck.link(this);
+ move(stackPointerRegister, argumentRegister0);
+ poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
+ Call callRegisterFileCheck = call();
+ jump(fromRegisterFileCheck);
+
+ // The fast entry point into a function does not check the correct number of arguments
+ // have been passed to the call (we only use the fast entry point where we can statically
+ // determine the correct number of arguments have been passed, or have already checked).
+ // In cases where an arity check is necessary, we enter here.
+ // FIXME: change this from a cti call to a DFG style operation (normal C calling conventions).
+ Label arityCheck = label();
+ preserveReturnAddressAfterCall(regT2);
+ emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
+ branch32(Equal, regT1, Imm32(m_codeBlock->m_numParameters)).linkTo(fromArityCheck, this);
+ move(stackPointerRegister, argumentRegister0);
+ poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
+ Call callArityCheck = call();
+ move(regT0, callFrameRegister);
+ jump(fromArityCheck);
+
+
+ // === Stage 4 - Link ===
+ //
+ // Link the code, populate data in CodeBlock data structures.
+
+ LinkBuffer linkBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size()), 0);
+
+ // Link all calls out from the JIT code to their respective functions.
+ for (unsigned i = 0; i < m_calls.size(); ++i)
+ linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
+
+ if (m_codeBlock->needsCallReturnIndices()) {
+ m_codeBlock->callReturnIndexVector().reserveCapacity(exceptionCheckCount);
+ for (unsigned i = 0; i < m_calls.size(); ++i) {
+ if (m_calls[i].m_exceptionCheck.isSet()) {
+ unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call);
+ unsigned exceptionInfo = m_calls[i].m_exceptionInfo;
+ m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
+ }
+ }
+ }
+
+ // FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs.
+ linkBuffer.link(callRegisterFileCheck, cti_register_file_check);
+ linkBuffer.link(callArityCheck, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck);
+
+ entryWithArityCheck = linkBuffer.locationOf(arityCheck);
+ entry = linkBuffer.finalizeCode();
+}
+
+#if DFG_JIT_ASSERT
+void JITCompiler::jitAssertIsInt32(GPRReg gpr)
+{
+#if CPU(X86_64)
+ Jump checkInt32 = branchPtr(BelowOrEqual, gprToRegisterID(gpr), TrustedImmPtr(reinterpret_cast<void*>(static_cast<uintptr_t>(0xFFFFFFFFu))));
+ breakpoint();
+ checkInt32.link(this);
+#else
+ UNUSED_PARAM(gpr);
+#endif
+}
+
+void JITCompiler::jitAssertIsJSInt32(GPRReg gpr)
+{
+ Jump checkJSInt32 = branchPtr(AboveOrEqual, gprToRegisterID(gpr), tagTypeNumberRegister);
+ breakpoint();
+ checkJSInt32.link(this);
+}
+
+void JITCompiler::jitAssertIsJSNumber(GPRReg gpr)
+{
+ Jump checkJSNumber = branchTestPtr(MacroAssembler::NonZero, gprToRegisterID(gpr), tagTypeNumberRegister);
+ breakpoint();
+ checkJSNumber.link(this);
+}
+
+void JITCompiler::jitAssertIsJSDouble(GPRReg gpr)
+{
+ Jump checkJSInt32 = branchPtr(AboveOrEqual, gprToRegisterID(gpr), tagTypeNumberRegister);
+ Jump checkJSNumber = branchTestPtr(MacroAssembler::NonZero, gprToRegisterID(gpr), tagTypeNumberRegister);
+ checkJSInt32.link(this);
+ breakpoint();
+ checkJSNumber.link(this);
+}
+#endif
+
+#if ENABLE(SAMPLING_COUNTERS) && CPU(X86_64) // Or any other 64-bit platform!
+void JITCompiler::emitCount(AbstractSamplingCounter& counter, uint32_t increment)
+{
+ addPtr(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
+}
+#endif
+
+#if ENABLE(SAMPLING_COUNTERS) && CPU(X86) // Or any other little-endian 32-bit platform!
+void JITCompiler::emitCount(AbstractSamplingCounter& counter, uint32_t increment)
+{
+ intptr_t hiWord = reinterpret_cast<intptr_t>(counter.addressOfCounter()) + sizeof(int32_t);
+ add32(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
+ addWithCarry32(TrustedImm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
+}
+#endif
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
new file mode 100644
index 0000000..8b68434
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGJITCompiler_h
+#define DFGJITCompiler_h
+
+#if ENABLE(DFG_JIT)
+
+#include <assembler/MacroAssembler.h>
+#include <bytecode/CodeBlock.h>
+#include <dfg/DFGGraph.h>
+#include <jit/JITCode.h>
+
+namespace JSC {
+
+class AbstractSamplingCounter;
+class CodeBlock;
+class JSGlobalData;
+
+namespace DFG {
+
+class JITCodeGenerator;
+class NonSpeculativeJIT;
+class SpeculativeJIT;
+class SpeculationRecovery;
+
+struct EntryLocation;
+struct SpeculationCheck;
+
+// Abstracted sequential numbering of available machine registers (as opposed to MacroAssembler::RegisterID,
+// which are non-sequential, and not abstracted from the register numbering used by the underlying processor).
+enum GPRReg { gpr0, gpr1, gpr2, gpr3, gpr4, gpr5, numberOfGPRs, InvalidGPRReg = 0xFFFFFFFF };
+enum FPRReg { fpr0, fpr1, fpr2, fpr3, fpr4, fpr5, numberOfFPRs, InvalidFPRReg = 0xFFFFFFFF };
+
+// GPRReg/FPRReg are enum types to provide type checking at compile time, use these method to iterate.
+inline GPRReg next(GPRReg& reg)
+{
+ ASSERT(reg < numberOfGPRs);
+ return reg = static_cast<GPRReg>(reg + 1);
+}
+inline FPRReg next(FPRReg& reg)
+{
+ ASSERT(reg < numberOfFPRs);
+ return reg = static_cast<FPRReg>(reg + 1);
+}
+
+// === CallRecord ===
+//
+// A record of a call out from JIT code to a helper function.
+// Every CallRecord contains a reference to the call instruction & the function
+// that it needs to be linked to. Calls that might throw an exception also record
+// the Jump taken on exception (unset if not present), and ExceptionInfo (presently
+// an unsigned, bytecode index) used to recover handler/source info.
+struct CallRecord {
+ // Constructor for a call with no exception handler.
+ CallRecord(MacroAssembler::Call call, FunctionPtr function)
+ : m_call(call)
+ , m_function(function)
+ {
+ }
+
+ // Constructor for a call with an exception handler.
+ CallRecord(MacroAssembler::Call call, FunctionPtr function, MacroAssembler::Jump exceptionCheck, ExceptionInfo exceptionInfo)
+ : m_call(call)
+ , m_function(function)
+ , m_exceptionCheck(exceptionCheck)
+ , m_exceptionInfo(exceptionInfo)
+ {
+ }
+
+ MacroAssembler::Call m_call;
+ FunctionPtr m_function;
+ MacroAssembler::Jump m_exceptionCheck;
+ ExceptionInfo m_exceptionInfo;
+};
+
+// === JITCompiler ===
+//
+// DFG::JITCompiler is responsible for generating JIT code from the dataflow graph.
+// It does so by delegating to the speculative & non-speculative JITs, which
+// generate to a MacroAssembler (which the JITCompiler owns through an inheritance
+// relationship). The JITCompiler holds references to information required during
+// compilation, and also records information used in linking (e.g. a list of all
+// call to be linked).
+class JITCompiler : public MacroAssembler {
+public:
+ JITCompiler(JSGlobalData* globalData, Graph& dfg, CodeBlock* codeBlock)
+ : m_globalData(globalData)
+ , m_graph(dfg)
+ , m_codeBlock(codeBlock)
+ {
+ }
+
+ void compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck);
+
+ // Accessors for properties.
+ Graph& graph() { return m_graph; }
+ CodeBlock* codeBlock() { return m_codeBlock; }
+ JSGlobalData* globalData() { return m_globalData; }
+
+#if CPU(X86_64)
+ // These registers match the old JIT.
+ static const RegisterID timeoutCheckRegister = X86Registers::r12;
+ static const RegisterID callFrameRegister = X86Registers::r13;
+ static const RegisterID tagTypeNumberRegister = X86Registers::r14;
+ static const RegisterID tagMaskRegister = X86Registers::r15;
+
+ // Temporary registers (these correspond to the temporary GPRReg/FPRReg
+ // registers i.e. regT0 and grp0 refer to the same thing, grp0 being
+ // the abstracted, sequential name, and regT0 being the machine register
+ // number in the instruction set, as provided by the MacroAssembler).
+ static const RegisterID regT0 = X86Registers::eax;
+ static const RegisterID regT1 = X86Registers::edx;
+ static const RegisterID regT2 = X86Registers::ecx;
+ static const RegisterID regT3 = X86Registers::ebx;
+ static const RegisterID regT4 = X86Registers::edi;
+ static const RegisterID regT5 = X86Registers::esi;
+ static const FPRegisterID fpRegT0 = X86Registers::xmm0;
+ static const FPRegisterID fpRegT1 = X86Registers::xmm1;
+ static const FPRegisterID fpRegT2 = X86Registers::xmm2;
+ static const FPRegisterID fpRegT3 = X86Registers::xmm3;
+ static const FPRegisterID fpRegT4 = X86Registers::xmm4;
+ static const FPRegisterID fpRegT5 = X86Registers::xmm5;
+
+ // These constants provide both RegisterID & GPRReg style names for the
+ // general purpose argument & return value register.
+ static const GPRReg argumentGPR0 = gpr4;
+ static const GPRReg argumentGPR1 = gpr5;
+ static const GPRReg argumentGPR2 = gpr1;
+ static const GPRReg argumentGPR3 = gpr2;
+ static const RegisterID argumentRegister0 = regT4;
+ static const RegisterID argumentRegister1 = regT5;
+ static const RegisterID argumentRegister2 = regT1;
+ static const RegisterID argumentRegister3 = regT2;
+ static const GPRReg returnValueGPR = gpr0;
+ static const RegisterID returnValueRegister = regT0;
+ static const RegisterID returnValueRegister2 = regT1;
+
+ // These constants provide both FPRegisterID & FPRReg style names for the
+ // floating point argument & return value register.
+ static const FPRReg argumentFPR0 = fpr0;
+ static const FPRReg argumentFPR1 = fpr1;
+ static const FPRReg argumentFPR2 = fpr2;
+ static const FPRReg argumentFPR3 = fpr3;
+ static const FPRegisterID fpArgumentRegister0 = fpRegT0;
+ static const FPRegisterID fpArgumentRegister1 = fpRegT1;
+ static const FPRegisterID fpArgumentRegister2 = fpRegT2;
+ static const FPRegisterID fpArgumentRegister3 = fpRegT3;
+ static const FPRReg returnValueFPR = fpr0;
+ static const FPRegisterID fpReturnValueRegister = fpRegT0;
+
+
+ void preserveReturnAddressAfterCall(RegisterID reg)
+ {
+ pop(reg);
+ }
+
+ void restoreReturnAddressBeforeReturn(RegisterID reg)
+ {
+ push(reg);
+ }
+
+ void restoreReturnAddressBeforeReturn(Address address)
+ {
+ push(address);
+ }
+
+ void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to)
+ {
+ loadPtr(Address(callFrameRegister, entry * sizeof(Register)), to);
+ }
+ void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
+ {
+ storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
+ }
+
+ void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
+ {
+ storePtr(TrustedImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
+ }
+#endif
+
+ Address addressForArgument(int32_t argument)
+ {
+ return Address(callFrameRegister, (argument - (m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize)) * sizeof(Register));
+ }
+
+ static Address addressForGlobalVar(RegisterID global, int32_t varNumber)
+ {
+ return Address(global, varNumber * sizeof(Register));
+ }
+
+ static Address addressFor(VirtualRegister virtualRegister)
+ {
+ return Address(callFrameRegister, virtualRegister * sizeof(Register));
+ }
+
+ // These methods provide mapping from sequential register numbering (GPRReg/FPRReg)
+ // to machine register numbering (RegisterID/FPRegisterID).
+ static RegisterID gprToRegisterID(GPRReg reg)
+ {
+ ASSERT(reg < numberOfGPRs);
+ static const RegisterID idForRegister[numberOfGPRs] = { regT0, regT1, regT2, regT3, regT4, regT5 };
+ return idForRegister[reg];
+ }
+ static FPRegisterID fprToRegisterID(FPRReg reg)
+ {
+ ASSERT(reg < numberOfFPRs);
+ static const FPRegisterID idForRegister[numberOfFPRs] = { fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
+ return idForRegister[reg];
+ }
+
+ // Add a call out from JIT code, without an exception check.
+ void appendCall(const FunctionPtr& function)
+ {
+ m_calls.append(CallRecord(call(), function));
+ // FIXME: should be able to JIT_ASSERT here that globalData->exception is null on return back to JIT code.
+ }
+
+ // Add a call out from JIT code, with an exception check.
+ void appendCallWithExceptionCheck(const FunctionPtr& function, unsigned exceptionInfo)
+ {
+ Call functionCall = call();
+ Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception));
+ m_calls.append(CallRecord(functionCall, function, exceptionCheck, exceptionInfo));
+ }
+
+ // Helper methods to check nodes for constants.
+ bool isInt32Constant(NodeIndex nodeIndex)
+ {
+ return graph()[nodeIndex].op == Int32Constant;
+ }
+ bool isDoubleConstant(NodeIndex nodeIndex)
+ {
+ return graph()[nodeIndex].op == DoubleConstant;
+ }
+ bool isJSConstant(NodeIndex nodeIndex)
+ {
+ return graph()[nodeIndex].op == JSConstant;
+ }
+
+ // Helper methods get constant values from nodes.
+ int32_t valueOfInt32Constant(NodeIndex nodeIndex)
+ {
+ ASSERT(isInt32Constant(nodeIndex));
+ return graph()[nodeIndex].int32Constant();
+ }
+ double valueOfDoubleConstant(NodeIndex nodeIndex)
+ {
+ ASSERT(isDoubleConstant(nodeIndex));
+ return graph()[nodeIndex].numericConstant();
+ }
+ JSValue valueOfJSConstant(NodeIndex nodeIndex)
+ {
+ ASSERT(isJSConstant(nodeIndex));
+ unsigned constantIndex = graph()[nodeIndex].constantNumber();
+ return codeBlock()->constantRegister(FirstConstantRegisterIndex + constantIndex).get();
+ }
+
+ // These methods JIT generate dynamic, debug-only checks - akin to ASSERTs.
+#if DFG_JIT_ASSERT
+ void jitAssertIsInt32(GPRReg);
+ void jitAssertIsJSInt32(GPRReg);
+ void jitAssertIsJSNumber(GPRReg);
+ void jitAssertIsJSDouble(GPRReg);
+#else
+ void jitAssertIsInt32(GPRReg) {}
+ void jitAssertIsJSInt32(GPRReg) {}
+ void jitAssertIsJSNumber(GPRReg) {}
+ void jitAssertIsJSDouble(GPRReg) {}
+#endif
+
+#if ENABLE(SAMPLING_COUNTERS)
+ // Debug profiling tool.
+ void emitCount(AbstractSamplingCounter&, uint32_t increment = 1);
+#endif
+
+private:
+ // These methods used in linking the speculative & non-speculative paths together.
+ void fillNumericToDouble(NodeIndex, FPRReg, GPRReg temporary);
+ void fillInt32ToInteger(NodeIndex, GPRReg);
+ void fillToJS(NodeIndex, GPRReg);
+ void jumpFromSpeculativeToNonSpeculative(const SpeculationCheck&, const EntryLocation&, SpeculationRecovery*);
+ void linkSpeculationChecks(SpeculativeJIT&, NonSpeculativeJIT&);
+
+ // The globalData, used to access constants such as the vPtrs.
+ JSGlobalData* m_globalData;
+
+ // The dataflow graph currently being generated.
+ Graph& m_graph;
+
+ // The codeBlock currently being generated, used to access information such as constant values, immediates.
+ CodeBlock* m_codeBlock;
+
+ // Vector of calls out from JIT code, including exception handler information.
+ Vector<CallRecord> m_calls;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
+
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
new file mode 100644
index 0000000..11dbf0d
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGNode_h
+#define DFGNode_h
+
+#if ENABLE(DFG_JIT)
+
+#include <wtf/Vector.h>
+
+// Emit various logging information for debugging, including dumping the dataflow graphs.
+#define DFG_DEBUG_VERBOSE 0
+// Enable generation of dynamic checks into the instruction stream.
+#define DFG_JIT_ASSERT 0
+// Consistency check contents compiler data structures.
+#define DFG_CONSISTENCY_CHECK 0
+// Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
+#define DFG_JIT_BREAK_ON_ENTRY 0
+
+
+namespace JSC { namespace DFG {
+
+// Type for a virtual register number (spill location).
+// Using an enum to make this type-checked at compile time, to avert programmer errors.
+enum VirtualRegister { InvalidVirtualRegister = -1 };
+COMPILE_ASSERT(sizeof(VirtualRegister) == sizeof(int), VirtualRegister_is_32bit);
+
+// Type for a reference to another node in the graph.
+typedef uint32_t NodeIndex;
+static const NodeIndex NoNode = UINT_MAX;
+
+// Information used to map back from an exception to any handler/source information.
+// (Presently implemented as a bytecode index).
+typedef uint32_t ExceptionInfo;
+
+// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
+// and some additional informative flags (must generate, is constant, etc).
+#define NodeIdMask 0xFFF
+#define NodeResultMask 0xF000
+#define NodeMustGenerate 0x10000 // set on nodes that have side effects, and may not trivially be removed by DCE.
+#define NodeIsConstant 0x20000
+
+// These values record the result type of the node (as checked by NodeResultMask, above), 0 for no result.
+#define NodeResultJS 0x1000
+#define NodeResultDouble 0x2000
+#define NodeResultInt32 0x3000
+
+// This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
+#define FOR_EACH_DFG_OP(macro) \
+ /* Nodes for constants. */\
+ macro(JSConstant, NodeResultJS | NodeIsConstant) \
+ macro(Int32Constant, NodeResultJS | NodeIsConstant) \
+ macro(DoubleConstant, NodeResultJS | NodeIsConstant) \
+ macro(Argument, NodeResultJS) \
+ macro(ConvertThis, NodeResultJS) \
+ \
+ /* Nodes for bitwise operations. */\
+ macro(BitAnd, NodeResultInt32) \
+ macro(BitOr, NodeResultInt32) \
+ macro(BitXor, NodeResultInt32) \
+ macro(BitLShift, NodeResultInt32) \
+ macro(BitRShift, NodeResultInt32) \
+ macro(BitURShift, NodeResultInt32) \
+ /* Bitwise operators call ToInt32 on their operands. */\
+ macro(NumberToInt32, NodeResultInt32) \
+ macro(ValueToInt32, NodeResultInt32 | NodeMustGenerate) \
+ /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
+ macro(UInt32ToNumber, NodeResultDouble) \
+ \
+ /* Nodes for arithmetic operations. */\
+ macro(ArithAdd, NodeResultDouble) \
+ macro(ArithSub, NodeResultDouble) \
+ macro(ArithMul, NodeResultDouble) \
+ macro(ArithDiv, NodeResultDouble) \
+ macro(ArithMod, NodeResultDouble) \
+ /* Arithmetic operators call ToNumber on their operands. */\
+ macro(Int32ToNumber, NodeResultDouble) \
+ macro(ValueToNumber, NodeResultDouble | NodeMustGenerate) \
+ \
+ /* Add of values may either be arithmetic, or result in string concatenation. */\
+ macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
+ \
+ /* Property access. */\
+ /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
+ /* Since a put to 'length' may invalidate optimizations here, */\
+ /* this must be the directly subsequent property put. */\
+ macro(GetByVal, NodeResultJS | NodeMustGenerate) \
+ macro(PutByVal, NodeMustGenerate) \
+ macro(PutByValAlias, NodeMustGenerate) \
+ macro(GetById, NodeResultJS | NodeMustGenerate) \
+ macro(PutById, NodeMustGenerate) \
+ macro(PutByIdDirect, NodeMustGenerate) \
+ macro(GetGlobalVar, NodeResultJS | NodeMustGenerate) \
+ macro(PutGlobalVar, NodeMustGenerate) \
+ \
+ macro(Return, NodeMustGenerate)
+
+// This enum generates a monotonically increasing id for all Node types,
+// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
+enum NodeId {
+#define DFG_OP_ENUM(opcode, flags) opcode##_id,
+ FOR_EACH_DFG_OP(DFG_OP_ENUM)
+#undef DFG_OP_ENUM
+};
+
+// Entries in this enum describe all Node types.
+// The enum value contains a monotonically increasing id, a result type, and additional flags.
+enum NodeType {
+#define DFG_OP_ENUM(opcode, flags) opcode = opcode##_id | (flags),
+ FOR_EACH_DFG_OP(DFG_OP_ENUM)
+#undef DFG_OP_ENUM
+};
+
+// This type used in passing an immediate argument to Node constructor;
+// distinguishes an immediate value (typically an index into a CodeBlock data structure -
+// a constant index, argument, or identifier) from a NodeIndex.
+struct OpInfo {
+ explicit OpInfo(unsigned value) : m_value(value) {}
+ unsigned m_value;
+};
+
+// === Node ===
+//
+// Node represents a single operation in the data flow graph.
+struct Node {
+ // Construct a node with up to 3 children, no immediate value.
+ Node(NodeType op, ExceptionInfo exceptionInfo, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ : op(op)
+ , exceptionInfo(exceptionInfo)
+ , child1(child1)
+ , child2(child2)
+ , child3(child3)
+ , virtualRegister(InvalidVirtualRegister)
+ , refCount(0)
+ {
+ }
+
+ // Construct a node with up to 3 children and an immediate value.
+ Node(NodeType op, ExceptionInfo exceptionInfo, OpInfo imm, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ : op(op)
+ , exceptionInfo(exceptionInfo)
+ , child1(child1)
+ , child2(child2)
+ , child3(child3)
+ , virtualRegister(InvalidVirtualRegister)
+ , refCount(0)
+ , m_opInfo(imm.m_value)
+ {
+ }
+
+ bool mustGenerate()
+ {
+ return op & NodeMustGenerate;
+ }
+
+ bool isConstant()
+ {
+ return op & NodeIsConstant;
+ }
+
+ unsigned constantNumber()
+ {
+ ASSERT(isConstant());
+ return m_opInfo;
+ }
+
+ bool isArgument()
+ {
+ return op == Argument;
+ }
+
+ unsigned argumentNumber()
+ {
+ ASSERT(isArgument());
+ return m_opInfo;
+ }
+
+ bool hasIdentifier()
+ {
+ return op == GetById || op == PutById || op == PutByIdDirect;
+ }
+
+ unsigned identifierNumber()
+ {
+ ASSERT(hasIdentifier());
+ return m_opInfo;
+ }
+
+ bool hasVarNumber()
+ {
+ return op == GetGlobalVar || op == PutGlobalVar;
+ }
+
+ unsigned varNumber()
+ {
+ ASSERT(hasVarNumber());
+ return m_opInfo;
+ }
+
+ bool hasInt32Result()
+ {
+ return (op & NodeResultMask) == NodeResultInt32;
+ }
+
+ bool hasDoubleResult()
+ {
+ return (op & NodeResultMask) == NodeResultDouble;
+ }
+
+ bool hasJSResult()
+ {
+ return (op & NodeResultMask) == NodeResultJS;
+ }
+
+ // Check for integers or doubles.
+ bool hasNumericResult()
+ {
+ // This check will need updating if more result types are added.
+ ASSERT((hasInt32Result() || hasDoubleResult()) == !hasJSResult());
+ return !hasJSResult();
+ }
+
+ int32_t int32Constant()
+ {
+ ASSERT(op == Int32Constant);
+ return m_constantValue.asInt32;
+ }
+
+ void setInt32Constant(int32_t value)
+ {
+ ASSERT(op == Int32Constant);
+ m_constantValue.asInt32 = value;
+ }
+
+ double numericConstant()
+ {
+ ASSERT(op == DoubleConstant);
+ return m_constantValue.asDouble;
+ }
+
+ void setDoubleConstant(double value)
+ {
+ ASSERT(op == DoubleConstant);
+ m_constantValue.asDouble = value;
+ }
+
+ // This enum value describes the type of the node.
+ NodeType op;
+ // Used to look up exception handling information (currently implemented as a bytecode index).
+ ExceptionInfo exceptionInfo;
+ // References to up to 3 children (0 for no child).
+ NodeIndex child1, child2, child3;
+ // The virtual register number (spill location) associated with this .
+ VirtualRegister virtualRegister;
+ // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
+ unsigned refCount;
+
+private:
+ // An immediate value, accesses type-checked via accessors above.
+ unsigned m_opInfo;
+ // The value of an int32/double constant.
+ union {
+ int32_t asInt32;
+ double asDouble;
+ } m_constantValue;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
new file mode 100644
index 0000000..945c98a
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGNonSpeculativeJIT.h"
+
+#include "DFGSpeculativeJIT.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+const double twoToThe32 = (double)0x100000000ull;
+
+EntryLocation::EntryLocation(MacroAssembler::Label entry, NonSpeculativeJIT* jit)
+ : m_entry(entry)
+ , m_nodeIndex(jit->m_compileIndex)
+{
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister virtualRegister = jit->m_gprs.name(gpr);
+ if (virtualRegister != InvalidVirtualRegister) {
+ GenerationInfo& info = jit->m_generationInfo[virtualRegister];
+ m_gprInfo[gpr].nodeIndex = info.nodeIndex();
+ m_gprInfo[gpr].format = info.registerFormat();
+ } else
+ m_gprInfo[gpr].nodeIndex = NoNode;
+ }
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister virtualRegister = jit->m_fprs.name(fpr);
+ if (virtualRegister != InvalidVirtualRegister) {
+ GenerationInfo& info = jit->m_generationInfo[virtualRegister];
+ ASSERT(info.registerFormat() == DataFormatDouble);
+ m_fprInfo[fpr] = info.nodeIndex();
+ } else
+ m_fprInfo[fpr] = NoNode;
+ }
+}
+
+void NonSpeculativeJIT::valueToNumber(JSValueOperand& operand, FPRReg fpr)
+{
+ GPRReg jsValueGpr = operand.gpr();
+ GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?
+
+ JITCompiler::RegisterID jsValueReg = JITCompiler::gprToRegisterID(jsValueGpr);
+ JITCompiler::FPRegisterID fpReg = JITCompiler::fprToRegisterID(fpr);
+ JITCompiler::RegisterID tempReg = JITCompiler::gprToRegisterID(tempGpr);
+
+ JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueReg, JITCompiler::tagTypeNumberRegister);
+ JITCompiler::Jump nonNumeric = m_jit.branchTestPtr(MacroAssembler::Zero, jsValueReg, JITCompiler::tagTypeNumberRegister);
+
+ // First, if we get here we have a double encoded as a JSValue
+ m_jit.move(jsValueReg, tempReg);
+ m_jit.addPtr(JITCompiler::tagTypeNumberRegister, tempReg);
+ m_jit.movePtrToDouble(tempReg, fpReg);
+ JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
+
+ // Next handle cells (& other JS immediates)
+ nonNumeric.link(&m_jit);
+ silentSpillAllRegisters(jsValueGpr);
+ m_jit.move(jsValueReg, JITCompiler::argumentRegister1);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+ appendCallWithExceptionCheck(dfgConvertJSValueToNumber);
+ m_jit.moveDouble(JITCompiler::fpReturnValueRegister, fpReg);
+ silentFillAllRegisters(fpr);
+ JITCompiler::Jump hasCalledToNumber = m_jit.jump();
+
+ // Finally, handle integers.
+ isInteger.link(&m_jit);
+ m_jit.convertInt32ToDouble(jsValueReg, fpReg);
+ hasUnboxedDouble.link(&m_jit);
+ hasCalledToNumber.link(&m_jit);
+
+ m_gprs.unlock(tempGpr);
+}
+
+void NonSpeculativeJIT::valueToInt32(JSValueOperand& operand, GPRReg result)
+{
+ GPRReg jsValueGpr = operand.gpr();
+
+ JITCompiler::RegisterID jsValueReg = JITCompiler::gprToRegisterID(jsValueGpr);
+ JITCompiler::RegisterID resultReg = JITCompiler::gprToRegisterID(result);
+
+ JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueReg, JITCompiler::tagTypeNumberRegister);
+
+ // First handle non-integers
+ silentSpillAllRegisters(jsValueGpr);
+ m_jit.move(jsValueReg, JITCompiler::argumentRegister1);
+ m_jit.move(JITCompiler::callFrameRegister, JITCompiler::argumentRegister0);
+ appendCallWithExceptionCheck(dfgConvertJSValueToInt32);
+ m_jit.zeroExtend32ToPtr(JITCompiler::returnValueRegister, resultReg);
+ silentFillAllRegisters(result);
+ JITCompiler::Jump hasCalledToInt32 = m_jit.jump();
+
+ // Then handle integers.
+ isInteger.link(&m_jit);
+ m_jit.zeroExtend32ToPtr(jsValueReg, resultReg);
+ hasCalledToInt32.link(&m_jit);
+}
+
+void NonSpeculativeJIT::numberToInt32(FPRReg fpr, GPRReg gpr)
+{
+ JITCompiler::FPRegisterID fpReg = JITCompiler::fprToRegisterID(fpr);
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+
+ JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpReg, reg, JITCompiler::BranchIfTruncateSuccessful);
+
+ silentSpillAllRegisters(gpr); // don't really care!
+
+ m_jit.moveDouble(fpReg, JITCompiler::fpArgumentRegister0);
+ appendCallWithExceptionCheck(toInt32);
+ m_jit.zeroExtend32ToPtr(JITCompiler::returnValueRegister, reg);
+
+ silentFillAllRegisters(gpr);
+
+ truncatedToInteger.link(&m_jit);
+}
+
+void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, Node& node)
+{
+ // ...
+ if (checkIterator.hasCheckAtIndex(m_compileIndex))
+ trackEntry(m_jit.label());
+
+ checkConsistency();
+
+ NodeType op = node.op;
+
+ switch (op) {
+ case ConvertThis: {
+ JSValueOperand thisValue(this, node.child1);
+ GPRReg thisGPR = thisValue.gpr();
+ flushRegisters();
+
+ GPRResult result(this);
+ callOperation(operationConvertThis, result.gpr(), thisGPR);
+ cellResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case Int32Constant:
+ case DoubleConstant:
+ case JSConstant:
+ initConstantInfo(m_compileIndex);
+ break;
+
+ case Argument:
+ initArgumentInfo(m_compileIndex);
+ break;
+
+ case BitAnd:
+ case BitOr:
+ case BitXor:
+ if (isInt32Constant(node.child1)) {
+ IntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op2);
+
+ bitOp(op, valueOfInt32Constant(node.child1), op2.registerID(), result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ } else if (isInt32Constant(node.child2)) {
+ IntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+
+ bitOp(op, valueOfInt32Constant(node.child2), op1.registerID(), result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ } else {
+ IntegerOperand op1(this, node.child1);
+ IntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1, op2);
+
+ MacroAssembler::RegisterID reg1 = op1.registerID();
+ MacroAssembler::RegisterID reg2 = op2.registerID();
+ bitOp(op, reg1, reg2, result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ }
+ break;
+
+ case BitRShift:
+ case BitLShift:
+ case BitURShift:
+ if (isInt32Constant(node.child2)) {
+ IntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+
+ int shiftAmount = valueOfInt32Constant(node.child2) & 0x1f;
+ // Shifts by zero should have been optimized out of the graph!
+ ASSERT(shiftAmount);
+ shiftOp(op, op1.registerID(), shiftAmount, result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ } else {
+ // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
+ IntegerOperand op1(this, node.child1);
+ IntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1);
+
+ MacroAssembler::RegisterID reg1 = op1.registerID();
+ MacroAssembler::RegisterID reg2 = op2.registerID();
+ shiftOp(op, reg1, reg2, result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ }
+ break;
+
+ case UInt32ToNumber: {
+ IntegerOperand op1(this, node.child1);
+ FPRTemporary result(this);
+ m_jit.convertInt32ToDouble(op1.registerID(), result.registerID());
+
+ MacroAssembler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.registerID(), TrustedImm32(0));
+ m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), result.registerID());
+ positive.link(&m_jit);
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case Int32ToNumber: {
+ IntegerOperand op1(this, node.child1);
+ FPRTemporary result(this);
+ m_jit.convertInt32ToDouble(op1.registerID(), result.registerID());
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case NumberToInt32:
+ case ValueToInt32: {
+ ASSERT(!isInt32Constant(node.child1));
+ GenerationInfo& operandInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister];
+
+ switch (operandInfo.registerFormat()) {
+ case DataFormatInteger: {
+ IntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+ m_jit.move(op1.registerID(), result.registerID());
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case DataFormatDouble: {
+ DoubleOperand op1(this, node.child1);
+ GPRTemporary result(this);
+ numberToInt32(op1.fpr(), result.gpr());
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ default: {
+ JSValueOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+ op1.gpr(); // force op1 to be filled!
+ result.gpr(); // force result to be allocated!
+
+ switch (operandInfo.registerFormat()) {
+ case DataFormatNone:
+ case DataFormatInteger:
+ case DataFormatDouble:
+ // The operand has been filled as a JSValue; it cannot be in a !DataFormatJS state.
+ CRASH();
+
+ case DataFormatCell:
+ case DataFormatJS:
+ case DataFormatJSCell: {
+ if (op == NumberToInt32) {
+ FPRTemporary fpTemp(this);
+ FPRReg fpr = fpTemp.fpr();
+
+ JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, op1.registerID(), JITCompiler::tagTypeNumberRegister);
+
+ m_jit.move(op1.registerID(), result.registerID());
+ m_jit.addPtr(JITCompiler::tagTypeNumberRegister, result.registerID());
+ m_jit.movePtrToDouble(result.registerID(), fpTemp.registerID());
+ numberToInt32(fpr, result.gpr());
+ JITCompiler::Jump wasDouble = m_jit.jump();
+
+ isInteger.link(&m_jit);
+ m_jit.zeroExtend32ToPtr(op1.registerID(), result.registerID());
+
+ wasDouble.link(&m_jit);
+ } else
+ valueToInt32(op1, result.gpr());
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case DataFormatJSDouble: {
+ FPRTemporary fpTemp(this);
+ m_jit.move(op1.registerID(), result.registerID());
+ m_jit.addPtr(JITCompiler::tagTypeNumberRegister, result.registerID());
+ m_jit.movePtrToDouble(result.registerID(), fpTemp.registerID());
+ numberToInt32(fpTemp.fpr(), result.gpr());
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case DataFormatJSInteger: {
+ m_jit.move(op1.registerID(), result.registerID());
+ jsValueResult(result.gpr(), m_compileIndex, DataFormatJSInteger);
+ break;
+ }
+ }
+ }
+
+ }
+ break;
+ }
+
+ case ValueToNumber: {
+ ASSERT(!isInt32Constant(node.child1));
+ ASSERT(!isDoubleConstant(node.child1));
+ GenerationInfo& operandInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister];
+ switch (operandInfo.registerFormat()) {
+ case DataFormatNone:
+ case DataFormatCell:
+ case DataFormatJS:
+ case DataFormatJSCell: {
+ JSValueOperand op1(this, node.child1);
+ FPRTemporary result(this);
+ valueToNumber(op1, result.fpr());
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case DataFormatJSDouble:
+ case DataFormatDouble: {
+ DoubleOperand op1(this, node.child1);
+ FPRTemporary result(this, op1);
+ m_jit.moveDouble(op1.registerID(), result.registerID());
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case DataFormatJSInteger:
+ case DataFormatInteger: {
+ IntegerOperand op1(this, node.child1);
+ FPRTemporary result(this);
+ m_jit.convertInt32ToDouble(op1.registerID(), result.registerID());
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+ }
+ break;
+ }
+
+ case ValueAdd: {
+ JSValueOperand arg1(this, node.child1);
+ JSValueOperand arg2(this, node.child2);
+ GPRReg arg1GPR = arg1.gpr();
+ GPRReg arg2GPR = arg2.gpr();
+ flushRegisters();
+
+ GPRResult result(this);
+ callOperation(operationValueAdd, result.gpr(), arg1GPR, arg2GPR);
+
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithAdd: {
+ DoubleOperand op1(this, node.child1);
+ DoubleOperand op2(this, node.child2);
+ FPRTemporary result(this, op1, op2);
+
+ MacroAssembler::FPRegisterID reg1 = op1.registerID();
+ MacroAssembler::FPRegisterID reg2 = op2.registerID();
+ m_jit.addDouble(reg1, reg2, result.registerID());
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithSub: {
+ DoubleOperand op1(this, node.child1);
+ DoubleOperand op2(this, node.child2);
+ FPRTemporary result(this, op1);
+
+ MacroAssembler::FPRegisterID reg1 = op1.registerID();
+ MacroAssembler::FPRegisterID reg2 = op2.registerID();
+ m_jit.subDouble(reg1, reg2, result.registerID());
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithMul: {
+ DoubleOperand op1(this, node.child1);
+ DoubleOperand op2(this, node.child2);
+ FPRTemporary result(this, op1, op2);
+
+ MacroAssembler::FPRegisterID reg1 = op1.registerID();
+ MacroAssembler::FPRegisterID reg2 = op2.registerID();
+ m_jit.mulDouble(reg1, reg2, result.registerID());
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithDiv: {
+ DoubleOperand op1(this, node.child1);
+ DoubleOperand op2(this, node.child2);
+ FPRTemporary result(this, op1);
+
+ MacroAssembler::FPRegisterID reg1 = op1.registerID();
+ MacroAssembler::FPRegisterID reg2 = op2.registerID();
+ m_jit.divDouble(reg1, reg2, result.registerID());
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithMod: {
+ DoubleOperand arg1(this, node.child1);
+ DoubleOperand arg2(this, node.child2);
+ FPRReg arg1FPR = arg1.fpr();
+ FPRReg arg2FPR = arg2.fpr();
+ flushRegisters();
+
+ FPRResult result(this);
+ callOperation(fmod, result.fpr(), arg1FPR, arg2FPR);
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ case GetByVal: {
+ JSValueOperand arg1(this, node.child1);
+ JSValueOperand arg2(this, node.child2);
+ GPRReg arg1GPR = arg1.gpr();
+ GPRReg arg2GPR = arg2.gpr();
+ flushRegisters();
+
+ GPRResult result(this);
+ callOperation(operationGetByVal, result.gpr(), arg1GPR, arg2GPR);
+
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case PutByVal:
+ case PutByValAlias: {
+ JSValueOperand arg1(this, node.child1);
+ JSValueOperand arg2(this, node.child2);
+ JSValueOperand arg3(this, node.child3);
+ GPRReg arg1GPR = arg1.gpr();
+ GPRReg arg2GPR = arg2.gpr();
+ GPRReg arg3GPR = arg3.gpr();
+ flushRegisters();
+
+ GPRResult result(this);
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
+
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case GetById: {
+ JSValueOperand base(this, node.child1);
+ GPRReg baseGPR = base.gpr();
+ flushRegisters();
+
+ GPRResult result(this);
+ callOperation(operationGetById, result.gpr(), baseGPR, identifier(node.identifierNumber()));
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case PutById: {
+ JSValueOperand base(this, node.child1);
+ JSValueOperand value(this, node.child2);
+ GPRReg valueGPR = value.gpr();
+ GPRReg baseGPR = base.gpr();
+ flushRegisters();
+
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdStrict : operationPutByIdNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case PutByIdDirect: {
+ JSValueOperand base(this, node.child1);
+ JSValueOperand value(this, node.child2);
+ GPRReg valueGPR = value.gpr();
+ GPRReg baseGPR = base.gpr();
+ flushRegisters();
+
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdDirectStrict : operationPutByIdDirectNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case GetGlobalVar: {
+ GPRTemporary result(this);
+
+ JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
+ m_jit.loadPtr(globalObject->addressOfRegisters(), result.registerID());
+ m_jit.loadPtr(JITCompiler::addressForGlobalVar(result.registerID(), node.varNumber()), result.registerID());
+
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case PutGlobalVar: {
+ JSValueOperand value(this, node.child1);
+ GPRTemporary temp(this);
+
+ JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
+ m_jit.loadPtr(globalObject->addressOfRegisters(), temp.registerID());
+ m_jit.storePtr(value.registerID(), JITCompiler::addressForGlobalVar(temp.registerID(), node.varNumber()));
+
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case Return: {
+ ASSERT(JITCompiler::callFrameRegister != JITCompiler::regT1);
+ ASSERT(JITCompiler::regT1 != JITCompiler::returnValueRegister);
+ ASSERT(JITCompiler::returnValueRegister != JITCompiler::callFrameRegister);
+
+ // Return the result in returnValueRegister.
+ JSValueOperand op1(this, node.child1);
+ m_jit.move(op1.registerID(), JITCompiler::returnValueRegister);
+
+ // Grab the return address.
+ m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, JITCompiler::regT1);
+ // Restore our caller's "r".
+ m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, JITCompiler::callFrameRegister);
+ // Return.
+ m_jit.restoreReturnAddressBeforeReturn(JITCompiler::regT1);
+ m_jit.ret();
+
+ noResult(m_compileIndex);
+ break;
+ }
+ }
+
+ if (node.mustGenerate())
+ use(m_compileIndex);
+
+ checkConsistency();
+}
+
+void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator)
+{
+ ASSERT(!m_compileIndex);
+ Node* nodes = m_jit.graph().begin();
+
+ for (; m_compileIndex < m_jit.graph().size(); ++m_compileIndex) {
+#if DFG_DEBUG_VERBOSE
+ fprintf(stderr, "index(%d)\n", (int)m_compileIndex);
+#endif
+
+ Node& node = nodes[m_compileIndex];
+ if (!node.refCount)
+ continue;
+ compile(checkIterator, node);
+ }
+}
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.h
new file mode 100644
index 0000000..e140e45
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGNonSpeculativeJIT_h
+#define DFGNonSpeculativeJIT_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGJITCodeGenerator.h>
+
+namespace JSC { namespace DFG {
+
+class SpeculationCheckIndexIterator;
+
+// === EntryLocation ===
+//
+// This structure describes an entry point into the non-speculative
+// code path. This is used in linking bail-outs from the speculative path.
+struct EntryLocation {
+ EntryLocation(MacroAssembler::Label, NonSpeculativeJIT*);
+
+ // The node this entry point corresponds to, and the label
+ // marking the start of code for the given node.
+ MacroAssembler::Label m_entry;
+ NodeIndex m_nodeIndex;
+
+ // For every entry point we record a map recording for every
+ // machine register which, if any, values it contains. For
+ // GPR registers we must also record the format of the value.
+ struct RegisterInfo {
+ NodeIndex nodeIndex;
+ DataFormat format;
+ };
+ RegisterInfo m_gprInfo[numberOfGPRs];
+ NodeIndex m_fprInfo[numberOfFPRs];
+};
+
+// === NonSpeculativeJIT ===
+//
+// This class is used to generate code for the non-speculative path.
+// Code generation will take advantage of static information available
+// in the dataflow to perform safe optimizations - for example, avoiding
+// boxing numeric values between arithmetic operations, but will not
+// perform any unsafe optimizations that would render the code unable
+// to produce the correct results for any possible input.
+class NonSpeculativeJIT : public JITCodeGenerator {
+ friend struct EntryLocation;
+public:
+ NonSpeculativeJIT(JITCompiler& jit)
+ : JITCodeGenerator(jit, false)
+ {
+ }
+
+ void compile(SpeculationCheckIndexIterator&);
+
+ typedef SegmentedVector<EntryLocation, 16> EntryLocationVector;
+ EntryLocationVector& entryLocations() { return m_entryLocations; }
+
+private:
+ void compile(SpeculationCheckIndexIterator&, Node&);
+
+ // These methods are used when generating 'unexpected'
+ // calls out from JIT code to C++ helper routines -
+ // they spill all live values to the appropriate
+ // slots in the RegisterFile without changing any state
+ // in the GenerationInfo.
+ void silentSpill(VirtualRegister spillMe, GPRReg canTrample)
+ {
+ GenerationInfo& info = m_generationInfo[spillMe];
+ ASSERT(info.registerFormat() != DataFormatNone);
+ if (info.needsSpill()) {
+ DataFormat spillFormat = info.registerFormat();
+
+ if (spillFormat == DataFormatDouble) {
+ boxDouble(info.fpr(), canTrample);
+ m_jit.storePtr(JITCompiler::gprToRegisterID(canTrample), JITCompiler::addressFor(spillMe));
+ } else {
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(info.gpr());
+
+ if (spillFormat == DataFormatInteger) {
+ m_jit.orPtr(JITCompiler::tagTypeNumberRegister, reg);
+ m_jit.storePtr(reg, JITCompiler::addressFor(spillMe));
+ } else {
+ ASSERT(spillFormat & DataFormatJS || spillFormat == DataFormatCell);
+ m_jit.storePtr(reg, JITCompiler::addressFor(spillMe));
+ }
+ }
+ }
+ }
+ void silentFill(VirtualRegister spillMe, GPRReg canTrample)
+ {
+ GenerationInfo& info = m_generationInfo[spillMe];
+ NodeIndex nodeIndex = info.nodeIndex();
+ Node& node = m_jit.graph()[nodeIndex];
+ ASSERT(info.registerFormat() != DataFormatNone);
+ DataFormat spillFormat = info.registerFormat();
+
+ if (node.isConstant()) {
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(info.gpr());
+ m_jit.move(constantAsJSValueAsImmPtr(nodeIndex), reg);
+ } else if (node.isArgument()) {
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(info.gpr());
+ m_jit.loadPtr(m_jit.addressForArgument(m_jit.graph()[nodeIndex].argumentNumber()), reg);
+ } else if (spillFormat == DataFormatDouble) {
+ m_jit.loadPtr(JITCompiler::addressFor(spillMe), JITCompiler::gprToRegisterID(canTrample));
+ unboxDouble(canTrample, info.fpr());
+ } else if (spillFormat == DataFormatInteger) {
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(info.gpr());
+ m_jit.load32(JITCompiler::addressFor(spillMe), reg);
+ } else {
+ ASSERT(spillFormat & DataFormatJS || spillFormat == DataFormatCell);
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(info.gpr());
+ m_jit.loadPtr(JITCompiler::addressFor(spillMe), reg);
+ }
+ }
+ void silentSpillAllRegisters(GPRReg dontTrample)
+ {
+ GPRReg canTrample = (dontTrample == gpr0) ? gpr1 : gpr0;
+
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister name = m_gprs.name(gpr);
+ if (name != InvalidVirtualRegister)
+ silentSpill(name, canTrample);
+ }
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister name = m_fprs.name(fpr);
+ if (name != InvalidVirtualRegister)
+ silentSpill(name, canTrample);
+ }
+ }
+ void silentFillAllRegisters(GPRReg dontTrample)
+ {
+ GPRReg canTrample = (dontTrample == gpr0) ? gpr1 : gpr0;
+
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister name = m_fprs.name(fpr);
+ if (name != InvalidVirtualRegister)
+ silentFill(name, canTrample);
+ }
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister name = m_gprs.name(gpr);
+ if (name != InvalidVirtualRegister)
+ silentFill(name, canTrample);
+ }
+ }
+ void silentFillAllRegisters(FPRReg dontTrample)
+ {
+ GPRReg canTrample = gpr0;
+
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister name = m_fprs.name(fpr);
+ if (name != InvalidVirtualRegister) {
+#ifndef NDEBUG
+ ASSERT(fpr != dontTrample);
+#else
+ UNUSED_PARAM(dontTrample);
+#endif
+ silentFill(name, canTrample);
+ }
+ }
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister name = m_gprs.name(gpr);
+ if (name != InvalidVirtualRegister)
+ silentFill(name, canTrample);
+ }
+ }
+
+ // These methods are used to plant calls out to C++
+ // helper routines to convert between types.
+ void valueToNumber(JSValueOperand&, FPRReg result);
+ void valueToInt32(JSValueOperand&, GPRReg result);
+ void numberToInt32(FPRReg, GPRReg result);
+
+ // Record an entry location into the non-speculative code path;
+ // for every bail-out on the speculative path we record information
+ // to be able to re-enter into the non-speculative one.
+ void trackEntry(MacroAssembler::Label entry)
+ {
+ m_entryLocations.append(EntryLocation(entry, this));
+ }
+
+ EntryLocationVector m_entryLocations;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
+
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
new file mode 100644
index 0000000..de14415
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGOperations.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "CodeBlock.h"
+#include "Interpreter.h"
+#include "JSByteArray.h"
+#include "JSGlobalData.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+EncodedJSValue operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
+{
+ return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
+}
+
+EncodedJSValue operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
+{
+ JSValue op1 = JSValue::decode(encodedOp1);
+ JSValue op2 = JSValue::decode(encodedOp2);
+
+ if (op1.isInt32() && op2.isInt32()) {
+ int64_t result64 = static_cast<int64_t>(op1.asInt32()) + static_cast<int64_t>(op2.asInt32());
+ int32_t result32 = static_cast<int32_t>(result64);
+ if (LIKELY(result32 == result64))
+ return JSValue::encode(jsNumber(result32));
+ return JSValue::encode(jsNumber((double)result64));
+ }
+
+ double number1;
+ double number2;
+ if (op1.getNumber(number1) && op2.getNumber(number2))
+ return JSValue::encode(jsNumber(number1 + number2));
+
+ return JSValue::encode(jsAddSlowCase(exec, op1, op2));
+}
+
+EncodedJSValue operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
+{
+ JSValue baseValue = JSValue::decode(encodedBase);
+ JSValue property = JSValue::decode(encodedProperty);
+
+ if (LIKELY(baseValue.isCell())) {
+ JSCell* base = baseValue.asCell();
+
+ if (property.isUInt32()) {
+ JSGlobalData* globalData = &exec->globalData();
+ uint32_t i = property.asUInt32();
+
+ // FIXME: the JIT used to handle these in compiled code!
+ if (isJSArray(globalData, base) && asArray(base)->canGetIndex(i))
+ return JSValue::encode(asArray(base)->getIndex(i));
+
+ // FIXME: the JITstub used to relink this to an optimized form!
+ if (isJSString(globalData, base) && asString(base)->canGetIndex(i))
+ return JSValue::encode(asString(base)->getIndex(exec, i));
+
+ // FIXME: the JITstub used to relink this to an optimized form!
+ if (isJSByteArray(globalData, base) && asByteArray(base)->canAccessIndex(i))
+ return JSValue::encode(asByteArray(base)->getIndex(exec, i));
+
+ return JSValue::encode(baseValue.get(exec, i));
+ }
+
+ if (property.isString()) {
+ Identifier propertyName(exec, asString(property)->value(exec));
+ PropertySlot slot(base);
+ if (base->fastGetOwnPropertySlot(exec, propertyName, slot))
+ return JSValue::encode(slot.getValue(exec, propertyName));
+ }
+ }
+
+ Identifier ident(exec, property.toString(exec));
+ return JSValue::encode(baseValue.get(exec, ident));
+}
+
+EncodedJSValue operationGetById(ExecState* exec, EncodedJSValue encodedBase, Identifier* identifier)
+{
+ JSValue baseValue = JSValue::decode(encodedBase);
+ PropertySlot slot(baseValue);
+ return JSValue::encode(baseValue.get(exec, *identifier, slot));
+}
+
+template<bool strict>
+ALWAYS_INLINE static void operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
+{
+ JSGlobalData* globalData = &exec->globalData();
+
+ JSValue baseValue = JSValue::decode(encodedBase);
+ JSValue property = JSValue::decode(encodedProperty);
+ JSValue value = JSValue::decode(encodedValue);
+
+ if (LIKELY(property.isUInt32())) {
+ uint32_t i = property.asUInt32();
+
+ if (isJSArray(globalData, baseValue)) {
+ JSArray* jsArray = asArray(baseValue);
+ if (jsArray->canSetIndex(i)) {
+ jsArray->setIndex(*globalData, i, value);
+ return;
+ }
+
+ jsArray->JSArray::put(exec, i, value);
+ return;
+ }
+
+ if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ JSByteArray* jsByteArray = asByteArray(baseValue);
+ // FIXME: the JITstub used to relink this to an optimized form!
+ if (value.isInt32()) {
+ jsByteArray->setIndex(i, value.asInt32());
+ return;
+ }
+
+ double dValue = 0;
+ if (value.getNumber(dValue)) {
+ jsByteArray->setIndex(i, dValue);
+ return;
+ }
+ }
+
+ baseValue.put(exec, i, value);
+ return;
+ }
+
+ // Don't put to an object if toString throws an exception.
+ Identifier ident(exec, property.toString(exec));
+ if (!globalData->exception) {
+ PutPropertySlot slot(strict);
+ baseValue.put(exec, ident, value, slot);
+ }
+}
+
+void operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
+{
+ operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
+}
+
+void operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
+{
+ operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
+}
+
+void operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* identifier)
+{
+ PutPropertySlot slot(true);
+ JSValue::decode(encodedBase).put(exec, *identifier, JSValue::decode(encodedValue), slot);
+}
+
+void operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* identifier)
+{
+ PutPropertySlot slot(false);
+ JSValue::decode(encodedBase).put(exec, *identifier, JSValue::decode(encodedValue), slot);
+}
+
+void operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* identifier)
+{
+ PutPropertySlot slot(true);
+ JSValue::decode(encodedBase).putDirect(exec, *identifier, JSValue::decode(encodedValue), slot);
+}
+
+void operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* identifier)
+{
+ PutPropertySlot slot(false);
+ JSValue::decode(encodedBase).putDirect(exec, *identifier, JSValue::decode(encodedValue), slot);
+}
+
+DFGHandler lookupExceptionHandler(ExecState* exec, ReturnAddressPtr faultLocation)
+{
+ JSValue exceptionValue = exec->exception();
+ ASSERT(exceptionValue);
+
+ unsigned vPCIndex = exec->codeBlock()->bytecodeOffset(faultLocation);
+ HandlerInfo* handler = exec->globalData().interpreter->throwException(exec, exceptionValue, vPCIndex);
+
+ void* catchRoutine = handler ? handler->nativeCode.executableAddress() : (void*)ctiOpThrowNotCaught;
+ ASSERT(catchRoutine);
+ return DFGHandler(exec, catchRoutine);
+}
+
+double dfgConvertJSValueToNumber(ExecState* exec, EncodedJSValue value)
+{
+ return JSValue::decode(value).toNumber(exec);
+}
+
+int32_t dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
+{
+ return JSValue::decode(value).toInt32(exec);
+}
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
new file mode 100644
index 0000000..18570e2
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGOperations_h
+#define DFGOperations_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGJITCompiler.h>
+
+namespace JSC {
+
+class Identifier;
+
+namespace DFG {
+
+// These typedefs provide typechecking when generating calls out to helper routines;
+// this helps prevent calling a helper routine with the wrong arguments!
+typedef EncodedJSValue (*J_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
+typedef EncodedJSValue (*J_DFGOperation_EJ)(ExecState*, EncodedJSValue);
+typedef EncodedJSValue (*J_DFGOperation_EJP)(ExecState*, EncodedJSValue, void*);
+typedef EncodedJSValue (*J_DFGOperation_EJI)(ExecState*, EncodedJSValue, Identifier*);
+typedef void (*V_DFGOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
+typedef void (*V_DFGOperation_EJJP)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
+typedef void (*V_DFGOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*);
+typedef double (*D_DFGOperation_DD)(double, double);
+
+// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
+EncodedJSValue operationConvertThis(ExecState*, EncodedJSValue encodedOp1);
+EncodedJSValue operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
+EncodedJSValue operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty);
+EncodedJSValue operationGetById(ExecState*, EncodedJSValue encodedBase, Identifier*);
+void operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
+void operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
+void operationPutByIdStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdNonStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdDirectStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdDirectNonStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+
+// This method is used to lookup an exception hander, keyed by faultLocation, which is
+// the return location from one of the calls out to one of the helper operations above.
+struct DFGHandler {
+ DFGHandler(ExecState* exec, void* handler)
+ : exec(exec)
+ , handler(handler)
+ {
+ }
+
+ ExecState* exec;
+ void* handler;
+};
+DFGHandler lookupExceptionHandler(ExecState*, ReturnAddressPtr faultLocation);
+
+// These operations implement the implicitly called ToInt32 and ToNumber conversions from ES5.
+double dfgConvertJSValueToNumber(ExecState*, EncodedJSValue);
+int32_t dfgConvertJSValueToInt32(ExecState*, EncodedJSValue);
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGRegisterBank.h b/Source/JavaScriptCore/dfg/DFGRegisterBank.h
new file mode 100644
index 0000000..575e6b7
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGRegisterBank.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGRegisterBank_h
+#define DFGRegisterBank_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGJITCompiler.h>
+
+namespace JSC { namespace DFG {
+
+// === RegisterBank ===
+//
+// This class is used to implement the GPR and FPR register banks.
+// All registers have two pieces of state associated with them:
+// a lock count (used to indicate this register is already in use
+// in code generation of the current node, and cannot be spilled or
+// allocated as a temporary), and VirtualRegister 'name', recording
+// which value (if any) a machine register currently holds.
+// Either or both of these pieces of information may be valid for a
+// given register. A register may be:
+//
+// - unlocked, and unnamed: Available for allocation.
+// - locked, but unnamed: Already allocated as a temporary or
+// result for the current node.
+// - unlocked, but named: Contains the result of a prior operation,
+// not yet in use for this node,
+// - locked, but named: Contains the result of a prior operation,
+// already allocated as a operand to the
+// current operation.
+//
+// For every named register we also record a hint value indicating
+// the order in which registers should be selected to be spilled;
+// registers that can be more cheaply spilled and/or filled should
+// be selected first.
+//
+// Locking register is a strong retention mechanism; a locked register
+// will never be reallocated (this is used to ensure the operands to
+// the current node are in registers). Naming, conversely, in a weak
+// retention mechanism - allocating a register may force a named value
+// to be spilled.
+//
+// All named values must be given a hint that is greater than Min and
+// less than Max.
+template<typename RegID, size_t NUM_REGS, typename SpillHint, SpillHint SpillHintMin, SpillHint SpillHintMax>
+class RegisterBank {
+public:
+ RegisterBank()
+ : m_lastAllocated(NUM_REGS - 1)
+ {
+ }
+
+ // Allocate a register - this function finds an unlocked register,
+ // locks it, and returns it. If any named registers exist, one
+ // of these should be selected to be allocated. If all unlocked
+ // registers are named, then one of the named registers will need
+ // to be spilled. In this case the register selected to be spilled
+ // will be one of the registers that has the lowest 'spillOrder'
+ // cost associated with it.
+ //
+ // This method select the register to be allocated, and calls the
+ // private 'allocateInternal' method to update internal data
+ // structures accordingly.
+ RegID allocate(VirtualRegister &spillMe)
+ {
+ uint32_t currentLowest = NUM_REGS;
+ SpillHint currentSpillOrder = SpillHintMax;
+
+ // Scan through all register, starting at the last allocated & looping around.
+ ASSERT(m_lastAllocated < NUM_REGS);
+
+ // This loop is broken into two halves, looping from the last allocated
+ // register (the register returned last time this method was called) to
+ // the maximum register value, then from 0 to the last allocated.
+ // This implements a simple round-robin like approach to try to reduce
+ // thrash, and minimize time spent scanning locked registers in allocation.
+ // If a unlocked and unnamed register is found return it immediately.
+ // Otherwise, find the first unlocked register with the lowest spillOrder.
+ for (uint32_t i = m_lastAllocated + 1; i < NUM_REGS; ++i) {
+ // (1) If the current register is locked, it is not a candidate.
+ if (m_data[i].lockCount)
+ continue;
+ // (2) If the current register's spill order is 0, pick this! – unassigned registers have spill order 0.
+ SpillHint spillOrder = m_data[i].spillOrder;
+ if (!spillOrder)
+ return allocateInternal(i, spillMe);
+ // If this register is better (has a lower spill order value) than any prior
+ // candidate, then record it.
+ if (spillOrder < currentSpillOrder) {
+ currentSpillOrder = spillOrder;
+ currentLowest = i;
+ }
+ }
+ // Loop over the remaining entries.
+ for (uint32_t i = 0; i <= m_lastAllocated; ++i) {
+ if (m_data[i].lockCount)
+ continue;
+ SpillHint spillOrder = m_data[i].spillOrder;
+ if (!spillOrder)
+ return allocateInternal(i, spillMe);
+ if (spillOrder < currentSpillOrder) {
+ currentSpillOrder = spillOrder;
+ currentLowest = i;
+ }
+ }
+
+ // Deadlock check - this could only occur is all registers are locked!
+ ASSERT(currentLowest != NUM_REGS && currentSpillOrder != SpillHintMax);
+ // There were no available registers; currentLowest will need to be spilled.
+ return allocateInternal(currentLowest, spillMe);
+ }
+
+ // retain/release - these methods are used to associate/disassociate names
+ // with values in registers. retain should only be called on locked registers.
+ void retain(RegID reg, VirtualRegister name, SpillHint spillOrder)
+ {
+ // 'reg' must be a valid, locked register.
+ ASSERT(reg < NUM_REGS);
+ ASSERT(m_data[reg].lockCount);
+ // 'reg' should not currently be named, the new name must be valid.
+ ASSERT(m_data[reg].name == InvalidVirtualRegister);
+ ASSERT(name != InvalidVirtualRegister);
+ // 'reg' should not currently have a spillOrder, the new spill order must be valid.
+ ASSERT(spillOrder && spillOrder < SpillHintMax);
+ ASSERT(m_data[reg].spillOrder == SpillHintMin);
+
+ m_data[reg].name = name;
+ m_data[reg].spillOrder = spillOrder;
+ }
+ void release(RegID reg)
+ {
+ // 'reg' must be a valid register.
+ ASSERT(reg < NUM_REGS);
+ // 'reg' should currently be named.
+ ASSERT(m_data[reg].name != InvalidVirtualRegister);
+ // 'reg' should currently have a valid spill order.
+ ASSERT(m_data[reg].spillOrder > SpillHintMin && m_data[reg].spillOrder < SpillHintMax);
+
+ m_data[reg].name = InvalidVirtualRegister;
+ m_data[reg].spillOrder = SpillHintMin;
+ }
+
+ // lock/unlock register, ensures that they are not spilled.
+ void lock(RegID reg)
+ {
+ ASSERT(reg < NUM_REGS);
+ ++m_data[reg].lockCount;
+ ASSERT(m_data[reg].lockCount);
+ }
+ void unlock(RegID reg)
+ {
+ ASSERT(reg < NUM_REGS);
+ ASSERT(m_data[reg].lockCount);
+ --m_data[reg].lockCount;
+ }
+ bool isLocked(RegID reg)
+ {
+ ASSERT(reg < NUM_REGS);
+ return m_data[reg].lockCount;
+ }
+
+ // Get the name (VirtualRegister) associated with the
+ // given register (or InvalidVirtualRegister for none).
+ VirtualRegister name(RegID reg)
+ {
+ ASSERT(reg < NUM_REGS);
+ return m_data[reg].name;
+ }
+
+#ifndef NDEBUG
+ void dump()
+ {
+ // For each register, print the VirtualRegister 'name'.
+ for (uint32_t i =0; i < NUM_REGS; ++i) {
+ if (m_data[i].name != InvalidVirtualRegister)
+ fprintf(stderr, "[%02d]", m_data[i].name);
+ else
+ fprintf(stderr, "[--]");
+ }
+ fprintf(stderr, "\n");
+ }
+#endif
+
+private:
+ // Used by 'allocate', above, to update inforamtion in the map.
+ RegID allocateInternal(uint32_t i, VirtualRegister &spillMe)
+ {
+ // 'i' must be a valid, unlocked register.
+ ASSERT(i < NUM_REGS && !m_data[i].lockCount);
+
+ // Return the VirtualRegister of the named value currently stored in
+ // the register being returned - or InvalidVirtualRegister if none.
+ spillMe = m_data[i].name;
+
+ // Clear any name/spillOrder currently associated with the register,
+ m_data[i] = MapEntry();
+ m_data[i].lockCount = 1;
+ // Mark the register as locked (with a lock count of 1).
+ m_lastAllocated = i;
+ return (RegID)i;
+ }
+
+ // === MapEntry ===
+ //
+ // This structure provides information for an individual machine register
+ // being managed by the RegisterBank. For each register we track a lock
+ // count, name and spillOrder hint.
+ struct MapEntry {
+ MapEntry()
+ : name(InvalidVirtualRegister)
+ , spillOrder(SpillHintMin)
+ , lockCount(0)
+ {
+ }
+
+ VirtualRegister name;
+ SpillHint spillOrder;
+ uint32_t lockCount;
+ };
+
+ // Holds the current status of all registers.
+ MapEntry m_data[NUM_REGS];
+ // Used to to implement a simple round-robin like allocation scheme.
+ uint32_t m_lastAllocated;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGScoreBoard.h b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
new file mode 100644
index 0000000..eefed9e
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGScoreBoard_h
+#define DFGScoreBoard_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGGraph.h>
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+// === ScoreBoard ===
+//
+// This class is used in performing a virtual register allocation over the graph.
+// VirtualRegisters are allocated to nodes, with a used count for each virtual
+// register tracking the lifespan of the value; after the final use of a node
+// the VirtualRegister associated is freed such that it can be reused for
+// another node.
+class ScoreBoard {
+public:
+ ScoreBoard(Graph& graph)
+ : m_graph(graph)
+ {
+ }
+
+#if DFG_CONSISTENCY_CHECK
+ ~ScoreBoard()
+ {
+ // Every VirtualRegister that was allocated should now be free.
+ ASSERT(m_used.size() == m_free.size());
+ // For every entry in the free list, the use count of the virtual register should be zero.
+ // * By using the virtual register numbers from m_free, we are checking that all values
+ // in m_free are < m_used.size(), and correspond to an allocated VirtualRegsiter.
+ // * By setting m_used to a non-zero value after checking it, we are checking that all
+ // entries in m_free are unique (otherwise the second test of m_used will fail).
+ for (size_t i = 0; i < m_free.size(); ++i) {
+ VirtualRegister virtualRegister = m_free[i];
+ ASSERT(!m_used[virtualRegister]);
+ m_used[virtualRegister] = 1;
+ }
+ }
+#endif
+
+ VirtualRegister allocate()
+ {
+ // Do we have any VirtualRegsiters in the free list, that were used by
+ // prior nodes, but are now available?
+ if (!m_free.isEmpty()) {
+ VirtualRegister result = m_free.last();
+ m_free.removeLast();
+ // Use count must have hit zero for it to have been added to the free list!
+ ASSERT(!m_used[result]);
+ return result;
+ }
+
+ // Allocate a new VirtualRegister, and add a corresponding entry to m_used.
+ size_t next = allocatedCount();
+ m_used.append(0);
+ return (VirtualRegister)next;
+ }
+
+ // Increment the usecount for the VirtualRegsiter associated with 'child',
+ // if it reaches the node's refcount, free the VirtualRegsiter.
+ void use(NodeIndex child)
+ {
+ if (child == NoNode)
+ return;
+
+ // Find the virtual register number for this child, increment its use count.
+ Node& node = m_graph[child];
+ VirtualRegister index = node.virtualRegister;
+ if (node.refCount == ++m_used[index]) {
+ // If the use count in the scoreboard reaches the use count for the node,
+ // then this was its last use; the virtual register is now free.
+ // Clear the use count & add to the free list.
+ m_used[index] = 0;
+ m_free.append(index);
+ }
+ }
+
+ unsigned allocatedCount()
+ {
+ // m_used contains an entry for every allocated VirtualRegister.
+ return m_used.size();
+ }
+
+private:
+ // The graph, so we can get refCounts for nodes, to determine when values are dead.
+ Graph& m_graph;
+ // For every virtual register that has been allocated (either currently alive, or in
+ // the free list), we keep a count of the number of remaining uses until it is dead
+ // (0, in the case of entries in the free list). Since there is an entry for every
+ // allocated VirtualRegister, the length of this array conveniently provides the
+ // next available VirtualRegister number.
+ Vector<uint32_t, 64> m_used;
+ // A free list of VirtualRegsiters no longer alive.
+ Vector<VirtualRegister, 64> m_free;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
new file mode 100644
index 0000000..95472e1
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGSpeculativeJIT.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+template<bool strict>
+GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat)
+{
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ switch (info.registerFormat()) {
+ case DataFormatNone: {
+ GPRReg gpr = allocate();
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+
+ if (node.isConstant()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ if (isInt32Constant(nodeIndex)) {
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), reg);
+ info.fillInteger(gpr);
+ returnFormat = DataFormatInteger;
+ return gpr;
+ }
+ m_jit.move(constantAsJSValueAsImmPtr(nodeIndex), reg);
+ } else if (node.isArgument()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderArgument);
+ m_jit.loadPtr(m_jit.addressForArgument(m_jit.graph()[nodeIndex].argumentNumber()), reg);
+ } else {
+ DataFormat spillFormat = info.spillFormat();
+ ASSERT(spillFormat & DataFormatJS);
+
+ m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
+
+ if (spillFormat == DataFormatJSInteger) {
+ // If we know this was spilled as an integer we can fill without checking.
+ if (strict) {
+ m_jit.load32(JITCompiler::addressFor(virtualRegister), reg);
+ info.fillInteger(gpr);
+ returnFormat = DataFormatInteger;
+ return gpr;
+ }
+ m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), reg);
+ info.fillJSValue(gpr, DataFormatJSInteger);
+ returnFormat = DataFormatJSInteger;
+ return gpr;
+ }
+ m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), reg);
+ }
+
+ // Fill as JSValue, and fall through.
+ info.fillJSValue(gpr, DataFormatJSInteger);
+ m_gprs.unlock(gpr);
+ }
+
+ case DataFormatJS: {
+ // Check the value is an integer.
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+ speculationCheck(m_jit.branchPtr(MacroAssembler::Below, reg, JITCompiler::tagTypeNumberRegister));
+ info.fillJSValue(gpr, DataFormatJSInteger);
+ // If !strict we're done, return.
+ if (!strict) {
+ returnFormat = DataFormatJSInteger;
+ return gpr;
+ }
+ // else fall through & handle as DataFormatJSInteger.
+ m_gprs.unlock(gpr);
+ }
+
+ case DataFormatJSInteger: {
+ // In a strict fill we need to strip off the value tag.
+ if (strict) {
+ GPRReg gpr = info.gpr();
+ GPRReg result;
+ // If the register has already been locked we need to take a copy.
+ // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
+ if (m_gprs.isLocked(gpr))
+ result = allocate();
+ else {
+ m_gprs.lock(gpr);
+ info.fillInteger(gpr);
+ result = gpr;
+ }
+ m_jit.zeroExtend32ToPtr(JITCompiler::gprToRegisterID(gpr), JITCompiler::gprToRegisterID(result));
+ returnFormat = DataFormatInteger;
+ return result;
+ }
+
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ returnFormat = DataFormatJSInteger;
+ return gpr;
+ }
+
+ case DataFormatInteger: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ returnFormat = DataFormatInteger;
+ return gpr;
+ }
+
+ case DataFormatDouble:
+ case DataFormatCell:
+ case DataFormatJSDouble:
+ case DataFormatJSCell: {
+ terminateSpeculativeExecution();
+ returnFormat = DataFormatInteger;
+ return allocate();
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return InvalidGPRReg;
+}
+
+SpeculationCheck::SpeculationCheck(MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex)
+ : m_check(check)
+ , m_nodeIndex(jit->m_compileIndex)
+ , m_recoveryIndex(recoveryIndex)
+{
+ for (GPRReg gpr = gpr0; gpr < numberOfGPRs; next(gpr)) {
+ VirtualRegister virtualRegister = jit->m_gprs.name(gpr);
+ if (virtualRegister != InvalidVirtualRegister) {
+ GenerationInfo& info = jit->m_generationInfo[virtualRegister];
+ m_gprInfo[gpr].nodeIndex = info.nodeIndex();
+ m_gprInfo[gpr].format = info.registerFormat();
+ } else
+ m_gprInfo[gpr].nodeIndex = NoNode;
+ }
+ for (FPRReg fpr = fpr0; fpr < numberOfFPRs; next(fpr)) {
+ VirtualRegister virtualRegister = jit->m_fprs.name(fpr);
+ if (virtualRegister != InvalidVirtualRegister) {
+ GenerationInfo& info = jit->m_generationInfo[virtualRegister];
+ ASSERT(info.registerFormat() == DataFormatDouble);
+ m_fprInfo[fpr] = info.nodeIndex();
+ } else
+ m_fprInfo[fpr] = NoNode;
+ }
+}
+
+GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat)
+{
+ return fillSpeculateIntInternal<false>(nodeIndex, returnFormat);
+}
+
+GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
+{
+ DataFormat mustBeDataFormatInteger;
+ GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger);
+ ASSERT(mustBeDataFormatInteger == DataFormatInteger);
+ return result;
+}
+
+GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
+{
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister;
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ switch (info.registerFormat()) {
+ case DataFormatNone: {
+ GPRReg gpr = allocate();
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+
+ if (node.isConstant()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ JSValue jsValue = constantAsJSValue(nodeIndex);
+ if (jsValue.isCell()) {
+ m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), reg);
+ info.fillJSValue(gpr, DataFormatJSCell);
+ return gpr;
+ }
+ terminateSpeculativeExecution();
+ return gpr;
+ }
+ if (node.isArgument()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderArgument);
+ m_jit.loadPtr(m_jit.addressForArgument(m_jit.graph()[nodeIndex].argumentNumber()), reg);
+ speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, reg, JITCompiler::tagMaskRegister));
+ info.fillJSValue(gpr, DataFormatJSCell);
+ return gpr;
+ }
+ ASSERT(info.spillFormat() & DataFormatJS);
+ m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
+ m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), reg);
+
+ if (info.spillFormat() != DataFormatJSCell)
+ speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, reg, JITCompiler::tagMaskRegister));
+ info.fillJSValue(gpr, DataFormatJSCell);
+ return gpr;
+ }
+
+ case DataFormatCell:
+ case DataFormatJSCell: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ return gpr;
+ }
+
+ case DataFormatJS: {
+ GPRReg gpr = info.gpr();
+ m_gprs.lock(gpr);
+ JITCompiler::RegisterID reg = JITCompiler::gprToRegisterID(gpr);
+ speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, reg, JITCompiler::tagMaskRegister));
+ info.fillJSValue(gpr, DataFormatJSCell);
+ return gpr;
+ }
+
+ case DataFormatJSInteger:
+ case DataFormatInteger:
+ case DataFormatJSDouble:
+ case DataFormatDouble: {
+ terminateSpeculativeExecution();
+ return allocate();
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return InvalidGPRReg;
+}
+
+bool SpeculativeJIT::compile(Node& node)
+{
+ checkConsistency();
+
+ NodeType op = node.op;
+
+ switch (op) {
+ case Int32Constant:
+ case DoubleConstant:
+ case JSConstant:
+ initConstantInfo(m_compileIndex);
+ break;
+
+ case Argument:
+ initArgumentInfo(m_compileIndex);
+ break;
+
+ case BitAnd:
+ case BitOr:
+ case BitXor:
+ if (isInt32Constant(node.child1)) {
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op2);
+
+ bitOp(op, valueOfInt32Constant(node.child1), op2.registerID(), result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ } else if (isInt32Constant(node.child2)) {
+ SpeculateIntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+
+ bitOp(op, valueOfInt32Constant(node.child2), op1.registerID(), result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ } else {
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1, op2);
+
+ MacroAssembler::RegisterID reg1 = op1.registerID();
+ MacroAssembler::RegisterID reg2 = op2.registerID();
+ bitOp(op, reg1, reg2, result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ }
+ break;
+
+ case BitRShift:
+ case BitLShift:
+ case BitURShift:
+ if (isInt32Constant(node.child2)) {
+ SpeculateIntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+
+ shiftOp(op, op1.registerID(), valueOfInt32Constant(node.child2) & 0x1f, result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ } else {
+ // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1);
+
+ MacroAssembler::RegisterID reg1 = op1.registerID();
+ MacroAssembler::RegisterID reg2 = op2.registerID();
+ shiftOp(op, reg1, reg2, result.registerID());
+
+ integerResult(result.gpr(), m_compileIndex);
+ }
+ break;
+
+ case UInt32ToNumber: {
+ IntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+
+ // Test the operand is positive.
+ speculationCheck(m_jit.branch32(MacroAssembler::LessThan, op1.registerID(), TrustedImm32(0)));
+
+ m_jit.move(op1.registerID(), result.registerID());
+ integerResult(result.gpr(), m_compileIndex, op1.format());
+ break;
+ }
+
+ case NumberToInt32: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+ m_jit.move(op1.registerID(), result.registerID());
+ integerResult(result.gpr(), m_compileIndex, op1.format());
+ break;
+ }
+
+ case Int32ToNumber: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+ m_jit.move(op1.registerID(), result.registerID());
+ integerResult(result.gpr(), m_compileIndex, op1.format());
+ break;
+ }
+ case ValueToInt32: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+ m_jit.move(op1.registerID(), result.registerID());
+ integerResult(result.gpr(), m_compileIndex, op1.format());
+ break;
+ }
+
+ case ValueToNumber: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ GPRTemporary result(this, op1);
+ m_jit.move(op1.registerID(), result.registerID());
+ integerResult(result.gpr(), m_compileIndex, op1.format());
+ break;
+ }
+
+ case ValueAdd:
+ case ArithAdd: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1, op2);
+
+ GPRReg gpr1 = op1.gpr();
+ GPRReg gpr2 = op2.gpr();
+ GPRReg gprResult = result.gpr();
+ MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, JITCompiler::gprToRegisterID(gpr1), JITCompiler::gprToRegisterID(gpr2), JITCompiler::gprToRegisterID(gprResult));
+
+ if (gpr1 == gprResult)
+ speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
+ else if (gpr2 == gprResult)
+ speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
+ else
+ speculationCheck(check);
+
+ integerResult(gprResult, m_compileIndex);
+ break;
+ }
+
+ case ArithSub: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this);
+
+ MacroAssembler::RegisterID reg1 = op1.registerID();
+ MacroAssembler::RegisterID reg2 = op2.registerID();
+ speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, reg1, reg2, result.registerID()));
+
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithMul: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this);
+
+ MacroAssembler::RegisterID reg1 = op1.registerID();
+ MacroAssembler::RegisterID reg2 = op2.registerID();
+ speculationCheck(m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.registerID()));
+ speculationCheck(m_jit.branchTest32(MacroAssembler::Zero, result.registerID()));
+
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithDiv: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1, op2);
+
+ terminateSpeculativeExecution();
+
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case ArithMod: {
+ SpeculateIntegerOperand op1(this, node.child1);
+ SpeculateIntegerOperand op2(this, node.child2);
+ GPRTemporary result(this, op1, op2);
+
+ terminateSpeculativeExecution();
+
+ integerResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case GetByVal: {
+ NodeIndex alias = node.child3;
+ if (alias != NoNode) {
+ // FIXME: result should be able to reuse child1, child2. Should have an 'UnusedOperand' type.
+ JSValueOperand aliasedValue(this, node.child3);
+ GPRTemporary result(this, aliasedValue);
+ m_jit.move(aliasedValue.registerID(), result.registerID());
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ SpeculateCellOperand base(this, node.child1);
+ SpeculateStrictInt32Operand property(this, node.child2);
+ GPRTemporary storage(this);
+
+ MacroAssembler::RegisterID baseReg = base.registerID();
+ MacroAssembler::RegisterID propertyReg = property.registerID();
+ MacroAssembler::RegisterID storageReg = storage.registerID();
+
+ // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
+ // an access with offset JSArray::storageOffset() is valid for all JSCells!
+ m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
+
+ // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
+ speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+ speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
+
+ // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache
+ // the storage pointer - especially if there happens to be another register free right now. If we do so,
+ // then we'll need to allocate a new temporary for result.
+ GPRTemporary& result = storage;
+ m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.registerID());
+ speculationCheck(m_jit.branchTestPtr(MacroAssembler::Zero, result.registerID()));
+
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case PutByVal:
+ case PutByValAlias: {
+ SpeculateStrictInt32Operand property(this, node.child2);
+ GPRTemporary storage(this);
+
+ MacroAssembler::RegisterID propertyReg;
+ MacroAssembler::RegisterID storageReg;
+
+ // This block also defines the scope for base, and all bails to the non-speculative path.
+ // At the end of this scope base will be release, and as such may be reused by for 'value'.
+ //
+ // If we've already read from this location on the speculative pass, then it cannot be beyond array bounds, or a hole.
+ if (op == PutByValAlias) {
+ SpeculateCellOperand base(this, node.child1);
+
+ // Map base & property into registers, allocate a register for storage.
+ propertyReg = property.registerID();
+ storageReg = storage.registerID();
+ MacroAssembler::RegisterID baseReg = base.registerID();
+
+ // Get the array storage.
+ m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
+ } else {
+ SpeculateCellOperand base(this, node.child1);
+
+ // Map base & property into registers, allocate a register for storage.
+ propertyReg = property.registerID();
+ storageReg = storage.registerID();
+ MacroAssembler::RegisterID baseReg = base.registerID();
+
+ // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
+ speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+ speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
+
+ // Get the array storage.
+ m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
+
+ // Check if we're writing to a hole; if so increment m_numValuesInVector.
+ MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+
+ // If we're writing to a hole we might be growing the array;
+ MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+ m_jit.add32(TrustedImm32(1), propertyReg);
+ m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+ m_jit.sub32(TrustedImm32(1), propertyReg);
+
+ lengthDoesNotNeedUpdate.link(&m_jit);
+ notHoleValue.link(&m_jit);
+ }
+ // After this point base goes out of scope. This may free the register.
+ // As such, after this point we'd better not have any bails out to the non-speculative path!
+
+ // Store the value to the array.
+ JSValueOperand value(this, node.child3);
+ MacroAssembler::RegisterID valueReg = value.registerID();
+ m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case Return: {
+ ASSERT(JITCompiler::callFrameRegister != JITCompiler::regT1);
+ ASSERT(JITCompiler::regT1 != JITCompiler::returnValueRegister);
+ ASSERT(JITCompiler::returnValueRegister != JITCompiler::callFrameRegister);
+
+ // Return the result in returnValueRegister.
+ JSValueOperand op1(this, node.child1);
+ m_jit.move(op1.registerID(), JITCompiler::returnValueRegister);
+
+ // Grab the return address.
+ m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, JITCompiler::regT1);
+ // Restore our caller's "r".
+ m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, JITCompiler::callFrameRegister);
+ // Return.
+ m_jit.restoreReturnAddressBeforeReturn(JITCompiler::regT1);
+ m_jit.ret();
+
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case ConvertThis: {
+ SpeculateCellOperand thisValue(this, node.child1);
+ GPRTemporary temp(this);
+
+ m_jit.loadPtr(JITCompiler::Address(thisValue.registerID(), JSCell::structureOffset()), temp.registerID());
+ speculationCheck(m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(temp.registerID(), Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(NeedsThisConversion)));
+
+ cellResult(thisValue.gpr(), m_compileIndex);
+ break;
+ }
+
+ case GetById: {
+ JSValueOperand base(this, node.child1);
+ GPRReg baseGPR = base.gpr();
+ flushRegisters();
+
+ GPRResult result(this);
+ callOperation(operationGetById, result.gpr(), baseGPR, identifier(node.identifierNumber()));
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case PutById: {
+ JSValueOperand base(this, node.child1);
+ JSValueOperand value(this, node.child2);
+ GPRReg valueGPR = value.gpr();
+ GPRReg baseGPR = base.gpr();
+ flushRegisters();
+
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdStrict : operationPutByIdNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case PutByIdDirect: {
+ JSValueOperand base(this, node.child1);
+ JSValueOperand value(this, node.child2);
+ GPRReg valueGPR = value.gpr();
+ GPRReg baseGPR = base.gpr();
+ flushRegisters();
+
+ callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdDirectStrict : operationPutByIdDirectNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ noResult(m_compileIndex);
+ break;
+ }
+
+ case GetGlobalVar: {
+ GPRTemporary result(this);
+
+ JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
+ m_jit.loadPtr(globalObject->addressOfRegisters(), result.registerID());
+ m_jit.loadPtr(JITCompiler::addressForGlobalVar(result.registerID(), node.varNumber()), result.registerID());
+
+ jsValueResult(result.gpr(), m_compileIndex);
+ break;
+ }
+
+ case PutGlobalVar: {
+ JSValueOperand value(this, node.child1);
+ GPRTemporary temp(this);
+
+ JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
+ m_jit.loadPtr(globalObject->addressOfRegisters(), temp.registerID());
+ m_jit.storePtr(value.registerID(), JITCompiler::addressForGlobalVar(temp.registerID(), node.varNumber()));
+
+ noResult(m_compileIndex);
+ break;
+ }
+ }
+
+ // Check if generation for the speculative path has failed catastrophically. :-)
+ // In the future, we may want to throw away the code we've generated in this case.
+ // For now, there is no point generating any further code, return immediately.
+ if (m_didTerminate)
+ return false;
+
+ if (node.mustGenerate())
+ use(m_compileIndex);
+
+ checkConsistency();
+
+ return true;
+}
+
+bool SpeculativeJIT::compile()
+{
+ ASSERT(!m_compileIndex);
+ Node* nodes = m_jit.graph().begin();
+
+ for (; m_compileIndex < m_jit.graph().size(); ++m_compileIndex) {
+#if DFG_DEBUG_VERBOSE
+ fprintf(stderr, "index(%d)\n", (int)m_compileIndex);
+#endif
+
+ Node& node = nodes[m_compileIndex];
+ if (!node.refCount)
+ continue;
+ if (!compile(node))
+ return false;
+ }
+ return true;
+}
+
+} } // namespace JSC::DFG
+
+#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
new file mode 100644
index 0000000..93983c6
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGSpeculativeJIT_h
+#define DFGSpeculativeJIT_h
+
+#if ENABLE(DFG_JIT)
+
+#include <dfg/DFGJITCodeGenerator.h>
+
+namespace JSC { namespace DFG {
+
+class SpeculativeJIT;
+
+// This enum describes the types of additional recovery that
+// may need be performed should a speculation check fail.
+enum SpeculationRecoveryType {
+ SpeculativeAdd
+};
+
+// === SpeculationRecovery ===
+//
+// This class provides additional information that may be associated with a
+// speculation check - for example
+class SpeculationRecovery {
+public:
+ SpeculationRecovery(SpeculationRecoveryType type, GPRReg dest, GPRReg src)
+ : m_type(type)
+ , m_dest(dest)
+ , m_src(src)
+ {
+ }
+
+ SpeculationRecoveryType type() { return m_type; }
+ GPRReg dest() { return m_dest; }
+ GPRReg src() { return m_src; }
+
+private:
+ // Indicates the type of additional recovery to be performed.
+ SpeculationRecoveryType m_type;
+ // different recovery types may required different additional information here.
+ GPRReg m_dest;
+ GPRReg m_src;
+};
+
+// === SpeculationCheck ===
+//
+// This structure records a bail-out from the speculative path,
+// which will need to be linked in to the non-speculative one.
+struct SpeculationCheck {
+ SpeculationCheck(MacroAssembler::Jump, SpeculativeJIT*, unsigned recoveryIndex = 0);
+
+ // The location of the jump out from the speculative path,
+ // and the node we were generating code for.
+ MacroAssembler::Jump m_check;
+ NodeIndex m_nodeIndex;
+ // Used to record any additional recovery to be performed; this
+ // value is an index into the SpeculativeJIT's m_speculationRecoveryList
+ // array, offset by 1. (m_recoveryIndex == 0) means no recovery.
+ unsigned m_recoveryIndex;
+
+ struct RegisterInfo {
+ NodeIndex nodeIndex;
+ DataFormat format;
+ };
+ RegisterInfo m_gprInfo[numberOfGPRs];
+ NodeIndex m_fprInfo[numberOfFPRs];
+};
+
+
+// === SpeculativeJIT ===
+//
+// The SpeculativeJIT is used to generate a fast, but potentially
+// incomplete code path for the dataflow. When code generating
+// we may make assumptions about operand types, dynamically check,
+// and bail-out to an alternate code path if these checks fail.
+// Importantly, the speculative code path cannot be reentered once
+// a speculative check has failed. This allows the SpeculativeJIT
+// to propagate type information (including information that has
+// only speculatively been asserted) through the dataflow.
+class SpeculativeJIT : public JITCodeGenerator {
+ friend struct SpeculationCheck;
+public:
+ // The speculation
+ typedef SegmentedVector<SpeculationCheck, 16> SpeculationCheckVector;
+
+ SpeculativeJIT(JITCompiler& jit)
+ : JITCodeGenerator(jit, true)
+ , m_didTerminate(false)
+ {
+ }
+
+ bool compile();
+
+ // Retrieve the list of bail-outs from the speculative path,
+ // and additional recovery information.
+ SpeculationCheckVector& speculationChecks()
+ {
+ return m_speculationChecks;
+ }
+ SpeculationRecovery* speculationRecovery(size_t index)
+ {
+ // SpeculationCheck::m_recoveryIndex is offset by 1,
+ // 0 means no recovery.
+ return index ? &m_speculationRecoveryList[index - 1] : 0;
+ }
+
+ // Called by the speculative operand types, below, to fill operand to
+ // machine registers, implicitly generating speculation checks as needed.
+ GPRReg fillSpeculateInt(NodeIndex, DataFormat& returnFormat);
+ GPRReg fillSpeculateIntStrict(NodeIndex);
+ GPRReg fillSpeculateCell(NodeIndex);
+
+private:
+ bool compile(Node&);
+
+ // Add a speculation check without additional recovery.
+ void speculationCheck(MacroAssembler::Jump jumpToFail)
+ {
+ m_speculationChecks.append(SpeculationCheck(jumpToFail, this));
+ }
+ // Add a speculation check with additional recovery.
+ void speculationCheck(MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+ {
+ m_speculationRecoveryList.append(recovery);
+ m_speculationChecks.append(SpeculationCheck(jumpToFail, this, m_speculationRecoveryList.size()));
+ }
+
+ // Called when we statically determine that a speculation will fail.
+ void terminateSpeculativeExecution()
+ {
+ // FIXME: in cases where we can statically determine we're going to bail out from the speculative
+ // JIT we should probably rewind code generation and only produce the non-speculative path.
+ m_didTerminate = true;
+ speculationCheck(m_jit.jump());
+ }
+
+ template<bool strict>
+ GPRReg fillSpeculateIntInternal(NodeIndex, DataFormat& returnFormat);
+
+ // It is possible, during speculative generation, to reach a situation in which we
+ // can statically determine a speculation will fail (for example, when two nodes
+ // will make conflicting speculations about the same operand). In such cases this
+ // flag is set, indicating no further code generation should take place.
+ bool m_didTerminate;
+ // This vector tracks bail-outs from the speculative path to the non-speculative one.
+ SpeculationCheckVector m_speculationChecks;
+ // Some bail-outs need to record additional information recording specific recovery
+ // to be performed (for example, on detected overflow from an add, we may need to
+ // reverse the addition if an operand is being overwritten).
+ Vector<SpeculationRecovery, 16> m_speculationRecoveryList;
+};
+
+
+// === Speculative Operand types ===
+//
+// SpeculateIntegerOperand, SpeculateStrictInt32Operand and SpeculateCellOperand.
+//
+// These are used to lock the operands to a node into machine registers within the
+// SpeculativeJIT. The classes operate like those provided by the JITCodeGenerator,
+// however these will perform a speculative check for a more restrictive type than
+// we can statically determine the operand to have. If the operand does not have
+// the requested type, a bail-out to the non-speculative path will be taken.
+
+class SpeculateIntegerOperand {
+public:
+ explicit SpeculateIntegerOperand(SpeculativeJIT* jit, NodeIndex index)
+ : m_jit(jit)
+ , m_index(index)
+ , m_gprOrInvalid(InvalidGPRReg)
+#ifndef NDEBUG
+ , m_format(DataFormatNone)
+#endif
+ {
+ ASSERT(m_jit);
+ if (jit->isFilled(index))
+ gpr();
+ }
+
+ ~SpeculateIntegerOperand()
+ {
+ ASSERT(m_gprOrInvalid != InvalidGPRReg);
+ m_jit->unlock(m_gprOrInvalid);
+ }
+
+ NodeIndex index() const
+ {
+ return m_index;
+ }
+
+ GPRReg gpr()
+ {
+ if (m_gprOrInvalid == InvalidGPRReg)
+ m_gprOrInvalid = m_jit->fillSpeculateInt(index(), m_format);
+ return m_gprOrInvalid;
+ }
+
+ DataFormat format()
+ {
+ gpr(); // m_format is set when m_gpr is locked.
+ ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
+ return m_format;
+ }
+
+ MacroAssembler::RegisterID registerID()
+ {
+ return JITCompiler::gprToRegisterID(gpr());
+ }
+
+private:
+ SpeculativeJIT* m_jit;
+ NodeIndex m_index;
+ GPRReg m_gprOrInvalid;
+ DataFormat m_format;
+};
+
+class SpeculateStrictInt32Operand {
+public:
+ explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, NodeIndex index)
+ : m_jit(jit)
+ , m_index(index)
+ , m_gprOrInvalid(InvalidGPRReg)
+ {
+ ASSERT(m_jit);
+ if (jit->isFilled(index))
+ gpr();
+ }
+
+ ~SpeculateStrictInt32Operand()
+ {
+ ASSERT(m_gprOrInvalid != InvalidGPRReg);
+ m_jit->unlock(m_gprOrInvalid);
+ }
+
+ NodeIndex index() const
+ {
+ return m_index;
+ }
+
+ GPRReg gpr()
+ {
+ if (m_gprOrInvalid == InvalidGPRReg)
+ m_gprOrInvalid = m_jit->fillSpeculateIntStrict(index());
+ return m_gprOrInvalid;
+ }
+
+ MacroAssembler::RegisterID registerID()
+ {
+ return JITCompiler::gprToRegisterID(gpr());
+ }
+
+private:
+ SpeculativeJIT* m_jit;
+ NodeIndex m_index;
+ GPRReg m_gprOrInvalid;
+};
+
+class SpeculateCellOperand {
+public:
+ explicit SpeculateCellOperand(SpeculativeJIT* jit, NodeIndex index)
+ : m_jit(jit)
+ , m_index(index)
+ , m_gprOrInvalid(InvalidGPRReg)
+ {
+ ASSERT(m_jit);
+ if (jit->isFilled(index))
+ gpr();
+ }
+
+ ~SpeculateCellOperand()
+ {
+ ASSERT(m_gprOrInvalid != InvalidGPRReg);
+ m_jit->unlock(m_gprOrInvalid);
+ }
+
+ NodeIndex index() const
+ {
+ return m_index;
+ }
+
+ GPRReg gpr()
+ {
+ if (m_gprOrInvalid == InvalidGPRReg)
+ m_gprOrInvalid = m_jit->fillSpeculateCell(index());
+ return m_gprOrInvalid;
+ }
+
+ MacroAssembler::RegisterID registerID()
+ {
+ return JITCompiler::gprToRegisterID(gpr());
+ }
+
+private:
+ SpeculativeJIT* m_jit;
+ NodeIndex m_index;
+ GPRReg m_gprOrInvalid;
+};
+
+
+// === SpeculationCheckIndexIterator ===
+//
+// This class is used by the non-speculative JIT to check which
+// nodes require entry points from the speculative path.
+class SpeculationCheckIndexIterator {
+public:
+ SpeculationCheckIndexIterator(SpeculativeJIT& speculativeJIT)
+ : m_speculationChecks(speculativeJIT.speculationChecks())
+ , m_iter(m_speculationChecks.begin())
+ , m_end(m_speculationChecks.end())
+ {
+ }
+
+ bool hasCheckAtIndex(NodeIndex nodeIndex)
+ {
+ while (m_iter != m_end) {
+ NodeIndex current = m_iter->m_nodeIndex;
+ if (current >= nodeIndex)
+ return current == nodeIndex;
+ ++m_iter;
+ }
+ return false;
+ }
+
+private:
+ SpeculativeJIT::SpeculationCheckVector& m_speculationChecks;
+ SpeculativeJIT::SpeculationCheckVector::Iterator m_iter;
+ SpeculativeJIT::SpeculationCheckVector::Iterator m_end;
+};
+
+} } // namespace JSC::DFG
+
+#endif
+#endif
+
diff --git a/Source/JavaScriptCore/gyp/JavaScriptCore.gyp b/Source/JavaScriptCore/gyp/JavaScriptCore.gyp
index 1e46094..a520344 100644
--- a/Source/JavaScriptCore/gyp/JavaScriptCore.gyp
+++ b/Source/JavaScriptCore/gyp/JavaScriptCore.gyp
@@ -3,30 +3,43 @@
'../../gyp/common.gypi',
'../JavaScriptCore.gypi',
],
- 'xcode_config_file': '<(DEPTH)/JavaScriptCore/Configurations/DebugRelease.xcconfig',
+ 'configurations': {
+ 'Production': {
+ 'xcode_config_file': '<(project_dir)/Configurations/Base.xcconfig',
+ },
+ 'Profiling': {
+ 'xcode_config_file': '<(project_dir)/Configurations/DebugRelease.xcconfig',
+ 'xcode_settings': {
+ 'STRIP_INSTALLED_PRODUCT': 'NO',
+ },
+ },
+ 'Release': {
+ 'xcode_config_file': '<(project_dir)/Configurations/DebugRelease.xcconfig',
+ 'xcode_settings': {
+ 'STRIP_INSTALLED_PRODUCT': 'NO',
+ },
+ },
+ 'Debug': {
+ 'xcode_config_file': '<(project_dir)/Configurations/DebugRelease.xcconfig',
+ 'xcode_settings': {
+ 'DEAD_CODE_STRIPPING': '$(DEAD_CODE_STRIPPING_debug)',
+ 'DEBUG_DEFINES': '$(DEBUG_DEFINES_debug)',
+ 'GCC_OPTIMIZATION_LEVEL': '$(GCC_OPTIMIZATION_LEVEL_debug)',
+ 'STRIP_INSTALLED_PRODUCT': '$(STRIP_INSTALLED_PRODUCT_debug)',
+ },
+ },
+ },
'variables': {
- # FIXME: We should use a header map instead of listing these explicitly.
'javascriptcore_include_dirs': [
- '<(DEPTH)', # Some paths in API include JavaScriptCore/
- '<(DEPTH)/JavaScriptCore',
- '<(DEPTH)/JavaScriptCore/ForwardingHeaders',
- '<(DEPTH)/JavaScriptCore/API',
- '<(DEPTH)/JavaScriptCore/assembler',
- '<(DEPTH)/JavaScriptCore/collector/handles',
- '<(DEPTH)/JavaScriptCore/bytecode',
- '<(DEPTH)/JavaScriptCore/bytecompiler',
- '<(DEPTH)/JavaScriptCore/debugger',
- '<(DEPTH)/JavaScriptCore/icu',
- '<(DEPTH)/JavaScriptCore/interpreter',
- '<(DEPTH)/JavaScriptCore/jit',
- '<(DEPTH)/JavaScriptCore/parser',
- '<(DEPTH)/JavaScriptCore/profiler',
- '<(DEPTH)/JavaScriptCore/runtime',
- '<(DEPTH)/JavaScriptCore/wtf',
- '<(DEPTH)/JavaScriptCore/wtf/unicode',
- '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore',
+ '<(project_dir)',
+ '<(project_dir)/icu',
],
},
+ 'target_defaults': {
+ 'configurations': {
+ 'Profiling': {},
+ },
+ },
'targets': [
{
'target_name': 'JavaScriptCore',
@@ -37,15 +50,22 @@
],
'include_dirs': [
'<@(javascriptcore_include_dirs)',
+ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore',
],
+ 'configurations': {
+ 'Production': {
+ 'INSTALL_PATH': '$(BUILT_PRODUCTS_DIR)',
+ },
+ },
'sources': [
'<@(javascriptcore_files)',
'<@(javascriptcore_publicheader_files)',
'<@(javascriptcore_privateheader_files)',
+ '<@(javascriptcore_derived_source_files)',
'$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
'$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
- 'libicucore.dylib',
- 'libobjc.dylib',
+ '/usr/lib/libicucore.dylib',
+ '/usr/lib/libobjc.dylib',
],
'mac_framework_headers': [
'<@(javascriptcore_publicheader_files)',
@@ -53,47 +73,41 @@
'mac_framework_private_headers': [
'<@(javascriptcore_privateheader_files)',
],
- 'xcode_config_file': '<(DEPTH)/JavaScriptCore/Configurations/JavaScriptCore.xcconfig',
+ 'xcode_config_file': '<(project_dir)/Configurations/JavaScriptCore.xcconfig',
'sources/': [
- ['exclude', 'qt'],
- ['exclude', 'os-win32'],
- ['exclude', 'wtf/android'],
- ['exclude', 'wtf/brew'],
- ['exclude', 'wtf/efl'],
- ['exclude', 'wtf/gtk'],
- ['exclude', 'wtf/qt'],
- ['exclude', 'wtf/haiku'],
- ['exclude', 'API/tests'],
- ['exclude', 'wtf/url'],
- ['exclude', 'wtf/wince'],
- ['exclude', 'wtf/wx'],
- ['exclude', 'wtf/unicode/brew'],
- ['exclude', 'wtf/unicode/wince'],
- ['exclude', 'wtf/unicode/glib'],
- ['exclude', 'wtf/unicode/qt4'],
+ ['exclude', 'API/tests/'],
+ ['exclude', 'ForwardingHeaders/'],
+ ['exclude', '(?<!unicode)/icu/'],
+ ['exclude', 'os-win32/'],
+ ['exclude', 'qt/'],
+ ['exclude', 'wtf/(android|brew|efl|gtk|haiku|qt|wince|wx)/'],
+ ['exclude', 'wtf/unicode/brew/'],
+ ['exclude', 'wtf/unicode/glib/'],
+ ['exclude', 'wtf/unicode/qt4/'],
+ ['exclude', 'wtf/unicode/wince/'],
+ ['exclude', 'wtf/url/'],
['exclude', '/(gtk|glib|gobject)/.*\\.(cpp|h)$'],
['exclude', '(Default|Gtk|Chromium|None|Qt|Win|Wx|Symbian)\\.(cpp|mm|h)$'],
- ['exclude', 'GCActivityCallback\.cpp'],
- ['exclude', '.*BSTR.*$'],
- ['exclude', 'jsc.cpp$'],
+ ['exclude', 'GCActivityCallback\.cpp$'],
+ ['exclude', 'BSTR[^/]*$'],
],
'postbuilds': [
{
'postbuild_name': 'Check For Global Initializers',
'action': [
- 'sh', '<(DEPTH)/gyp/run-if-exists.sh', '<(DEPTH)/../Tools/Scripts/check-for-global-initializers'
+ 'sh', '<(project_dir)/gyp/run-if-exists.sh', '<(DEPTH)/../Tools/Scripts/check-for-global-initializers'
],
},
{
'postbuild_name': 'Check For Exit Time Destructors',
'action': [
- 'sh', '<(DEPTH)/gyp/run-if-exists.sh', '<(DEPTH)/../Tools/Scripts/check-for-exit-time-destructors'
+ 'sh', '<(project_dir)/gyp/run-if-exists.sh', '<(DEPTH)/../Tools/Scripts/check-for-exit-time-destructors'
],
},
{
'postbuild_name': 'Check For Weak VTables and Externals',
'action': [
- 'sh', '<(DEPTH)/gyp/run-if-exists.sh', '<(DEPTH)/../Tools/Scripts/check-for-weak-vtables-and-externals'
+ 'sh', '<(project_dir)/gyp/run-if-exists.sh', '<(DEPTH)/../Tools/Scripts/check-for-weak-vtables-and-externals'
],
},
],
@@ -103,29 +117,8 @@
'xcode_settings': {
# FIXME: Remove these overrides once JavaScriptCore.xcconfig is
# used only by this project.
- 'GCC_PREFIX_HEADER': '<(DEPTH)/JavaScriptCore/JavaScriptCorePrefix.h',
- 'INFOPLIST_FILE': '<(DEPTH)/JavaScriptCore/Info.plist',
- # This setting mirrors the setting in Base.xcconfig, with
- # one difference noted below.
- 'WARNING_CFLAGS_BASE': [
- '-Wall',
- '-Wextra',
- '-Wcast-qual',
- '-Wchar-subscripts',
- '-Wextra-tokens',
- '-Wformat=2',
- '-Winit-self',
- # FIXME: For some reason, -Wmissing-format-attribute causes a
- # build error in Assertions.cpp in the GYP build but not in the
- # non-GYP build.
- # '-Wmissing-format-attribute',
- '-Wmissing-noreturn',
- '-Wpacked',
- '-Wpointer-arith',
- '-Wredundant-decls',
- '-Wundef',
- '-Wwrite-strings',
- ],
+ 'GCC_PREFIX_HEADER': '<(project_dir)/JavaScriptCorePrefix.h',
+ 'INFOPLIST_FILE': '<(project_dir)/Info.plist',
},
}],
],
@@ -133,14 +126,26 @@
{
'target_name': 'Derived Sources',
'type': 'none',
- 'actions': [{
- 'action_name': 'Generate Derived Sources',
- 'inputs': [],
- 'outputs': [],
- 'action': [
- 'sh', 'generate-derived-sources.sh',
- ],
- }],
+ 'actions': [
+ {
+ 'action_name': 'Generate Derived Sources',
+ 'inputs': [],
+ 'outputs': [
+ '<@(javascriptcore_derived_source_files)',
+ ],
+ 'action': [
+ 'sh', 'generate-derived-sources.sh'
+ ],
+ },
+ {
+ 'action_name': 'Generate DTrace Header',
+ 'inputs': [],
+ 'outputs': [],
+ 'action': [
+ 'sh', '<(project_dir)/gyp/generate-dtrace-header.sh', '<(project_dir)'
+ ]
+ }
+ ],
},
{
'target_name': 'Update Version',
@@ -150,7 +155,7 @@
'inputs': [],
'outputs': [],
'action': [
- 'sh', '<(DEPTH)/gyp/update-info-plist.sh', '<(DEPTH)/JavaScriptCore/Info.plist'
+ 'sh', '<(project_dir)/gyp/update-info-plist.sh', '<(project_dir)/Info.plist'
]
}],
},
@@ -206,10 +211,17 @@
'include_dirs': [
'<@(javascriptcore_include_dirs)',
],
+ 'configurations': {
+ 'Production': {
+ 'xcode_settings': {
+ 'INSTALL_PATH': '$(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/Resources',
+ },
+ },
+ },
'sources': [
'<@(jsc_files)',
'$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
- 'libedit.dylib',
+ '/usr/lib/libedit.dylib',
],
},
], # targets
diff --git a/Source/JavaScriptCore/gyp/generate-dtrace-header.sh b/Source/JavaScriptCore/gyp/generate-dtrace-header.sh
new file mode 100755
index 0000000..a3c31dd
--- /dev/null
+++ b/Source/JavaScriptCore/gyp/generate-dtrace-header.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+TRACING_D="$1/runtime/Tracing.d";
+TRACING_H="$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h";
+
+if [[ "${HAVE_DTRACE}" = "1" && "${TRACING_D}" -nt "${TRACING_H}" ]]; then
+ dtrace -h -o "${TRACING_H}" -s "${TRACING_D}";
+fi;
+
diff --git a/Source/JavaScriptCore/gyp/run-if-exists.sh b/Source/JavaScriptCore/gyp/run-if-exists.sh
new file mode 100755
index 0000000..242ffc8
--- /dev/null
+++ b/Source/JavaScriptCore/gyp/run-if-exists.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if [ -f $1 ]; then
+ $1 || exit $?;
+fi
diff --git a/Source/JavaScriptCore/gyp/update-info-plist.sh b/Source/JavaScriptCore/gyp/update-info-plist.sh
new file mode 100755
index 0000000..d02ecce
--- /dev/null
+++ b/Source/JavaScriptCore/gyp/update-info-plist.sh
@@ -0,0 +1,4 @@
+# Touch Info.plist to let Xcode know it needs to copy it into the built product
+if [[ "${CONFIGURATION}" != "Production" ]]; then
+ touch "$1";
+fi
diff --git a/Source/JavaScriptCore/interpreter/CachedCall.h b/Source/JavaScriptCore/interpreter/CachedCall.h
index 05e9056..04f2210 100644
--- a/Source/JavaScriptCore/interpreter/CachedCall.h
+++ b/Source/JavaScriptCore/interpreter/CachedCall.h
@@ -38,7 +38,7 @@ namespace JSC {
CachedCall(CallFrame* callFrame, JSFunction* function, int argCount)
: m_valid(false)
, m_interpreter(callFrame->interpreter())
- , m_globalObjectScope(callFrame, function->scope()->globalObject.get())
+ , m_globalObjectScope(callFrame->globalData(), function->scope()->globalObject.get())
{
ASSERT(!function->isHostFunction());
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argCount, function->scope());
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index e73e13a..28832e0 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -65,7 +65,7 @@ namespace JSC {
// But they're used in many places in legacy code, so they're not going away any time soon.
void clearException() { globalData().exception = JSValue(); }
- JSValue exception() const { return globalData().exception.get(); }
+ JSValue exception() const { return globalData().exception; }
bool hadException() const { return globalData().exception; }
const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index b9a9c40..6021279 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -106,7 +106,7 @@ NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, J
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- exceptionValue = callFrame->globalData().exception.get();
+ exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
callFrame->uncheckedR(dst) = JSValue(result);
@@ -145,7 +145,7 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- exceptionValue = callFrame->globalData().exception.get();
+ exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
ASSERT(result);
@@ -186,7 +186,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
return true;
}
- exceptionValue = callFrame->globalData().exception.get();
+ exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
callFrame->uncheckedR(dst) = JSValue(result);
@@ -226,7 +226,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- exceptionValue = callFrame->globalData().exception.get();
+ exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
ASSERT(result);
@@ -265,7 +265,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
return true;
}
- exceptionValue = callFrame->globalData().exception.get();
+ exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
ASSERT(result);
@@ -313,7 +313,7 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst
PropertySlot slot(base);
if (base->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- exceptionValue = callFrame->globalData().exception.get();
+ exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
callFrame->uncheckedR(propDst) = JSValue(result);
@@ -409,13 +409,13 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
ScopeChainNode* scopeChain = callFrame->scopeChain();
JSValue exceptionValue;
- RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
+ EvalExecutable* eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->ownerExecutable(), codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
ASSERT(!eval == exceptionValue);
if (UNLIKELY(!eval))
return throwError(callFrame, exceptionValue);
- return callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->uncheckedR(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain);
+ return callFrame->globalData().interpreter->execute(eval, callFrame, callFrame->uncheckedR(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain);
}
Interpreter::Interpreter(JSGlobalData& globalData)
@@ -738,6 +738,8 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
return checkedReturn(throwStackOverflowError(callFrame));
+ DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
+
JSObject* error = program->compile(callFrame, scopeChain);
if (error)
return checkedReturn(throwError(callFrame, error));
@@ -757,8 +759,6 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->m_numParameters, 0);
newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj);
- DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject.get());
-
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
(*profiler)->willExecute(callFrame, program->sourceURL(), program->lineNo());
@@ -813,6 +813,8 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
+ DynamicGlobalObjectScope globalObjectScope(*callDataScopeChain->globalData, callDataScopeChain->globalObject.get());
+
JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
if (UNLIKELY(!!compileError)) {
m_registerFile.shrink(oldEnd);
@@ -828,8 +830,6 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, callDataScopeChain->globalObject.get());
-
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
(*profiler)->willExecute(callFrame, function);
@@ -860,7 +860,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset);
newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject.get());
+ DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -902,6 +902,8 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (constructType == ConstructTypeJS) {
ScopeChainNode* constructDataScopeChain = constructData.js.scopeChain;
+ DynamicGlobalObjectScope globalObjectScope(*constructDataScopeChain->globalData, constructDataScopeChain->globalObject.get());
+
JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain);
if (UNLIKELY(!!compileError)) {
m_registerFile.shrink(oldEnd);
@@ -917,8 +919,6 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, constructDataScopeChain->globalObject.get());
-
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
(*profiler)->willExecute(callFrame, constructor);
@@ -952,7 +952,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset);
newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject.get());
+ DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -1066,11 +1066,11 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
{
ASSERT(!scopeChain->globalData->exception);
+ DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
+
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
return checkedReturn(throwStackOverflowError(callFrame));
- DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject.get());
-
JSObject* compileError = eval->compile(callFrame, scopeChain);
if (UNLIKELY(!!compileError))
return checkedReturn(throwError(callFrame, compileError));
@@ -1467,8 +1467,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#define CHECK_FOR_EXCEPTION() \
do { \
- if (UNLIKELY(globalData->exception.get() != JSValue())) { \
- exceptionValue = globalData->exception.get(); \
+ if (UNLIKELY(globalData->exception != JSValue())) { \
+ exceptionValue = globalData->exception; \
goto vm_throw; \
} \
} while (0)
@@ -1549,8 +1549,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
register dst.
*/
int dst = vPC[1].u.operand;
- int regExp = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = JSValue(new (globalData) RegExpObject(callFrame->lexicalGlobalObject(), callFrame->scopeChain()->globalObject->regExpStructure(), codeBlock->regexp(regExp)));
+ RegExp* regExp = codeBlock->regexp(vPC[2].u.operand);
+ if (!regExp->isValid()) {
+ exceptionValue = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
+ goto vm_throw;
+ }
+ callFrame->uncheckedR(dst) = JSValue(new (globalData) RegExpObject(callFrame->lexicalGlobalObject(), callFrame->scopeChain()->globalObject->regExpStructure(), regExp));
vPC += OPCODE_LENGTH(op_new_regexp);
NEXT_INSTRUCTION();
@@ -3533,10 +3537,9 @@ skip_id_custom_self:
to ptr, using pointer equality.
*/
int src = vPC[1].u.operand;
- JSValue ptr = JSValue(vPC[2].u.jsCell);
int target = vPC[3].u.operand;
JSValue srcValue = callFrame->r(src).jsValue();
- if (srcValue != ptr) {
+ if (srcValue != vPC[2].u.jsCell.get()) {
vPC += target;
NEXT_INSTRUCTION();
}
@@ -3831,7 +3834,7 @@ skip_id_custom_self:
if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset);
- if ((exceptionValue = globalData->exception.get()))
+ if ((exceptionValue = globalData->exception))
goto vm_throw;
functionReturnValue = result;
@@ -4261,7 +4264,7 @@ skip_id_custom_self:
Structure* structure;
JSValue proto = callFrame->r(protoRegister).jsValue();
if (proto.isObject())
- structure = asObject(proto)->inheritorID();
+ structure = asObject(proto)->inheritorID(callFrame->globalData());
else
structure = constructor->scope()->globalObject->emptyObjectStructure();
callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure);
diff --git a/Source/JavaScriptCore/interpreter/Register.h b/Source/JavaScriptCore/interpreter/Register.h
index 3944642..fb02c12 100644
--- a/Source/JavaScriptCore/interpreter/Register.h
+++ b/Source/JavaScriptCore/interpreter/Register.h
@@ -54,11 +54,10 @@ namespace JSC {
Register(const JSValue&);
Register& operator=(const JSValue&);
JSValue jsValue() const;
+ EncodedJSValue encodedJSValue() const;
- Register& operator=(JSActivation*);
Register& operator=(CallFrame*);
Register& operator=(CodeBlock*);
- Register& operator=(JSPropertyNameIterator*);
Register& operator=(ScopeChainNode*);
Register& operator=(Instruction*);
@@ -73,29 +72,17 @@ namespace JSC {
static Register withInt(int32_t i)
{
- Register r;
- r.u.i = i;
+ Register r = jsNumber(i);
return r;
}
- static Register withCallee(JSObject* callee)
- {
- Register r;
- r.u.function = callee;
- return r;
- }
+ static inline Register withCallee(JSObject* callee);
private:
union {
- int32_t i;
EncodedJSValue value;
-
- JSActivation* activation;
CallFrame* callFrame;
CodeBlock* codeBlock;
- JSObject* function;
- JSPropertyNameIterator* propertyNameIterator;
- ScopeChainNode* scopeChain;
Instruction* vPC;
} u;
};
@@ -129,14 +116,13 @@ namespace JSC {
return JSValue::decode(u.value);
}
- // Interpreter functions
-
- ALWAYS_INLINE Register& Register::operator=(JSActivation* activation)
+ ALWAYS_INLINE EncodedJSValue Register::encodedJSValue() const
{
- u.activation = activation;
- return *this;
+ return u.value;
}
+ // Interpreter functions
+
ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame)
{
u.callFrame = callFrame;
@@ -155,28 +141,11 @@ namespace JSC {
return *this;
}
- ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
- {
- u.scopeChain = scopeChain;
- return *this;
- }
-
- ALWAYS_INLINE Register& Register::operator=(JSPropertyNameIterator* propertyNameIterator)
- {
- u.propertyNameIterator = propertyNameIterator;
- return *this;
- }
-
ALWAYS_INLINE int32_t Register::i() const
{
- return u.i;
+ return jsValue().asInt32();
}
-
- ALWAYS_INLINE JSActivation* Register::activation() const
- {
- return u.activation;
- }
-
+
ALWAYS_INLINE CallFrame* Register::callFrame() const
{
return u.callFrame;
@@ -186,22 +155,7 @@ namespace JSC {
{
return u.codeBlock;
}
-
- ALWAYS_INLINE JSObject* Register::function() const
- {
- return u.function;
- }
-
- ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
- {
- return u.propertyNameIterator;
- }
-
- ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
- {
- return u.scopeChain;
- }
-
+
ALWAYS_INLINE Instruction* Register::vPC() const
{
return u.vPC;
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.cpp b/Source/JavaScriptCore/interpreter/RegisterFile.cpp
index 47f0c18..b3a87e5 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.cpp
+++ b/Source/JavaScriptCore/interpreter/RegisterFile.cpp
@@ -29,6 +29,7 @@
#include "config.h"
#include "RegisterFile.h"
+#include "ConservativeSet.h"
#include "Interpreter.h"
#include "JSGlobalData.h"
#include "JSGlobalObject.h"
@@ -51,6 +52,16 @@ RegisterFile::~RegisterFile()
m_reservation.deallocate();
}
+void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
+{
+ for (Register* it = start(); it != end(); ++it) {
+ JSValue v = it->jsValue();
+ if (!v.isCell())
+ continue;
+ conservativeRoots.add(v.asCell());
+ }
+}
+
void RegisterFile::releaseExcessCapacity()
{
m_reservation.decommit(m_start, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(m_start));
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.h b/Source/JavaScriptCore/interpreter/RegisterFile.h
index bb42902..4d04085 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.h
+++ b/Source/JavaScriptCore/interpreter/RegisterFile.h
@@ -91,7 +91,6 @@ namespace JSC {
class RegisterFile {
WTF_MAKE_NONCOPYABLE(RegisterFile);
- friend class JIT;
public:
enum CallFrameHeaderEntry {
CallFrameHeaderSize = 6,
@@ -114,6 +113,8 @@ namespace JSC {
RegisterFile(JSGlobalData&, size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
~RegisterFile();
+
+ void gatherConservativeRoots(ConservativeRoots&);
Register* start() const { return m_start; }
Register* end() const { return m_end; }
@@ -136,6 +137,11 @@ namespace JSC {
static Finalizer* globalObjectCollectedNotifier();
+ Register* const * addressOfEnd() const
+ {
+ return &m_end;
+ }
+
private:
void releaseExcessCapacity();
void addToCommittedByteCount(long);
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 29e3778..063ae8c 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -92,7 +92,7 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock, void* linkerOffset)
#if USE(JSVALUE32_64)
void JIT::emitTimeoutCheck()
{
- Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);
+ Jump skipTimeout = branchSub32(NonZero, TrustedImm32(1), timeoutCheckRegister);
JITStubCall stubCall(this, cti_timeout_check);
stubCall.addArgument(regT1, regT0); // save last result registers.
stubCall.call(timeoutCheckRegister);
@@ -102,7 +102,7 @@ void JIT::emitTimeoutCheck()
#else
void JIT::emitTimeoutCheck()
{
- Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);
+ Jump skipTimeout = branchSub32(NonZero, TrustedImm32(1), timeoutCheckRegister);
JITStubCall(this, cti_timeout_check).call(timeoutCheckRegister);
skipTimeout.link(this);
@@ -475,7 +475,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
- registerFileCheck = branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile().m_end), regT1);
+ registerFileCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1);
}
Label functionBody = label();
@@ -497,7 +497,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
arityCheck = label();
preserveReturnAddressAfterCall(regT2);
emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
- branch32(Equal, regT1, Imm32(m_codeBlock->m_numParameters)).linkTo(beginLabel, this);
+ branch32(Equal, regT1, TrustedImm32(m_codeBlock->m_numParameters)).linkTo(beginLabel, this);
restoreArgumentReference();
JITStubCall(this, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck).call(callFrameRegister);
@@ -567,7 +567,6 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
#if ENABLE(JIT_OPTIMIZE_CALL)
for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) {
CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
- info.ownerCodeBlock = m_codeBlock;
info.callReturnLocation = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation);
info.hotPathBegin = patchBuffer.locationOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
info.hotPathOther = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].hotPathOther);
@@ -588,18 +587,6 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
}
#if ENABLE(JIT_OPTIMIZE_CALL)
-void JIT::unlinkCallOrConstruct(CallLinkInfo* callLinkInfo)
-{
- // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
- // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
- // match). Reset the check so it no longer matches.
- RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock);
-#if USE(JSVALUE32_64)
- repatchBuffer.repatch(callLinkInfo->hotPathBegin, 0);
-#else
- repatchBuffer.repatch(callLinkInfo->hotPathBegin, JSValue::encode(JSValue()));
-#endif
-}
void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
{
@@ -609,10 +596,7 @@ void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* ca
// If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) {
ASSERT(!callLinkInfo->isLinked());
-
- if (calleeCodeBlock)
- calleeCodeBlock->addCaller(callLinkInfo);
-
+ callLinkInfo->callee.set(*globalData, callerCodeBlock->ownerExecutable(), callee);
repatchBuffer.repatch(callLinkInfo->hotPathBegin, callee);
repatchBuffer.relink(callLinkInfo->hotPathOther, code);
}
@@ -629,10 +613,7 @@ void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBloc
// If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) {
ASSERT(!callLinkInfo->isLinked());
-
- if (calleeCodeBlock)
- calleeCodeBlock->addCaller(callLinkInfo);
-
+ callLinkInfo->callee.set(*globalData, callerCodeBlock->ownerExecutable(), callee);
repatchBuffer.repatch(callLinkInfo->hotPathBegin, callee);
repatchBuffer.relink(callLinkInfo->hotPathOther, code);
}
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index f98158c..61bd2ab 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -245,7 +245,6 @@ namespace JSC {
static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
- static void unlinkCallOrConstruct(CallLinkInfo*);
private:
struct JSRInfo {
@@ -310,7 +309,7 @@ namespace JSC {
void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister);
void emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32 = false);
- void emitStoreInt32(unsigned index, Imm32 payload, bool indexIsInt32 = false);
+ void emitStoreInt32(unsigned index, TrustedImm32 payload, bool indexIsInt32 = false);
void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false);
void emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool = false);
void emitStoreDouble(unsigned index, FPRegisterID value);
@@ -854,6 +853,8 @@ namespace JSC {
void emitInitRegister(unsigned dst);
void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
+ void emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry);
+ void emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry);
void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry);
void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp
index cd05f51..edf2290 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp
@@ -167,7 +167,7 @@ void JIT::emit_op_urshift(Instruction* currentInstruction)
// a toUint conversion, which can result in a value we can represent
// as an immediate int.
if (shift < 0 || !(shift & 31))
- addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+ addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
return;
@@ -179,7 +179,7 @@ void JIT::emit_op_urshift(Instruction* currentInstruction)
emitFastArithImmToInt(regT0);
emitFastArithImmToInt(regT1);
urshift32(regT1, regT0);
- addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+ addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
}
@@ -202,7 +202,7 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
if (shift)
urshift32(Imm32(shift & 0x1f), regT0);
if (shift < 0 || !(shift & 31))
- failures.append(branch32(LessThan, regT0, Imm32(0)));
+ failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
@@ -224,7 +224,7 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
failures.append(emitJumpIfNotImmediateInteger(regT1)); // op2 is not an int
emitFastArithImmToInt(regT1);
urshift32(regT1, regT0);
- failures.append(branch32(LessThan, regT0, Imm32(0)));
+ failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
@@ -773,7 +773,7 @@ void JIT::emit_op_post_inc(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(1), regT1));
+ addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
@@ -800,7 +800,7 @@ void JIT::emit_op_post_dec(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchSub32(Zero, Imm32(1), regT1));
+ addSlowCase(branchSub32(Zero, TrustedImm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
@@ -825,7 +825,7 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+ addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0));
emitFastArithIntToImmNoCheck(regT0, regT0);
emitPutVirtualRegister(srcDst);
}
@@ -849,7 +849,7 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchSub32(Zero, Imm32(1), regT0));
+ addSlowCase(branchSub32(Zero, TrustedImm32(1), regT0));
emitFastArithIntToImmNoCheck(regT0, regT0);
emitPutVirtualRegister(srcDst);
}
@@ -888,7 +888,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
emitJumpSlowCaseIfNotImmediateInteger(regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT2);
- addSlowCase(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNumber(0)))));
+ addSlowCase(branchPtr(Equal, regT2, TrustedImmPtr(JSValue::encode(jsNumber(0)))));
m_assembler.cdq();
m_assembler.idivl_r(regT2);
emitFastArithReTagImmediate(regT1, regT0);
diff --git a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
index e0b31f0..6865489 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
@@ -54,17 +54,17 @@ void JIT::emit_op_negate(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
- Jump srcNotInt = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
- addSlowCase(branchTest32(Zero, regT0, Imm32(0x7fffffff)));
+ Jump srcNotInt = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
+ addSlowCase(branchTest32(Zero, regT0, TrustedImm32(0x7fffffff)));
neg32(regT0);
emitStoreInt32(dst, regT0, (dst == src));
Jump end = jump();
srcNotInt.link(this);
- addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
- xor32(Imm32(1 << 31), regT1);
+ xor32(TrustedImm32(1 << 31), regT1);
store32(regT1, tagFor(dst));
if (dst != src)
store32(regT0, payloadFor(dst));
@@ -96,7 +96,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
// Character less.
if (isOperandConstantImmediateChar(op1)) {
emitLoad(op2, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
JumpList failures;
emitLoadCharacterString(regT0, regT0, failures);
addSlowCase(failures);
@@ -105,7 +105,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
}
if (isOperandConstantImmediateChar(op2)) {
emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
JumpList failures;
emitLoadCharacterString(regT0, regT0, failures);
addSlowCase(failures);
@@ -115,16 +115,16 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
// Int32 less.
emitLoad(op2, regT3, regT2);
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
} else if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
} else {
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(GreaterThanOrEqual, regT0, regT2), target);
}
@@ -185,7 +185,7 @@ void JIT::emit_op_jless(Instruction* currentInstruction)
// Character less.
if (isOperandConstantImmediateChar(op1)) {
emitLoad(op2, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
JumpList failures;
emitLoadCharacterString(regT0, regT0, failures);
addSlowCase(failures);
@@ -194,7 +194,7 @@ void JIT::emit_op_jless(Instruction* currentInstruction)
}
if (isOperandConstantImmediateChar(op2)) {
emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
JumpList failures;
emitLoadCharacterString(regT0, regT0, failures);
addSlowCase(failures);
@@ -203,16 +203,16 @@ void JIT::emit_op_jless(Instruction* currentInstruction)
}
if (isOperandConstantImmediateInt(op1)) {
emitLoad(op2, regT3, regT2);
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
} else if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
} else {
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(LessThan, regT0, regT2), target);
}
@@ -272,7 +272,7 @@ void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
// Character less.
if (isOperandConstantImmediateChar(op1)) {
emitLoad(op2, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
JumpList failures;
emitLoadCharacterString(regT0, regT0, failures);
addSlowCase(failures);
@@ -281,7 +281,7 @@ void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
}
if (isOperandConstantImmediateChar(op2)) {
emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
JumpList failures;
emitLoadCharacterString(regT0, regT0, failures);
addSlowCase(failures);
@@ -290,16 +290,16 @@ void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
}
if (isOperandConstantImmediateInt(op1)) {
emitLoad(op2, regT3, regT2);
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
} else if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
} else {
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT2), target);
}
@@ -368,7 +368,7 @@ void JIT::emit_op_lshift(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
lshift32(Imm32(getConstantOperand(op2).asInt32()), regT0);
emitStoreInt32(dst, regT0, dst == op1);
return;
@@ -376,8 +376,8 @@ void JIT::emit_op_lshift(Instruction* currentInstruction)
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
if (!isOperandConstantImmediateInt(op1))
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
lshift32(regT2, regT0);
emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
}
@@ -410,7 +410,7 @@ void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned)
// shift arguments, so any changes must be updated there as well.
if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
int shift = getConstantOperand(op2).asInt32();
if (isUnsigned) {
if (shift)
@@ -419,7 +419,7 @@ void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned)
// a toUint conversion, which can result in a value we can represent
// as an immediate int.
if (shift < 0 || !(shift & 31))
- addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+ addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
} else if (shift) { // signed right shift by zero is simply toInt conversion
rshift32(Imm32(shift & 0x1f), regT0);
}
@@ -429,11 +429,11 @@ void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned)
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
if (!isOperandConstantImmediateInt(op1))
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
if (isUnsigned) {
urshift32(regT2, regT0);
- addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+ addSlowCase(branch32(LessThan, regT0, TrustedImm32(0)));
} else
rshift32(regT2, regT0);
emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
@@ -450,14 +450,14 @@ void JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCas
linkSlowCase(iter); // int32 check
if (supportsFloatingPointTruncate()) {
JumpList failures;
- failures.append(branch32(AboveOrEqual, regT1, Imm32(JSValue::LowestTag)));
+ failures.append(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
emitLoadDouble(op1, fpRegT0);
failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
if (isUnsigned) {
if (shift)
urshift32(Imm32(shift & 0x1f), regT0);
if (shift < 0 || !(shift & 31))
- failures.append(branch32(LessThan, regT0, Imm32(0)));
+ failures.append(branch32(LessThan, regT0, TrustedImm32(0)));
} else if (shift)
rshift32(Imm32(shift & 0x1f), regT0);
emitStoreInt32(dst, regT0, false);
@@ -472,9 +472,9 @@ void JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCas
if (!isOperandConstantImmediateInt(op1)) {
linkSlowCase(iter); // int32 check -- op1 is not an int
if (supportsFloatingPointTruncate()) {
- Jump notDouble = branch32(Above, regT1, Imm32(JSValue::LowestTag)); // op1 is not a double
+ Jump notDouble = branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)); // op1 is not a double
emitLoadDouble(op1, fpRegT0);
- Jump notInt = branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)); // op2 is not an int
+ Jump notInt = branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)); // op2 is not an int
Jump cantTruncate = branchTruncateDoubleToInt32(fpRegT0, regT0);
if (isUnsigned)
urshift32(regT2, regT0);
@@ -535,15 +535,15 @@ void JIT::emit_op_bitand(Instruction* currentInstruction)
int32_t constant;
if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
emitLoad(op, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
and32(Imm32(constant), regT0);
emitStoreInt32(dst, regT0, (op == dst));
return;
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
and32(regT2, regT0);
emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
}
@@ -576,15 +576,15 @@ void JIT::emit_op_bitor(Instruction* currentInstruction)
int32_t constant;
if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
emitLoad(op, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
or32(Imm32(constant), regT0);
emitStoreInt32(dst, regT0, (op == dst));
return;
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
or32(regT2, regT0);
emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
}
@@ -617,15 +617,15 @@ void JIT::emit_op_bitxor(Instruction* currentInstruction)
int32_t constant;
if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
emitLoad(op, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
xor32(Imm32(constant), regT0);
emitStoreInt32(dst, regT0, (op == dst));
return;
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
xor32(regT2, regT0);
emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
}
@@ -654,7 +654,7 @@ void JIT::emit_op_bitnot(Instruction* currentInstruction)
unsigned src = currentInstruction[2].u.operand;
emitLoad(src, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
not32(regT0);
emitStoreInt32(dst, regT0, (dst == src));
@@ -679,14 +679,14 @@ void JIT::emit_op_post_inc(Instruction* currentInstruction)
unsigned srcDst = currentInstruction[2].u.operand;
emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
if (dst == srcDst) // x = x++ is a noop for ints.
return;
emitStoreInt32(dst, regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+ addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0));
emitStoreInt32(srcDst, regT0, true);
}
@@ -713,14 +713,14 @@ void JIT::emit_op_post_dec(Instruction* currentInstruction)
unsigned srcDst = currentInstruction[2].u.operand;
emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
if (dst == srcDst) // x = x-- is a noop for ints.
return;
emitStoreInt32(dst, regT0);
- addSlowCase(branchSub32(Overflow, Imm32(1), regT0));
+ addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT0));
emitStoreInt32(srcDst, regT0, true);
}
@@ -735,7 +735,7 @@ void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseE
JITStubCall stubCall(this, cti_op_post_dec);
stubCall.addArgument(srcDst);
- stubCall.addArgument(Imm32(srcDst));
+ stubCall.addArgument(TrustedImm32(srcDst));
stubCall.call(dst);
}
@@ -747,8 +747,8 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction)
emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0));
emitStoreInt32(srcDst, regT0, true);
}
@@ -772,8 +772,8 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction)
emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branchSub32(Overflow, Imm32(1), regT0));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT0));
emitStoreInt32(srcDst, regT0, true);
}
@@ -817,8 +817,8 @@ void JIT::emit_op_add(Instruction* currentInstruction)
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
// Int32 case.
addSlowCase(branchAdd32(Overflow, regT2, regT0));
@@ -840,7 +840,7 @@ void JIT::emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultT
{
// Int32 case.
emitLoad(op, regT1, regT0);
- Jump notInt32 = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+ Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
addSlowCase(branchAdd32(Overflow, Imm32(constant), regT0));
emitStoreInt32(dst, regT0, (op == dst));
@@ -853,7 +853,7 @@ void JIT::emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultT
notInt32.link(this);
if (!opType.definitelyIsNumber())
- addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
move(Imm32(constant), regT2);
convertInt32ToDouble(regT2, fpRegT0);
emitLoadDouble(op, fpRegT1);
@@ -926,8 +926,8 @@ void JIT::emit_op_sub(Instruction* currentInstruction)
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
// Int32 case.
addSlowCase(branchSub32(Overflow, regT2, regT0));
@@ -949,7 +949,7 @@ void JIT::emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultT
{
// Int32 case.
emitLoad(op, regT1, regT0);
- Jump notInt32 = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+ Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
addSlowCase(branchSub32(Overflow, Imm32(constant), regT0));
emitStoreInt32(dst, regT0, (op == dst));
@@ -962,7 +962,7 @@ void JIT::emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultT
notInt32.link(this);
if (!opType.definitelyIsNumber())
- addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
move(Imm32(constant), regT2);
convertInt32ToDouble(regT2, fpRegT0);
emitLoadDouble(op, fpRegT1);
@@ -1019,15 +1019,15 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
// Verify Op1 is double.
if (!types.first().definitelyIsNumber())
- addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
if (!op2IsInRegisters)
emitLoad(op2, regT3, regT2);
- Jump doubleOp2 = branch32(Below, regT3, Imm32(JSValue::LowestTag));
+ Jump doubleOp2 = branch32(Below, regT3, TrustedImm32(JSValue::LowestTag));
if (!types.second().definitelyIsNumber())
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
convertInt32ToDouble(regT2, fpRegT0);
Jump doTheMath = jump();
@@ -1096,7 +1096,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
// Verify op2 is double.
if (!types.second().definitelyIsNumber())
- addSlowCase(branch32(Above, regT3, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT3, TrustedImm32(JSValue::LowestTag)));
// Do the math.
switch (opcodeID) {
@@ -1157,8 +1157,8 @@ void JIT::emit_op_mul(Instruction* currentInstruction)
JumpList notInt32Op2;
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
// Int32 case.
move(regT0, regT3);
@@ -1189,7 +1189,7 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>
linkSlowCase(iter); // zero result check
Jump negZero = branchOr32(Signed, regT2, regT3);
- emitStoreInt32(dst, Imm32(0), (op1 == dst || op2 == dst));
+ emitStoreInt32(dst, TrustedImm32(0), (op1 == dst || op2 == dst));
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_mul));
@@ -1240,8 +1240,8 @@ void JIT::emit_op_div(Instruction* currentInstruction)
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
convertInt32ToDouble(regT0, fpRegT0);
convertInt32ToDouble(regT2, fpRegT1);
@@ -1312,16 +1312,16 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) {
emitLoad(op1, regT1, regT0);
move(Imm32(getConstantOperand(op2).asInt32()), regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
if (getConstantOperand(op2).asInt32() == -1)
- addSlowCase(branch32(Equal, regT0, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
+ addSlowCase(branch32(Equal, regT0, TrustedImm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
} else {
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
- addSlowCase(branch32(Equal, regT0, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
- addSlowCase(branch32(Equal, regT2, Imm32(0))); // divide by 0
+ addSlowCase(branch32(Equal, regT0, TrustedImm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
+ addSlowCase(branch32(Equal, regT2, TrustedImm32(0))); // divide by 0
}
move(regT0, regT3); // Save dividend payload, in case of 0.
@@ -1335,7 +1335,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
// If the remainder is zero and the dividend is negative, the result is -0.
Jump storeResult1 = branchTest32(NonZero, regT1);
- Jump storeResult2 = branchTest32(Zero, regT3, Imm32(0x80000000)); // not negative
+ Jump storeResult2 = branchTest32(Zero, regT3, TrustedImm32(0x80000000)); // not negative
emitStore(dst, jsNumber(-0.0));
Jump end = jump();
@@ -1378,10 +1378,10 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
#if ENABLE(JIT_USE_SOFT_MODULO)
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
- addSlowCase(branch32(Equal, regT2, Imm32(0)));
+ addSlowCase(branch32(Equal, regT2, TrustedImm32(0)));
emitNakedCall(m_globalData->jitStubs->ctiSoftModulo());
diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp
index 524e576..77c2a69 100644
--- a/Source/JavaScriptCore/jit/JITCall.cpp
+++ b/Source/JavaScriptCore/jit/JITCall.cpp
@@ -48,10 +48,11 @@ namespace JSC {
void JIT::compileOpCallInitializeCallFrame()
{
- store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // newScopeChain
- storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
- storePtr(regT3, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
+ // regT0 holds callee, regT1 holds argCount
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // scopeChain
+ emitPutIntToCallFrameHeader(regT1, RegisterFile::ArgumentCount);
+ emitPutCellToCallFrameHeader(regT0, RegisterFile::Callee);
+ emitPutCellToCallFrameHeader(regT3, RegisterFile::ScopeChain);
}
void JIT::emit_op_call_put_result(Instruction* instruction)
@@ -67,15 +68,16 @@ void JIT::compileOpCallVarargs(Instruction* instruction)
int registerOffset = instruction[3].u.operand;
emitGetVirtualRegister(argCountRegister, regT1);
+ emitFastArithImmToInt(regT1);
emitGetVirtualRegister(callee, regT0);
addPtr(Imm32(registerOffset), regT1, regT2);
// Check for JSFunctions.
emitJumpSlowCaseIfNotJSCell(regT0);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr)));
// Speculatively roll the callframe, assuming argCount will match the arity.
- mul32(Imm32(sizeof(Register)), regT2, regT2);
+ mul32(TrustedImm32(sizeof(Register)), regT2, regT2);
intptr_t offset = (intptr_t)sizeof(Register) * (intptr_t)RegisterFile::CallerFrame;
addPtr(Imm32((int32_t)offset), regT2, regT3);
addPtr(callFrameRegister, regT3);
@@ -118,14 +120,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
- wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue())));
+ wasEval = branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue())));
}
emitGetVirtualRegister(callee, regT0);
// Check for JSFunctions.
emitJumpSlowCaseIfNotJSCell(regT0);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr)));
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
@@ -175,7 +177,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
- wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue())));
+ wasEval = branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue())));
}
// This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
@@ -185,7 +187,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
BEGIN_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
- Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue())));
+ Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, TrustedImmPtr(JSValue::encode(JSValue())));
END_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
@@ -199,8 +201,9 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
// Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT1); // newScopeChain
-
- store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
+
+ store32(TrustedImm32(Int32Tag), intTagFor(registerOffset + RegisterFile::ArgumentCount));
+ store32(Imm32(argCount), intPayloadFor(registerOffset + RegisterFile::ArgumentCount));
storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
storePtr(regT0, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
@@ -224,7 +227,7 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
// Fast check for JS function.
Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT0);
- Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr));
+ Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr));
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp
index ac231a9..9ffa495 100644
--- a/Source/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp
@@ -49,10 +49,10 @@ namespace JSC {
void JIT::compileOpCallInitializeCallFrame()
{
// regT0 holds callee, regT1 holds argCount
- store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // scopeChain
- storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); // callee
- storePtr(regT3, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); // scopeChain
+ emitPutIntToCallFrameHeader(regT1, RegisterFile::ArgumentCount);
+ emitPutCellToCallFrameHeader(regT0, RegisterFile::Callee);
+ emitPutCellToCallFrameHeader(regT3, RegisterFile::ScopeChain);
}
void JIT::emit_op_call_put_result(Instruction* instruction)
@@ -72,12 +72,13 @@ void JIT::compileOpCallVarargs(Instruction* instruction)
addPtr(Imm32(registerOffset), regT2, regT3); // registerOffset
emitJumpSlowCaseIfNotJSCell(callee, regT1);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr)));
// Speculatively roll the callframe, assuming argCount will match the arity.
- mul32(Imm32(sizeof(Register)), regT3, regT3);
+ mul32(TrustedImm32(sizeof(Register)), regT3, regT3);
addPtr(callFrameRegister, regT3);
- storePtr(callFrameRegister, Address(regT3, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register))));
+ store32(TrustedImm32(JSValue::CellTag), tagFor(RegisterFile::CallerFrame, regT3));
+ storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame, regT3));
move(regT3, callFrameRegister);
move(regT2, regT1); // argCount
@@ -121,9 +122,9 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
unsigned thisReg = currentInstruction[2].u.operand;
emitLoad(result, regT1, regT0);
- Jump notJSCell = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- Jump notObject = branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType));
+ Jump notJSCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ Jump notObject = branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
@@ -199,18 +200,19 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
- wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
+ wasEval = branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag));
}
emitLoad(callee, regT1, regT0);
emitJumpSlowCaseIfNotJSCell(callee, regT1);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr)));
// Speculatively roll the callframe, assuming argCount will match the arity.
- storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+ store32(TrustedImm32(JSValue::CellTag), tagFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
+ storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
- move(Imm32(argCount), regT1);
+ move(TrustedImm32(argCount), regT1);
emitNakedCall(opcodeID == op_construct ? m_globalData->jitStubs->ctiVirtualConstruct() : m_globalData->jitStubs->ctiVirtualCall());
@@ -255,7 +257,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
- wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
+ wasEval = branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag));
}
emitLoad(callee, regT1, regT0);
@@ -264,7 +266,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
BEGIN_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
- Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(0));
+ Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, TrustedImmPtr(0));
END_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
@@ -272,7 +274,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump);
m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
// The following is the fast case, only used whan a callee can be linked.
@@ -280,10 +282,12 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
// Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT2);
- store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
- storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
+ store32(TrustedImm32(JSValue::Int32Tag), tagFor(registerOffset + RegisterFile::ArgumentCount));
+ store32(Imm32(argCount), payloadFor(registerOffset + RegisterFile::ArgumentCount));
+ storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
emitStore(registerOffset + RegisterFile::Callee, regT1, regT0);
- storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
+ store32(TrustedImm32(JSValue::CellTag), tagFor(registerOffset + RegisterFile::ScopeChain));
+ store32(regT2, payloadFor(registerOffset + RegisterFile::ScopeChain));
addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister);
// Call to the callee
@@ -305,11 +309,12 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
linkSlowCase(iter);
// Fast check for JS function.
- Jump callLinkFailNotObject = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
- Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr));
+ Jump callLinkFailNotObject = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+ Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr));
// Speculatively roll the callframe, assuming argCount will match the arity.
- storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+ store32(TrustedImm32(JSValue::CellTag), tagFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
+ storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
move(Imm32(argCount), regT1);
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index 39ca4a5..16c2335 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -52,12 +52,26 @@ ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src)
ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
{
- storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
+ storePtr(from, payloadFor(entry, callFrameRegister));
+}
+
+ALWAYS_INLINE void JIT::emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
+{
+#if USE(JSVALUE32_64)
+ store32(TrustedImm32(JSValue::CellTag), tagFor(entry, callFrameRegister));
+#endif
+ storePtr(from, payloadFor(entry, callFrameRegister));
+}
+
+ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
+{
+ store32(TrustedImm32(Int32Tag), intTagFor(entry, callFrameRegister));
+ store32(from, intPayloadFor(entry, callFrameRegister));
}
ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
{
- storePtr(ImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
+ storePtr(TrustedImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
}
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
@@ -70,9 +84,9 @@ ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHea
ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
{
- failures.append(branchPtr(NotEqual, Address(src), ImmPtr(m_globalData->jsStringVPtr)));
+ failures.append(branchPtr(NotEqual, Address(src), TrustedImmPtr(m_globalData->jsStringVPtr)));
failures.append(branchTest32(NonZero, Address(src, OBJECT_OFFSETOF(JSString, m_fiberCount))));
- failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), Imm32(1)));
+ failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
loadPtr(MacroAssembler::Address(dst, ThunkHelpers::stringImplDataOffset()), dst);
load16(MacroAssembler::Address(dst, 0), dst);
@@ -200,7 +214,7 @@ ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
{
#if CPU(X86)
// Within a trampoline the return address will be on the stack at this point.
- addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister);
+ addPtr(TrustedImm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister);
#elif CPU(ARM)
move(stackPointerRegister, firstArgumentRegister);
#endif
@@ -209,7 +223,7 @@ ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
{
- return branchPtr(NotEqual, Address(reg, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(structure));
+ return branchPtr(NotEqual, Address(reg, JSCell::structureOffset()), TrustedImmPtr(structure));
}
ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg)
@@ -254,14 +268,14 @@ ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag)
{
ASSERT(flag >= 1);
ASSERT(flag <= 32);
- or32(Imm32(1u << (flag - 1)), AbsoluteAddress(&SamplingFlags::s_flags));
+ or32(TrustedImm32(1u << (flag - 1)), AbsoluteAddress(&SamplingFlags::s_flags));
}
ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag)
{
ASSERT(flag >= 1);
ASSERT(flag <= 32);
- and32(Imm32(~(1u << (flag - 1))), AbsoluteAddress(&SamplingFlags::s_flags));
+ and32(TrustedImm32(~(1u << (flag - 1))), AbsoluteAddress(&SamplingFlags::s_flags));
}
#endif
@@ -269,11 +283,11 @@ ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag)
ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count)
{
#if CPU(X86_64) // Or any other 64-bit plattform.
- addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter));
+ addPtr(TrustedImm32(count), AbsoluteAddress(counter.addressOfCounter()));
#elif CPU(X86) // Or any other little-endian 32-bit plattform.
- intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t);
- add32(Imm32(count), AbsoluteAddress(&counter.m_counter));
- addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
+ intptr_t hiWord = reinterpret_cast<intptr_t>(counter.addressOfCounter()) + sizeof(int32_t);
+ add32(TrustedImm32(count), AbsoluteAddress(counter.addressOfCounter()));
+ addWithCarry32(TrustedImm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
#else
#error "SAMPLING_FLAGS not implemented on this platform."
#endif
@@ -284,13 +298,13 @@ ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t cou
#if CPU(X86_64)
ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
{
- move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86Registers::ecx);
- storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86Registers::ecx);
+ move(TrustedImmPtr(m_interpreter->sampler()->sampleSlot()), X86Registers::ecx);
+ storePtr(TrustedImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86Registers::ecx);
}
#else
ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
{
- storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
+ storePtr(TrustedImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
}
#endif
#endif
@@ -299,13 +313,13 @@ ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostF
#if CPU(X86_64)
ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
{
- move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86Registers::ecx);
- storePtr(ImmPtr(codeBlock), X86Registers::ecx);
+ move(TrustedImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86Registers::ecx);
+ storePtr(TrustedImmPtr(codeBlock), X86Registers::ecx);
}
#else
ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
{
- storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
+ storePtr(TrustedImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
}
#endif
#endif
@@ -396,7 +410,7 @@ inline void JIT::emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1
inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
{
if (m_codeBlock->isConstantRegisterIndex(index)) {
- Register& inConstantPool = m_codeBlock->constantRegister(index);
+ WriteBarrier<Unknown>& inConstantPool = m_codeBlock->constantRegister(index);
loadDouble(&inConstantPool, value);
} else
loadDouble(addressFor(index), value);
@@ -405,7 +419,7 @@ inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value)
{
if (m_codeBlock->isConstantRegisterIndex(index)) {
- Register& inConstantPool = m_codeBlock->constantRegister(index);
+ WriteBarrier<Unknown>& inConstantPool = m_codeBlock->constantRegister(index);
char* bytePointer = reinterpret_cast<char*>(&inConstantPool);
convertInt32ToDouble(AbsoluteAddress(bytePointer + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), value);
} else
@@ -422,27 +436,27 @@ inline void JIT::emitStoreInt32(unsigned index, RegisterID payload, bool indexIs
{
store32(payload, payloadFor(index, callFrameRegister));
if (!indexIsInt32)
- store32(Imm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
+ store32(TrustedImm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
}
-inline void JIT::emitStoreInt32(unsigned index, Imm32 payload, bool indexIsInt32)
+inline void JIT::emitStoreInt32(unsigned index, TrustedImm32 payload, bool indexIsInt32)
{
store32(payload, payloadFor(index, callFrameRegister));
if (!indexIsInt32)
- store32(Imm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
+ store32(TrustedImm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
}
inline void JIT::emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell)
{
store32(payload, payloadFor(index, callFrameRegister));
if (!indexIsCell)
- store32(Imm32(JSValue::CellTag), tagFor(index, callFrameRegister));
+ store32(TrustedImm32(JSValue::CellTag), tagFor(index, callFrameRegister));
}
inline void JIT::emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool)
{
if (!indexIsBool)
- store32(Imm32(0), payloadFor(index, callFrameRegister));
+ store32(TrustedImm32(0), payloadFor(index, callFrameRegister));
store32(tag, tagFor(index, callFrameRegister));
}
@@ -550,7 +564,7 @@ inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, Regi
if (m_codeBlock->isConstantRegisterIndex(virtualRegisterIndex))
addSlowCase(jump());
else
- addSlowCase(branch32(NotEqual, tag, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, tag, TrustedImm32(JSValue::CellTag)));
}
}
@@ -652,7 +666,7 @@ ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from)
ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
{
- storePtr(ImmPtr(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
+ storePtr(TrustedImmPtr(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
}
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
@@ -660,7 +674,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
#if USE(JSVALUE64)
return branchTestPtr(Zero, reg, tagMaskRegister);
#else
- return branchTest32(Zero, reg, Imm32(JSImmediate::TagMask));
+ return branchTest32(Zero, reg, TrustedImm32(JSImmediate::TagMask));
#endif
}
@@ -681,7 +695,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg)
#if USE(JSVALUE64)
return branchTestPtr(NonZero, reg, tagMaskRegister);
#else
- return branchTest32(NonZero, reg, Imm32(JSImmediate::TagMask));
+ return branchTest32(NonZero, reg, TrustedImm32(JSImmediate::TagMask));
#endif
}
@@ -701,7 +715,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, int vReg)
inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
{
if (m_codeBlock->isConstantRegisterIndex(index)) {
- Register& inConstantPool = m_codeBlock->constantRegister(index);
+ WriteBarrier<Unknown>& inConstantPool = m_codeBlock->constantRegister(index);
loadDouble(&inConstantPool, value);
} else
loadDouble(addressFor(index), value);
@@ -710,8 +724,8 @@ inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value)
{
if (m_codeBlock->isConstantRegisterIndex(index)) {
- Register& inConstantPool = m_codeBlock->constantRegister(index);
- convertInt32ToDouble(AbsoluteAddress(&inConstantPool), value);
+ ASSERT(isOperandConstantImmediateInt(index));
+ convertInt32ToDouble(Imm32(getConstantOperand(index).asInt32()), value);
} else
convertInt32ToDouble(addressFor(index), value);
}
@@ -722,7 +736,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
#if USE(JSVALUE64)
return branchPtr(AboveOrEqual, reg, tagTypeNumberRegister);
#else
- return branchTest32(NonZero, reg, Imm32(JSImmediate::TagTypeNumber));
+ return branchTest32(NonZero, reg, TrustedImm32(JSImmediate::TagTypeNumber));
#endif
}
@@ -731,7 +745,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg)
#if USE(JSVALUE64)
return branchPtr(Below, reg, tagTypeNumberRegister);
#else
- return branchTest32(Zero, reg, Imm32(JSImmediate::TagTypeNumber));
+ return branchTest32(Zero, reg, TrustedImm32(JSImmediate::TagTypeNumber));
#endif
}
@@ -760,12 +774,12 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg)
#if USE(JSVALUE32_64)
ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
{
- subPtr(Imm32(JSImmediate::TagTypeNumber), reg);
+ subPtr(TrustedImm32(JSImmediate::TagTypeNumber), reg);
}
ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID reg)
{
- return branchSubPtr(Zero, Imm32(JSImmediate::TagTypeNumber), reg);
+ return branchSubPtr(Zero, TrustedImm32(JSImmediate::TagTypeNumber), reg);
}
#endif
@@ -776,7 +790,7 @@ ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID d
#else
if (src != dest)
move(src, dest);
- addPtr(Imm32(JSImmediate::TagTypeNumber), dest);
+ addPtr(TrustedImm32(JSImmediate::TagTypeNumber), dest);
#endif
}
@@ -796,8 +810,8 @@ ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID
ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
{
- lshift32(Imm32(JSImmediate::ExtendedPayloadShift), reg);
- or32(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg);
+ lshift32(TrustedImm32(JSImmediate::ExtendedPayloadShift), reg);
+ or32(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg);
}
#endif // USE(JSVALUE32_64)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index fc769db..daceea6 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -52,12 +52,12 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// Check eax is a string
Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
- Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+ Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
// Checks out okay! - get the length from the Ustring.
load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT0);
- Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
+ Jump string_failureCases3 = branch32(Above, regT0, TrustedImm32(JSImmediate::maxImmediateInt));
// regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
emitFastArithIntToImmNoCheck(regT0, regT0);
@@ -102,7 +102,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock3 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), Imm32(0));
+ Jump hasCodeBlock3 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), TrustedImm32(0));
preserveReturnAddressAfterCall(regT3);
restoreArgumentReference();
Call callCompileCall = call();
@@ -122,7 +122,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock4 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), Imm32(0));
+ Jump hasCodeBlock4 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), TrustedImm32(0));
preserveReturnAddressAfterCall(regT3);
restoreArgumentReference();
Call callCompileConstruct = call();
@@ -141,10 +141,10 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
restoreReturnAddressBeforeReturn(regT1);
- move(ImmPtr(&globalData->exceptionLocation), regT2);
+ move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
- poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
+ poke(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
ret();
// NativeCall Trampoline
@@ -199,7 +199,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
peek(regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
@@ -208,21 +208,21 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// Host function signature: f(ExecState*);
move(callFrameRegister, X86Registers::edi);
- subPtr(Imm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
+ subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::esi);
loadPtr(Address(X86Registers::esi, OBJECT_OFFSETOF(JSFunction, m_executable)), X86Registers::r9);
move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
call(Address(X86Registers::r9, executableOffsetToFunction));
- addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister);
+ addPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister);
#elif CPU(ARM)
// Load caller frame's scope chain into this callframe so that whatever we call can
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
@@ -243,7 +243,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
@@ -253,7 +253,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// Allocate stack space for 16 bytes (8-byte aligned)
// 16 bytes (unused) for 4 arguments
- subPtr(Imm32(16), stackPointerRegister);
+ subPtr(TrustedImm32(16), stackPointerRegister);
// Setup arg0
move(callFrameRegister, MIPSRegisters::a0);
@@ -265,7 +265,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
call(Address(regT2, executableOffsetToFunction));
// Restore stack space
- addPtr(Imm32(16), stackPointerRegister);
+ addPtr(TrustedImm32(16), stackPointerRegister);
restoreReturnAddressBeforeReturn(regT3);
@@ -289,12 +289,12 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// Grab the return address.
preserveReturnAddressAfterCall(regT1);
- move(ImmPtr(&globalData->exceptionLocation), regT2);
+ move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
// Set the return address.
- move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
+ move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
restoreReturnAddressBeforeReturn(regT1);
ret();
@@ -378,8 +378,8 @@ void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT0, baseVal);
// Check that baseVal 'ImplementsHasInstance'.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
+ addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsHasInstance)));
}
void JIT::emit_op_instanceof(Instruction* currentInstruction)
@@ -400,29 +400,29 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT1, proto);
// Check that prototype is an object
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT3);
- addSlowCase(branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ loadPtr(Address(regT1, JSCell::structureOffset()), regT3);
+ addSlowCase(branch8(NotEqual, Address(regT3, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType)));
// Fixme: this check is only needed because the JSC API allows HasInstance to be overridden; we should deprecate this.
// Check that baseVal 'ImplementsDefaultHasInstance'.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
+ addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
- move(ImmPtr(JSValue::encode(jsBoolean(true))), regT0);
+ move(TrustedImmPtr(JSValue::encode(jsBoolean(true))), regT0);
Label loop(this);
// Load the prototype of the object in regT2. If this is equal to regT1 - WIN!
// Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again.
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
+ loadPtr(Address(regT2, JSCell::structureOffset()), regT2);
+ loadPtr(Address(regT2, Structure::prototypeOffset()), regT2);
Jump isInstance = branchPtr(Equal, regT2, regT1);
emitJumpIfJSCell(regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0);
+ move(TrustedImmPtr(JSValue::encode(jsBoolean(false))), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
isInstance.link(this);
@@ -452,7 +452,7 @@ void JIT::emit_op_construct(Instruction* currentInstruction)
void JIT::emit_op_get_global_var(Instruction* currentInstruction)
{
JSVariableObject* globalObject = m_codeBlock->globalObject();
- loadPtr(&globalObject->d->registers, regT0);
+ loadPtr(&globalObject->m_registers, regT0);
loadPtr(Address(regT0, currentInstruction[2].u.operand * sizeof(Register)), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -461,7 +461,7 @@ void JIT::emit_op_put_global_var(Instruction* currentInstruction)
{
emitGetVirtualRegister(currentInstruction[2].u.operand, regT1);
JSVariableObject* globalObject = m_codeBlock->globalObject();
- loadPtr(&globalObject->d->registers, regT0);
+ loadPtr(&globalObject->m_registers, regT0);
storePtr(regT1, Address(regT0, currentInstruction[1].u.operand * sizeof(Register)));
}
@@ -483,8 +483,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT0);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSVariableObject, d)), regT0);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT0);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSVariableObject, m_registers)), regT0);
loadPtr(Address(regT0, currentInstruction[2].u.operand * sizeof(Register)), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -508,8 +507,7 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSVariableObject, d)), regT1);
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT1);
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSVariableObject, m_registers)), regT1);
storePtr(regT0, Address(regT1, currentInstruction[1].u.operand * sizeof(Register)));
}
@@ -567,8 +565,8 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
// Return the result in %eax.
emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
Jump notJSCell = emitJumpIfNotJSCell(returnValueRegister);
- loadPtr(Address(returnValueRegister, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- Jump notObject = branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType));
+ loadPtr(Address(returnValueRegister, JSCell::structureOffset()), regT2);
+ Jump notObject = branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
// Grab the return address.
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
@@ -607,7 +605,7 @@ void JIT::emit_op_new_array(Instruction* currentInstruction)
void JIT::emit_op_resolve(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -619,7 +617,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
emitGetVirtualRegister(src, regT0);
Jump isImm = emitJumpIfNotJSCell(regT0);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
isImm.link(this);
if (dst != src)
@@ -638,7 +636,7 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -646,14 +644,14 @@ void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_ensure_property_exists);
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_skip);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -667,9 +665,9 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool)
void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
// Check Structure of global object
- move(ImmPtr(globalObject), regT0);
+ move(TrustedImmPtr(globalObject), regT0);
loadPtr(structureAddress, regT1);
- addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)))); // Structures don't match
+ addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, JSCell::structureOffset()))); // Structures don't match
// Load cached property
// Assume that the global object always uses external storage.
@@ -688,7 +686,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_resolve_global);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(Imm32(currentIndex));
stubCall.addArgument(regT0);
stubCall.call(dst);
@@ -697,9 +695,9 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
void JIT::emit_op_not(Instruction* currentInstruction)
{
emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
- xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
- addSlowCase(branchTestPtr(NonZero, regT0, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
- xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);
+ xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+ addSlowCase(branchTestPtr(NonZero, regT0, TrustedImm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
+ xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -708,11 +706,11 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
unsigned target = currentInstruction[2].u.operand;
emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(0)))), target);
+ addJump(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsNumber(0)))), target);
Jump isNonZero = emitJumpIfImmediateInteger(regT0);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target);
- addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))));
+ addJump(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsBoolean(false)))), target);
+ addSlowCase(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(jsBoolean(true)))));
isNonZero.link(this);
RECORD_JUMP_TARGET(target);
@@ -727,14 +725,14 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
Jump isImmediate = emitJumpIfNotJSCell(regT0);
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ addJump(branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target);
+ andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ addJump(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsNull()))), target);
wasNotImmediate.link(this);
RECORD_JUMP_TARGET(target);
@@ -748,14 +746,14 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
Jump isImmediate = emitJumpIfNotJSCell(regT0);
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest8(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ addJump(branchTest8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target);
+ andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(jsNull()))), target);
wasNotImmediate.link(this);
RECORD_JUMP_TARGET(target);
@@ -764,11 +762,11 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
{
unsigned src = currentInstruction[1].u.operand;
- JSCell* ptr = currentInstruction[2].u.jsCell;
+ JSCell* ptr = currentInstruction[2].u.jsCell.get();
unsigned target = currentInstruction[3].u.operand;
emitGetVirtualRegister(src, regT0);
- addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target);
+ addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue(ptr)))), target);
RECORD_JUMP_TARGET(target);
}
@@ -777,7 +775,7 @@ void JIT::emit_op_jsr(Instruction* currentInstruction)
{
int retAddrDst = currentInstruction[1].u.operand;
int target = currentInstruction[2].u.operand;
- DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
+ DataLabelPtr storeLocation = storePtrWithPatch(TrustedImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
addJump(jump(), target);
m_jsrSites.append(JSRInfo(storeLocation, label()));
killLastResultRegister();
@@ -811,7 +809,7 @@ void JIT::emit_op_bitnot(Instruction* currentInstruction)
void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_with_base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.call(currentInstruction[2].u.operand);
}
@@ -819,7 +817,7 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_new_func_exp);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -828,11 +826,11 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction)
unsigned target = currentInstruction[2].u.operand;
emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(0))));
+ Jump isZero = branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsNumber(0))));
addJump(emitJumpIfImmediateInteger(regT0), target);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target);
- addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))));
+ addJump(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsBoolean(true)))), target);
+ addSlowCase(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(jsBoolean(false)))));
isZero.link(this);
RECORD_JUMP_TARGET(target);
@@ -893,8 +891,8 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
if (!m_codeBlock->isKnownNotImmediate(base))
isNotObject.append(emitJumpIfNotJSCell(regT0));
if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) {
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ isNotObject.append(branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType)));
}
// We could inline the case where you have a valid cache, but
@@ -904,14 +902,15 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
getPnamesStubCall.addArgument(regT0);
getPnamesStubCall.call(dst);
load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
- store32(Imm32(0), addressFor(i));
- store32(regT3, addressFor(size));
+ storePtr(tagTypeNumberRegister, payloadFor(i));
+ store32(TrustedImm32(Int32Tag), intTagFor(size));
+ store32(regT3, intPayloadFor(size));
Jump end = jump();
isNotObject.link(this);
move(regT0, regT1);
- and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT1);
- addJump(branch32(Equal, regT1, Imm32(JSImmediate::FullTagTypeNull)), breakTarget);
+ and32(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT1);
+ addJump(branch32(Equal, regT1, TrustedImm32(JSImmediate::FullTagTypeNull)), breakTarget);
JITStubCall toObjectStubCall(this, cti_to_object);
toObjectStubCall.addArgument(regT0);
@@ -933,8 +932,8 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
JumpList callHasProperty;
Label begin(this);
- load32(addressFor(i), regT0);
- Jump end = branch32(Equal, regT0, addressFor(size));
+ load32(intPayloadFor(i), regT0);
+ Jump end = branch32(Equal, regT0, intPayloadFor(size));
// Grab key @ i
loadPtr(addressFor(it), regT1);
@@ -945,14 +944,14 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
emitPutVirtualRegister(dst, regT2);
// Increment i
- add32(Imm32(1), regT0);
- store32(regT0, addressFor(i));
+ add32(TrustedImm32(1), regT0);
+ store32(regT0, intPayloadFor(i));
// Verify that i is valid:
emitGetVirtualRegister(base, regT0);
// Test base's structure
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
// Test base's prototype chain
@@ -961,11 +960,11 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
addJump(branchTestPtr(Zero, Address(regT3)), target);
Label checkPrototype(this);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
+ loadPtr(Address(regT2, Structure::prototypeOffset()), regT2);
callHasProperty.append(emitJumpIfNotJSCell(regT2));
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ loadPtr(Address(regT2, JSCell::structureOffset()), regT2);
callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
- addPtr(Imm32(sizeof(Structure*)), regT3);
+ addPtr(TrustedImm32(sizeof(Structure*)), regT3);
branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
// Continue loop.
@@ -1040,8 +1039,8 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
Jump wasImmediate = emitJumpIfImmediateInteger(regT0);
emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addSlowCase(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ addSlowCase(branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(NumberType)));
wasImmediate.link(this);
@@ -1051,7 +1050,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
void JIT::emit_op_push_new_scope(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_push_new_scope);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(currentInstruction[3].u.operand, regT2);
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1062,7 +1061,7 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
move(regT0, callFrameRegister);
peek(regT3, OBJECT_OFFSETOF(struct JITStackFrame, globalData) / sizeof(void*));
loadPtr(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception)), regT0);
- storePtr(ImmPtr(JSValue::encode(JSValue())), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception)));
+ storePtr(TrustedImmPtr(JSValue::encode(JSValue())), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception)));
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -1157,15 +1156,15 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
emitGetVirtualRegister(src1, regT0);
Jump isImmediate = emitJumpIfNotJSCell(regT0);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- set32Test8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ set32Test8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
Jump wasNotImmediate = jump();
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- setPtr(Equal, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
+ andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ setPtr(Equal, regT0, TrustedImm32(JSImmediate::FullTagTypeNull), regT0);
wasNotImmediate.link(this);
@@ -1182,15 +1181,15 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
emitGetVirtualRegister(src1, regT0);
Jump isImmediate = emitJumpIfNotJSCell(regT0);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- set32Test8(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ set32Test8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
Jump wasNotImmediate = jump();
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- setPtr(NotEqual, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
+ andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ setPtr(NotEqual, regT0, TrustedImm32(JSImmediate::FullTagTypeNull), regT0);
wasNotImmediate.link(this);
@@ -1237,7 +1236,7 @@ void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
- storePtr(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * dst));
+ storePtr(TrustedImmPtr(0), Address(callFrameRegister, sizeof(Register) * dst));
}
void JIT::emit_op_convert_this(Instruction* currentInstruction)
@@ -1245,22 +1244,22 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
emitJumpSlowCaseIfNotJSCell(regT0);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
- addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
+ addSlowCase(branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(NeedsThisConversion)));
}
void JIT::emit_op_convert_this_strict(Instruction* currentInstruction)
{
emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
Jump notNull = branchTestPtr(NonZero, regT0);
- move(ImmPtr(JSValue::encode(jsNull())), regT0);
+ move(TrustedImmPtr(JSValue::encode(jsNull())), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand, regT0);
Jump setThis = jump();
notNull.link(this);
Jump isImmediate = emitJumpIfNotJSCell(regT0);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
- Jump notAnObject = branch8(NotEqual, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
- addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
+ Jump notAnObject = branch8(NotEqual, Address(regT1, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
+ addSlowCase(branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(NeedsThisConversion)));
isImmediate.link(this);
notAnObject.link(this);
setThis.link(this);
@@ -1375,7 +1374,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
- xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+ xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
JITStubCall stubCall(this, cti_op_not);
stubCall.addArgument(regT0);
stubCall.call(currentInstruction[1].u.operand);
@@ -1443,7 +1442,7 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
stubCall.call();
- xor32(Imm32(0x1), regT0);
+ xor32(TrustedImm32(0x1), regT0);
emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -1533,7 +1532,7 @@ void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
int argumentsRegister = currentInstruction[2].u.operand;
addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister)));
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
- sub32(Imm32(1), regT0);
+ sub32(TrustedImm32(1), regT0);
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
}
@@ -1548,7 +1547,7 @@ void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vect
emitGetVirtualRegister(base, regT0);
JITStubCall stubCall(this, cti_op_get_by_id_generic);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.call(dst);
}
@@ -1560,7 +1559,7 @@ void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister)));
emitGetVirtualRegister(property, regT1);
addSlowCase(emitJumpIfNotImmediateInteger(regT1));
- add32(Imm32(1), regT1);
+ add32(TrustedImm32(1), regT1);
// regT1 now contains the integer index of the argument we want, including this
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT2);
addSlowCase(branch32(AboveOrEqual, regT1, regT2));
@@ -1576,7 +1575,7 @@ void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
}
addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT0);
- mul32(Imm32(sizeof(Register)), regT2, regT2);
+ mul32(TrustedImm32(sizeof(Register)), regT2, regT2);
subPtr(regT2, regT0);
loadPtr(BaseIndex(regT0, regT1, TimesEight, 0), regT0);
if (numArgs)
@@ -1644,7 +1643,7 @@ void JIT::emitSlow_op_resolve_global_dynamic(Instruction* currentInstruction, Ve
while (skip--)
linkSlowCase(iter);
JITStubCall resolveStubCall(this, cti_op_resolve);
- resolveStubCall.addArgument(ImmPtr(ident));
+ resolveStubCall.addArgument(TrustedImmPtr(ident));
resolveStubCall.call(dst);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_resolve_global_dynamic));
@@ -1652,7 +1651,7 @@ void JIT::emitSlow_op_resolve_global_dynamic(Instruction* currentInstruction, Ve
linkSlowCase(iter); // We managed to skip all the nodes in the scope chain, but the cache missed.
JITStubCall stubCall(this, cti_op_resolve_global);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(Imm32(currentIndex));
stubCall.addArgument(regT0);
stubCall.call(dst);
@@ -1661,7 +1660,7 @@ void JIT::emitSlow_op_resolve_global_dynamic(Instruction* currentInstruction, Ve
void JIT::emit_op_new_regexp(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_new_regexp);
- stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1685,26 +1684,27 @@ void JIT::emit_op_load_varargs(Instruction* currentInstruction)
}
#if USE(JSVALUE32_64)
- addSlowCase(branch32(NotEqual, tagFor(argsOffset), Imm32(JSValue::EmptyValueTag)));
+ addSlowCase(branch32(NotEqual, tagFor(argsOffset), TrustedImm32(JSValue::EmptyValueTag)));
#else
addSlowCase(branchTestPtr(NonZero, addressFor(argsOffset)));
#endif
// Load arg count into regT0
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
- storePtr(regT0, addressFor(argCountDst));
- Jump endBranch = branch32(Equal, regT0, Imm32(1));
+ store32(TrustedImm32(Int32Tag), intTagFor(argCountDst));
+ store32(regT0, intPayloadFor(argCountDst));
+ Jump endBranch = branch32(Equal, regT0, TrustedImm32(1));
- mul32(Imm32(sizeof(Register)), regT0, regT3);
- addPtr(Imm32(static_cast<unsigned>(sizeof(Register) - RegisterFile::CallFrameHeaderSize * sizeof(Register))), callFrameRegister, regT1);
+ mul32(TrustedImm32(sizeof(Register)), regT0, regT3);
+ addPtr(TrustedImm32(static_cast<unsigned>(sizeof(Register) - RegisterFile::CallFrameHeaderSize * sizeof(Register))), callFrameRegister, regT1);
subPtr(regT3, regT1); // regT1 is now the start of the out of line arguments
addPtr(Imm32(argsOffset * sizeof(Register)), callFrameRegister, regT2); // regT2 is the target buffer
// Bounds check the registerfile
addPtr(regT2, regT3);
addPtr(Imm32((registerOffset - argsOffset) * sizeof(Register)), regT3);
- addSlowCase(branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile().m_end), regT3));
+ addSlowCase(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT3));
- sub32(Imm32(1), regT0);
+ sub32(TrustedImm32(1), regT0);
Label loopStart = label();
loadPtr(BaseIndex(regT1, regT0, TimesEight, static_cast<unsigned>(0 - 2 * sizeof(Register))), regT3);
storePtr(regT3, BaseIndex(regT2, regT0, TimesEight, static_cast<unsigned>(0 - sizeof(Register))));
@@ -1712,7 +1712,7 @@ void JIT::emit_op_load_varargs(Instruction* currentInstruction)
loadPtr(BaseIndex(regT1, regT0, TimesEight, static_cast<unsigned>(sizeof(void*) - 2 * sizeof(Register))), regT3);
storePtr(regT3, BaseIndex(regT2, regT0, TimesEight, static_cast<unsigned>(sizeof(void*) - sizeof(Register))));
#endif
- branchSubPtr(NonZero, Imm32(1), regT0).linkTo(loopStart, this);
+ branchSubPtr(NonZero, TrustedImm32(1), regT0).linkTo(loopStart, this);
endBranch.link(this);
}
@@ -1729,8 +1729,9 @@ void JIT::emitSlow_op_load_varargs(Instruction* currentInstruction, Vector<SlowC
JITStubCall stubCall(this, cti_op_load_varargs);
stubCall.addArgument(Imm32(argsOffset));
stubCall.call();
- // Stores a naked int32 in the register file.
- store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
+
+ store32(TrustedImm32(Int32Tag), intTagFor(argCountDst));
+ store32(returnValueRegister, intPayloadFor(argCountDst));
}
void JIT::emit_op_new_func(Instruction* currentInstruction)
@@ -1739,13 +1740,13 @@ void JIT::emit_op_new_func(Instruction* currentInstruction)
int dst = currentInstruction[1].u.operand;
if (currentInstruction[3].u.operand) {
#if USE(JSVALUE32_64)
- lazyJump = branch32(NotEqual, tagFor(dst), Imm32(JSValue::EmptyValueTag));
+ lazyJump = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
#else
lazyJump = branchTestPtr(NonZero, addressFor(dst));
#endif
}
JITStubCall stubCall(this, cti_op_new_func);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
if (currentInstruction[3].u.operand)
lazyJump.link(this);
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 0c8402b..bc0b2cb 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -52,15 +52,15 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// regT0 holds payload, regT1 holds tag
- Jump string_failureCases1 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
- Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+ Jump string_failureCases1 = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+ Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
// Checks out okay! - get the length from the Ustring.
load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT2);
- Jump string_failureCases3 = branch32(Above, regT2, Imm32(INT_MAX));
+ Jump string_failureCases3 = branch32(Above, regT2, TrustedImm32(INT_MAX));
move(regT2, regT0);
- move(Imm32(JSValue::Int32Tag), regT1);
+ move(TrustedImm32(JSValue::Int32Tag), regT1);
ret();
#endif
@@ -103,7 +103,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock3 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), Imm32(0));
+ Jump hasCodeBlock3 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), TrustedImm32(0));
preserveReturnAddressAfterCall(regT3);
restoreArgumentReference();
Call callCompileCall = call();
@@ -123,7 +123,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock4 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), Imm32(0));
+ Jump hasCodeBlock4 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), TrustedImm32(0));
preserveReturnAddressAfterCall(regT3);
restoreArgumentReference();
Call callCompileCconstruct = call();
@@ -142,10 +142,10 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
restoreReturnAddressBeforeReturn(regT1);
- move(ImmPtr(&globalData->exceptionLocation), regT2);
+ move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
- poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
+ poke(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
ret();
// NativeCall Trampoline
@@ -205,7 +205,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
peek(regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
@@ -214,7 +214,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// Host function signature: f(ExecState*);
move(callFrameRegister, X86Registers::ecx);
- subPtr(Imm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
+ subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
// call the function
emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT1);
@@ -222,14 +222,14 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
call(Address(regT1, executableOffsetToFunction));
- addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister);
+ addPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister);
#elif CPU(ARM)
// Load caller frame's scope chain into this callframe so that whatever we call can
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
@@ -251,7 +251,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
@@ -261,7 +261,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// Allocate stack space for 16 bytes (8-byte aligned)
// 16 bytes (unused) for 4 arguments
- subPtr(Imm32(16), stackPointerRegister);
+ subPtr(TrustedImm32(16), stackPointerRegister);
// Setup arg0
move(callFrameRegister, MIPSRegisters::a0);
@@ -273,7 +273,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
call(Address(regT2, executableOffsetToFunction));
// Restore stack space
- addPtr(Imm32(16), stackPointerRegister);
+ addPtr(TrustedImm32(16), stackPointerRegister);
restoreReturnAddressBeforeReturn(regT3);
@@ -285,7 +285,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
#endif // CPU(X86)
// Check for an exception
- Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag));
+ Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
// Return.
ret();
@@ -296,12 +296,12 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// Grab the return address.
preserveReturnAddressAfterCall(regT1);
- move(ImmPtr(&globalData->exceptionLocation), regT2);
+ move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
// Set the return address.
- move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
+ move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
restoreReturnAddressBeforeReturn(regT1);
ret();
@@ -321,7 +321,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
peek(regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
@@ -330,21 +330,21 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// Host function signature: f(ExecState*);
move(callFrameRegister, X86Registers::ecx);
- subPtr(Imm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
+ subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
// call the function
nativeCall = call();
- addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister);
+ addPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister);
#elif CPU(ARM)
// Load caller frame's scope chain into this callframe so that whatever we call can
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
@@ -367,7 +367,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
- emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
@@ -377,7 +377,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// Allocate stack space for 16 bytes (8-byte aligned)
// 16 bytes (unused) for 4 arguments
- subPtr(Imm32(16), stackPointerRegister);
+ subPtr(TrustedImm32(16), stackPointerRegister);
// Setup arg0
move(callFrameRegister, MIPSRegisters::a0);
@@ -391,7 +391,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
nativeCall = call();
// Restore stack space
- addPtr(Imm32(16), stackPointerRegister);
+ addPtr(TrustedImm32(16), stackPointerRegister);
restoreReturnAddressBeforeReturn(regT3);
@@ -402,7 +402,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
#endif // CPU(X86)
// Check for an exception
- Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag));
+ Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
// Return.
ret();
@@ -413,12 +413,12 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// Grab the return address.
preserveReturnAddressAfterCall(regT1);
- move(ImmPtr(&globalData->exceptionLocation), regT2);
+ move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
// Set the return address.
- move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
+ move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
restoreReturnAddressBeforeReturn(regT1);
ret();
@@ -470,21 +470,21 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitLoad(op2, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target);
return;
}
if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
return;
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
addJump(branch32(LessThanOrEqual, regT0, regT2), target);
}
@@ -520,8 +520,8 @@ void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(baseVal);
// Check that baseVal 'ImplementsHasInstance'.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
+ addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsHasInstance)));
}
void JIT::emit_op_instanceof(Instruction* currentInstruction)
@@ -542,29 +542,29 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(proto);
// Check that prototype is an object
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT3);
- addSlowCase(branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ loadPtr(Address(regT1, JSCell::structureOffset()), regT3);
+ addSlowCase(branch8(NotEqual, Address(regT3, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType)));
// Fixme: this check is only needed because the JSC API allows HasInstance to be overridden; we should deprecate this.
// Check that baseVal 'ImplementsDefaultHasInstance'.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
+ addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
- move(Imm32(JSValue::TrueTag), regT0);
+ move(TrustedImm32(JSValue::TrueTag), regT0);
Label loop(this);
// Load the prototype of the cell in regT2. If this is equal to regT1 - WIN!
// Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again.
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- load32(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
+ loadPtr(Address(regT2, JSCell::structureOffset()), regT2);
+ load32(Address(regT2, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
Jump isInstance = branchPtr(Equal, regT2, regT1);
branchTest32(NonZero, regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- move(Imm32(JSValue::FalseTag), regT0);
+ move(TrustedImm32(JSValue::FalseTag), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
isInstance.link(this);
@@ -609,7 +609,7 @@ void JIT::emit_op_get_global_var(Instruction* currentInstruction)
ASSERT(globalObject->isGlobalObject());
int index = currentInstruction[2].u.operand;
- loadPtr(&globalObject->d()->registers, regT2);
+ loadPtr(&globalObject->m_registers, regT2);
emitLoad(index, regT1, regT0, regT2);
emitStore(dst, regT1, regT0);
@@ -625,7 +625,7 @@ void JIT::emit_op_put_global_var(Instruction* currentInstruction)
emitLoad(value, regT1, regT0);
- loadPtr(&globalObject->d()->registers, regT2);
+ loadPtr(&globalObject->m_registers, regT2);
emitStore(index, regT1, regT0, regT2);
map(m_bytecodeOffset + OPCODE_LENGTH(op_put_global_var), value, regT1, regT0);
}
@@ -642,7 +642,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
if (checkTopLevel && skip--) {
Jump activationNotCreated;
if (checkTopLevel)
- activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), TrustedImm32(JSValue::EmptyValueTag));
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
activationNotCreated.link(this);
}
@@ -650,8 +650,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, d)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT2);
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, m_registers)), regT2);
emitLoad(index, regT1, regT0, regT2);
emitStore(dst, regT1, regT0);
@@ -672,7 +671,7 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
if (checkTopLevel && skip--) {
Jump activationNotCreated;
if (checkTopLevel)
- activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), TrustedImm32(JSValue::EmptyValueTag));
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
activationNotCreated.link(this);
}
@@ -680,8 +679,7 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, d)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT2);
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, m_registers)), regT2);
emitStore(index, regT1, regT0, regT2);
map(m_bytecodeOffset + OPCODE_LENGTH(op_put_scoped_var), value, regT1, regT0);
@@ -691,8 +689,8 @@ void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
{
unsigned activation = currentInstruction[1].u.operand;
unsigned arguments = currentInstruction[2].u.operand;
- Jump activationCreated = branch32(NotEqual, tagFor(activation), Imm32(JSValue::EmptyValueTag));
- Jump argumentsNotCreated = branch32(Equal, tagFor(arguments), Imm32(JSValue::EmptyValueTag));
+ Jump activationCreated = branch32(NotEqual, tagFor(activation), TrustedImm32(JSValue::EmptyValueTag));
+ Jump argumentsNotCreated = branch32(Equal, tagFor(arguments), TrustedImm32(JSValue::EmptyValueTag));
activationCreated.link(this);
JITStubCall stubCall(this, cti_op_tear_off_activation);
stubCall.addArgument(currentInstruction[1].u.operand);
@@ -705,7 +703,7 @@ void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
- Jump argsNotCreated = branch32(Equal, tagFor(unmodifiedArgumentsRegister(dst)), Imm32(JSValue::EmptyValueTag));
+ Jump argsNotCreated = branch32(Equal, tagFor(unmodifiedArgumentsRegister(dst)), TrustedImm32(JSValue::EmptyValueTag));
JITStubCall stubCall(this, cti_op_tear_off_arguments);
stubCall.addArgument(unmodifiedArgumentsRegister(dst));
stubCall.call();
@@ -723,7 +721,7 @@ void JIT::emit_op_new_array(Instruction* currentInstruction)
void JIT::emit_op_resolve(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -734,8 +732,8 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
- Jump isImm = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
+ Jump isImm = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
isImm.link(this);
if (dst != src)
@@ -765,7 +763,7 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -773,14 +771,14 @@ void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_ensure_property_exists);
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_skip);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -797,9 +795,9 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool dynamic)
void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
// Verify structure.
- move(ImmPtr(globalObject), regT0);
+ move(TrustedImmPtr(globalObject), regT0);
loadPtr(structureAddress, regT1);
- addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure))));
+ addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, JSCell::structureOffset())));
// Load property.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT2);
@@ -819,7 +817,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_resolve_global);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(Imm32(currentIndex));
stubCall.call(dst);
}
@@ -831,9 +829,9 @@ void JIT::emit_op_not(Instruction* currentInstruction)
emitLoadTag(src, regT0);
- xor32(Imm32(JSValue::FalseTag), regT0);
- addSlowCase(branchTest32(NonZero, regT0, Imm32(~1)));
- xor32(Imm32(JSValue::TrueTag), regT0);
+ xor32(TrustedImm32(JSValue::FalseTag), regT0);
+ addSlowCase(branchTest32(NonZero, regT0, TrustedImm32(~1)));
+ xor32(TrustedImm32(JSValue::TrueTag), regT0);
emitStoreBool(dst, regT0, (dst == src));
}
@@ -857,17 +855,17 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
emitLoad(cond, regT1, regT0);
- Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag));
- addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target);
+ Jump isTrue = branch32(Equal, regT1, TrustedImm32(JSValue::TrueTag));
+ addJump(branch32(Equal, regT1, TrustedImm32(JSValue::FalseTag)), target);
- Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
- Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0));
+ Jump isNotInteger = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
+ Jump isTrue2 = branch32(NotEqual, regT0, TrustedImm32(0));
addJump(jump(), target);
if (supportsFloatingPoint()) {
isNotInteger.link(this);
- addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
emitLoadDouble(cond, fpRegT0);
addJump(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
@@ -897,17 +895,17 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction)
emitLoad(cond, regT1, regT0);
- Jump isFalse = branch32(Equal, regT1, Imm32(JSValue::FalseTag));
- addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target);
+ Jump isFalse = branch32(Equal, regT1, TrustedImm32(JSValue::FalseTag));
+ addJump(branch32(Equal, regT1, TrustedImm32(JSValue::TrueTag)), target);
- Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
- Jump isFalse2 = branch32(Equal, regT0, Imm32(0));
+ Jump isNotInteger = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
+ Jump isFalse2 = branch32(Equal, regT0, TrustedImm32(0));
addJump(jump(), target);
if (supportsFloatingPoint()) {
isNotInteger.link(this);
- addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
emitLoadDouble(cond, fpRegT0);
addJump(branchDoubleNonZero(fpRegT0, fpRegT1), target);
@@ -937,11 +935,11 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
- Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+ Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ addJump(branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
@@ -949,7 +947,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
isImmediate.link(this);
ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1));
- addJump(branch32(AboveOrEqual, regT1, Imm32(JSValue::UndefinedTag)), target);
+ addJump(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::UndefinedTag)), target);
wasNotImmediate.link(this);
}
@@ -961,11 +959,11 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
- Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+ Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest8(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ addJump(branchTest8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
@@ -973,7 +971,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
isImmediate.link(this);
ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1));
- addJump(branch32(Below, regT1, Imm32(JSValue::UndefinedTag)), target);
+ addJump(branch32(Below, regT1, TrustedImm32(JSValue::UndefinedTag)), target);
wasNotImmediate.link(this);
}
@@ -981,19 +979,19 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
{
unsigned src = currentInstruction[1].u.operand;
- JSCell* ptr = currentInstruction[2].u.jsCell;
+ JSCell* ptr = currentInstruction[2].u.jsCell.get();
unsigned target = currentInstruction[3].u.operand;
emitLoad(src, regT1, regT0);
- addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target);
- addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target);
+ addJump(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)), target);
+ addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(ptr)), target);
}
void JIT::emit_op_jsr(Instruction* currentInstruction)
{
int retAddrDst = currentInstruction[1].u.operand;
int target = currentInstruction[2].u.operand;
- DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
+ DataLabelPtr storeLocation = storePtrWithPatch(TrustedImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
addJump(jump(), target);
m_jsrSites.append(JSRInfo(storeLocation, label()));
}
@@ -1011,11 +1009,11 @@ void JIT::emit_op_eq(Instruction* currentInstruction)
emitLoad2(src1, regT1, regT0, src2, regT3, regT2);
addSlowCase(branch32(NotEqual, regT1, regT3));
- addSlowCase(branch32(Equal, regT1, Imm32(JSValue::CellTag)));
- addSlowCase(branch32(Below, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::CellTag)));
+ addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
set8Compare32(Equal, regT0, regT2, regT0);
- or32(Imm32(JSValue::FalseTag), regT0);
+ or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1032,8 +1030,8 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
- genericCase.append(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsStringVPtr)));
+ genericCase.append(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+ genericCase.append(branchPtr(NotEqual, Address(regT2), TrustedImmPtr(m_globalData->jsStringVPtr)));
// String case.
JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1051,7 +1049,7 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
stubCallEq.call(regT0);
storeResult.link(this);
- or32(Imm32(JSValue::FalseTag), regT0);
+ or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1063,11 +1061,11 @@ void JIT::emit_op_neq(Instruction* currentInstruction)
emitLoad2(src1, regT1, regT0, src2, regT3, regT2);
addSlowCase(branch32(NotEqual, regT1, regT3));
- addSlowCase(branch32(Equal, regT1, Imm32(JSValue::CellTag)));
- addSlowCase(branch32(Below, regT1, Imm32(JSValue::LowestTag)));
+ addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::CellTag)));
+ addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
set8Compare32(NotEqual, regT0, regT2, regT0);
- or32(Imm32(JSValue::FalseTag), regT0);
+ or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1082,8 +1080,8 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
- genericCase.append(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsStringVPtr)));
+ genericCase.append(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr)));
+ genericCase.append(branchPtr(NotEqual, Address(regT2), TrustedImmPtr(m_globalData->jsStringVPtr)));
// String case.
JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1101,8 +1099,8 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
stubCallEq.call(regT0);
storeResult.link(this);
- xor32(Imm32(0x1), regT0);
- or32(Imm32(JSValue::FalseTag), regT0);
+ xor32(TrustedImm32(0x1), regT0);
+ or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1119,15 +1117,15 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
// cells and/or Int32s.
move(regT0, regT2);
and32(regT1, regT2);
- addSlowCase(branch32(Below, regT2, Imm32(JSValue::LowestTag)));
- addSlowCase(branch32(AboveOrEqual, regT2, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(Below, regT2, TrustedImm32(JSValue::LowestTag)));
+ addSlowCase(branch32(AboveOrEqual, regT2, TrustedImm32(JSValue::CellTag)));
if (type == OpStrictEq)
set8Compare32(Equal, regT0, regT1, regT0);
else
set8Compare32(NotEqual, regT0, regT1, regT0);
- or32(Imm32(JSValue::FalseTag), regT0);
+ or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1178,22 +1176,22 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
unsigned src = currentInstruction[2].u.operand;
emitLoad(src, regT1, regT0);
- Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+ Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
- set32Test8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT1);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
+ set32Test8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT1);
Jump wasNotImmediate = jump();
isImmediate.link(this);
- set8Compare32(Equal, regT1, Imm32(JSValue::NullTag), regT2);
- set8Compare32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1);
+ set8Compare32(Equal, regT1, TrustedImm32(JSValue::NullTag), regT2);
+ set8Compare32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
or32(regT2, regT1);
wasNotImmediate.link(this);
- or32(Imm32(JSValue::FalseTag), regT1);
+ or32(TrustedImm32(JSValue::FalseTag), regT1);
emitStoreBool(dst, regT1);
}
@@ -1204,22 +1202,22 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
unsigned src = currentInstruction[2].u.operand;
emitLoad(src, regT1, regT0);
- Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+ Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
- set32Test8(Zero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT1);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
+ set32Test8(Zero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT1);
Jump wasNotImmediate = jump();
isImmediate.link(this);
- set8Compare32(NotEqual, regT1, Imm32(JSValue::NullTag), regT2);
- set8Compare32(NotEqual, regT1, Imm32(JSValue::UndefinedTag), regT1);
+ set8Compare32(NotEqual, regT1, TrustedImm32(JSValue::NullTag), regT2);
+ set8Compare32(NotEqual, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
and32(regT2, regT1);
wasNotImmediate.link(this);
- or32(Imm32(JSValue::FalseTag), regT1);
+ or32(TrustedImm32(JSValue::FalseTag), regT1);
emitStoreBool(dst, regT1);
}
@@ -1227,7 +1225,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_with_base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.call(currentInstruction[2].u.operand);
}
@@ -1235,7 +1233,7 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_new_func_exp);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1265,10 +1263,10 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
emitLoad(base, regT1, regT0);
if (!m_codeBlock->isKnownNotImmediate(base))
- isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ isNotObject.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) {
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ isNotObject.append(branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType)));
}
// We could inline the case where you have a valid cache, but
@@ -1278,13 +1276,15 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
getPnamesStubCall.addArgument(regT0);
getPnamesStubCall.call(dst);
load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
- store32(Imm32(0), addressFor(i));
- store32(regT3, addressFor(size));
+ store32(TrustedImm32(Int32Tag), intTagFor(i));
+ store32(TrustedImm32(0), intPayloadFor(i));
+ store32(TrustedImm32(Int32Tag), intTagFor(size));
+ store32(regT3, payloadFor(size));
Jump end = jump();
isNotObject.link(this);
- addJump(branch32(Equal, regT1, Imm32(JSValue::NullTag)), breakTarget);
- addJump(branch32(Equal, regT1, Imm32(JSValue::UndefinedTag)), breakTarget);
+ addJump(branch32(Equal, regT1, TrustedImm32(JSValue::NullTag)), breakTarget);
+ addJump(branch32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag)), breakTarget);
JITStubCall toObjectStubCall(this, cti_to_object);
toObjectStubCall.addArgument(regT1, regT0);
toObjectStubCall.call(base);
@@ -1305,25 +1305,25 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
JumpList callHasProperty;
Label begin(this);
- load32(addressFor(i), regT0);
- Jump end = branch32(Equal, regT0, addressFor(size));
+ load32(intPayloadFor(i), regT0);
+ Jump end = branch32(Equal, regT0, intPayloadFor(size));
// Grab key @ i
- loadPtr(addressFor(it), regT1);
+ loadPtr(payloadFor(it), regT1);
loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
load32(BaseIndex(regT2, regT0, TimesEight), regT2);
- store32(Imm32(JSValue::CellTag), tagFor(dst));
+ store32(TrustedImm32(JSValue::CellTag), tagFor(dst));
store32(regT2, payloadFor(dst));
// Increment i
- add32(Imm32(1), regT0);
- store32(regT0, addressFor(i));
+ add32(TrustedImm32(1), regT0);
+ store32(regT0, intPayloadFor(i));
// Verify that i is valid:
- loadPtr(addressFor(base), regT0);
+ loadPtr(payloadFor(base), regT0);
// Test base's structure
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
// Test base's prototype chain
@@ -1332,11 +1332,11 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
addJump(branchTestPtr(Zero, Address(regT3)), target);
Label checkPrototype(this);
- callHasProperty.append(branch32(Equal, Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::NullTag)));
- loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ callHasProperty.append(branch32(Equal, Address(regT2, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::NullTag)));
+ loadPtr(Address(regT2, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
+ loadPtr(Address(regT2, JSCell::structureOffset()), regT2);
callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
- addPtr(Imm32(sizeof(Structure*)), regT3);
+ addPtr(TrustedImm32(sizeof(Structure*)), regT3);
branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
// Continue loop.
@@ -1377,8 +1377,8 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
- Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag));
- addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::EmptyValueTag)));
+ Jump isInt32 = branch32(Equal, regT1, TrustedImm32(JSValue::Int32Tag));
+ addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
isInt32.link(this);
if (src != dst)
@@ -1400,7 +1400,7 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa
void JIT::emit_op_push_new_scope(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_push_new_scope);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(currentInstruction[3].u.operand);
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1414,8 +1414,8 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(struct JITStackFrame, globalData)), regT3);
load32(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
load32(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
- store32(Imm32(JSValue().payload()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- store32(Imm32(JSValue().tag()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ store32(TrustedImm32(JSValue().payload()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+ store32(TrustedImm32(JSValue().tag()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
unsigned exception = currentInstruction[1].u.operand;
emitStore(exception, regT1, regT0);
@@ -1520,7 +1520,7 @@ void JIT::emit_op_create_activation(Instruction* currentInstruction)
{
unsigned activation = currentInstruction[1].u.operand;
- Jump activationCreated = branch32(NotEqual, tagFor(activation), Imm32(JSValue::EmptyValueTag));
+ Jump activationCreated = branch32(NotEqual, tagFor(activation), TrustedImm32(JSValue::EmptyValueTag));
JITStubCall(this, cti_op_push_activation).call(activation);
activationCreated.link(this);
}
@@ -1529,7 +1529,7 @@ void JIT::emit_op_create_arguments(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
- Jump argsCreated = branch32(NotEqual, tagFor(dst), Imm32(JSValue::EmptyValueTag));
+ Jump argsCreated = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
if (m_codeBlock->m_numParameters == 1)
JITStubCall(this, cti_op_create_arguments_no_params).call();
@@ -1571,10 +1571,10 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
emitLoad(thisRegister, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addSlowCase(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ addSlowCase(branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(NeedsThisConversion)));
map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0);
}
@@ -1585,14 +1585,14 @@ void JIT::emit_op_convert_this_strict(Instruction* currentInstruction)
emitLoad(thisRegister, regT1, regT0);
- Jump notNull = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
+ Jump notNull = branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag));
emitStore(thisRegister, jsNull());
Jump setThis = jump();
notNull.link(this);
- Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- Jump notAnObject = branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
- addSlowCase(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ Jump notAnObject = branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
+ addSlowCase(branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(NeedsThisConversion)));
isImmediate.link(this);
notAnObject.link(this);
setThis.link(this);
@@ -1648,9 +1648,9 @@ void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
int argumentsRegister = currentInstruction[2].u.operand;
- addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), Imm32(JSValue::EmptyValueTag)));
+ addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
- sub32(Imm32(1), regT0);
+ sub32(TrustedImm32(1), regT0);
emitStoreInt32(dst, regT0);
}
@@ -1663,7 +1663,7 @@ void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vect
JITStubCall stubCall(this, cti_op_get_by_id_generic);
stubCall.addArgument(base);
- stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+ stubCall.addArgument(TrustedImmPtr(&(m_codeBlock->identifier(ident))));
stubCall.call(dst);
}
@@ -1672,10 +1672,10 @@ void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
int dst = currentInstruction[1].u.operand;
int argumentsRegister = currentInstruction[2].u.operand;
int property = currentInstruction[3].u.operand;
- addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), Imm32(JSValue::EmptyValueTag)));
+ addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
emitLoad(property, regT1, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- add32(Imm32(1), regT2);
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
+ add32(TrustedImm32(1), regT2);
// regT2 now contains the integer index of the argument we want, including this
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT3);
addSlowCase(branch32(AboveOrEqual, regT2, regT3));
@@ -1692,7 +1692,7 @@ void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
}
addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT1);
- mul32(Imm32(sizeof(Register)), regT3, regT3);
+ mul32(TrustedImm32(sizeof(Register)), regT3, regT3);
subPtr(regT3, regT1);
loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
@@ -1734,17 +1734,17 @@ void JIT::softModulo()
push(regT3);
move(regT2, regT3);
move(regT0, regT2);
- move(Imm32(0), regT1);
+ move(TrustedImm32(0), regT1);
// Check for negative result reminder
- Jump positiveRegT3 = branch32(GreaterThanOrEqual, regT3, Imm32(0));
+ Jump positiveRegT3 = branch32(GreaterThanOrEqual, regT3, TrustedImm32(0));
neg32(regT3);
- xor32(Imm32(1), regT1);
+ xor32(TrustedImm32(1), regT1);
positiveRegT3.link(this);
- Jump positiveRegT2 = branch32(GreaterThanOrEqual, regT2, Imm32(0));
+ Jump positiveRegT2 = branch32(GreaterThanOrEqual, regT2, TrustedImm32(0));
neg32(regT2);
- xor32(Imm32(2), regT1);
+ xor32(TrustedImm32(2), regT1);
positiveRegT2.link(this);
// Save the condition for negative reminder
@@ -1754,7 +1754,7 @@ void JIT::softModulo()
// Power of two fast case
move(regT3, regT0);
- sub32(Imm32(1), regT0);
+ sub32(TrustedImm32(1), regT0);
Jump powerOfTwo = branchTest32(NotEqual, regT0, regT3);
and32(regT0, regT2);
powerOfTwo.link(this);
@@ -1767,10 +1767,10 @@ void JIT::softModulo()
countLeadingZeros32(regT3, regT1);
sub32(regT0, regT1);
- Jump useFullTable = branch32(Equal, regT1, Imm32(31));
+ Jump useFullTable = branch32(Equal, regT1, TrustedImm32(31));
neg32(regT1);
- add32(Imm32(31), regT1);
+ add32(TrustedImm32(31), regT1);
int elementSizeByShift = -1;
#if CPU(ARM)
@@ -1805,7 +1805,7 @@ void JIT::softModulo()
// Check for negative reminder
pop(regT1);
- Jump positiveResult = branch32(Equal, regT1, Imm32(0));
+ Jump positiveResult = branch32(Equal, regT1, TrustedImm32(0));
neg32(regT2);
positiveResult.link(this);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index b497319..68f8dda 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -54,7 +54,7 @@ JIT::CodePtr JIT::stringGetByValStubGenerator(JSGlobalData* globalData, Executab
{
JSInterfaceJIT jit;
JumpList failures;
- failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr)));
+ failures.append(jit.branchPtr(NotEqual, Address(regT0), TrustedImmPtr(globalData->jsStringVPtr)));
failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount))));
// Load string length to regT1, and start the process of loading the data pointer into regT0
@@ -68,13 +68,13 @@ JIT::CodePtr JIT::stringGetByValStubGenerator(JSGlobalData* globalData, Executab
// Load the character
jit.load16(BaseIndex(regT0, regT1, TimesTwo, 0), regT0);
- failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100)));
- jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
+ failures.append(jit.branch32(AboveOrEqual, regT0, TrustedImm32(0x100)));
+ jit.move(TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
jit.ret();
failures.link(&jit);
- jit.move(Imm32(0), regT0);
+ jit.move(TrustedImm32(0), regT0);
jit.ret();
LinkBuffer patchBuffer(&jit, pool, 0);
@@ -99,10 +99,10 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
zeroExtend32ToPtr(regT1, regT1);
emitJumpSlowCaseIfNotJSCell(regT0, base);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
- addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
+ loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
+ addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, JSArray::vectorLengthOffset())));
loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0);
addSlowCase(branchTestPtr(Zero, regT0));
@@ -120,7 +120,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
linkSlowCaseIfNotJSCell(iter, base); // base cell check
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+ Jump notString = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
emitNakedCall(m_globalData->getCTIStub(stringGetByValStubGenerator));
Jump failed = branchTestPtr(Zero, regT0);
emitPutVirtualRegister(dst, regT0);
@@ -159,10 +159,10 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT0, base);
// Test base's structure
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
load32(addressFor(i), regT3);
- sub32(Imm32(1), regT3);
+ sub32(TrustedImm32(1), regT3);
addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
compileGetDirectOffset(regT0, regT0, regT3, regT1);
@@ -197,10 +197,10 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
// See comment in op_get_by_val.
zeroExtend32ToPtr(regT1, regT1);
emitJumpSlowCaseIfNotJSCell(regT0, base);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
- addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
+ addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, JSArray::vectorLengthOffset())));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+ loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
Label storeResult(this);
@@ -209,11 +209,11 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
Jump end = jump();
empty.link(this);
- add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ add32(TrustedImm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
move(regT1, regT0);
- add32(Imm32(1), regT0);
+ add32(TrustedImm32(1), regT0);
store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)));
jump().linkTo(storeResult, this);
@@ -224,7 +224,7 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_put_by_index);
stubCall.addArgument(currentInstruction[1].u.operand, regT2);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
stubCall.addArgument(currentInstruction[3].u.operand, regT2);
stubCall.call();
}
@@ -233,7 +233,7 @@ void JIT::emit_op_put_getter(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_put_getter);
stubCall.addArgument(currentInstruction[1].u.operand, regT2);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(currentInstruction[3].u.operand, regT2);
stubCall.call();
}
@@ -242,7 +242,7 @@ void JIT::emit_op_put_setter(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_put_setter);
stubCall.addArgument(currentInstruction[1].u.operand, regT2);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(currentInstruction[3].u.operand, regT2);
stubCall.call();
}
@@ -251,7 +251,7 @@ void JIT::emit_op_del_by_id(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_del_by_id);
stubCall.addArgument(currentInstruction[2].u.operand, regT2);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -276,7 +276,7 @@ void JIT::emit_op_get_by_id(Instruction* currentInstruction)
emitGetVirtualRegister(baseVReg, regT0);
JITStubCall stubCall(this, cti_op_get_by_id_generic);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.call(resultVReg);
m_propertyAccessInstructionIndex++;
@@ -298,7 +298,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct_generic, cti_op_put_by_id_generic);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(regT1);
stubCall.call();
@@ -336,12 +336,12 @@ void JIT::emit_op_method_check(Instruction* currentInstruction)
BEGIN_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
- Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
- DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT1);
- Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), info.structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(TrustedImmPtr(0), regT1);
+ Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT1, JSCell::structureOffset()), protoStructureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
// This will be relinked to load the function without doing a load.
- DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0);
+ DataLabelPtr putFunction = moveWithPatch(TrustedImmPtr(0), regT0);
END_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
@@ -414,7 +414,7 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert
m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
DataLabelPtr structureToCompare;
- Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
addSlowCase(structureCheck);
ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure);
ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase)
@@ -457,7 +457,7 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident
#endif
JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
Call call = stubCall.call(resultVReg);
END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
@@ -492,7 +492,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
// It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
DataLabelPtr structureToCompare;
- addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
+ addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure);
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0);
@@ -516,7 +516,7 @@ void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCase
JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct : cti_op_put_by_id);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(regT1);
Call call = stubCall.call();
@@ -564,10 +564,10 @@ void JIT::testPrototype(JSValue prototype, JumpList& failureCases)
// values. In the non X86_64 case, the generated code is slightly more efficient because it uses
// two less instructions and doesn't require any scratch registers.
#if CPU(X86_64)
- move(ImmPtr(prototype.asCell()->structure()), regT3);
- failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), regT3));
+ move(TrustedImmPtr(prototype.asCell()->structure()), regT3);
+ failureCases.append(branchPtr(NotEqual, AbsoluteAddress(prototype.asCell()->addressOfStructure()), regT3));
#else
- failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), ImmPtr(prototype.asCell()->structure())));
+ failureCases.append(branchPtr(NotEqual, AbsoluteAddress(prototype.asCell()->addressOfStructure()), TrustedImmPtr(prototype.asCell()->structure())));
#endif
}
@@ -576,7 +576,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
JumpList failureCases;
// Check eax is an object of the right Structure.
failureCases.append(emitJumpIfNotJSCell(regT0));
- failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
+ failureCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(oldStructure)));
testPrototype(oldStructure->storedPrototype(), failureCases);
// ecx = baseObject->m_structure
@@ -598,8 +598,8 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
stubCall.skipArgument(); // base
stubCall.skipArgument(); // ident
stubCall.skipArgument(); // value
- stubCall.addArgument(Imm32(oldStructure->propertyStorageCapacity()));
- stubCall.addArgument(Imm32(newStructure->propertyStorageCapacity()));
+ stubCall.addArgument(TrustedImm32(oldStructure->propertyStorageCapacity()));
+ stubCall.addArgument(TrustedImm32(newStructure->propertyStorageCapacity()));
stubCall.call(regT0);
emitGetJITStubArg(2, regT1);
@@ -608,9 +608,9 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
// Assumes m_refCount can be decremented easily, refcount decrement is safe as
// codeblock should ensure oldStructure->m_refCount > 0
- sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
- add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
- storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)));
+ sub32(TrustedImm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
+ add32(TrustedImm32(1), AbsoluteAddress(newStructure->addressOfCount()));
+ storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
// write the value
compilePutDirectOffset(regT0, regT1, newStructure, cachedOffset);
@@ -692,12 +692,12 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
// Check eax is an array
- Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
+ Jump failureCases1 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr));
// Checks out okay! - get the length from the storage
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
+ loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
load32(Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
- Jump failureCases2 = branch32(Above, regT2, Imm32(JSImmediate::maxImmediateInt));
+ Jump failureCases2 = branch32(Above, regT2, TrustedImm32(JSImmediate::maxImmediateInt));
emitFastArithIntToImmNoCheck(regT2, regT0);
Jump success = jump();
@@ -735,12 +735,12 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure** prototypeStructureAddress = &(protoObject->m_structure);
+ Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
- move(ImmPtr(prototypeStructure), regT3);
+ move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
- Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), TrustedImmPtr(prototypeStructure));
#endif
bool needsStubLink = false;
@@ -752,15 +752,15 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT0, cachedOffset);
@@ -804,15 +804,15 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(regT0, regT0, structure, cachedOffset);
@@ -858,12 +858,12 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure** prototypeStructureAddress = &(protoObject->m_structure);
+ Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
- move(ImmPtr(prototypeStructure), regT3);
+ move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
- Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), TrustedImmPtr(prototypeStructure));
#endif
// Checks out okay!
@@ -874,15 +874,15 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT0, cachedOffset);
@@ -944,15 +944,15 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT0, cachedOffset);
@@ -979,8 +979,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
// Track the stub we have created so that it will be deleted later.
structure->ref();
- chain->ref();
- prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
+ prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, chain);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
@@ -1014,15 +1013,15 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT0, cachedOffset);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 3562200..2a47e5c 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -70,7 +70,7 @@ void JIT::emit_op_put_getter(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_put_getter);
stubCall.addArgument(base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(property)));
stubCall.addArgument(function);
stubCall.call();
}
@@ -83,7 +83,7 @@ void JIT::emit_op_put_setter(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_put_setter);
stubCall.addArgument(base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(property)));
stubCall.addArgument(function);
stubCall.call();
}
@@ -96,7 +96,7 @@ void JIT::emit_op_del_by_id(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_del_by_id);
stubCall.addArgument(base);
- stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property)));
+ stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(property)));
stubCall.call(dst);
}
@@ -155,7 +155,7 @@ void JIT::emit_op_get_by_id(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_get_by_id_generic);
stubCall.addArgument(base);
- stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+ stubCall.addArgument(TrustedImmPtr(&(m_codeBlock->identifier(ident))));
stubCall.call(dst);
m_propertyAccessInstructionIndex++;
@@ -175,7 +175,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_put_by_id_generic);
stubCall.addArgument(base);
- stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+ stubCall.addArgument(TrustedImmPtr(&(m_codeBlock->identifier(ident))));
stubCall.addArgument(value);
stubCall.call();
@@ -213,16 +213,16 @@ void JIT::emit_op_method_check(Instruction* currentInstruction)
BEGIN_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
- Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
- DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT2);
- Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), info.structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(TrustedImmPtr(0), regT2);
+ Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT2, JSCell::structureOffset()), protoStructureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
// This will be relinked to load the function without doing a load.
- DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0);
+ DataLabelPtr putFunction = moveWithPatch(TrustedImmPtr(0), regT0);
END_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
- move(Imm32(JSValue::CellTag), regT1);
+ move(TrustedImm32(JSValue::CellTag), regT1);
Jump match = jump();
ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj);
@@ -271,7 +271,7 @@ JIT::CodePtr JIT::stringGetByValStubGenerator(JSGlobalData* globalData, Executab
{
JSInterfaceJIT jit;
JumpList failures;
- failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr)));
+ failures.append(jit.branchPtr(NotEqual, Address(regT0), TrustedImmPtr(globalData->jsStringVPtr)));
failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount))));
// Load string length to regT1, and start the process of loading the data pointer into regT0
@@ -285,14 +285,14 @@ JIT::CodePtr JIT::stringGetByValStubGenerator(JSGlobalData* globalData, Executab
// Load the character
jit.load16(BaseIndex(regT0, regT2, TimesTwo, 0), regT0);
- failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100)));
- jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
+ failures.append(jit.branch32(AboveOrEqual, regT0, TrustedImm32(0x100)));
+ jit.move(TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
- jit.move(Imm32(JSValue::CellTag), regT1); // We null check regT0 on return so this is safe
+ jit.move(TrustedImm32(JSValue::CellTag), regT1); // We null check regT0 on return so this is safe
jit.ret();
failures.link(&jit);
- jit.move(Imm32(0), regT0);
+ jit.move(TrustedImm32(0), regT0);
jit.ret();
LinkBuffer patchBuffer(&jit, pool, 0);
@@ -307,16 +307,16 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitLoad2(base, regT1, regT0, property, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
emitJumpSlowCaseIfNotJSCell(base, regT1);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
- addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
+ loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
+ addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
- addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)));
+ addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
emitStore(dst, regT1, regT0);
map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0);
@@ -333,7 +333,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+ Jump notString = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsStringVPtr));
emitNakedCall(m_globalData->getCTIStub(stringGetByValStubGenerator));
Jump failed = branchTestPtr(Zero, regT0);
emitStore(dst, regT1, regT0);
@@ -359,14 +359,14 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
emitLoad2(base, regT1, regT0, property, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
emitJumpSlowCaseIfNotJSCell(base, regT1);
- addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
- addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
+ addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
+ loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
- Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag));
+ Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
Label storeResult(this);
emitLoad(value, regT1, regT0);
@@ -375,10 +375,10 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
Jump end = jump();
empty.link(this);
- add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ add32(TrustedImm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
- add32(Imm32(1), regT2, regT0);
+ add32(TrustedImm32(1), regT2, regT0);
store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)));
jump().linkTo(storeResult, this);
@@ -429,7 +429,7 @@ void JIT::compileGetByIdHotPath()
m_propertyAccessInstructionIndex++;
DataLabelPtr structureToCompare;
- Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
addSlowCase(structureCheck);
ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure);
ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase);
@@ -472,7 +472,7 @@ void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<Sl
#endif
JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id);
stubCall.addArgument(regT1, regT0);
- stubCall.addArgument(ImmPtr(ident));
+ stubCall.addArgument(TrustedImmPtr(ident));
Call call = stubCall.call(dst);
END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
@@ -505,7 +505,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
// It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
DataLabelPtr structureToCompare;
- addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
+ addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure);
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0);
@@ -529,7 +529,7 @@ void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCase
JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct : cti_op_put_by_id);
stubCall.addArgument(regT1, regT0);
- stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+ stubCall.addArgument(TrustedImmPtr(&(m_codeBlock->identifier(ident))));
stubCall.addArgument(regT3, regT2);
Call call = stubCall.call();
@@ -579,10 +579,10 @@ void JIT::testPrototype(JSValue prototype, JumpList& failureCases)
// values. In the non X86_64 case, the generated code is slightly more efficient because it uses
// two less instructions and doesn't require any scratch registers.
#if CPU(X86_64)
- move(ImmPtr(prototype.asCell()->structure()), regT3);
- failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), regT3));
+ move(TrustedImmPtr(prototype.asCell()->structure()), regT3);
+ failureCases.append(branchPtr(NotEqual, AbsoluteAddress(prototype.asCell()->addressOfStructure()), regT3));
#else
- failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), ImmPtr(prototype.asCell()->structure())));
+ failureCases.append(branchPtr(NotEqual, AbsoluteAddress(prototype.asCell()->addressOfStructure()), TrustedImmPtr(prototype.asCell()->structure())));
#endif
}
@@ -591,8 +591,8 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
// It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack.
JumpList failureCases;
- failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
- failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
+ failureCases.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
+ failureCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(oldStructure)));
testPrototype(oldStructure->storedPrototype(), failureCases);
if (!direct) {
@@ -613,16 +613,16 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
stubCall.skipArgument(); // base
stubCall.skipArgument(); // ident
stubCall.skipArgument(); // value
- stubCall.addArgument(Imm32(oldStructure->propertyStorageCapacity()));
- stubCall.addArgument(Imm32(newStructure->propertyStorageCapacity()));
+ stubCall.addArgument(TrustedImm32(oldStructure->propertyStorageCapacity()));
+ stubCall.addArgument(TrustedImm32(newStructure->propertyStorageCapacity()));
stubCall.call(regT0);
restoreReturnAddressBeforeReturn(regT3);
}
- sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
- add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
- storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)));
+ sub32(TrustedImm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
+ add32(TrustedImm32(1), AbsoluteAddress(newStructure->addressOfCount()));
+ storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
#if CPU(MIPS)
// For MIPS, we don't add sizeof(void*) to the stack offset.
@@ -717,15 +717,15 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
// regT0 holds a JSCell*
// Check for array
- Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
+ Jump failureCases1 = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr));
// Checks out okay! - get the length from the storage
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+ loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
- Jump failureCases2 = branch32(Above, regT2, Imm32(INT_MAX));
+ Jump failureCases2 = branch32(Above, regT2, TrustedImm32(INT_MAX));
move(regT2, regT0);
- move(Imm32(JSValue::Int32Tag), regT1);
+ move(TrustedImm32(JSValue::Int32Tag), regT1);
Jump success = jump();
LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0);
@@ -762,12 +762,12 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure** prototypeStructureAddress = &(protoObject->m_structure);
+ Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
- move(ImmPtr(prototypeStructure), regT3);
+ move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
- Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), TrustedImmPtr(prototypeStructure));
#endif
bool needsStubLink = false;
// Checks out okay!
@@ -777,15 +777,15 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
@@ -834,15 +834,15 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(regT0, regT1, regT0, structure, cachedOffset);
@@ -889,12 +889,12 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure** prototypeStructureAddress = &(protoObject->m_structure);
+ Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
- move(ImmPtr(prototypeStructure), regT3);
+ move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
- Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), TrustedImmPtr(prototypeStructure));
#endif
bool needsStubLink = false;
@@ -904,15 +904,15 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
@@ -973,15 +973,15 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
@@ -1007,8 +1007,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
// Track the stub we have created so that it will be deleted later.
structure->ref();
- chain->ref();
- prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
+ prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, chain);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
@@ -1043,15 +1042,15 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
stubCall.addArgument(regT1);
stubCall.addArgument(regT0);
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else if (slot.cachedPropertyType() == PropertySlot::Custom) {
needsStubLink = true;
JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
- stubCall.addArgument(ImmPtr(protoObject));
- stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
- stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
- stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(protoObject));
+ stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+ stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));
+ stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));
stubCall.call();
} else
compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
@@ -1113,10 +1112,10 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
emitLoadPayload(iter, regT1);
// Test base's structure
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+ loadPtr(Address(regT2, JSCell::structureOffset()), regT0);
addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
load32(addressFor(i), regT3);
- sub32(Imm32(1), regT3);
+ sub32(TrustedImm32(1), regT3);
addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
compileGetDirectOffset(regT2, regT1, regT0, regT3);
diff --git a/Source/JavaScriptCore/jit/JITStubCall.h b/Source/JavaScriptCore/jit/JITStubCall.h
index 4478d06..a0341d6 100644
--- a/Source/JavaScriptCore/jit/JITStubCall.h
+++ b/Source/JavaScriptCore/jit/JITStubCall.h
@@ -99,13 +99,13 @@ namespace JSC {
m_stackIndex += stackIndexStep;
}
- void addArgument(JIT::Imm32 argument)
+ void addArgument(JIT::TrustedImm32 argument)
{
m_jit->poke(argument, m_stackIndex);
m_stackIndex += stackIndexStep;
}
- void addArgument(JIT::ImmPtr argument)
+ void addArgument(JIT::TrustedImmPtr argument)
{
m_jit->poke(argument, m_stackIndex);
m_stackIndex += stackIndexStep;
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 95bf52c..e52c7c8 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -40,6 +40,7 @@
#include "Debugger.h"
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
+#include "Global.h"
#include "JIT.h"
#include "JSActivation.h"
#include "JSArray.h"
@@ -679,6 +680,7 @@ __asm void ctiOpThrowNotCaught()
#endif
JITThunks::JITThunks(JSGlobalData* globalData)
+ : m_hostFunctionStubMap(new HostFunctionStubMap)
{
if (!globalData->executableAllocator.isValid())
return;
@@ -941,17 +943,17 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
#define CHECK_FOR_EXCEPTION() \
do { \
- if (UNLIKELY(stackFrame.globalData->exception.get())) \
+ if (UNLIKELY(stackFrame.globalData->exception)) \
VM_THROW_EXCEPTION(); \
} while (0)
#define CHECK_FOR_EXCEPTION_AT_END() \
do { \
- if (UNLIKELY(stackFrame.globalData->exception.get())) \
+ if (UNLIKELY(stackFrame.globalData->exception)) \
VM_THROW_EXCEPTION_AT_END(); \
} while (0)
#define CHECK_FOR_EXCEPTION_VOID() \
do { \
- if (UNLIKELY(stackFrame.globalData->exception.get())) { \
+ if (UNLIKELY(stackFrame.globalData->exception)) { \
VM_THROW_EXCEPTION_AT_END(); \
return; \
} \
@@ -976,7 +978,7 @@ static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame,
return exceptionHandler;
}
-#if CPU(ARM_THUMB2)
+#if CPU(ARM_THUMB2) && COMPILER(GCC)
#define DEFINE_STUB_FUNCTION(rtype, op) \
extern "C" { \
@@ -1072,7 +1074,7 @@ static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame,
); \
rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
-#elif CPU(ARM_TRADITIONAL) && COMPILER(RVCT)
+#elif (CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL)) && COMPILER(RVCT)
#define DEFINE_STUB_FUNCTION(rtype, op) rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
@@ -1085,7 +1087,7 @@ static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame,
RVCT(extern "C" #rtype# JITStubThunked_#op#(STUB_ARGS_DECLARATION);)
RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION))
RVCT({)
-RVCT( ARM)
+RVCT( PRESERVE8)
RVCT( IMPORT JITStubThunked_#op#)
RVCT( str lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
RVCT( bl JITStubThunked_#op#)
@@ -1172,7 +1174,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this)
Structure* structure;
JSValue proto = stackFrame.args[0].jsValue();
if (proto.isObject())
- structure = asObject(proto)->inheritorID();
+ structure = asObject(proto)->inheritorID(*stackFrame.globalData);
else
structure = constructor->scope()->globalObject->emptyObjectStructure();
JSValue result = constructEmptyObject(callFrame, structure);
@@ -1551,7 +1553,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
return JSValue::encode(result);
}
-static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSGlobalData& globalData, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
{
PolymorphicAccessStructureList* prototypeStructureList = 0;
listIndex = 1;
@@ -1563,7 +1565,7 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Str
stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
break;
case access_get_by_id_chain:
- prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
+ prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
stubInfo->stubRoutine = CodeLocationLabel();
stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
break;
@@ -1651,7 +1653,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
}
int listIndex;
- PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
@@ -1661,7 +1663,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
} else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
ASSERT(!baseValue.asCell()->structure()->isDictionary());
int listIndex;
- PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
StructureChain* protoChain = structure->prototypeChain(callFrame);
@@ -3067,7 +3069,15 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), stackFrame.args[0].regExp());
+ CallFrame* callFrame = stackFrame.callFrame;
+
+ RegExp* regExp = stackFrame.args[0].regExp();
+ if (!regExp->isValid()) {
+ stackFrame.globalData->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
+ VM_THROW_EXCEPTION();
+ }
+
+ return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
@@ -3462,7 +3472,7 @@ DEFINE_STUB_FUNCTION(void*, vm_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
JSGlobalData* globalData = stackFrame.globalData;
- ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception.get(), globalData->exceptionLocation);
+ ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -3483,22 +3493,27 @@ MacroAssemblerCodePtr JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerato
return entry.first->second;
}
-PassRefPtr<NativeExecutable> JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function)
+NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function)
{
- std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap.add(function, 0);
+ std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Global<NativeExecutable>(Global<NativeExecutable>::EmptyValue));
if (entry.second)
- entry.first->second = NativeExecutable::create(JIT::compileCTINativeCall(globalData, m_executablePool, function), function, ctiNativeConstruct(), callHostFunctionAsConstructor);
- return entry.first->second;
+ entry.first->second.set(*globalData, NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, m_executablePool, function), function, ctiNativeConstruct(), callHostFunctionAsConstructor));
+ return entry.first->second.get();
}
-PassRefPtr<NativeExecutable> JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator)
+NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator)
{
- std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap.add(function, 0);
+ std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Global<NativeExecutable>(Global<NativeExecutable>::EmptyValue));
if (entry.second) {
MacroAssemblerCodePtr code = globalData->canUseJIT() ? generator(globalData, m_executablePool.get()) : MacroAssemblerCodePtr();
- entry.first->second = NativeExecutable::create(code, function, ctiNativeConstruct(), callHostFunctionAsConstructor);
+ entry.first->second.set(*globalData, NativeExecutable::create(*globalData, code, function, ctiNativeConstruct(), callHostFunctionAsConstructor));
}
- return entry.first->second;
+ return entry.first->second.get();
+}
+
+void JITThunks::clearHostFunctionStubs()
+{
+ m_hostFunctionStubMap.clear();
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index 65f6a55..af6e13f 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -254,6 +254,8 @@ namespace JSC {
extern "C" void ctiOpThrowNotCaught();
extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*);
+ template <typename T> class Global;
+
class JITThunks {
public:
JITThunks(JSGlobalData*);
@@ -273,13 +275,16 @@ namespace JSC {
MacroAssemblerCodePtr ctiStub(JSGlobalData* globalData, ThunkGenerator generator);
- PassRefPtr<NativeExecutable> hostFunctionStub(JSGlobalData* globalData, NativeFunction func);
- PassRefPtr<NativeExecutable> hostFunctionStub(JSGlobalData* globalData, NativeFunction func, ThunkGenerator generator);
+ NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction);
+ NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction, ThunkGenerator);
+
+ void clearHostFunctionStubs();
+
private:
typedef HashMap<ThunkGenerator, MacroAssemblerCodePtr> CTIStubMap;
CTIStubMap m_ctiStubMap;
- typedef HashMap<NativeFunction, RefPtr<NativeExecutable> > HostFunctionStubMap;
- HostFunctionStubMap m_hostFunctionStubMap;
+ typedef HashMap<NativeFunction, Global<NativeExecutable> > HostFunctionStubMap;
+ OwnPtr<HostFunctionStubMap> m_hostFunctionStubMap;
RefPtr<ExecutablePool> m_executablePool;
TrampolineStructure m_trampolineStructure;
diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
index 6453bab..5d3f239 100644
--- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h
+++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
@@ -29,6 +29,7 @@
#include "JITCode.h"
#include "JITStubs.h"
#include "JSImmediate.h"
+#include "JSValue.h"
#include "MacroAssembler.h"
#include "RegisterFile.h"
#include <wtf/AlwaysInline.h>
@@ -157,13 +158,20 @@ namespace JSC {
#error "JIT not supported on this platform."
#endif
+#if USE(JSVALUE32_64)
+ // Can't just propogate JSValue::Int32Tag as visual studio doesn't like it
+ static const unsigned Int32Tag = 0xfffffffd;
+ COMPILE_ASSERT(Int32Tag == JSValue::Int32Tag, Int32Tag_out_of_sync);
+#else
+ static const unsigned Int32Tag = JSImmediate::TagTypeNumber >> 32;
+#endif
inline Jump emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload);
inline Jump emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst);
inline Jump emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch);
#if USE(JSVALUE32_64)
inline Jump emitJumpIfNotJSCell(unsigned virtualRegisterIndex);
- inline Address tagFor(unsigned index, RegisterID base = callFrameRegister);
+ inline Address tagFor(int index, RegisterID base = callFrameRegister);
#endif
#if USE(JSVALUE64)
@@ -172,8 +180,10 @@ namespace JSC {
void emitFastArithImmToInt(RegisterID reg);
#endif
- inline Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
- inline Address addressFor(unsigned index, RegisterID base = callFrameRegister);
+ inline Address payloadFor(int index, RegisterID base = callFrameRegister);
+ inline Address intPayloadFor(int index, RegisterID base = callFrameRegister);
+ inline Address intTagFor(int index, RegisterID base = callFrameRegister);
+ inline Address addressFor(int index, RegisterID base = callFrameRegister);
};
struct ThunkHelpers {
@@ -192,34 +202,44 @@ namespace JSC {
inline JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotJSCell(unsigned virtualRegisterIndex)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
- return branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::CellTag));
+ return branch32(NotEqual, tagFor(virtualRegisterIndex), TrustedImm32(JSValue::CellTag));
}
inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
loadPtr(payloadFor(virtualRegisterIndex), dst);
- return branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::Int32Tag));
+ return branch32(NotEqual, tagFor(static_cast<int>(virtualRegisterIndex)), TrustedImm32(JSValue::Int32Tag));
}
- inline JSInterfaceJIT::Address JSInterfaceJIT::tagFor(unsigned virtualRegisterIndex, RegisterID base)
+ inline JSInterfaceJIT::Address JSInterfaceJIT::tagFor(int virtualRegisterIndex, RegisterID base)
{
- ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
- return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.tag));
+ ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
+ return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.tag));
}
- inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(unsigned virtualRegisterIndex, RegisterID base)
+ inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(int virtualRegisterIndex, RegisterID base)
{
- ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
- return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
+ ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
+ return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
+ }
+
+ inline JSInterfaceJIT::Address JSInterfaceJIT::intPayloadFor(int virtualRegisterIndex, RegisterID base)
+ {
+ return payloadFor(virtualRegisterIndex, base);
+ }
+
+ inline JSInterfaceJIT::Address JSInterfaceJIT::intTagFor(int virtualRegisterIndex, RegisterID base)
+ {
+ return tagFor(virtualRegisterIndex, base);
}
inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
loadPtr(tagFor(virtualRegisterIndex), scratch);
- Jump isDouble = branch32(Below, scratch, Imm32(JSValue::LowestTag));
- Jump notInt = branch32(NotEqual, scratch, Imm32(JSValue::Int32Tag));
+ Jump isDouble = branch32(Below, scratch, TrustedImm32(JSValue::LowestTag));
+ Jump notInt = branch32(NotEqual, scratch, TrustedImm32(JSValue::Int32Tag));
loadPtr(payloadFor(virtualRegisterIndex), scratch);
convertInt32ToDouble(scratch, dst);
Jump done = jump();
@@ -274,17 +294,28 @@ namespace JSC {
#endif
#if USE(JSVALUE64)
- inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(unsigned virtualRegisterIndex, RegisterID base)
+ inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(int virtualRegisterIndex, RegisterID base)
{
- ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+ ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
return addressFor(virtualRegisterIndex, base);
}
+
+ inline JSInterfaceJIT::Address JSInterfaceJIT::intPayloadFor(int virtualRegisterIndex, RegisterID base)
+ {
+ ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
+ return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+ }
+ inline JSInterfaceJIT::Address JSInterfaceJIT::intTagFor(int virtualRegisterIndex, RegisterID base)
+ {
+ ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
+ return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
+ }
#endif
- inline JSInterfaceJIT::Address JSInterfaceJIT::addressFor(unsigned virtualRegisterIndex, RegisterID base)
+ inline JSInterfaceJIT::Address JSInterfaceJIT::addressFor(int virtualRegisterIndex, RegisterID base)
{
- ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
- return Address(base, (virtualRegisterIndex * sizeof(Register)));
+ ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
+ return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)));
}
}
diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
index 5c593d9..8c79692 100644
--- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
+++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
@@ -43,7 +43,7 @@ namespace JSC {
, m_pool(pool)
{
// Check that we have the expected number of arguments
- m_failures.append(branch32(NotEqual, Address(callFrameRegister, RegisterFile::ArgumentCount * (int)sizeof(Register)), Imm32(expectedArgCount + 1)));
+ m_failures.append(branch32(NotEqual, Address(callFrameRegister, RegisterFile::ArgumentCount * (int)sizeof(Register)), TrustedImm32(expectedArgCount + 1)));
}
void loadDoubleArgument(int argument, FPRegisterID dst, RegisterID scratch)
@@ -61,7 +61,7 @@ namespace JSC {
void loadJSStringArgument(int argument, RegisterID dst)
{
loadCellArgument(argument, dst);
- m_failures.append(branchPtr(NotEqual, Address(dst, 0), ImmPtr(m_globalData->jsStringVPtr)));
+ m_failures.append(branchPtr(NotEqual, Address(dst, 0), TrustedImmPtr(m_globalData->jsStringVPtr)));
m_failures.append(branchTest32(NonZero, Address(dst, OBJECT_OFFSETOF(JSString, m_fiberCount))));
}
@@ -87,7 +87,7 @@ namespace JSC {
{
if (src != regT0)
move(src, regT0);
- loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+ loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
@@ -101,7 +101,7 @@ namespace JSC {
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1);
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0);
#endif
- loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+ loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
@@ -110,7 +110,7 @@ namespace JSC {
if (src != regT0)
move(src, regT0);
tagReturnAsInt32();
- loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+ loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
@@ -119,7 +119,7 @@ namespace JSC {
if (src != regT0)
move(src, regT0);
tagReturnAsJSCell();
- loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+ loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
@@ -141,14 +141,14 @@ namespace JSC {
#if USE(JSVALUE64)
orPtr(tagTypeNumberRegister, regT0);
#else
- move(Imm32(JSValue::Int32Tag), regT1);
+ move(TrustedImm32(JSValue::Int32Tag), regT1);
#endif
}
void tagReturnAsJSCell()
{
#if USE(JSVALUE32_64)
- move(Imm32(JSValue::CellTag), regT1);
+ move(TrustedImm32(JSValue::CellTag), regT1);
#endif
}
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
index 9b40f12..1201696 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -57,8 +57,8 @@ static void stringCharLoad(SpecializedThunkJIT& jit)
static void charToString(SpecializedThunkJIT& jit, JSGlobalData* globalData, MacroAssembler::RegisterID src, MacroAssembler::RegisterID dst, MacroAssembler::RegisterID scratch)
{
- jit.appendFailure(jit.branch32(MacroAssembler::AboveOrEqual, src, MacroAssembler::Imm32(0x100)));
- jit.move(MacroAssembler::ImmPtr(globalData->smallStrings.singleCharacterStrings()), scratch);
+ jit.appendFailure(jit.branch32(MacroAssembler::AboveOrEqual, src, MacroAssembler::TrustedImm32(0x100)));
+ jit.move(MacroAssembler::TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), scratch);
jit.loadPtr(MacroAssembler::BaseIndex(scratch, src, MacroAssembler::ScalePtr, 0), dst);
jit.appendFailure(jit.branchTestPtr(MacroAssembler::Zero, dst));
}
@@ -115,16 +115,16 @@ MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
MacroAssembler::Jump nonIntExponent;
jit.loadInt32Argument(1, SpecializedThunkJIT::regT0, nonIntExponent);
- jit.appendFailure(jit.branch32(MacroAssembler::LessThan, SpecializedThunkJIT::regT0, MacroAssembler::Imm32(0)));
+ jit.appendFailure(jit.branch32(MacroAssembler::LessThan, SpecializedThunkJIT::regT0, MacroAssembler::TrustedImm32(0)));
MacroAssembler::Jump exponentIsZero = jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0);
MacroAssembler::Label startLoop(jit.label());
- MacroAssembler::Jump exponentIsEven = jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0, MacroAssembler::Imm32(1));
+ MacroAssembler::Jump exponentIsEven = jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0, MacroAssembler::TrustedImm32(1));
jit.mulDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
exponentIsEven.link(&jit);
jit.mulDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
- jit.rshift32(MacroAssembler::Imm32(1), SpecializedThunkJIT::regT0);
+ jit.rshift32(MacroAssembler::TrustedImm32(1), SpecializedThunkJIT::regT0);
jit.branchTest32(MacroAssembler::NonZero, SpecializedThunkJIT::regT0).linkTo(startLoop, &jit);
exponentIsZero.link(&jit);
diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp
index 1873659..8ccb039 100644
--- a/Source/JavaScriptCore/jsc.cpp
+++ b/Source/JavaScriptCore/jsc.cpp
@@ -141,14 +141,14 @@ long StopWatch::getElapsedMS()
class GlobalObject : public JSGlobalObject {
public:
- GlobalObject(const Vector<UString>& arguments);
+ GlobalObject(JSGlobalData&, const Vector<UString>& arguments);
virtual UString className() const { return "global"; }
};
COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
-GlobalObject::GlobalObject(const Vector<UString>& arguments)
- : JSGlobalObject()
+GlobalObject::GlobalObject(JSGlobalData& globalData, const Vector<UString>& arguments)
+ : JSGlobalObject(globalData)
{
putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
@@ -212,7 +212,7 @@ EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
if (!fillBufferWithContentsOfFile(fileName, script))
return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
- GlobalObject* globalObject = new (&exec->globalData()) GlobalObject(Vector<UString>());
+ GlobalObject* globalObject = new (&exec->globalData()) GlobalObject(exec->globalData(), Vector<UString>());
StopWatch stopWatch;
stopWatch.start();
@@ -536,7 +536,7 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData)
Options options;
parseArguments(argc, argv, options, globalData);
- GlobalObject* globalObject = new (globalData) GlobalObject(options.arguments);
+ GlobalObject* globalObject = new (globalData) GlobalObject(*globalData, options.arguments);
bool success = runWithScripts(globalObject, options.scripts, options.dump);
if (options.interactive && success)
runInteractive(globalObject);
diff --git a/Source/JavaScriptCore/jsc.pro b/Source/JavaScriptCore/jsc.pro
index a550c48..21ffeea 100644
--- a/Source/JavaScriptCore/jsc.pro
+++ b/Source/JavaScriptCore/jsc.pro
@@ -27,6 +27,10 @@ mac {
LIBS_PRIVATE += -framework AppKit
}
+win* {
+ LIBS += -ladvapi32
+}
+
wince* {
LIBS += mmtimer.lib
}
diff --git a/Source/JavaScriptCore/profiler/CallIdentifier.h b/Source/JavaScriptCore/profiler/CallIdentifier.h
index a9827c0..1ba5ec6 100644
--- a/Source/JavaScriptCore/profiler/CallIdentifier.h
+++ b/Source/JavaScriptCore/profiler/CallIdentifier.h
@@ -63,7 +63,7 @@ namespace JSC {
key.m_url.impl()->hash(),
key.m_lineNumber
};
- return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
}
static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
index 68d1733..5db38bc 100644
--- a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -40,19 +40,19 @@ namespace JSC {
static const char* NonJSExecution = "(idle)";
-PassRefPtr<ProfileGenerator> ProfileGenerator::create(const UString& title, ExecState* originatingExec, unsigned uid)
+PassRefPtr<ProfileGenerator> ProfileGenerator::create(ExecState* exec, const UString& title, unsigned uid)
{
- return adoptRef(new ProfileGenerator(title, originatingExec, uid));
+ return adoptRef(new ProfileGenerator(exec, title, uid));
}
-ProfileGenerator::ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid)
- : m_originatingGlobalExec(originatingExec ? originatingExec->lexicalGlobalObject()->globalExec() : 0)
- , m_profileGroup(originatingExec ? originatingExec->lexicalGlobalObject()->profileGroup() : 0)
+ProfileGenerator::ProfileGenerator(ExecState* exec, const UString& title, unsigned uid)
+ : m_origin(exec ? exec->lexicalGlobalObject() : 0)
+ , m_profileGroup(exec ? exec->lexicalGlobalObject()->profileGroup() : 0)
{
m_profile = Profile::create(title, uid);
m_currentNode = m_head = m_profile->head();
- if (originatingExec)
- addParentForConsoleStart(originatingExec);
+ if (exec)
+ addParentForConsoleStart(exec);
}
void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
@@ -80,7 +80,7 @@ void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentif
JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber);
}
- if (!m_originatingGlobalExec)
+ if (!m_origin)
return;
ASSERT(m_currentNode);
@@ -95,7 +95,7 @@ void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifi
JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber);
}
- if (!m_originatingGlobalExec)
+ if (!m_origin)
return;
ASSERT(m_currentNode);
diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.h b/Source/JavaScriptCore/profiler/ProfileGenerator.h
index cbed73b..8c8b817 100644
--- a/Source/JavaScriptCore/profiler/ProfileGenerator.h
+++ b/Source/JavaScriptCore/profiler/ProfileGenerator.h
@@ -34,6 +34,7 @@
namespace JSC {
class ExecState;
+ class JSGlobalObject;
class Profile;
class ProfileNode;
class UString;
@@ -41,12 +42,12 @@ namespace JSC {
class ProfileGenerator : public RefCounted<ProfileGenerator> {
public:
- static PassRefPtr<ProfileGenerator> create(const UString& title, ExecState* originatingExec, unsigned uid);
+ static PassRefPtr<ProfileGenerator> create(ExecState*, const UString& title, unsigned uid);
// Members
const UString& title() const;
PassRefPtr<Profile> profile() const { return m_profile; }
- ExecState* originatingGlobalExec() const { return m_originatingGlobalExec; }
+ JSGlobalObject* origin() const { return m_origin; }
unsigned profileGroup() const { return m_profileGroup; }
// Collecting
@@ -61,14 +62,14 @@ namespace JSC {
typedef void (ProfileGenerator::*ProfileFunction)(ExecState* callerOrHandlerCallFrame, const CallIdentifier& callIdentifier);
private:
- ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid);
+ ProfileGenerator(ExecState*, const UString& title, unsigned uid);
void addParentForConsoleStart(ExecState*);
void removeProfileStart();
void removeProfileEnd();
RefPtr<Profile> m_profile;
- ExecState* m_originatingGlobalExec;
+ JSGlobalObject* m_origin;
unsigned m_profileGroup;
RefPtr<ProfileNode> m_head;
RefPtr<ProfileNode> m_currentNode;
diff --git a/Source/JavaScriptCore/profiler/Profiler.cpp b/Source/JavaScriptCore/profiler/Profiler.cpp
index 301dc0c..bcaaaac 100644
--- a/Source/JavaScriptCore/profiler/Profiler.cpp
+++ b/Source/JavaScriptCore/profiler/Profiler.cpp
@@ -66,25 +66,25 @@ void Profiler::startProfiling(ExecState* exec, const UString& title)
// Check if we currently have a Profile for this global ExecState and title.
// If so return early and don't create a new Profile.
- ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0;
+ JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
for (size_t i = 0; i < m_currentProfiles.size(); ++i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
- if (profileGenerator->originatingGlobalExec() == globalExec && profileGenerator->title() == title)
+ if (profileGenerator->origin() == origin && profileGenerator->title() == title)
return;
}
s_sharedEnabledProfilerReference = this;
- RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(title, exec, ++ProfilesUID);
+ RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
m_currentProfiles.append(profileGenerator);
}
PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const UString& title)
{
- ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0;
+ JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
- if (profileGenerator->originatingGlobalExec() == globalExec && (title.isNull() || profileGenerator->title() == title)) {
+ if (profileGenerator->origin() == origin && (title.isNull() || profileGenerator->title() == title)) {
profileGenerator->stopProfiling();
RefPtr<Profile> returnProfile = profileGenerator->profile();
@@ -99,10 +99,23 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const UString& titl
return 0;
}
+void Profiler::stopProfiling(JSGlobalObject* origin)
+{
+ for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
+ ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
+ if (profileGenerator->origin() == origin) {
+ profileGenerator->stopProfiling();
+ m_currentProfiles.remove(i);
+ if (!m_currentProfiles.size())
+ s_sharedEnabledProfilerReference = 0;
+ }
+ }
+}
+
static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFrame, const Vector<RefPtr<ProfileGenerator> >& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup)
{
for (size_t i = 0; i < profiles.size(); ++i) {
- if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->originatingGlobalExec())
+ if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->origin())
(profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier);
}
}
diff --git a/Source/JavaScriptCore/profiler/Profiler.h b/Source/JavaScriptCore/profiler/Profiler.h
index f88746d..86366c1 100644
--- a/Source/JavaScriptCore/profiler/Profiler.h
+++ b/Source/JavaScriptCore/profiler/Profiler.h
@@ -38,6 +38,7 @@ namespace JSC {
class ExecState;
class JSGlobalData;
+ class JSGlobalObject;
class JSObject;
class JSValue;
class ProfileGenerator;
@@ -57,6 +58,7 @@ namespace JSC {
void startProfiling(ExecState*, const UString& title);
PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title);
+ void stopProfiling(JSGlobalObject*);
void willExecute(ExecState* callerCallFrame, JSValue function);
void willExecute(ExecState* callerCallFrame, const UString& sourceURL, int startingLineNumber);
diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp
index 25a8916..f46d108 100644
--- a/Source/JavaScriptCore/runtime/ArgList.cpp
+++ b/Source/JavaScriptCore/runtime/ArgList.cpp
@@ -23,6 +23,7 @@
#include "JSValue.h"
#include "JSCell.h"
+#include "JSObject.h"
#include "ScopeChain.h"
using std::min;
@@ -38,12 +39,12 @@ void ArgList::getSlice(int startIndex, ArgList& result) const
result = ArgList(m_args + startIndex, m_argCount - startIndex);
}
-void MarkedArgumentBuffer::markLists(MarkStack& markStack, ListSet& markSet)
+void MarkedArgumentBuffer::markLists(HeapRootMarker& heapRootMarker, ListSet& markSet)
{
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
MarkedArgumentBuffer* list = *it;
- markStack.deprecatedAppendValues(list->m_buffer, list->m_size);
+ heapRootMarker.mark(reinterpret_cast<JSValue*>(list->m_buffer), list->m_size);
}
}
@@ -55,8 +56,8 @@ void MarkedArgumentBuffer::slowAppend(JSValue v)
// our Vector's inline capacity, though, our values move to the
// heap, where they do need explicit marking.
if (!m_markSet) {
- // We can only register for explicit marking once we know which heap
- // is the current one, i.e., when a non-immediate value is appended.
+ // FIXME: Even if v is not a JSCell*, if previous values in the buffer
+ // are, then they won't be marked!
if (Heap* heap = Heap::heap(v)) {
ListSet& markSet = heap->markListSet();
markSet.add(this);
diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h
index 5564d5b..a794a04 100644
--- a/Source/JavaScriptCore/runtime/ArgList.h
+++ b/Source/JavaScriptCore/runtime/ArgList.h
@@ -141,7 +141,7 @@ namespace JSC {
const_iterator begin() const { return m_buffer; }
const_iterator end() const { return m_buffer + m_size; }
- static void markLists(MarkStack&, ListSet&);
+ static void markLists(HeapRootMarker&, ListSet&);
private:
void slowAppend(JSValue);
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index 007e0f1..950bb4e 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -92,9 +92,9 @@ namespace JSC {
d->registers = &activation->registerAt(0);
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
@@ -237,19 +237,17 @@ namespace JSC {
// This JSActivation function is defined here so it can get at Arguments::setRegisters.
inline void JSActivation::copyRegisters(JSGlobalData& globalData)
{
- ASSERT(!d()->registerArray);
+ ASSERT(!m_registerArray);
- size_t numParametersMinusThis = d()->functionExecutable->parameterCount();
- size_t numVars = d()->functionExecutable->capturedVariableCount();
- size_t numLocals = numVars + numParametersMinusThis;
+ size_t numLocals = m_numCapturedVars + m_numParametersMinusThis;
if (!numLocals)
return;
- int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
+ int registerOffset = m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, d()->registers - registerOffset, registerArraySize);
+ OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, m_registers - registerOffset, registerArraySize);
WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset;
setRegisters(registers, registerArray.release());
}
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
index af2afc6..e0f4b23 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -52,16 +52,18 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, JSGlobalObject* globalObject
static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
{
+ JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
+
// a single numeric argument denotes the array size (!)
if (args.size() == 1 && args.at(0).isNumber()) {
uint32_t n = args.at(0).toUInt32(exec);
if (n != args.at(0).toNumber(exec))
return throwError(exec, createRangeError(exec, "Array size is not a small enough positive integer."));
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n, CreateInitialized);
+ return new (exec) JSArray(globalObject->arrayStructure(), n, CreateInitialized);
}
// otherwise the array is constructed with the arguments in it
- return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), args);
+ return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), args);
}
static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index 488effd..fdbcd95 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -165,16 +165,20 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
bool isRealArray = isJSArray(&exec->globalData(), thisValue);
if (!isRealArray && !thisValue.inherits(&JSArray::s_info))
return throwVMTypeError(exec);
JSArray* thisObj = asArray(thisValue);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
return earlyReturnValue;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
#if OS(SYMBIAN)
// Symbian has very limited stack size available.
@@ -225,16 +229,20 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (!thisValue.inherits(&JSArray::s_info))
return throwVMTypeError(exec);
JSObject* thisObj = asArray(thisValue);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
return earlyReturnValue;
JSStringBuilder strBuffer;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -260,6 +268,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
@@ -271,7 +282,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
if (!exec->argument(0).isUndefined())
separator = exec->argument(0).toString(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (isJSArray(&exec->globalData(), thisObj)) {
JSArray* array = asArray(thisObj);
@@ -355,12 +365,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (isJSArray(&exec->globalData(), thisValue))
return JSValue::encode(asArray(thisValue)->pop());
JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue result;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ JSValue result;
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
result = jsUndefined();
@@ -375,6 +389,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (isJSArray(&exec->globalData(), thisValue) && exec->argumentCount() == 1) {
JSArray* array = asArray(thisValue);
array->push(exec, exec->argument(0));
@@ -383,6 +398,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
JSObject* thisObj = thisValue.toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
for (unsigned n = 0; n < exec->argumentCount(); n++)
thisObj->put(exec, length + n, exec->argument(n));
length += exec->argumentCount();
@@ -394,8 +412,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- unsigned middle = length / 2;
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ unsigned middle = length / 2;
for (unsigned k = 0; k < middle; k++) {
unsigned lk1 = length - k - 1;
JSValue obj2 = getProperty(exec, thisObj, lk1);
@@ -420,6 +440,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
JSValue result;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
result = jsUndefined();
@@ -451,6 +474,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
JSValue result = resObj;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
@@ -466,6 +492,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (!length || exec->hadException())
+ return JSValue::encode(thisObj);
JSValue function = exec->argument(0);
CallData callData;
@@ -481,11 +510,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
return JSValue::encode(thisObj);
}
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-
- if (!length)
- return JSValue::encode(thisObj);
-
// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
@@ -523,14 +547,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
{
- JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
// 15.4.4.12
+ JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
if (!exec->argumentCount())
return JSValue::encode(constructEmptyArray(exec));
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned deleteCount = length - begin;
@@ -589,10 +615,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
{
- JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
// 15.4.4.13
+
+ JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
unsigned nrArgs = exec->argumentCount();
if ((nrArgs) && (length)) {
if (isJSArray(&exec->globalData(), thisObj))
@@ -616,6 +645,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -627,7 +659,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -674,6 +705,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -683,8 +717,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-
JSArray* resultArray = constructEmptyArray(exec, length);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
@@ -731,6 +763,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -742,7 +777,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
JSValue result = jsBoolean(true);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -787,6 +821,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -796,7 +833,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -832,6 +868,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -843,7 +882,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
JSValue result = jsBoolean(false);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -885,7 +923,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue function = exec->argument(0);
CallData callData;
CallType callType = getCallData(function, callData);
@@ -894,9 +935,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
unsigned i = 0;
JSValue rv;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && exec->argumentCount() == 1)
return throwVMTypeError(exec);
+
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
@@ -955,7 +996,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue function = exec->argument(0);
CallData callData;
CallType callType = getCallData(function, callData);
@@ -964,9 +1008,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
unsigned i = 0;
JSValue rv;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && exec->argumentCount() == 1)
return throwVMTypeError(exec);
+
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
@@ -1023,13 +1067,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
{
- // JavaScript 1.5 Extension by Mozilla
- // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
+ // 15.4.4.14
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
JSValue searchElement = exec->argument(0);
for (; index < length; ++index) {
JSValue e = getProperty(exec, thisObj, index);
@@ -1044,10 +1088,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec)
{
- // JavaScript 1.6 Extension by Mozilla
- // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
+ // 15.4.4.15
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length)
return JSValue::encode(jsNumber(-1));
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h
index e41d8ca..96641bd 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h
@@ -35,9 +35,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index 21ef5bb..e5b0f3d 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -40,7 +40,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, JSGlobalObject* globalOb
// ECMA 15.6.2
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
- BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), exec->lexicalGlobalObject()->booleanObjectStructure());
+ BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure());
obj->setInternalValue(exec->globalData(), jsBoolean(args.at(0).toBoolean(exec)));
return obj;
}
@@ -69,9 +69,9 @@ CallType BooleanConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue immediateBooleanValue)
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSGlobalObject* globalObject, JSValue immediateBooleanValue)
{
- BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), exec->lexicalGlobalObject()->booleanObjectStructure());
+ BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), globalObject->booleanObjectStructure());
obj->setInternalValue(exec->globalData(), immediateBooleanValue);
return obj;
}
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.h b/Source/JavaScriptCore/runtime/BooleanConstructor.h
index 0f3efa7..2550b3b 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.h
@@ -36,7 +36,7 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue);
+ JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSGlobalObject*, JSValue);
JSObject* constructBoolean(ExecState*, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp
index 16c4669..2945c0e 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp
@@ -27,8 +27,8 @@ ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0 };
-BooleanObject::BooleanObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(globalData, structure)
+BooleanObject::BooleanObject(JSGlobalData&, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h
index e2af0c2..ef2d403 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.h
+++ b/Source/JavaScriptCore/runtime/BooleanObject.h
@@ -31,9 +31,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
};
diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp
index 83d8bd8..ac19705 100644
--- a/Source/JavaScriptCore/runtime/Completion.cpp
+++ b/Source/JavaScriptCore/runtime/Completion.cpp
@@ -39,7 +39,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
- RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
+ ProgramExecutable* program = ProgramExecutable::create(exec, source);
JSObject* error = program->checkSyntax(exec);
if (error)
return Completion(Throw, error);
@@ -52,14 +52,16 @@ Completion evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCod
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
- RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
- JSObject* error = program->compile(exec, scopeChain);
- if (error)
- return Completion(Throw, error);
+ ProgramExecutable* program = ProgramExecutable::create(exec, source);
+ if (!program) {
+ JSValue exception = exec->globalData().exception;
+ exec->globalData().exception = JSValue();
+ return Completion(Throw, exception);
+ }
JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
- JSValue result = exec->interpreter()->execute(program.get(), exec, scopeChain, thisObj);
+ JSValue result = exec->interpreter()->execute(program, exec, scopeChain, thisObj);
if (exec->hadException()) {
JSValue exception = exec->exception();
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.cpp b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
index bc8bd6d..8872023 100644
--- a/Source/JavaScriptCore/runtime/ConservativeSet.cpp
+++ b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
@@ -33,33 +33,26 @@ inline bool isPointerAligned(void* p)
return !((intptr_t)(p) & (sizeof(char*) - 1));
}
-void ConservativeSet::grow()
+void ConservativeRoots::grow()
{
size_t newCapacity = m_capacity == inlineCapacity ? nonInlineCapacity : m_capacity * 2;
- DeprecatedPtr<JSCell>* newSet = static_cast<DeprecatedPtr<JSCell>*>(OSAllocator::reserveAndCommit(newCapacity * sizeof(JSCell*)));
- memcpy(newSet, m_set, m_size * sizeof(JSCell*));
- if (m_set != m_inlineSet)
- OSAllocator::decommitAndRelease(m_set, m_capacity * sizeof(JSCell*));
+ JSCell** newRoots = static_cast<JSCell**>(OSAllocator::reserveAndCommit(newCapacity * sizeof(JSCell*)));
+ memcpy(newRoots, m_roots, m_size * sizeof(JSCell*));
+ if (m_roots != m_inlineRoots)
+ OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*));
m_capacity = newCapacity;
- m_set = newSet;
+ m_roots = newRoots;
}
-void ConservativeSet::add(void* begin, void* end)
+void ConservativeRoots::add(void* begin, void* end)
{
ASSERT(begin <= end);
ASSERT((static_cast<char*>(end) - static_cast<char*>(begin)) < 0x1000000);
ASSERT(isPointerAligned(begin));
ASSERT(isPointerAligned(end));
- for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it) {
- if (!m_heap->contains(*it))
- continue;
-
- if (m_size == m_capacity)
- grow();
-
- m_set[m_size++] = reinterpret_cast<JSCell*>(*it);
- }
+ for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it)
+ add(*it);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.h b/Source/JavaScriptCore/runtime/ConservativeSet.h
index e7c2c4a..d078606 100644
--- a/Source/JavaScriptCore/runtime/ConservativeSet.h
+++ b/Source/JavaScriptCore/runtime/ConservativeSet.h
@@ -23,24 +23,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ConservativeSet_h
-#define ConservativeSet_h
+#ifndef ConservativeRoots_h
+#define ConservativeRoots_h
#include "Heap.h"
-#include "MarkStack.h"
+#include <wtf/OSAllocator.h>
#include <wtf/Vector.h>
namespace JSC {
class JSCell;
+class Heap;
-class ConservativeSet {
+// May contain duplicates.
+
+class ConservativeRoots {
public:
- ConservativeSet(Heap*);
- ~ConservativeSet();
+ ConservativeRoots(Heap*);
+ ~ConservativeRoots();
+ void add(void*);
void add(void* begin, void* end);
- void mark(MarkStack&);
+
+ size_t size();
+ JSCell** roots();
private:
static const size_t inlineCapacity = 128;
@@ -49,32 +55,47 @@ private:
void grow();
Heap* m_heap;
- DeprecatedPtr<JSCell>* m_set;
+ JSCell** m_roots;
size_t m_size;
size_t m_capacity;
- DeprecatedPtr<JSCell> m_inlineSet[inlineCapacity];
+ JSCell* m_inlineRoots[inlineCapacity];
};
-inline ConservativeSet::ConservativeSet(Heap* heap)
+inline ConservativeRoots::ConservativeRoots(Heap* heap)
: m_heap(heap)
- , m_set(m_inlineSet)
+ , m_roots(m_inlineRoots)
, m_size(0)
, m_capacity(inlineCapacity)
{
}
-inline ConservativeSet::~ConservativeSet()
+inline ConservativeRoots::~ConservativeRoots()
+{
+ if (m_roots != m_inlineRoots)
+ OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*));
+}
+
+inline void ConservativeRoots::add(void* p)
+{
+ if (!m_heap->contains(p))
+ return;
+
+ if (m_size == m_capacity)
+ grow();
+
+ m_roots[m_size++] = reinterpret_cast<JSCell*>(p);
+}
+
+inline size_t ConservativeRoots::size()
{
- if (m_set != m_inlineSet)
- OSAllocator::decommitAndRelease(m_set, m_capacity * sizeof(DeprecatedPtr<JSCell>*));
+ return m_size;
}
-inline void ConservativeSet::mark(MarkStack& markStack)
+inline JSCell** ConservativeRoots::roots()
{
- for (size_t i = 0; i < m_size; ++i)
- markStack.append(&m_set[i]);
+ return m_roots;
}
} // namespace JSC
-#endif // ConservativeSet_h
+#endif // ConservativeRoots_h
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index efaeb0f..0a06148 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -70,7 +70,7 @@ DateConstructor::DateConstructor(ExecState* exec, JSGlobalObject* globalObject,
}
// ECMA 15.9.3
-JSObject* constructDate(ExecState* exec, const ArgList& args)
+JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
int numArgs = args.size();
@@ -121,13 +121,13 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
}
}
- return new (exec) DateInstance(exec, value);
+ return new (exec) DateInstance(exec, globalObject->dateStructure(), value);
}
static EncodedJSValue JSC_HOST_CALL constructWithDateConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructDate(exec, args));
+ return JSValue::encode(constructDate(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType DateConstructor::getConstructData(ConstructData& constructData)
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.h b/Source/JavaScriptCore/runtime/DateConstructor.h
index 2adcd08..bd529f1 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.h
+++ b/Source/JavaScriptCore/runtime/DateConstructor.h
@@ -36,7 +36,7 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructDate(ExecState*, const ArgList&);
+ JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/DateConversion.cpp b/Source/JavaScriptCore/runtime/DateConversion.cpp
index 597f1e9..1418876 100644
--- a/Source/JavaScriptCore/runtime/DateConversion.cpp
+++ b/Source/JavaScriptCore/runtime/DateConversion.cpp
@@ -44,6 +44,7 @@
#include "DateConversion.h"
#include "CallFrame.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#include "UString.h"
#include <wtf/DateMath.h>
diff --git a/Source/JavaScriptCore/runtime/DateInstance.cpp b/Source/JavaScriptCore/runtime/DateInstance.cpp
index 95d5dc2..74adda4 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.cpp
+++ b/Source/JavaScriptCore/runtime/DateInstance.cpp
@@ -35,21 +35,14 @@ namespace JSC {
const ClassInfo DateInstance::s_info = {"Date", &JSWrapperObject::s_info, 0, 0};
DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsNaN());
}
DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure, double time)
- : JSWrapperObject(exec->globalData(), structure)
-{
- ASSERT(inherits(&s_info));
- setInternalValue(exec->globalData(), jsNumber(timeClip(time)));
-}
-
-DateInstance::DateInstance(ExecState* exec, double time)
- : JSWrapperObject(exec->globalData(), exec->lexicalGlobalObject()->dateStructure())
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsNumber(timeClip(time)));
diff --git a/Source/JavaScriptCore/runtime/DateInstance.h b/Source/JavaScriptCore/runtime/DateInstance.h
index 627b9e7..d0dcf0b 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.h
+++ b/Source/JavaScriptCore/runtime/DateInstance.h
@@ -31,7 +31,6 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
public:
- DateInstance(ExecState*, double);
DateInstance(ExecState*, NonNullPassRefPtr<Structure>, double);
explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>);
@@ -53,14 +52,11 @@ namespace JSC {
return calculateGregorianDateTimeUTC(exec);
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- protected:
- static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags;
-
private:
const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.h b/Source/JavaScriptCore/runtime/DatePrototype.h
index dca90e3..0ebbedc 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.h
+++ b/Source/JavaScriptCore/runtime/DatePrototype.h
@@ -36,14 +36,16 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
+ COMPILE_ASSERT(!DateInstance::AnonymousSlotCount, DatePrototype_stomps_on_your_anonymous_slot);
+ static const unsigned AnonymousSlotCount = 1;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
index 2e53b95..7f4f82c 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -42,7 +42,7 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, JSGlobalObject* globalObject
static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState* exec)
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
- Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
+ Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
@@ -55,7 +55,7 @@ ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec)
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
- Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
+ Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h
index c1beef7..82dbf0f 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.h
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.h
@@ -29,9 +29,9 @@ namespace JSC {
public:
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static ErrorInstance* create(JSGlobalData*, NonNullPassRefPtr<Structure>, const UString&);
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 607a2c2..a059ed2 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -33,6 +33,11 @@
#include "UStringBuilder.h"
#include "Vector.h"
+#if ENABLE(DFG_JIT)
+#include "DFGByteCodeParser.h"
+#include "DFGJITCompiler.h"
+#endif
+
namespace JSC {
NativeExecutable::~NativeExecutable()
@@ -44,7 +49,7 @@ VPtrHackExecutable::~VPtrHackExecutable()
}
EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
- : ScriptExecutable(exec, source, inStrictContext)
+ : ScriptExecutable(exec->globalData().evalExecutableStructure.get(), exec, source, inStrictContext)
{
}
@@ -53,7 +58,7 @@ EvalExecutable::~EvalExecutable()
}
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source, false)
+ : ScriptExecutable(exec->globalData().programExecutableStructure.get(), exec, source, false)
{
}
@@ -62,7 +67,7 @@ ProgramExecutable::~ProgramExecutable()
}
FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
- : ScriptExecutable(globalData, source, inStrictContext)
+ : ScriptExecutable(globalData->functionExecutableStructure.get(), globalData, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -74,7 +79,7 @@ FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifie
}
FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
- : ScriptExecutable(exec, source, inStrictContext)
+ : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -85,9 +90,6 @@ FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name,
m_lastLine = lastLine;
}
-FunctionExecutable::~FunctionExecutable()
-{
-}
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
@@ -127,6 +129,13 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
return 0;
}
+void EvalExecutable::markChildren(MarkStack& markStack)
+{
+ ScriptExecutable::markChildren(markStack);
+ if (m_evalCodeBlock)
+ m_evalCodeBlock->markAggregate(markStack);
+}
+
JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
{
JSObject* exception = 0;
@@ -178,6 +187,41 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
return 0;
}
+#if ENABLE(JIT)
+static bool tryDFGCompile(JSGlobalData* globalData, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck)
+{
+#if ENABLE(DFG_JIT)
+#if ENABLE(DFG_JIT_RESTRICTIONS)
+ // FIXME: No flow control yet supported, don't bother scanning the bytecode if there are any jump targets.
+ // FIXME: temporarily disable property accesses until we fix regressions.
+ if (codeBlock->numberOfJumpTargets() || codeBlock->numberOfStructureStubInfos())
+ return false;
+#endif
+
+ DFG::Graph dfg;
+ if (!parse(dfg, globalData, codeBlock))
+ return false;
+
+ DFG::JITCompiler dataFlowJIT(globalData, dfg, codeBlock);
+ dataFlowJIT.compileFunction(jitCode, jitCodeWithArityCheck);
+ return true;
+#else
+ UNUSED_PARAM(globalData);
+ UNUSED_PARAM(codeBlock);
+ UNUSED_PARAM(jitCode);
+ UNUSED_PARAM(jitCodeWithArityCheck);
+ return false;
+#endif
+}
+#endif
+
+void ProgramExecutable::markChildren(MarkStack& markStack)
+{
+ ScriptExecutable::markChildren(markStack);
+ if (m_programCodeBlock)
+ m_programCodeBlock->markAggregate(markStack);
+}
+
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
JSObject* exception = 0;
@@ -212,7 +256,10 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
#if ENABLE(JIT)
if (exec->globalData().canUseJIT()) {
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
+ bool dfgCompiled = tryDFGCompile(&exec->globalData(), m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
+ if (!dfgCompiled)
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
+
#if !ENABLE(OPCODE_SAMPLING)
if (!BytecodeGenerator::dumpsGeneratedCode())
m_codeBlockForCall->discardBytecode();
@@ -268,8 +315,9 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
return 0;
}
-void FunctionExecutable::markAggregate(MarkStack& markStack)
+void FunctionExecutable::markChildren(MarkStack& markStack)
{
+ ScriptExecutable::markChildren(markStack);
if (m_codeBlockForCall)
m_codeBlockForCall->markAggregate(markStack);
if (m_codeBlockForConstruct)
@@ -288,7 +336,7 @@ void FunctionExecutable::discardCode()
#endif
}
-PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
+FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception);
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index b2565a0..f15df07 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -44,7 +44,7 @@ namespace JSC {
struct ExceptionInfo;
- class ExecutableBase : public RefCounted<ExecutableBase> {
+ class ExecutableBase : public JSCell {
friend class JIT;
protected:
@@ -52,21 +52,23 @@ namespace JSC {
static const int NUM_PARAMETERS_NOT_COMPILED = -1;
public:
- ExecutableBase(int numParameters)
- : m_numParametersForCall(numParameters)
+ ExecutableBase(Structure* structure, int numParameters)
+ : JSCell(structure)
+ , m_numParametersForCall(numParameters)
, m_numParametersForConstruct(numParameters)
{
}
- virtual ~ExecutableBase() {}
-
bool isHostFunction() const
{
ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
}
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+
protected:
+ static const unsigned StructureFlags = 0;
int m_numParametersForCall;
int m_numParametersForConstruct;
@@ -96,16 +98,16 @@ namespace JSC {
friend class JIT;
public:
#if ENABLE(JIT)
- static PassRefPtr<NativeExecutable> create(MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor)
+ static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor)
{
if (!callThunk)
- return adoptRef(new NativeExecutable(JITCode(), function, JITCode(), constructor));
- return adoptRef(new NativeExecutable(JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor));
+ return new (&globalData) NativeExecutable(globalData, JITCode(), function, JITCode(), constructor);
+ return new (&globalData) NativeExecutable(globalData, JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor);
}
#else
- static PassRefPtr<NativeExecutable> create(NativeFunction function, NativeFunction constructor)
+ static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
{
- return adoptRef(new NativeExecutable(function, constructor));
+ return new (&globalData) NativeExecutable(globalData, function, constructor);
}
#endif
@@ -115,8 +117,8 @@ namespace JSC {
private:
#if ENABLE(JIT)
- NativeExecutable(JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor)
- : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ NativeExecutable(JSGlobalData& globalData, JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor)
+ : ExecutableBase(globalData.executableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -126,8 +128,8 @@ namespace JSC {
m_jitCodeForConstructWithArityCheck = constructThunk.addressForCall();
}
#else
- NativeExecutable(NativeFunction function, NativeFunction constructor)
- : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
+ : ExecutableBase(globalData.executableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -142,8 +144,8 @@ namespace JSC {
class VPtrHackExecutable : public ExecutableBase {
public:
- VPtrHackExecutable()
- : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ VPtrHackExecutable(Structure* structure)
+ : ExecutableBase(structure, NUM_PARAMETERS_IS_HOST)
{
}
@@ -152,8 +154,8 @@ namespace JSC {
class ScriptExecutable : public ExecutableBase {
public:
- ScriptExecutable(JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
+ ScriptExecutable(Structure* structure, JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
+ : ExecutableBase(structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
{
@@ -166,8 +168,8 @@ namespace JSC {
#endif
}
- ScriptExecutable(ExecState* exec, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
+ ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
+ : ExecutableBase(structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
{
@@ -214,6 +216,7 @@ namespace JSC {
JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_evalCodeBlock)
error = compileInternal(exec, scopeChainNode);
@@ -227,7 +230,7 @@ namespace JSC {
return *m_evalCodeBlock;
}
- static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return adoptRef(new EvalExecutable(exec, source, isInStrictContext)); }
+ static EvalExecutable* create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return new (exec) EvalExecutable(exec, source, isInStrictContext); }
#if ENABLE(JIT)
JITCode& generatedJITCode()
@@ -235,26 +238,30 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
+ static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
EvalExecutable(ExecState*, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
+ virtual void markChildren(MarkStack&);
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
};
class ProgramExecutable : public ScriptExecutable {
public:
- static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source)
+ static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
{
- return adoptRef(new ProgramExecutable(exec, source));
+ return new (exec) ProgramExecutable(exec, source);
}
~ProgramExecutable();
JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_programCodeBlock)
error = compileInternal(exec, scopeChainNode);
@@ -276,11 +283,15 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
+
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
+ static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
ProgramExecutable(ExecState*, const SourceCode&);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
+ virtual void markChildren(MarkStack&);
OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
@@ -288,18 +299,16 @@ namespace JSC {
class FunctionExecutable : public ScriptExecutable {
friend class JIT;
public:
- static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ static FunctionExecutable* create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
+ return new (exec) FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine);
}
- static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ static FunctionExecutable* create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
+ return new (globalData) FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine);
}
- ~FunctionExecutable();
-
JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
{
return new (exec) JSFunction(exec, this, scopeChain);
@@ -318,6 +327,7 @@ namespace JSC {
JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForCall)
error = compileForCallInternal(exec, scopeChainNode);
@@ -338,6 +348,7 @@ namespace JSC {
JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForConstruct)
error = compileForConstructInternal(exec, scopeChainNode);
@@ -363,8 +374,9 @@ namespace JSC {
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
void discardCode();
- void markAggregate(MarkStack&);
- static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+ void markChildren(MarkStack&);
+ static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
@@ -372,7 +384,8 @@ namespace JSC {
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
-
+
+ static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index e642594..a9f0a06 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -49,7 +49,7 @@ FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* global
static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructFunction(exec, args));
+ return JSValue::encode(constructFunction(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType FunctionConstructor::getConstructData(ConstructData& constructData)
@@ -61,7 +61,7 @@ ConstructType FunctionConstructor::getConstructData(ConstructData& constructData
static EncodedJSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructFunction(exec, args));
+ return JSValue::encode(constructFunction(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
// ECMA 15.3.1 The Function Constructor Called as a Function
@@ -72,7 +72,7 @@ CallType FunctionConstructor::getCallData(CallData& callData)
}
// ECMA 15.3.2 The Function Constructor
-JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
+JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
// Functions need to have a space following the opening { due to for web compatibility
// see https://bugs.webkit.org/show_bug.cgi?id=24350
@@ -96,11 +96,10 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
program = builder.toUString();
}
- JSGlobalObject* globalObject = exec->lexicalGlobalObject();
JSGlobalData& globalData = globalObject->globalData();
SourceCode source = makeSource(program, sourceURL, lineNumber);
JSObject* exception = 0;
- RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
+ FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
if (!function) {
ASSERT(exception);
return throwError(exec, exception);
@@ -111,9 +110,9 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
}
// ECMA 15.3.2 The Function Constructor
-JSObject* constructFunction(ExecState* exec, const ArgList& args)
+JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
- return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1);
+ return constructFunction(exec, globalObject, args, Identifier(exec, "anonymous"), UString(), 1);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.h b/Source/JavaScriptCore/runtime/FunctionConstructor.h
index 6af4861..7f21b20 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.h
@@ -36,8 +36,8 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
- JSObject* constructFunction(ExecState*, const ArgList&);
+ JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
+ JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.h b/Source/JavaScriptCore/runtime/FunctionPrototype.h
index fb0bb48..447f00b 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.h
@@ -30,9 +30,9 @@ namespace JSC {
FunctionPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>);
void addFunctionProperties(ExecState*, JSGlobalObject*, Structure* functionStructure, JSFunction** callFunction, JSFunction** applyFunction);
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
index a941cfa..2e878bf 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
@@ -33,6 +33,7 @@
#include "Heap.h"
#include "JSGlobalData.h"
#include "JSLock.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#include <wtf/RetainPtr.h>
#include <wtf/WTFThreadData.h>
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h
index 68a8c70..8241275 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.h
+++ b/Source/JavaScriptCore/runtime/GetterSetter.h
@@ -47,9 +47,9 @@ namespace JSC {
void setGetter(JSGlobalData& globalData, JSObject* getter) { m_getter.set(globalData, this, getter); }
JSObject* setter() const { return m_setter.get(); }
void setSetter(JSGlobalData& globalData, JSObject* setter) { m_setter.set(globalData, this, setter); }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount, 0);
}
private:
virtual bool isGetterSetter() const;
diff --git a/Source/JavaScriptCore/runtime/Heap.cpp b/Source/JavaScriptCore/runtime/Heap.cpp
index c52bcfe..e3ef8bb 100644
--- a/Source/JavaScriptCore/runtime/Heap.cpp
+++ b/Source/JavaScriptCore/runtime/Heap.cpp
@@ -46,7 +46,7 @@ Heap::Heap(JSGlobalData* globalData)
, m_markListSet(0)
, m_activityCallback(DefaultGCActivityCallback::create(this))
, m_globalData(globalData)
- , m_machineStackMarker(this)
+ , m_machineThreads(this)
, m_markStack(globalData->jsArrayVPtr)
, m_handleHeap(globalData)
, m_extraCost(0)
@@ -75,6 +75,10 @@ void Heap::destroy()
// (and thus the global data) before other objects that may use the global data.
RefPtr<JSGlobalData> protect(m_globalData);
+#if ENABLE(JIT)
+ m_globalData->jitStubs->clearHostFunctionStubs();
+#endif
+
delete m_markListSet;
m_markListSet = 0;
m_markedSpace.clearMarks();
@@ -97,7 +101,7 @@ void Heap::reportExtraMemoryCostSlowCase(size_t cost)
// if a large value survives one garbage collection, there is not much point to
// collecting more frequently as long as it stays alive.
- if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.capacity() / 2)
+ if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.highWaterMark() / 2)
collectAllGarbage();
m_extraCost += cost;
}
@@ -147,11 +151,11 @@ bool Heap::unprotect(JSValue k)
return m_protectedValues.remove(k.asCell());
}
-void Heap::markProtectedObjects(MarkStack& markStack)
+void Heap::markProtectedObjects(HeapRootMarker& heapRootMarker)
{
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- markStack.deprecatedAppend(&it->first);
+ heapRootMarker.mark(&it->first);
}
void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
@@ -165,7 +169,7 @@ void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
m_tempSortingVectors.removeLast();
}
-void Heap::markTempSortVectors(MarkStack& markStack)
+void Heap::markTempSortVectors(HeapRootMarker& heapRootMarker)
{
typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
@@ -176,7 +180,7 @@ void Heap::markTempSortVectors(MarkStack& markStack)
Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
if (vectorIt->first)
- markStack.deprecatedAppend(&vectorIt->first);
+ heapRootMarker.mark(&vectorIt->first);
}
}
}
@@ -195,52 +199,52 @@ void Heap::markRoots()
}
#endif
+ void* dummy;
+
ASSERT(m_operationInProgress == NoOperation);
if (m_operationInProgress != NoOperation)
CRASH();
m_operationInProgress = Collection;
- // We gather the conservative set before clearing mark bits, because
+ MarkStack& markStack = m_markStack;
+ HeapRootMarker heapRootMarker(markStack);
+
+ // We gather conservative roots before clearing mark bits because
// conservative gathering uses the mark bits from our last mark pass to
// determine whether a reference is valid.
- ConservativeSet conservativeSet(this);
- m_machineStackMarker.markMachineStackConservatively(conservativeSet);
- conservativeSet.add(registerFile().start(), registerFile().end());
+ ConservativeRoots machineThreadRoots(this);
+ m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);
+
+ ConservativeRoots registerFileRoots(this);
+ registerFile().gatherConservativeRoots(registerFileRoots);
m_markedSpace.clearMarks();
- MarkStack& markStack = m_markStack;
- conservativeSet.mark(markStack);
+ markStack.append(machineThreadRoots);
markStack.drain();
- // Mark explicitly registered roots.
- markProtectedObjects(markStack);
+ markStack.append(registerFileRoots);
markStack.drain();
-
- // Mark temporary vector for Array sorting
- markTempSortVectors(markStack);
+
+ markProtectedObjects(heapRootMarker);
markStack.drain();
- HashSet<GlobalCodeBlock*>::const_iterator end = m_codeBlocks.end();
- for (HashSet<GlobalCodeBlock*>::const_iterator it = m_codeBlocks.begin(); it != end; ++it)
- (*it)->markAggregate(markStack);
+ markTempSortVectors(heapRootMarker);
markStack.drain();
- // Mark misc. other roots.
if (m_markListSet && m_markListSet->size())
- MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
+ MarkedArgumentBuffer::markLists(heapRootMarker, *m_markListSet);
if (m_globalData->exception)
- markStack.append(&m_globalData->exception);
- if (m_globalData->firstStringifierToMark)
- JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
+ heapRootMarker.mark(&m_globalData->exception);
markStack.drain();
- m_handleHeap.markStrongHandles(markStack);
+ m_handleHeap.markStrongHandles(heapRootMarker);
+ m_handleStack.mark(heapRootMarker);
// Mark the small strings cache last, since it will clear itself if nothing
// else has marked it.
- m_globalData->smallStrings.markChildren(markStack);
+ m_globalData->smallStrings.markChildren(heapRootMarker);
markStack.drain();
markStack.compact();
@@ -371,7 +375,7 @@ void Heap::reset(SweepToggle sweepToggle)
m_extraCost = 0;
#if ENABLE(JSC_ZOMBIES)
- sweep();
+ sweepToggle = DoSweep;
#endif
if (sweepToggle == DoSweep) {
@@ -379,7 +383,11 @@ void Heap::reset(SweepToggle sweepToggle)
m_markedSpace.shrink();
}
- size_t proportionalBytes = static_cast<size_t>(1.5 * m_markedSpace.size());
+ // To avoid pathological GC churn in large heaps, we set the allocation high
+ // water mark to be proportional to the current size of the heap. The exact
+ // proportion is a bit arbitrary. A 2X multiplier gives a 1:1 (heap size :
+ // new bytes allocated) proportion, and seems to work well in benchmarks.
+ size_t proportionalBytes = 2 * m_markedSpace.size();
m_markedSpace.setHighWaterMark(max(proportionalBytes, minBytesPerCycle));
JAVASCRIPTCORE_GC_END();
diff --git a/Source/JavaScriptCore/runtime/Heap.h b/Source/JavaScriptCore/runtime/Heap.h
index eb8af70..c2d3bac 100644
--- a/Source/JavaScriptCore/runtime/Heap.h
+++ b/Source/JavaScriptCore/runtime/Heap.h
@@ -23,6 +23,7 @@
#define Heap_h
#include "HandleHeap.h"
+#include "HandleStack.h"
#include "MarkStack.h"
#include "MarkedSpace.h"
#include <wtf/Forward.h>
@@ -33,6 +34,7 @@ namespace JSC {
class GCActivityCallback;
class GlobalCodeBlock;
+ class HeapRootMarker;
class JSCell;
class JSGlobalData;
class JSValue;
@@ -65,7 +67,7 @@ namespace JSC {
JSGlobalData* globalData() const { return m_globalData; }
MarkedSpace& markedSpace() { return m_markedSpace; }
- MachineStackMarker& machineStackMarker() { return m_machineStackMarker; }
+ MachineThreads& machineThreads() { return m_machineThreads; }
GCActivityCallback* activityCallback();
void setActivityCallback(PassOwnPtr<GCActivityCallback>);
@@ -92,14 +94,15 @@ namespace JSC {
void pushTempSortVector(Vector<ValueStringPair>*);
void popTempSortVector(Vector<ValueStringPair>*);
-
- HashSet<GlobalCodeBlock*>& codeBlocks() { return m_codeBlocks; }
-
+
HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
template <typename Functor> void forEach(Functor&);
HandleSlot allocateGlobalHandle() { return m_handleHeap.allocate(); }
+ HandleSlot allocateLocalHandle() { return m_handleStack.push(); }
+
+ HandleStack* handleStack() { return &m_handleStack; }
private:
friend class JSGlobalData;
@@ -111,8 +114,8 @@ namespace JSC {
void reportExtraMemoryCostSlowCase(size_t);
void markRoots();
- void markProtectedObjects(MarkStack&);
- void markTempSortVectors(MarkStack&);
+ void markProtectedObjects(HeapRootMarker&);
+ void markTempSortVectors(HeapRootMarker&);
enum SweepToggle { DoNotSweep, DoSweep };
void reset(SweepToggle);
@@ -124,7 +127,6 @@ namespace JSC {
ProtectCountSet m_protectedValues;
Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
- HashSet<GlobalCodeBlock*> m_codeBlocks;
HashSet<MarkedArgumentBuffer*>* m_markListSet;
@@ -132,10 +134,11 @@ namespace JSC {
JSGlobalData* m_globalData;
- MachineStackMarker m_machineStackMarker;
+ MachineThreads m_machineThreads;
MarkStack m_markStack;
HandleHeap m_handleHeap;
-
+ HandleStack m_handleStack;
+
size_t m_extraCost;
};
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp
index 3992418..4a99b19 100644
--- a/Source/JavaScriptCore/runtime/Identifier.cpp
+++ b/Source/JavaScriptCore/runtime/Identifier.cpp
@@ -22,6 +22,7 @@
#include "Identifier.h"
#include "CallFrame.h"
+#include "JSObject.h"
#include "NumericStrings.h"
#include "ScopeChain.h"
#include <new> // for placement new
@@ -90,7 +91,7 @@ bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length)
struct IdentifierCStringTranslator {
static unsigned hash(const char* c)
{
- return WTF::StringHasher::createHash<char>(c);
+ return StringHasher::computeHash<char>(c);
}
static bool equal(StringImpl* r, const char* s)
@@ -150,7 +151,7 @@ struct UCharBuffer {
struct IdentifierUCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
- return WTF::StringHasher::createHash<UChar>(buf.s, buf.length);
+ return StringHasher::computeHash<UChar>(buf.s, buf.length);
}
static bool equal(StringImpl* str, const UCharBuffer& buf)
@@ -216,7 +217,7 @@ PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const UChar* s,
{
if (length == 1) {
UChar c = s[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
}
if (!length)
@@ -243,7 +244,7 @@ PassRefPtr<StringImpl> Identifier::addSlowCase(JSGlobalData* globalData, StringI
if (r->length() == 1) {
UChar c = r->characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
r = globalData->smallStrings.singleCharacterStringRep(c);
if (r->isIdentifier())
return r;
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index 8427b8c..08c98a5 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -39,9 +39,9 @@ namespace JSC {
const UString displayName(ExecState*);
const UString calculatedDisplayName(ExecState*);
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 43dd0d3..54fe909 100644
--- a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -35,9 +35,9 @@ namespace JSC {
virtual bool isAPIValueWrapper() const { return true; }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount, 0);
}
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index eb9c7c1..d0c50dd 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -39,15 +39,23 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0 };
-JSActivation::JSActivation(CallFrame* callFrame, NonNullPassRefPtr<FunctionExecutable> functionExecutable)
- : Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers()))
+JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
+ : Base(callFrame->globalData().activationStructure, functionExecutable->symbolTable(), callFrame->registers())
+ , m_numParametersMinusThis(static_cast<int>(functionExecutable->parameterCount()))
+ , m_numCapturedVars(functionExecutable->capturedVariableCount())
+ , m_requiresDynamicChecks(functionExecutable->usesEval())
+ , m_argumentsRegister(functionExecutable->generatedBytecode().argumentsRegister())
{
ASSERT(inherits(&s_info));
+
+ // We have to manually ref and deref the symbol table as JSVariableObject
+ // doesn't know about SharedSymbolTable
+ static_cast<SharedSymbolTable*>(m_symbolTable)->ref();
}
JSActivation::~JSActivation()
{
- delete d();
+ static_cast<SharedSymbolTable*>(m_symbolTable)->deref();
}
void JSActivation::markChildren(MarkStack& markStack)
@@ -55,30 +63,26 @@ void JSActivation::markChildren(MarkStack& markStack)
Base::markChildren(markStack);
// No need to mark our registers if they're still in the RegisterFile.
- WriteBarrier<Unknown>* registerArray = d()->registerArray.get();
+ WriteBarrier<Unknown>* registerArray = m_registerArray.get();
if (!registerArray)
return;
- size_t numParametersMinusThis = d()->functionExecutable->parameterCount();
-
- size_t count = numParametersMinusThis;
- markStack.appendValues(registerArray, count);
-
- size_t numVars = d()->functionExecutable->capturedVariableCount();
+ markStack.appendValues(registerArray, m_numParametersMinusThis);
// Skip the call frame, which sits between the parameters and vars.
- markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
+ markStack.appendValues(registerArray + m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize, m_numCapturedVars, MayContainNullValues);
}
inline bool JSActivation::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
{
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
- if (!entry.isNull()) {
- ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
- slot.setValue(registerAt(entry.getIndex()).get());
- return true;
- }
- return false;
+ if (entry.isNull())
+ return false;
+ if (entry.getIndex() >= m_numCapturedVars)
+ return false;
+
+ slot.setValue(registerAt(entry.getIndex()).get());
+ return true;
}
inline bool JSActivation::symbolTablePut(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
@@ -90,7 +94,9 @@ inline bool JSActivation::symbolTablePut(JSGlobalData& globalData, const Identif
return false;
if (entry.isReadOnly())
return true;
- ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
+ if (entry.getIndex() >= m_numCapturedVars)
+ return false;
+
registerAt(entry.getIndex()).set(globalData, this, value);
return true;
}
@@ -99,9 +105,11 @@ void JSActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& prope
{
SymbolTable::const_iterator end = symbolTable().end();
for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
- ASSERT(it->second.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
- if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
- propertyNames.add(Identifier(exec, it->first.get()));
+ if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
+ continue;
+ if (it->second.getIndex() >= m_numCapturedVars)
+ continue;
+ propertyNames.add(Identifier(exec, it->first.get()));
}
// Skip the JSVariableObject implementation of getOwnPropertyNames
JSObject::getOwnPropertyNames(exec, propertyNames, mode);
@@ -116,8 +124,9 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
return false;
SymbolTableEntry& entry = iter->second;
ASSERT(!entry.isNull());
- if (entry.getIndex() >= static_cast<int>(d()->functionExecutable->capturedVariableCount()))
+ if (entry.getIndex() >= m_numCapturedVars)
return false;
+
entry.setAttributes(attributes);
registerAt(entry.getIndex()).set(globalData, this, value);
return true;
@@ -195,15 +204,15 @@ JSValue JSActivation::toStrictThisObject(ExecState*) const
bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
{
- requiresDynamicChecks = d()->functionExecutable->usesEval();
+ requiresDynamicChecks = m_requiresDynamicChecks;
return false;
}
JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identifier&)
{
JSActivation* activation = asActivation(slotBase);
- CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->d()->registers));
- int argumentsRegister = activation->d()->functionExecutable->generatedBytecode().argumentsRegister();
+ CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
+ int argumentsRegister = activation->m_argumentsRegister;
if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue())
return arguments;
int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister);
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 6e04041..7463f47 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -42,7 +42,7 @@ namespace JSC {
class JSActivation : public JSVariableObject {
typedef JSVariableObject Base;
public:
- JSActivation(CallFrame*, NonNullPassRefPtr<FunctionExecutable>);
+ JSActivation(CallFrame*, FunctionExecutable*);
virtual ~JSActivation();
virtual void markChildren(MarkStack&);
@@ -66,29 +66,12 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
private:
- struct JSActivationData : public JSVariableObjectData {
- JSActivationData(NonNullPassRefPtr<FunctionExecutable> _functionExecutable, Register* registers)
- : JSVariableObjectData(_functionExecutable->symbolTable(), registers)
- , functionExecutable(_functionExecutable)
- {
- // We have to manually ref and deref the symbol table as JSVariableObjectData
- // doesn't know about SharedSymbolTable
- functionExecutable->symbolTable()->ref();
- }
- ~JSActivationData()
- {
- static_cast<SharedSymbolTable*>(symbolTable)->deref();
- }
-
- RefPtr<FunctionExecutable> functionExecutable;
- };
-
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertyDescriptor&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
@@ -98,7 +81,10 @@ namespace JSC {
static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
- JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
+ int m_numParametersMinusThis;
+ int m_numCapturedVars : 31;
+ bool m_requiresDynamicChecks : 1;
+ int m_argumentsRegister;
};
JSActivation* asActivation(JSValue);
@@ -108,6 +94,11 @@ namespace JSC {
ASSERT(asObject(value)->inherits(&JSActivation::s_info));
return static_cast<JSActivation*>(asObject(value));
}
+
+ ALWAYS_INLINE JSActivation* Register::activation() const
+ {
+ return asActivation(jsValue());
+ }
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 822b84c..1d621fe 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -127,7 +127,7 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
#endif
JSArray::JSArray(VPtrStealingHackType)
- : JSNonFinalObject(createStructure(jsNull()))
+ : JSNonFinalObject(Structure::create(Structure::VPtrStealingHack, &s_info))
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index ede3c61..1a6eba8 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -58,7 +58,6 @@ namespace JSC {
enum ArrayCreationMode { CreateCompact, CreateInitialized };
class JSArray : public JSNonFinalObject {
- friend class JIT;
friend class Walker;
public:
@@ -125,13 +124,23 @@ namespace JSC {
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToRegisters(ExecState*, Register*, uint32_t);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
inline void markChildrenDirect(MarkStack& markStack);
+ static ptrdiff_t storageOffset()
+ {
+ return OBJECT_OFFSETOF(JSArray, m_storage);
+ }
+
+ static ptrdiff_t vectorLengthOffset()
+ {
+ return OBJECT_OFFSETOF(JSArray, m_vectorLength);
+ }
+
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -142,7 +151,7 @@ namespace JSC {
void* subclassData() const;
void setSubclassData(void*);
-
+
private:
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
void putSlowCase(ExecState*, unsigned propertyName, JSValue);
@@ -174,11 +183,8 @@ namespace JSC {
return asArray(value.asCell());
}
- inline bool isJSArray(JSGlobalData* globalData, JSValue v)
- {
- return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr;
- }
inline bool isJSArray(JSGlobalData* globalData, JSCell* cell) { return cell->vptr() == globalData->jsArrayVPtr; }
+ inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && isJSArray(globalData, v.asCell()); }
inline void JSArray::markChildrenDirect(MarkStack& markStack)
{
@@ -196,77 +202,6 @@ namespace JSC {
}
}
- inline void MarkStack::markChildren(JSCell* cell)
- {
- ASSERT(Heap::isMarked(cell));
- if (!cell->structure()->typeInfo().overridesMarkChildren()) {
-#ifdef NDEBUG
- asObject(cell)->markChildrenDirect(*this);
-#else
- ASSERT(!m_isCheckingForDefaultMarkViolation);
- m_isCheckingForDefaultMarkViolation = true;
- cell->markChildren(*this);
- ASSERT(m_isCheckingForDefaultMarkViolation);
- m_isCheckingForDefaultMarkViolation = false;
-#endif
- return;
- }
- if (cell->vptr() == m_jsArrayVPtr) {
- asArray(cell)->markChildrenDirect(*this);
- return;
- }
- cell->markChildren(*this);
- }
-
- inline void MarkStack::drain()
- {
-#if !ASSERT_DISABLED
- ASSERT(!m_isDraining);
- m_isDraining = true;
-#endif
- while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
- while (!m_markSets.isEmpty() && m_values.size() < 50) {
- ASSERT(!m_markSets.isEmpty());
- MarkSet& current = m_markSets.last();
- ASSERT(current.m_values);
- JSValue* end = current.m_end;
- ASSERT(current.m_values);
- ASSERT(current.m_values != end);
- findNextUnmarkedNullValue:
- ASSERT(current.m_values != end);
- JSValue value = *current.m_values;
- current.m_values++;
-
- JSCell* cell;
- if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
- if (current.m_values == end) {
- m_markSets.removeLast();
- continue;
- }
- goto findNextUnmarkedNullValue;
- }
-
- if (cell->structure()->typeInfo().type() < CompoundType) {
- if (current.m_values == end) {
- m_markSets.removeLast();
- continue;
- }
- goto findNextUnmarkedNullValue;
- }
-
- if (current.m_values == end)
- m_markSets.removeLast();
-
- markChildren(cell);
- }
- while (!m_values.isEmpty())
- markChildren(m_values.removeLast());
- }
-#if !ASSERT_DISABLED
- m_isDraining = false;
-#endif
- }
-
// Rule from ECMA 15.2 about what an array index is.
// Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
inline unsigned Identifier::toArrayIndex(bool& ok) const
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.cpp b/Source/JavaScriptCore/runtime/JSByteArray.cpp
index ae735dc..fbaea1d 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSByteArray.cpp
@@ -50,9 +50,9 @@ JSByteArray::~JSByteArray()
#endif
-PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype, const JSC::ClassInfo* classInfo)
+PassRefPtr<Structure> JSByteArray::createStructure(JSGlobalData& globalData, JSValue prototype, const JSC::ClassInfo* classInfo)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, classInfo);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, classInfo);
}
bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.h b/Source/JavaScriptCore/runtime/JSByteArray.h
index 6e91594..e674958 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.h
+++ b/Source/JavaScriptCore/runtime/JSByteArray.h
@@ -76,7 +76,7 @@ namespace JSC {
}
JSByteArray(ExecState*, NonNullPassRefPtr<Structure>, WTF::ByteArray* storage);
- static PassRefPtr<Structure> createStructure(JSValue prototype, const JSC::ClassInfo* = &s_defaultInfo);
+ static PassRefPtr<Structure> createStructure(JSGlobalData&, JSValue prototype, const JSC::ClassInfo* = &s_defaultInfo);
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
@@ -102,7 +102,7 @@ namespace JSC {
private:
enum VPtrStealingHackType { VPtrStealingHack };
JSByteArray(VPtrStealingHackType)
- : JSNonFinalObject(createStructure(jsNull()))
+ : JSNonFinalObject(Structure::create(Structure::VPtrStealingHack, &s_info))
{
}
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index 9acb777..ce7fe22 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -119,7 +119,7 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, P
// This is not a general purpose implementation of getOwnPropertySlot.
// It should only be called by JSValue::get.
// It calls getPropertySlot, not getOwnPropertySlot.
- JSObject* object = toObject(exec);
+ JSObject* object = toObject(exec, exec->lexicalGlobalObject());
slot.setBase(object);
if (!object->getPropertySlot(exec, identifier, slot))
slot.setUndefined();
@@ -131,7 +131,7 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
// This is not a general purpose implementation of getOwnPropertySlot.
// It should only be called by JSValue::get.
// It calls getPropertySlot, not getOwnPropertySlot.
- JSObject* object = toObject(exec);
+ JSObject* object = toObject(exec, exec->lexicalGlobalObject());
slot.setBase(object);
if (!object->getPropertySlot(exec, identifier, slot))
slot.setUndefined();
@@ -140,27 +140,27 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot)
{
- toObject(exec)->put(exec, identifier, value, slot);
+ toObject(exec, exec->lexicalGlobalObject())->put(exec, identifier, value, slot);
}
void JSCell::put(ExecState* exec, unsigned identifier, JSValue value)
{
- toObject(exec)->put(exec, identifier, value);
+ toObject(exec, exec->lexicalGlobalObject())->put(exec, identifier, value);
}
bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
{
- return toObject(exec)->deleteProperty(exec, identifier);
+ return toObject(exec, exec->lexicalGlobalObject())->deleteProperty(exec, identifier);
}
bool JSCell::deleteProperty(ExecState* exec, unsigned identifier)
{
- return toObject(exec)->deleteProperty(exec, identifier);
+ return toObject(exec, exec->lexicalGlobalObject())->deleteProperty(exec, identifier);
}
JSObject* JSCell::toThisObject(ExecState* exec) const
{
- return toObject(exec);
+ return toObject(exec, exec->lexicalGlobalObject());
}
JSValue JSCell::getJSNumber()
@@ -203,7 +203,7 @@ UString JSCell::toString(ExecState*) const
return UString();
}
-JSObject* JSCell::toObject(ExecState*) const
+JSObject* JSCell::toObject(ExecState*, JSGlobalObject*) const
{
ASSERT_NOT_REACHED();
return 0;
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 7313d52..ab0e237 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -35,6 +35,8 @@
namespace JSC {
+ class JSGlobalObject;
+
#if COMPILER(MSVC)
// If WTF_MAKE_NONCOPYABLE is applied to JSCell we end up with a bunch of
// undefined references to the JSCell copy constructor and assignment operator
@@ -53,10 +55,9 @@ namespace JSC {
WTF_MAKE_NONCOPYABLE(JSCell);
#endif
+ friend class ExecutableBase;
friend class GetterSetter;
friend class Heap;
- friend class JIT;
- friend class JSNumberCell;
friend class JSObject;
friend class JSPropertyNameIterator;
friend class JSString;
@@ -67,15 +68,16 @@ namespace JSC {
friend class MarkedSpace;
friend class MarkedBlock;
friend class ScopeChainNode;
+ friend class StructureChain;
private:
explicit JSCell(Structure*);
virtual ~JSCell();
public:
- static PassRefPtr<Structure> createDummyStructure()
+ static PassRefPtr<Structure> createDummyStructure(JSGlobalData& globalData)
{
- return Structure::create(jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount, 0);
+ return Structure::create(globalData, jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount, 0);
}
// Querying the type.
@@ -107,7 +109,7 @@ namespace JSC {
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
// Garbage collection.
void* operator new(size_t, ExecState*);
@@ -137,6 +139,16 @@ namespace JSC {
// property names, we want a similar interface with appropriate optimizations.)
bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+ static ptrdiff_t structureOffset()
+ {
+ return OBJECT_OFFSETOF(JSCell, m_structure);
+ }
+
+ Structure* const * addressOfStructure() const
+ {
+ return &m_structure;
+ }
+
protected:
static const unsigned AnonymousSlotCount = 0;
@@ -203,6 +215,11 @@ namespace JSC {
return isCell() ? asCell()->getString(exec) : UString();
}
+ template <typename Base> UString HandleConverter<Base, Unknown>::getString(ExecState* exec) const
+ {
+ return jsValue().getString(exec);
+ }
+
inline JSObject* JSValue::getObject() const
{
return isCell() ? asCell()->getObject() : 0;
@@ -322,24 +339,19 @@ namespace JSC {
inline JSObject* JSValue::toObject(ExecState* exec) const
{
- return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec);
+ return isCell() ? asCell()->toObject(exec, exec->lexicalGlobalObject()) : toObjectSlowCase(exec, exec->lexicalGlobalObject());
}
- inline JSObject* JSValue::toThisObject(ExecState* exec) const
+ inline JSObject* JSValue::toObject(ExecState* exec, JSGlobalObject* globalObject) const
{
- return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
+ return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject);
}
-
- template <typename T> void MarkStack::append(DeprecatedPtr<T>* slot)
+
+ inline JSObject* JSValue::toThisObject(ExecState* exec) const
{
- internalAppend(slot->get());
+ return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
}
- template <typename T> void MarkStack::append(WriteBarrierBase<T>* slot)
- {
- internalAppend(slot->get());
- }
-
ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
{
ASSERT(!m_isCheckingForDefaultMarkViolation);
@@ -350,31 +362,6 @@ namespace JSC {
m_values.append(cell);
}
- ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
- {
- ASSERT(value);
- internalAppend(*value);
- }
-
- ALWAYS_INLINE void MarkStack::deprecatedAppend(JSValue* value)
- {
- ASSERT(value);
- internalAppend(*value);
- }
-
- ALWAYS_INLINE void MarkStack::deprecatedAppend(Register* value)
- {
- ASSERT(value);
- internalAppend(value->jsValue());
- }
-
- ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
- {
- ASSERT(value);
- if (value.isCell())
- internalAppend(value.asCell());
- }
-
inline Heap* Heap::heap(JSValue v)
{
if (!v.isCell())
@@ -411,8 +398,10 @@ namespace JSC {
inline MarkedSpace::SizeClass& MarkedSpace::sizeClassFor(size_t bytes)
{
- ASSERT(bytes && bytes <= preciseCutoff);
- return m_preciseSizeClasses[(bytes - 1) / preciseStep];
+ ASSERT(bytes && bytes < maxCellSize);
+ if (bytes < preciseCutoff)
+ return m_preciseSizeClasses[(bytes - 1) / preciseStep];
+ return m_impreciseSizeClasses[(bytes - 1) / impreciseStep];
}
inline void* MarkedSpace::allocate(size_t bytes)
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 2ade441..dbfc606 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -56,16 +56,16 @@ bool JSFunction::isHostFunctionNonInline() const
return isHostFunction();
}
-JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
+JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure, VPtrHackExecutable* executable)
: Base(structure)
- , m_executable(adoptRef(new VPtrHackExecutable()))
{
ASSERT(inherits(&s_info));
+ m_executable.setWithoutWriteBarrier(executable);
}
-JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, PassRefPtr<NativeExecutable> thunk)
+JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeExecutable* thunk)
: Base(globalObject, structure)
- , m_executable(thunk)
+ , m_executable(exec->globalData(), this, thunk)
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
ASSERT(inherits(&s_info));
@@ -75,17 +75,20 @@ JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPas
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
: Base(globalObject, structure)
- , m_executable(exec->globalData().getHostFunction(func))
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
ASSERT(inherits(&s_info));
+ // We separate out intialisation from setting the executable
+ // as getHostFunction may perform a GC allocation, so we have to be able to
+ // mark ourselves safely
+ m_executable.set(exec->globalData(), this, exec->globalData().getHostFunction(func));
putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
-JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
+JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChainNode)
: Base(scopeChainNode->globalObject.get(), scopeChainNode->globalObject->functionStructure())
- , m_executable(executable)
+ , m_executable(exec->globalData(), this, executable)
, m_scopeChain(exec->globalData(), this, scopeChainNode)
{
ASSERT(inherits(&s_info));
@@ -96,19 +99,6 @@ JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> ex
JSFunction::~JSFunction()
{
ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
-
- // JIT code for other functions may have had calls linked directly to the code for this function; these links
- // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
- // this memory is freed and may be reused (potentially for another, different JSFunction).
- if (!isHostFunction()) {
-#if ENABLE(JIT_OPTIMIZE_CALL)
- ASSERT(m_executable);
- if (jsExecutable()->isGeneratedForCall())
- jsExecutable()->generatedBytecodeForCall().unlinkCallers();
- if (jsExecutable()->isGeneratedForConstruct())
- jsExecutable()->generatedBytecodeForConstruct().unlinkCallers();
-#endif
- }
}
static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
@@ -148,9 +138,13 @@ const UString JSFunction::calculatedDisplayName(ExecState* exec)
void JSFunction::markChildren(MarkStack& markStack)
{
Base::markChildren(markStack);
- if (!isHostFunction()) {
- jsExecutable()->markAggregate(markStack);
- markStack.append(&m_scopeChain);
+
+ markStack.append(&m_scopeChain);
+ if (m_executable) {
+ // Delightful race condition: m_executable may not have been initialised
+ // if this is a host function, as the executable isn't necessarily created
+ // until after the function has been allocated.
+ markStack.append(&m_executable);
}
}
diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h
index 089f42e..505b9de 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.h
+++ b/Source/JavaScriptCore/runtime/JSFunction.h
@@ -34,6 +34,7 @@ namespace JSC {
class JSActivation;
class JSGlobalObject;
class NativeExecutable;
+ class VPtrHackExecutable;
EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
@@ -45,8 +46,8 @@ namespace JSC {
public:
JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
- JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, PassRefPtr<NativeExecutable>);
- JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*);
+ JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeExecutable*);
+ JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
virtual ~JSFunction();
const UString& name(ExecState*);
@@ -72,9 +73,9 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
NativeFunction nativeFunction();
@@ -86,7 +87,7 @@ namespace JSC {
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
private:
- JSFunction(NonNullPassRefPtr<Structure>);
+ JSFunction(NonNullPassRefPtr<Structure>, VPtrHackExecutable*);
bool isHostFunctionNonInline() const;
@@ -102,7 +103,7 @@ namespace JSC {
static JSValue callerGetter(ExecState*, JSValue, const Identifier&);
static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
- RefPtr<ExecutableBase> m_executable;
+ WriteBarrier<ExecutableBase> m_executable;
WriteBarrier<ScopeChainNode> m_scopeChain;
};
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index e25040c..ee1829b 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -68,6 +68,27 @@
using namespace WTF;
+namespace {
+
+using namespace JSC;
+
+class Recompiler {
+public:
+ void operator()(JSCell*);
+};
+
+inline void Recompiler::operator()(JSCell* cell)
+{
+ if (!cell->inherits(&JSFunction::s_info))
+ return;
+ JSFunction* function = asFunction(cell);
+ if (function->executable()->isHostFunction())
+ return;
+ function->jsExecutable()->discardCode();
+}
+
+} // namespace
+
namespace JSC {
extern JSC_CONST_HASHTABLE HashTable arrayTable;
@@ -107,8 +128,12 @@ void JSGlobalData::storeVPtrs()
jsString->~JSCell();
COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(storage), sizeof_JSFunction_must_be_less_than_storage);
- JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
+ char executableStorage[sizeof(VPtrHackExecutable)];
+ RefPtr<Structure> executableStructure = Structure::create(Structure::VPtrStealingHack, 0);
+ JSCell* executable = new (executableStorage) VPtrHackExecutable(executableStructure.get());
+ JSCell* jsFunction = new (storage) JSFunction(Structure::create(Structure::VPtrStealingHack, &JSFunction::s_info), static_cast<VPtrHackExecutable*>(executable));
JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
+ executable->~JSCell();
jsFunction->~JSCell();
}
@@ -124,18 +149,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, regExpTable(fastNew<HashTable>(JSC::regExpTable))
, regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
, stringTable(fastNew<HashTable>(JSC::stringTable))
- , activationStructure(JSActivation::createStructure(jsNull()))
- , interruptedExecutionErrorStructure(JSNonFinalObject::createStructure(jsNull()))
- , terminatedExecutionErrorStructure(JSNonFinalObject::createStructure(jsNull()))
- , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
- , strictEvalActivationStructure(StrictEvalActivation::createStructure(jsNull()))
- , stringStructure(JSString::createStructure(jsNull()))
- , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
- , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull()))
- , getterSetterStructure(GetterSetter::createStructure(jsNull()))
- , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
- , scopeChainNodeStructure(ScopeChainNode::createStructure(jsNull()))
- , dummyMarkableCellStructure(JSCell::createDummyStructure())
, identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
@@ -145,7 +158,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, heap(this)
, globalObjectCount(0)
, dynamicGlobalObject(0)
- , firstStringifierToMark(0)
, cachedUTCOffset(NaN)
, maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
, m_regExpCache(new RegExpCache(this))
@@ -156,6 +168,24 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, exclusiveThread(0)
#endif
{
+ activationStructure = JSActivation::createStructure(*this, jsNull());
+ interruptedExecutionErrorStructure = JSNonFinalObject::createStructure(*this, jsNull());
+ terminatedExecutionErrorStructure = JSNonFinalObject::createStructure(*this, jsNull());
+ staticScopeStructure = JSStaticScopeObject::createStructure(*this, jsNull());
+ strictEvalActivationStructure = StrictEvalActivation::createStructure(*this, jsNull());
+ stringStructure = JSString::createStructure(*this, jsNull());
+ notAnObjectStructure = JSNotAnObject::createStructure(*this, jsNull());
+ propertyNameIteratorStructure = JSPropertyNameIterator::createStructure(*this, jsNull());
+ getterSetterStructure = GetterSetter::createStructure(*this, jsNull());
+ apiWrapperStructure = JSAPIValueWrapper::createStructure(*this, jsNull());
+ scopeChainNodeStructure = ScopeChainNode::createStructure(*this, jsNull());
+ executableStructure = ExecutableBase::createStructure(*this, jsNull());
+ evalExecutableStructure = EvalExecutable::createStructure(*this, jsNull());
+ programExecutableStructure = ProgramExecutable::createStructure(*this, jsNull());
+ functionExecutableStructure = FunctionExecutable::createStructure(*this, jsNull());
+ dummyMarkableCellStructure = JSCell::createDummyStructure(*this);
+ structureChainStructure = StructureChain::createStructure(*this, jsNull());
+
interpreter = new Interpreter(*this);
if (globalDataType == Default)
m_stack = wtfThreadData().stack();
@@ -282,18 +312,18 @@ JSGlobalData*& JSGlobalData::sharedInstanceInternal()
}
#if ENABLE(JIT)
-PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
+NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function)
{
return jitStubs->hostFunctionStub(this, function);
}
-PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
+NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
{
return jitStubs->hostFunctionStub(this, function, generator);
}
#else
-PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
+NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function)
{
- return NativeExecutable::create(function, callHostFunctionAsConstructor);
+ return NativeExecutable::create(*this, function, callHostFunctionAsConstructor);
}
#endif
@@ -325,22 +355,6 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
interpreter->dumpSampleData(exec);
}
-class Recompiler {
-public:
- void operator()(JSCell*);
-};
-
-inline void Recompiler::operator()(JSCell* cell)
-{
- if (!cell->inherits(&JSFunction::s_info))
- return;
- JSFunction* function = asFunction(cell);
- if (function->executable()->isHostFunction())
- return;
- function->jsExecutable()->discardCode();
-}
-
-
void JSGlobalData::recompileAllJSFunctions()
{
// If JavaScript is running, it's not safe to recompile, since we'll end
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index ee3e067..34ea75d 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -57,6 +57,7 @@ namespace JSC {
class CodeBlock;
class CommonIdentifiers;
+ class HandleStack;
class IdentifierTable;
class Interpreter;
class JSGlobalObject;
@@ -128,7 +129,7 @@ namespace JSC {
#if ENABLE(JSC_MULTIPLE_THREADS)
// Will start tracking threads that use the heap, which is resource-heavy.
- void makeUsableFromMultipleThreads() { heap.machineStackMarker().makeUsableFromMultipleThreads(); }
+ void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
#endif
GlobalDataType globalDataType;
@@ -155,7 +156,12 @@ namespace JSC {
RefPtr<Structure> getterSetterStructure;
RefPtr<Structure> apiWrapperStructure;
RefPtr<Structure> scopeChainNodeStructure;
+ RefPtr<Structure> executableStructure;
+ RefPtr<Structure> evalExecutableStructure;
+ RefPtr<Structure> programExecutableStructure;
+ RefPtr<Structure> functionExecutableStructure;
RefPtr<Structure> dummyMarkableCellStructure;
+ RefPtr<Structure> structureChainStructure;
static void storeVPtrs();
static JS_EXPORTDATA void* jsArrayVPtr;
@@ -199,15 +205,15 @@ namespace JSC {
{
return jitStubs->ctiStub(this, generator);
}
- PassRefPtr<NativeExecutable> getHostFunction(NativeFunction, ThunkGenerator);
+ NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator);
#endif
- PassRefPtr<NativeExecutable> getHostFunction(NativeFunction);
+ NativeExecutable* getHostFunction(NativeFunction);
TimeoutChecker timeoutChecker;
Terminator terminator;
Heap heap;
- DeprecatedPtr<Unknown> exception;
+ JSValue exception;
#if ENABLE(JIT)
ReturnAddressPtr exceptionLocation;
#endif
@@ -219,8 +225,6 @@ namespace JSC {
HashSet<JSObject*> stringRecursionCheckVisitedObjects;
- Stringifier* firstStringifierToMark;
-
double cachedUTCOffset;
DSTOffsetCache dstOffsetCache;
@@ -255,6 +259,7 @@ namespace JSC {
#endif
void dumpRegExpTrace();
HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
+ HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
private:
JSGlobalData(GlobalDataType, ThreadStackType);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 28fc07d..a2bbfbd 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -88,21 +88,21 @@ static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s
{
if (s && s->storedPrototype())
markStack.append(s->storedPrototypeSlot());
+ if (s && *s->cachedPrototypeChainSlot())
+ markStack.append(s->cachedPrototypeChainSlot());
}
JSGlobalObject::~JSGlobalObject()
{
ASSERT(JSLock::currentThreadIsHoldingLock());
- if (d()->debugger)
- d()->debugger->detach(this);
+ if (m_debugger)
+ m_debugger->detach(this);
Profiler** profiler = Profiler::enabledProfilerReference();
if (UNLIKELY(*profiler != 0)) {
- (*profiler)->stopProfiling(globalExec(), UString());
+ (*profiler)->stopProfiling(this);
}
-
- d()->destructor(d());
}
void JSGlobalObject::init(JSObject* thisValue)
@@ -111,14 +111,14 @@ void JSGlobalObject::init(JSObject* thisValue)
structure()->disableSpecificFunctionTracking();
- d()->globalData = Heap::heap(this)->globalData();
- d()->globalScopeChain.set(*d()->globalData, this, new (d()->globalData.get()) ScopeChainNode(0, this, d()->globalData.get(), this, thisValue));
+ m_globalData = Heap::heap(this)->globalData();
+ m_globalScopeChain.set(*m_globalData, this, new (m_globalData.get()) ScopeChainNode(0, this, m_globalData.get(), this, thisValue));
- JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.get(), CallFrame::noCaller(), 0, 0);
+ JSGlobalObject::globalExec()->init(0, 0, m_globalScopeChain.get(), CallFrame::noCaller(), 0, 0);
- d()->debugger = 0;
+ m_debugger = 0;
- d()->profileGroup = 0;
+ m_profileGroup = 0;
reset(prototype());
}
@@ -177,80 +177,80 @@ void JSGlobalObject::reset(JSValue prototype)
// Prototypes
- d()->functionPrototype.set(exec->globalData(), this, new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull()))); // The real prototype will be set once ObjectPrototype is created.
- d()->functionStructure = JSFunction::createStructure(d()->functionPrototype.get());
- d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype.get());
+ m_functionPrototype.set(exec->globalData(), this, new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(exec->globalData(), jsNull()))); // The real prototype will be set once ObjectPrototype is created.
+ m_functionStructure = JSFunction::createStructure(exec->globalData(), m_functionPrototype.get());
+ m_internalFunctionStructure = InternalFunction::createStructure(exec->globalData(), m_functionPrototype.get());
JSFunction* callFunction = 0;
JSFunction* applyFunction = 0;
- d()->functionPrototype->addFunctionProperties(exec, this, d()->functionStructure.get(), &callFunction, &applyFunction);
- d()->callFunction.set(exec->globalData(), this, callFunction);
- d()->applyFunction.set(exec->globalData(), this, applyFunction);
- d()->objectPrototype.set(exec->globalData(), this, new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(jsNull()), d()->functionStructure.get()));
- d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype.get());
+ m_functionPrototype->addFunctionProperties(exec, this, m_functionStructure.get(), &callFunction, &applyFunction);
+ m_callFunction.set(exec->globalData(), this, callFunction);
+ m_applyFunction.set(exec->globalData(), this, applyFunction);
+ m_objectPrototype.set(exec->globalData(), this, new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(exec->globalData(), jsNull()), m_functionStructure.get()));
+ m_functionPrototype->structure()->setPrototypeWithoutTransition(m_objectPrototype.get());
- d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
+ m_emptyObjectStructure = m_objectPrototype->inheritorID(exec->globalData());
- d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype.get());
- d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype.get());
- d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype.get());
- d()->callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(d()->objectPrototype.get());
+ m_callbackFunctionStructure = JSCallbackFunction::createStructure(exec->globalData(), m_functionPrototype.get());
+ m_argumentsStructure = Arguments::createStructure(exec->globalData(), m_objectPrototype.get());
+ m_callbackConstructorStructure = JSCallbackConstructor::createStructure(exec->globalData(), m_objectPrototype.get());
+ m_callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(exec->globalData(), m_objectPrototype.get());
- d()->arrayPrototype.set(exec->globalData(), this, new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(d()->objectPrototype.get())));
- d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype.get());
- d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype.get());
+ m_arrayPrototype.set(exec->globalData(), this, new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(exec->globalData(), m_objectPrototype.get())));
+ m_arrayStructure = JSArray::createStructure(exec->globalData(), m_arrayPrototype.get());
+ m_regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(exec->globalData(), m_arrayPrototype.get());
- d()->stringPrototype.set(exec->globalData(), this, new (exec) StringPrototype(exec, this, StringPrototype::createStructure(d()->objectPrototype.get())));
- d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype.get());
+ m_stringPrototype.set(exec->globalData(), this, new (exec) StringPrototype(exec, this, StringPrototype::createStructure(exec->globalData(), m_objectPrototype.get())));
+ m_stringObjectStructure = StringObject::createStructure(exec->globalData(), m_stringPrototype.get());
- d()->booleanPrototype.set(exec->globalData(), this, new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get()));
- d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype.get());
+ m_booleanPrototype.set(exec->globalData(), this, new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get()));
+ m_booleanObjectStructure = BooleanObject::createStructure(exec->globalData(), m_booleanPrototype.get());
- d()->numberPrototype.set(exec->globalData(), this, new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get()));
- d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype.get());
+ m_numberPrototype.set(exec->globalData(), this, new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get()));
+ m_numberObjectStructure = NumberObject::createStructure(exec->globalData(), m_numberPrototype.get());
- d()->datePrototype.set(exec->globalData(), this, new (exec) DatePrototype(exec, this, DatePrototype::createStructure(d()->objectPrototype.get())));
- d()->dateStructure = DateInstance::createStructure(d()->datePrototype.get());
+ m_datePrototype.set(exec->globalData(), this, new (exec) DatePrototype(exec, this, DatePrototype::createStructure(exec->globalData(), m_objectPrototype.get())));
+ m_dateStructure = DateInstance::createStructure(exec->globalData(), m_datePrototype.get());
- d()->regExpPrototype.set(exec->globalData(), this, new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get()));
- d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype.get());
+ m_regExpPrototype.set(exec->globalData(), this, new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get()));
+ m_regExpStructure = RegExpObject::createStructure(exec->globalData(), m_regExpPrototype.get());
- d()->methodCallDummy.set(exec->globalData(), this, constructEmptyObject(exec));
+ m_methodCallDummy.set(exec->globalData(), this, constructEmptyObject(exec));
- ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get());
- d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
+ ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get());
+ m_errorStructure = ErrorInstance::createStructure(exec->globalData(), errorPrototype);
// Constructors
- JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(d()->functionPrototype.get()), d()->objectPrototype.get());
- JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(d()->functionPrototype.get()), d()->functionPrototype.get());
- JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(d()->functionPrototype.get()), d()->arrayPrototype.get(), d()->functionStructure.get());
- JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(d()->functionPrototype.get()), d()->functionStructure.get(), d()->stringPrototype.get());
- JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(d()->functionPrototype.get()), d()->booleanPrototype.get());
- JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(d()->functionPrototype.get()), d()->numberPrototype.get());
- JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(d()->functionPrototype.get()), d()->functionStructure.get(), d()->datePrototype.get());
-
- d()->regExpConstructor.set(exec->globalData(), this, new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(d()->functionPrototype.get()), d()->regExpPrototype.get()));
-
- d()->errorConstructor.set(exec->globalData(), this, new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(d()->functionPrototype.get()), errorPrototype));
-
- RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
- RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype.get());
- d()->evalErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError"));
- d()->rangeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError"));
- d()->referenceErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError"));
- d()->syntaxErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError"));
- d()->typeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError"));
- d()->URIErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError"));
-
- d()->objectPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum);
- d()->functionPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum);
- d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
- d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
- d()->stringPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, stringConstructor, DontEnum);
- d()->numberPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, numberConstructor, DontEnum);
- d()->datePrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
- d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, d()->regExpConstructor.get(), DontEnum);
- errorPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, d()->errorConstructor.get(), DontEnum);
+ JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_objectPrototype.get());
+ JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_functionPrototype.get());
+ JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_arrayPrototype.get(), m_functionStructure.get());
+ JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_functionStructure.get(), m_stringPrototype.get());
+ JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_booleanPrototype.get());
+ JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_numberPrototype.get());
+ JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_functionStructure.get(), m_datePrototype.get());
+
+ m_regExpConstructor.set(exec->globalData(), this, new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_regExpPrototype.get()));
+
+ m_errorConstructor.set(exec->globalData(), this, new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), errorPrototype));
+
+ RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->globalData(), errorPrototype);
+ RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(exec->globalData(), m_functionPrototype.get());
+ m_evalErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError"));
+ m_rangeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError"));
+ m_referenceErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError"));
+ m_syntaxErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError"));
+ m_typeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError"));
+ m_URIErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError"));
+
+ m_objectPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum);
+ m_functionPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum);
+ m_arrayPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
+ m_booleanPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
+ m_stringPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, stringConstructor, DontEnum);
+ m_numberPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, numberConstructor, DontEnum);
+ m_datePrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
+ m_regExpPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum);
+ errorPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum);
// Set global constructors
@@ -263,42 +263,42 @@ void JSGlobalObject::reset(JSValue prototype)
putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "String"), stringConstructor, DontEnum);
putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Number"), numberConstructor, DontEnum);
putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Date"), dateConstructor, DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RegExp"), d()->regExpConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Error"), d()->errorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "EvalError"), d()->evalErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RangeError"), d()->rangeErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), d()->typeErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), d()->URIErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RegExp"), m_regExpConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Error"), m_errorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "EvalError"), m_evalErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RangeError"), m_rangeErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "ReferenceError"), m_referenceErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), m_syntaxErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), m_typeErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), m_URIErrorConstructor.get(), DontEnum);
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(d()->objectPrototype.get())), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(exec->globalData(), m_objectPrototype.get())), DontEnum | DontDelete),
GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly),
- GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(d()->objectPrototype.get())), DontEnum | DontDelete)
+ GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(exec->globalData(), m_objectPrototype.get())), DontEnum | DontDelete)
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
// Set global functions.
- d()->evalFunction.set(exec->globalData(), this, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, exec->propertyNames().eval, globalFuncEval));
- putDirectFunctionWithoutTransition(exec, d()->evalFunction.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+ m_evalFunction.set(exec->globalData(), this, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, exec->propertyNames().eval, globalFuncEval));
+ putDirectFunctionWithoutTransition(exec, m_evalFunction.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
#ifndef NDEBUG
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
#endif
resetPrototype(prototype);
@@ -310,7 +310,7 @@ void JSGlobalObject::resetPrototype(JSValue prototype)
setPrototype(prototype);
JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
- JSObject* objectPrototype = d()->objectPrototype.get();
+ JSObject* objectPrototype = m_objectPrototype.get();
if (oldLastInPrototypeChain != objectPrototype)
oldLastInPrototypeChain->setPrototype(objectPrototype);
}
@@ -318,67 +318,63 @@ void JSGlobalObject::resetPrototype(JSValue prototype)
void JSGlobalObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
-
- markIfNeeded(markStack, &d()->globalScopeChain);
-
- markIfNeeded(markStack, &d()->regExpConstructor);
- markIfNeeded(markStack, &d()->errorConstructor);
- markIfNeeded(markStack, &d()->evalErrorConstructor);
- markIfNeeded(markStack, &d()->rangeErrorConstructor);
- markIfNeeded(markStack, &d()->referenceErrorConstructor);
- markIfNeeded(markStack, &d()->syntaxErrorConstructor);
- markIfNeeded(markStack, &d()->typeErrorConstructor);
- markIfNeeded(markStack, &d()->URIErrorConstructor);
-
- markIfNeeded(markStack, &d()->evalFunction);
- markIfNeeded(markStack, &d()->callFunction);
- markIfNeeded(markStack, &d()->applyFunction);
-
- markIfNeeded(markStack, &d()->objectPrototype);
- markIfNeeded(markStack, &d()->functionPrototype);
- markIfNeeded(markStack, &d()->arrayPrototype);
- markIfNeeded(markStack, &d()->booleanPrototype);
- markIfNeeded(markStack, &d()->stringPrototype);
- markIfNeeded(markStack, &d()->numberPrototype);
- markIfNeeded(markStack, &d()->datePrototype);
- markIfNeeded(markStack, &d()->regExpPrototype);
-
- markIfNeeded(markStack, &d()->methodCallDummy);
-
- markIfNeeded(markStack, d()->errorStructure);
- markIfNeeded(markStack, d()->argumentsStructure);
- markIfNeeded(markStack, d()->arrayStructure);
- markIfNeeded(markStack, d()->booleanObjectStructure);
- markIfNeeded(markStack, d()->callbackConstructorStructure);
- markIfNeeded(markStack, d()->callbackFunctionStructure);
- markIfNeeded(markStack, d()->callbackObjectStructure);
- markIfNeeded(markStack, d()->dateStructure);
- markIfNeeded(markStack, d()->emptyObjectStructure);
- markIfNeeded(markStack, d()->errorStructure);
- markIfNeeded(markStack, d()->functionStructure);
- markIfNeeded(markStack, d()->numberObjectStructure);
- markIfNeeded(markStack, d()->regExpMatchesArrayStructure);
- markIfNeeded(markStack, d()->regExpStructure);
- markIfNeeded(markStack, d()->stringObjectStructure);
-
- // No need to mark the other structures, because their prototypes are all
- // guaranteed to be referenced elsewhere.
-
- if (d()->registerArray) {
+
+ markIfNeeded(markStack, &m_globalScopeChain);
+ markIfNeeded(markStack, &m_methodCallDummy);
+
+ markIfNeeded(markStack, &m_regExpConstructor);
+ markIfNeeded(markStack, &m_errorConstructor);
+ markIfNeeded(markStack, &m_evalErrorConstructor);
+ markIfNeeded(markStack, &m_rangeErrorConstructor);
+ markIfNeeded(markStack, &m_referenceErrorConstructor);
+ markIfNeeded(markStack, &m_syntaxErrorConstructor);
+ markIfNeeded(markStack, &m_typeErrorConstructor);
+ markIfNeeded(markStack, &m_URIErrorConstructor);
+
+ markIfNeeded(markStack, &m_evalFunction);
+ markIfNeeded(markStack, &m_callFunction);
+ markIfNeeded(markStack, &m_applyFunction);
+
+ markIfNeeded(markStack, &m_objectPrototype);
+ markIfNeeded(markStack, &m_functionPrototype);
+ markIfNeeded(markStack, &m_arrayPrototype);
+ markIfNeeded(markStack, &m_booleanPrototype);
+ markIfNeeded(markStack, &m_stringPrototype);
+ markIfNeeded(markStack, &m_numberPrototype);
+ markIfNeeded(markStack, &m_datePrototype);
+ markIfNeeded(markStack, &m_regExpPrototype);
+
+ markIfNeeded(markStack, m_argumentsStructure);
+ markIfNeeded(markStack, m_arrayStructure);
+ markIfNeeded(markStack, m_booleanObjectStructure);
+ markIfNeeded(markStack, m_callbackConstructorStructure);
+ markIfNeeded(markStack, m_callbackFunctionStructure);
+ markIfNeeded(markStack, m_callbackObjectStructure);
+ markIfNeeded(markStack, m_dateStructure);
+ markIfNeeded(markStack, m_emptyObjectStructure);
+ markIfNeeded(markStack, m_errorStructure);
+ markIfNeeded(markStack, m_functionStructure);
+ markIfNeeded(markStack, m_numberObjectStructure);
+ markIfNeeded(markStack, m_regExpMatchesArrayStructure);
+ markIfNeeded(markStack, m_regExpStructure);
+ markIfNeeded(markStack, m_stringObjectStructure);
+ markIfNeeded(markStack, m_internalFunctionStructure);
+
+ if (m_registerArray) {
// Outside the execution of global code, when our variables are torn off,
// we can mark the torn-off array.
- markStack.appendValues(d()->registerArray.get(), d()->registerArraySize);
- } else if (d()->registers) {
+ markStack.appendValues(m_registerArray.get(), m_registerArraySize);
+ } else if (m_registers) {
// During execution of global code, when our variables are in the register file,
// the symbol table tells us how many variables there are, and registers
// points to where they end, and the registers used for execution begin.
- markStack.appendValues(d()->registers - symbolTable().size(), symbolTable().size());
+ markStack.appendValues(m_registers - symbolTable().size(), symbolTable().size());
}
}
ExecState* JSGlobalObject::globalExec()
{
- return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
+ return CallFrame::create(m_globalCallFrame + RegisterFile::CallFrameHeaderSize);
}
bool JSGlobalObject::isDynamicScope(bool&) const
@@ -388,12 +384,12 @@ bool JSGlobalObject::isDynamicScope(bool&) const
void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
{
- ASSERT(!d()->registerArray);
- ASSERT(!d()->registerArraySize);
+ ASSERT(!m_registerArray);
+ ASSERT(!m_registerArraySize);
int numGlobals = registerFile.numGlobals();
if (!numGlobals) {
- d()->registers = 0;
+ m_registers = 0;
return;
}
@@ -411,24 +407,24 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
registerFile.setGlobalObject(this);
registerFile.setNumGlobals(symbolTable().size());
- if (d()->registerArray) {
+ if (m_registerArray) {
// The register file is always a gc root so no barrier is needed here
- memcpy(registerFile.start() - d()->registerArraySize, d()->registerArray.get(), d()->registerArraySize * sizeof(WriteBarrier<Unknown>));
+ memcpy(registerFile.start() - m_registerArraySize, m_registerArray.get(), m_registerArraySize * sizeof(WriteBarrier<Unknown>));
setRegisters(reinterpret_cast<WriteBarrier<Unknown>*>(registerFile.start()), nullptr, 0);
}
}
void JSGlobalObject::resizeRegisters(int oldSize, int newSize)
{
- ASSERT(symbolTable().size() == newSize);
+ ASSERT(oldSize <= newSize);
if (newSize == oldSize)
return;
ASSERT(newSize && newSize > oldSize);
- if (d()->registerArray || !d()->registers) {
- ASSERT(static_cast<size_t>(oldSize) == d()->registerArraySize);
+ if (m_registerArray || !m_registers) {
+ ASSERT(static_cast<size_t>(oldSize) == m_registerArraySize);
OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[newSize]);
for (int i = 0; i < oldSize; i++)
- registerArray[newSize - oldSize + i].set(globalData(), this, d()->registerArray[i].get());
+ registerArray[newSize - oldSize + i].set(globalData(), this, m_registerArray[i].get());
WriteBarrier<Unknown>* registers = registerArray.get() + newSize;
setRegisters(registers, registerArray.release(), newSize);
} else {
@@ -437,7 +433,7 @@ void JSGlobalObject::resizeRegisters(int oldSize, int newSize)
}
for (int i = -newSize; i < -oldSize; ++i)
- d()->registers[i].setUndefined();
+ m_registers[i].setUndefined();
}
void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
@@ -445,26 +441,21 @@ void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
return globalData->heap.allocate(size);
}
-void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData)
-{
- delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData);
-}
-
-DynamicGlobalObjectScope::DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
- : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
+DynamicGlobalObjectScope::DynamicGlobalObjectScope(JSGlobalData& globalData, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(globalData.dynamicGlobalObject)
, m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
{
if (!m_dynamicGlobalObjectSlot) {
#if ENABLE(ASSEMBLER)
if (ExecutableAllocator::underMemoryPressure())
- callFrame->globalData().recompileAllJSFunctions();
+ globalData.recompileAllJSFunctions();
#endif
m_dynamicGlobalObjectSlot = dynamicGlobalObject;
// Reset the date cache between JS invocations to force the VM
// to observe time zone changes.
- callFrame->globalData().resetDateCache();
+ globalData.resetDateCache();
}
}
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 03b39fc..04f63eb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -28,6 +28,7 @@
#include "JSWeakObjectMapRefInternal.h"
#include "NumberPrototype.h"
#include "StringPrototype.h"
+#include "StructureChain.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/RandomNumber.h>
@@ -54,92 +55,70 @@ namespace JSC {
class JSGlobalObject : public JSVariableObject {
protected:
- using JSVariableObject::JSVariableObjectData;
typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
- struct JSGlobalObjectData : public JSVariableObjectData {
- // We use an explicit destructor function pointer instead of a
- // virtual destructor because we want to avoid adding a vtable
- // pointer to this struct. Adding a vtable pointer would force the
- // compiler to emit costly pointer fixup code when casting from
- // JSVariableObjectData* to JSGlobalObjectData*.
- typedef void (*Destructor)(void*);
-
- JSGlobalObjectData(Destructor destructor)
- : JSVariableObjectData(&symbolTable, 0)
- , destructor(destructor)
- , registerArraySize(0)
- , globalScopeChain()
- , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
- {
- }
-
- Destructor destructor;
-
- size_t registerArraySize;
-
- JSGlobalObject* next;
- JSGlobalObject* prev;
-
- Debugger* debugger;
-
- WriteBarrier<ScopeChainNode> globalScopeChain;
- Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
-
- WriteBarrier<RegExpConstructor> regExpConstructor;
- WriteBarrier<ErrorConstructor> errorConstructor;
- WriteBarrier<NativeErrorConstructor> evalErrorConstructor;
- WriteBarrier<NativeErrorConstructor> rangeErrorConstructor;
- WriteBarrier<NativeErrorConstructor> referenceErrorConstructor;
- WriteBarrier<NativeErrorConstructor> syntaxErrorConstructor;
- WriteBarrier<NativeErrorConstructor> typeErrorConstructor;
- WriteBarrier<NativeErrorConstructor> URIErrorConstructor;
-
- WriteBarrier<JSFunction> evalFunction;
- WriteBarrier<JSFunction> callFunction;
- WriteBarrier<JSFunction> applyFunction;
-
- WriteBarrier<ObjectPrototype> objectPrototype;
- WriteBarrier<FunctionPrototype> functionPrototype;
- WriteBarrier<ArrayPrototype> arrayPrototype;
- WriteBarrier<BooleanPrototype> booleanPrototype;
- WriteBarrier<StringPrototype> stringPrototype;
- WriteBarrier<NumberPrototype> numberPrototype;
- WriteBarrier<DatePrototype> datePrototype;
- WriteBarrier<RegExpPrototype> regExpPrototype;
-
- WriteBarrier<JSObject> methodCallDummy;
-
- RefPtr<Structure> argumentsStructure;
- RefPtr<Structure> arrayStructure;
- RefPtr<Structure> booleanObjectStructure;
- RefPtr<Structure> callbackConstructorStructure;
- RefPtr<Structure> callbackFunctionStructure;
- RefPtr<Structure> callbackObjectStructure;
- RefPtr<Structure> dateStructure;
- RefPtr<Structure> emptyObjectStructure;
- RefPtr<Structure> errorStructure;
- RefPtr<Structure> functionStructure;
- RefPtr<Structure> numberObjectStructure;
- RefPtr<Structure> regExpMatchesArrayStructure;
- RefPtr<Structure> regExpStructure;
- RefPtr<Structure> stringObjectStructure;
- RefPtr<Structure> internalFunctionStructure;
-
- SymbolTable symbolTable;
- unsigned profileGroup;
-
- RefPtr<JSGlobalData> globalData;
-
- WeakMapSet weakMaps;
- WeakRandom weakRandom;
- };
+ RefPtr<JSGlobalData> m_globalData;
+
+ size_t m_registerArraySize;
+ Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize];
+
+ WriteBarrier<ScopeChainNode> m_globalScopeChain;
+ WriteBarrier<JSObject> m_methodCallDummy;
+
+ WriteBarrier<RegExpConstructor> m_regExpConstructor;
+ WriteBarrier<ErrorConstructor> m_errorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
+
+ WriteBarrier<JSFunction> m_evalFunction;
+ WriteBarrier<JSFunction> m_callFunction;
+ WriteBarrier<JSFunction> m_applyFunction;
+
+ WriteBarrier<ObjectPrototype> m_objectPrototype;
+ WriteBarrier<FunctionPrototype> m_functionPrototype;
+ WriteBarrier<ArrayPrototype> m_arrayPrototype;
+ WriteBarrier<BooleanPrototype> m_booleanPrototype;
+ WriteBarrier<StringPrototype> m_stringPrototype;
+ WriteBarrier<NumberPrototype> m_numberPrototype;
+ WriteBarrier<DatePrototype> m_datePrototype;
+ WriteBarrier<RegExpPrototype> m_regExpPrototype;
+
+ RefPtr<Structure> m_argumentsStructure;
+ RefPtr<Structure> m_arrayStructure;
+ RefPtr<Structure> m_booleanObjectStructure;
+ RefPtr<Structure> m_callbackConstructorStructure;
+ RefPtr<Structure> m_callbackFunctionStructure;
+ RefPtr<Structure> m_callbackObjectStructure;
+ RefPtr<Structure> m_dateStructure;
+ RefPtr<Structure> m_emptyObjectStructure;
+ RefPtr<Structure> m_errorStructure;
+ RefPtr<Structure> m_functionStructure;
+ RefPtr<Structure> m_numberObjectStructure;
+ RefPtr<Structure> m_regExpMatchesArrayStructure;
+ RefPtr<Structure> m_regExpStructure;
+ RefPtr<Structure> m_stringObjectStructure;
+ RefPtr<Structure> m_internalFunctionStructure;
+
+ unsigned m_profileGroup;
+ Debugger* m_debugger;
+
+ WeakMapSet m_weakMaps;
+ WeakRandom m_weakRandom;
+
+ SymbolTable m_symbolTable;
public:
void* operator new(size_t, JSGlobalData*);
- explicit JSGlobalObject()
- : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
+ explicit JSGlobalObject(JSGlobalData& globalData)
+ : JSVariableObject(JSGlobalObject::createStructure(globalData, jsNull()), &m_symbolTable, 0)
+ , m_registerArraySize(0)
+ , m_globalScopeChain()
+ , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
@@ -147,7 +126,10 @@ namespace JSC {
}
explicit JSGlobalObject(NonNullPassRefPtr<Structure> structure)
- : JSVariableObject(structure, new JSGlobalObjectData(destroyJSGlobalObjectData))
+ : JSVariableObject(structure, &m_symbolTable, 0)
+ , m_registerArraySize(0)
+ , m_globalScopeChain()
+ , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
@@ -155,8 +137,11 @@ namespace JSC {
}
protected:
- JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
- : JSVariableObject(structure, data)
+ JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSObject* thisValue)
+ : JSVariableObject(structure, &m_symbolTable, 0)
+ , m_registerArraySize(0)
+ , m_globalScopeChain()
+ , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
@@ -184,55 +169,57 @@ namespace JSC {
// The following accessors return pristine values, even if a script
// replaces the global object's associated property.
- RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor.get(); }
-
- ErrorConstructor* errorConstructor() const { return d()->errorConstructor.get(); }
- NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor.get(); }
- NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor.get(); }
- NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor.get(); }
- NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor.get(); }
- NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor.get(); }
- NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor.get(); }
-
- JSFunction* evalFunction() const { return d()->evalFunction.get(); }
-
- ObjectPrototype* objectPrototype() const { return d()->objectPrototype.get(); }
- FunctionPrototype* functionPrototype() const { return d()->functionPrototype.get(); }
- ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype.get(); }
- BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype.get(); }
- StringPrototype* stringPrototype() const { return d()->stringPrototype.get(); }
- NumberPrototype* numberPrototype() const { return d()->numberPrototype.get(); }
- DatePrototype* datePrototype() const { return d()->datePrototype.get(); }
- RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype.get(); }
-
- JSObject* methodCallDummy() const { return d()->methodCallDummy.get(); }
-
- Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
- Structure* arrayStructure() const { return d()->arrayStructure.get(); }
- Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
- Structure* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
- Structure* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
- Structure* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
- Structure* dateStructure() const { return d()->dateStructure.get(); }
- Structure* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
- Structure* errorStructure() const { return d()->errorStructure.get(); }
- Structure* functionStructure() const { return d()->functionStructure.get(); }
- Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
- Structure* internalFunctionStructure() const { return d()->internalFunctionStructure.get(); }
- Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
- Structure* regExpStructure() const { return d()->regExpStructure.get(); }
- Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
-
- void setProfileGroup(unsigned value) { d()->profileGroup = value; }
- unsigned profileGroup() const { return d()->profileGroup; }
-
- Debugger* debugger() const { return d()->debugger; }
- void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
+ RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
+
+ ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
+ NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
+ NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
+ NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
+ NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); }
+ NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
+ NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); }
+
+ JSFunction* evalFunction() const { return m_evalFunction.get(); }
+ JSFunction* callFunction() const { return m_callFunction.get(); }
+ JSFunction* applyFunction() const { return m_applyFunction.get(); }
+
+ ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
+ FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
+ ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
+ BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
+ StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
+ NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
+ DatePrototype* datePrototype() const { return m_datePrototype.get(); }
+ RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
+
+ JSObject* methodCallDummy() const { return m_methodCallDummy.get(); }
+
+ Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
+ Structure* arrayStructure() const { return m_arrayStructure.get(); }
+ Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
+ Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
+ Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
+ Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); }
+ Structure* dateStructure() const { return m_dateStructure.get(); }
+ Structure* emptyObjectStructure() const { return m_emptyObjectStructure.get(); }
+ Structure* errorStructure() const { return m_errorStructure.get(); }
+ Structure* functionStructure() const { return m_functionStructure.get(); }
+ Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
+ Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
+ Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
+ Structure* regExpStructure() const { return m_regExpStructure.get(); }
+ Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
+
+ void setProfileGroup(unsigned value) { m_profileGroup = value; }
+ unsigned profileGroup() const { return m_profileGroup; }
+
+ Debugger* debugger() const { return m_debugger; }
+ void setDebugger(Debugger* debugger) { m_debugger = debugger; }
virtual bool supportsProfiling() const { return false; }
virtual bool supportsRichSourceInfo() const { return true; }
- ScopeChainNode* globalScopeChain() { return d()->globalScopeChain.get(); }
+ ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); }
virtual bool isGlobalObject() const { return true; }
@@ -250,25 +237,24 @@ namespace JSC {
void resetPrototype(JSValue prototype);
- JSGlobalData& globalData() const { return *d()->globalData.get(); }
- JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
+ JSGlobalData& globalData() const { return *m_globalData.get(); }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
void registerWeakMap(OpaqueJSWeakObjectMap* map)
{
- d()->weakMaps.add(map);
+ m_weakMaps.add(map);
}
void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
{
- d()->weakMaps.remove(map);
+ m_weakMaps.remove(map);
}
- double weakRandomNumber() { return d()->weakRandom.get(); }
+ double weakRandomNumber() { return m_weakRandom.get(); }
protected:
static const unsigned AnonymousSlotCount = JSVariableObject::AnonymousSlotCount + 1;
@@ -289,8 +275,6 @@ namespace JSC {
void addStaticGlobals(GlobalPropertyInfo*, int count);
private:
- static void destroyJSGlobalObjectData(void*);
-
// FIXME: Fold reset into init.
void init(JSObject* thisValue);
void reset(JSValue prototype);
@@ -311,17 +295,17 @@ namespace JSC {
inline void JSGlobalObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count)
{
JSVariableObject::setRegisters(registers, registerArray);
- d()->registerArraySize = count;
+ m_registerArraySize = count;
}
inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
{
- size_t oldSize = d()->registerArraySize;
+ size_t oldSize = m_registerArraySize;
size_t newSize = oldSize + count;
OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[newSize]);
- if (d()->registerArray) {
+ if (m_registerArray) {
// memcpy is safe here as we're copying barriers we already own from the existing array
- memcpy(registerArray.get() + count, d()->registerArray.get(), oldSize * sizeof(Register));
+ memcpy(registerArray.get() + count, m_registerArray.get(), oldSize * sizeof(Register));
}
WriteBarrier<Unknown>* registers = registerArray.get() + newSize;
@@ -379,7 +363,7 @@ namespace JSC {
// We cache our prototype chain so our clients can share it.
if (!isValid(exec, m_cachedPrototypeChain.get())) {
JSValue prototype = prototypeForLookup(exec);
- m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure());
+ m_cachedPrototypeChain = StructureChain::create(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure());
}
return m_cachedPrototypeChain.get();
}
@@ -451,7 +435,7 @@ namespace JSC {
class DynamicGlobalObjectScope {
WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
public:
- DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject);
+ DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
~DynamicGlobalObjectScope()
{
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index de1300a..f0da773 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -449,12 +449,12 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
if (JSValue parsedObject = preparser.tryLiteralParse())
return JSValue::encode(parsedObject);
- RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s), false);
+ EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false);
JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain());
if (error)
return throwVMError(exec, error);
- return JSValue::encode(exec->interpreter()->execute(eval.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain()));
+ return JSValue::encode(exec->interpreter()->execute(eval, exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain()));
}
EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp
index 64dcb08..fc543f0 100644
--- a/Source/JavaScriptCore/runtime/JSLock.cpp
+++ b/Source/JavaScriptCore/runtime/JSLock.cpp
@@ -23,6 +23,7 @@
#include "Heap.h"
#include "CallFrame.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#if USE(PTHREADS)
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
index e01b401..1115dc0 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -67,7 +67,7 @@ UString JSNotAnObject::toString(ExecState* exec) const
return "";
}
-JSObject* JSNotAnObject::toObject(ExecState* exec) const
+JSObject* JSNotAnObject::toObject(ExecState* exec, JSGlobalObject*) const
{
ASSERT_UNUSED(exec, exec->hadException());
return const_cast<JSNotAnObject*>(this);
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.h b/Source/JavaScriptCore/runtime/JSNotAnObject.h
index 7e70a98..75bca18 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.h
@@ -43,9 +43,9 @@ namespace JSC {
{
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
@@ -58,7 +58,7 @@ namespace JSC {
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
// JSObject methods
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
diff --git a/Source/JavaScriptCore/runtime/JSNumberCell.cpp b/Source/JavaScriptCore/runtime/JSNumberCell.cpp
index 3172cc9..79f2d2a 100644
--- a/Source/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "JSNumberCell.h"
+#include "JSObject.h"
#include "ScopeChain.h"
// Keep our exported symbols lists happy.
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index 7d18e08..8fc7ac9 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -32,6 +32,8 @@
#include "JSArray.h"
#include "JSGlobalObject.h"
#include "LiteralParser.h"
+#include "Local.h"
+#include "LocalScope.h"
#include "Lookup.h"
#include "PropertyNameArray.h"
#include "UStringBuilder.h"
@@ -74,24 +76,22 @@ private:
class Stringifier {
WTF_MAKE_NONCOPYABLE(Stringifier);
public:
- Stringifier(ExecState*, JSValue replacer, JSValue space);
- ~Stringifier();
- JSValue stringify(JSValue);
+ Stringifier(ExecState*, const Local<Unknown>& replacer, const Local<Unknown>& space);
+ Local<Unknown> stringify(Handle<Unknown>);
void markAggregate(MarkStack&);
private:
class Holder {
public:
- Holder(JSObject*);
+ Holder(JSGlobalData&, JSObject*);
JSObject* object() const { return m_object.get(); }
- DeprecatedPtr<JSObject>* objectSlot() { return &m_object; }
bool appendNextProperty(Stringifier&, UStringBuilder&);
private:
- DeprecatedPtr<JSObject> m_object;
+ Local<JSObject> m_object;
const bool m_isArray;
bool m_isJSArray;
unsigned m_index;
@@ -113,16 +113,14 @@ private:
void unindent();
void startNewLine(UStringBuilder&) const;
- Stringifier* const m_nextStringifierToMark;
ExecState* const m_exec;
- const JSValue m_replacer;
+ const Local<Unknown> m_replacer;
bool m_usingArrayReplacer;
PropertyNameArray m_arrayReplacerPropertyNames;
CallType m_replacerCallType;
CallData m_replacerCallData;
const UString m_gap;
- HashSet<JSObject*> m_holderCycleDetector;
Vector<Holder, 16> m_holderStack;
UString m_repeatedGap;
UString m_indent;
@@ -199,23 +197,20 @@ JSValue PropertyNameForFunctionCall::value(ExecState* exec) const
// ------------------------------ Stringifier --------------------------------
-Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
- : m_nextStringifierToMark(exec->globalData().firstStringifierToMark)
- , m_exec(exec)
+Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const Local<Unknown>& space)
+ : m_exec(exec)
, m_replacer(replacer)
, m_usingArrayReplacer(false)
, m_arrayReplacerPropertyNames(exec)
, m_replacerCallType(CallTypeNone)
- , m_gap(gap(exec, space))
+ , m_gap(gap(exec, space.get()))
{
- exec->globalData().firstStringifierToMark = this;
-
if (!m_replacer.isObject())
return;
- if (asObject(m_replacer)->inherits(&JSArray::s_info)) {
+ if (m_replacer.asObject()->inherits(&JSArray::s_info)) {
m_usingArrayReplacer = true;
- JSObject* array = asObject(m_replacer);
+ Handle<JSObject> array = m_replacer.asObject();
unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
for (unsigned i = 0; i < length; ++i) {
JSValue name = array->get(exec, i);
@@ -246,40 +241,25 @@ Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
return;
}
- m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData);
-}
-
-Stringifier::~Stringifier()
-{
- ASSERT(m_exec->globalData().firstStringifierToMark == this);
- m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark;
-}
-
-void Stringifier::markAggregate(MarkStack& markStack)
-{
- for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) {
- size_t size = m_holderStack.size();
- for (size_t i = 0; i < size; ++i)
- markStack.append(m_holderStack[i].objectSlot());
- }
+ m_replacerCallType = m_replacer.asObject()->getCallData(m_replacerCallData);
}
-JSValue Stringifier::stringify(JSValue value)
+Local<Unknown> Stringifier::stringify(Handle<Unknown> value)
{
JSObject* object = constructEmptyObject(m_exec);
if (m_exec->hadException())
- return jsNull();
+ return Local<Unknown>(m_exec->globalData(), jsNull());
PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
- object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value);
+ object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value.get());
UStringBuilder result;
- if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
- return jsUndefined();
+ if (appendStringifiedValue(result, value.get(), object, emptyPropertyName) != StringifySucceeded)
+ return Local<Unknown>(m_exec->globalData(), jsUndefined());
if (m_exec->hadException())
- return jsNull();
+ return Local<Unknown>(m_exec->globalData(), jsNull());
- return jsString(m_exec, result.toUString());
+ return Local<Unknown>(m_exec->globalData(), jsString(m_exec, result.toUString()));
}
void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& value)
@@ -372,7 +352,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder&
if (m_replacerCallType != CallTypeNone) {
JSValue list[] = { propertyName.value(m_exec), value };
ArgList args(list, WTF_ARRAY_LENGTH(list));
- value = call(m_exec, m_replacer, m_replacerCallType, m_replacerCallData, holder, args);
+ value = call(m_exec, m_replacer.get(), m_replacerCallType, m_replacerCallData, holder, args);
if (m_exec->hadException())
return StringifyFailed;
}
@@ -425,12 +405,14 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder&
}
// Handle cycle detection, and put the holder on the stack.
- if (!m_holderCycleDetector.add(object).second) {
- throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures."));
- return StringifyFailed;
+ for (unsigned i = 0; i < m_holderStack.size(); i++) {
+ if (m_holderStack[i].object() == object) {
+ throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures."));
+ return StringifyFailed;
+ }
}
bool holderStackWasEmpty = m_holderStack.isEmpty();
- m_holderStack.append(object);
+ m_holderStack.append(Holder(m_exec->globalData(), object));
if (!holderStackWasEmpty)
return StringifySucceeded;
@@ -450,7 +432,6 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder&
tickCount = localTimeoutChecker.ticksUntilNextCheck();
}
}
- m_holderCycleDetector.remove(m_holderStack.last().object());
m_holderStack.removeLast();
} while (!m_holderStack.isEmpty());
return StringifySucceeded;
@@ -485,8 +466,8 @@ inline void Stringifier::startNewLine(UStringBuilder& builder) const
builder.append(m_indent);
}
-inline Stringifier::Holder::Holder(JSObject* object)
- : m_object(object)
+inline Stringifier::Holder::Holder(JSGlobalData& globalData, JSObject* object)
+ : m_object(globalData, object)
, m_isArray(object->inherits(&JSArray::s_info))
, m_index(0)
{
@@ -623,16 +604,11 @@ bool JSONObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pro
return getStaticFunctionDescriptor<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, descriptor);
}
-void JSONObject::markStringifiers(MarkStack& markStack, Stringifier* stringifier)
-{
- stringifier->markAggregate(markStack);
-}
-
class Walker {
public:
- Walker(ExecState* exec, JSObject* function, CallType callType, CallData callData)
+ Walker(ExecState* exec, Handle<JSObject> function, CallType callType, CallData callData)
: m_exec(exec)
- , m_function(function)
+ , m_function(exec->globalData(), function)
, m_callType(callType)
, m_callData(callData)
{
@@ -649,7 +625,7 @@ private:
friend class Holder;
ExecState* m_exec;
- DeprecatedPtr<JSObject> m_function;
+ Local<JSObject> m_function;
CallType m_callType;
CallData m_callData;
};
@@ -663,8 +639,8 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
{
Vector<PropertyNameArray, 16> propertyStack;
Vector<uint32_t, 16> indexStack;
- Vector<JSObject*, 16> objectStack;
- Vector<JSArray*, 16> arrayStack;
+ LocalStack<JSObject, 16> objectStack(m_exec->globalData());
+ LocalStack<JSArray, 16> arrayStack(m_exec->globalData());
Vector<WalkerState, 16> stateStack;
WalkerState state = StateUnknown;
@@ -684,7 +660,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
return throwError(m_exec, createStackOverflowError(m_exec));
JSArray* array = asArray(inValue);
- arrayStack.append(array);
+ arrayStack.push(array);
indexStack.append(0);
// fallthrough
}
@@ -696,11 +672,11 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
tickCount = localTimeoutChecker.ticksUntilNextCheck();
}
- JSArray* array = arrayStack.last();
+ JSArray* array = arrayStack.peek();
uint32_t index = indexStack.last();
if (index == array->length()) {
outValue = array;
- arrayStack.removeLast();
+ arrayStack.pop();
indexStack.removeLast();
break;
}
@@ -722,7 +698,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
// fallthrough
}
case ArrayEndVisitMember: {
- JSArray* array = arrayStack.last();
+ JSArray* array = arrayStack.peek();
JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue);
if (filteredValue.isUndefined())
array->deleteProperty(m_exec, indexStack.last());
@@ -745,7 +721,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
return throwError(m_exec, createStackOverflowError(m_exec));
JSObject* object = asObject(inValue);
- objectStack.append(object);
+ objectStack.push(object);
indexStack.append(0);
propertyStack.append(PropertyNameArray(m_exec));
object->getOwnPropertyNames(m_exec, propertyStack.last());
@@ -759,12 +735,12 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
tickCount = localTimeoutChecker.ticksUntilNextCheck();
}
- JSObject* object = objectStack.last();
+ JSObject* object = objectStack.peek();
uint32_t index = indexStack.last();
PropertyNameArray& properties = propertyStack.last();
if (index == properties.size()) {
outValue = object;
- objectStack.removeLast();
+ objectStack.pop();
indexStack.removeLast();
propertyStack.removeLast();
break;
@@ -787,7 +763,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
// fallthrough
}
case ObjectEndVisitMember: {
- JSObject* object = objectStack.last();
+ JSObject* object = objectStack.peek();
Identifier prop = propertyStack.last()[indexStack.last()];
PutPropertySlot slot;
JSValue filteredValue = callReviver(object, jsString(m_exec, prop.ustring()), outValue);
@@ -838,7 +814,8 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
UString source = value.toString(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
-
+
+ LocalScope scope(exec->globalData());
LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON);
JSValue unfiltered = jsonParser.tryLiteralParse();
if (!unfiltered)
@@ -852,7 +829,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
CallType callType = getCallData(function, callData);
if (callType == CallTypeNone)
return JSValue::encode(unfiltered);
- return JSValue::encode(Walker(exec, asObject(function), callType, callData).walk(unfiltered));
+ return JSValue::encode(Walker(exec, Local<JSObject>(exec->globalData(), asObject(function)), callType, callData).walk(unfiltered));
}
// ECMA-262 v5 15.12.3
@@ -860,15 +837,17 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec)
{
if (!exec->argumentCount())
return throwVMError(exec, createError(exec, "No input to stringify"));
- JSValue value = exec->argument(0);
- JSValue replacer = exec->argument(1);
- JSValue space = exec->argument(2);
- return JSValue::encode(Stringifier(exec, replacer, space).stringify(value));
+ LocalScope scope(exec->globalData());
+ Local<Unknown> value(exec->globalData(), exec->argument(0));
+ Local<Unknown> replacer(exec->globalData(), exec->argument(1));
+ Local<Unknown> space(exec->globalData(), exec->argument(2));
+ return JSValue::encode(Stringifier(exec, replacer, space).stringify(value).get());
}
UString JSONStringify(ExecState* exec, JSValue value, unsigned indent)
{
- JSValue result = Stringifier(exec, jsNull(), jsNumber(indent)).stringify(value);
+ LocalScope scope(exec->globalData());
+ Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->globalData(), jsNull()), Local<Unknown>(exec->globalData(), jsNumber(indent))).stringify(Local<Unknown>(exec->globalData(), value));
if (result.isUndefinedOrNull())
return UString();
return result.getString(exec);
diff --git a/Source/JavaScriptCore/runtime/JSONObject.h b/Source/JavaScriptCore/runtime/JSONObject.h
index acffeca..a52c543 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.h
+++ b/Source/JavaScriptCore/runtime/JSONObject.h
@@ -36,13 +36,11 @@ namespace JSC {
public:
JSONObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- static void markStringifiers(MarkStack&, Stringifier*);
-
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 87fbb67..b307540 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -43,7 +43,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSObject);
ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject);
-ASSERT_CLASS_FILLS_CELL(JSFinalObject);
+ASSERT_CLASS_FITS_IN_CELL(JSFinalObject);
const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property.";
@@ -489,7 +489,7 @@ UString JSObject::toString(ExecState* exec) const
return primitive.toString(exec);
}
-JSObject* JSObject::toObject(ExecState*) const
+JSObject* JSObject::toObject(ExecState*, JSGlobalObject*) const
{
return const_cast<JSObject*>(this);
}
@@ -572,9 +572,9 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, WriteBarr
slot.setUndefined();
}
-Structure* JSObject::createInheritorID()
+Structure* JSObject::createInheritorID(JSGlobalData& globalData)
{
- m_inheritorID = createEmptyObjectStructure(this);
+ m_inheritorID = createEmptyObjectStructure(globalData, this);
return m_inheritorID.get();
}
@@ -743,12 +743,12 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
// Changing the accessor functions of an existing accessor property
ASSERT(descriptor.isAccessorDescriptor());
if (!current.configurable()) {
- if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
+ if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
if (throwException)
throwError(exec, createTypeError(exec, "Attempting to change the setter of an unconfigurable property."));
return false;
}
- if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
+ if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
if (throwException)
throwError(exec, createTypeError(exec, "Attempting to change the getter of an unconfigurable property."));
return false;
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 2b4db43..578b3cf 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -92,7 +92,7 @@ namespace JSC {
bool setPrototypeWithCycleCheck(JSValue prototype);
void setStructure(NonNullPassRefPtr<Structure>);
- Structure* inheritorID();
+ Structure* inheritorID(JSGlobalData&);
virtual UString className() const;
@@ -138,7 +138,7 @@ namespace JSC {
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
virtual JSObject* toThisObject(ExecState*) const;
virtual JSValue toStrictThisObject(ExecState*) const;
@@ -250,9 +250,9 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static const unsigned StructureFlags = 0;
@@ -296,7 +296,7 @@ namespace JSC {
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
- Structure* createInheritorID();
+ Structure* createInheritorID(JSGlobalData&);
PropertyStorage m_propertyStorage;
RefPtr<Structure> m_inheritorID;
@@ -320,9 +320,9 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
friend class JSObject;
public:
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
@@ -348,9 +348,9 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
return new (exec) JSFinalObject(structure);
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
@@ -377,9 +377,9 @@ inline JSObject* constructEmptyObject(ExecState* exec, NonNullPassRefPtr<Structu
return JSFinalObject::create(exec, structure);
}
-inline PassRefPtr<Structure> createEmptyObjectStructure(JSValue prototype)
+inline PassRefPtr<Structure> createEmptyObjectStructure(JSGlobalData& globalData, JSValue prototype)
{
- return JSFinalObject::createStructure(prototype);
+ return JSFinalObject::createStructure(globalData, prototype);
}
inline JSObject* asObject(JSCell* cell)
@@ -442,11 +442,11 @@ inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure)
m_structure = structure.leakRef(); // ~JSObject balances this ref()
}
-inline Structure* JSObject::inheritorID()
+inline Structure* JSObject::inheritorID(JSGlobalData& globalData)
{
if (m_inheritorID)
return m_inheritorID.get();
- return createInheritorID();
+ return createInheritorID(globalData);
}
inline bool Structure::isUsingInlineStorage() const
@@ -814,8 +814,10 @@ inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
{
JSCell::markChildren(markStack);
-
+
markStack.append(m_structure->storedPrototypeSlot());
+ if (*m_structure->cachedPrototypeChainSlot())
+ markStack.append(m_structure->cachedPrototypeChainSlot());
PropertyStorage storage = propertyStorage();
size_t storageSize = m_structure->propertyStorageSize();
markStack.appendValues(storage, storageSize);
@@ -840,6 +842,20 @@ inline JSValue JSValue::toStrictThisObject(ExecState* exec) const
return asObject(asCell())->toStrictThisObject(exec);
}
+ALWAYS_INLINE JSObject* Register::function() const
+{
+ if (!jsValue())
+ return 0;
+ return asObject(jsValue());
+}
+
+ALWAYS_INLINE Register Register::withCallee(JSObject* callee)
+{
+ Register r;
+ r = JSValue(callee);
+ return r;
+}
+
} // namespace JSC
#endif // JSObject_h
diff --git a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
index c5e3047..8380514 100644
--- a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
@@ -34,9 +34,9 @@ class JSGlobalObject;
class JSObjectWithGlobalObject : public JSNonFinalObject {
public:
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
JSGlobalObject* globalObject() const;
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 0d759cf..6f31f99 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -77,7 +77,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
return jsPropertyNameIterator;
}
- jsPropertyNameIterator->setCachedPrototypeChain(structureChain);
+ jsPropertyNameIterator->setCachedPrototypeChain(exec->globalData(), structureChain);
jsPropertyNameIterator->setCachedStructure(o->structure());
o->structure()->setEnumerationCache(exec->globalData(), jsPropertyNameIterator);
return jsPropertyNameIterator;
@@ -86,7 +86,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
{
JSValue identifier = m_jsStrings[i].get();
- if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
+ if (m_cachedStructure == base->structure() && m_cachedPrototypeChain.get() == base->structure()->prototypeChain(exec))
return identifier;
if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec))))
@@ -97,6 +97,8 @@ JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
void JSPropertyNameIterator::markChildren(MarkStack& markStack)
{
markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
+ if (m_cachedPrototypeChain)
+ markStack.append(&m_cachedPrototypeChain);
}
#if !ASSERT_DISABLED
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index d51cba8..499396c 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -45,9 +45,9 @@ namespace JSC {
public:
static JSPropertyNameIterator* create(ExecState*, JSObject*);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount, 0);
}
virtual bool isPropertyNameIterator() const { return true; }
@@ -73,7 +73,7 @@ namespace JSC {
}
Structure* cachedStructure() { return m_cachedStructure.get(); }
- void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+ void setCachedPrototypeChain(JSGlobalData& globalData, StructureChain* cachedPrototypeChain) { m_cachedPrototypeChain.set(globalData, this, cachedPrototypeChain); }
StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
private:
@@ -84,7 +84,7 @@ namespace JSC {
#endif
RefPtr<Structure> m_cachedStructure;
- RefPtr<StructureChain> m_cachedPrototypeChain;
+ WriteBarrier<StructureChain> m_cachedPrototypeChain;
uint32_t m_numCacheableSlots;
uint32_t m_jsStringsSize;
OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
@@ -106,6 +106,11 @@ namespace JSC {
return m_enumerationCache.get();
}
+ ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
+ {
+ return static_cast<JSPropertyNameIterator*>(jsValue().asCell());
+ }
+
} // namespace JSC
#endif // JSPropertyNameIterator_h
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index 727ac28..3d4dc7c 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -28,13 +28,12 @@
#include "JSStaticScopeObject.h"
namespace JSC {
-
ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject);
void JSStaticScopeObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
- markStack.deprecatedAppend(&d()->registerStore);
+ markStack.append(&m_registerStore);
}
JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
@@ -68,12 +67,6 @@ bool JSStaticScopeObject::isDynamicScope(bool&) const
return false;
}
-JSStaticScopeObject::~JSStaticScopeObject()
-{
- ASSERT(d());
- delete d();
-}
-
bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot& slot)
{
return symbolTableGet(propertyName, slot);
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
index b3c0695..3e19bbc 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -31,25 +31,14 @@
namespace JSC{
class JSStaticScopeObject : public JSVariableObject {
- protected:
- using JSVariableObject::JSVariableObjectData;
- struct JSStaticScopeObjectData : public JSVariableObjectData {
- JSStaticScopeObjectData()
- : JSVariableObjectData(&symbolTable, &registerStore + 1)
- {
- }
- SymbolTable symbolTable;
- Register registerStore;
- };
-
public:
JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue value, unsigned attributes)
- : JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData())
+ : JSVariableObject(exec->globalData().staticScopeStructure, &m_symbolTable, reinterpret_cast<Register*>(&m_registerStore + 1))
{
- d()->registerStore = value;
+ m_registerStore.set(exec->globalData(), this, value);
symbolTable().add(ident.impl(), SymbolTableEntry(-1, attributes));
}
- virtual ~JSStaticScopeObject();
+
virtual void markChildren(MarkStack&);
bool isDynamicScope(bool& requiresDynamicChecks) const;
virtual JSObject* toThisObject(ExecState*) const;
@@ -58,13 +47,14 @@ namespace JSC{
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
private:
- JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
+ SymbolTable m_symbolTable;
+ WriteBarrier<Unknown> m_registerStore;
};
}
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index 848c431..d9c4d46 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -152,7 +152,7 @@ JSString* JSString::substringFromRope(ExecState* exec, unsigned substringStart,
if (substringLength == 1) {
ASSERT(substringFiberCount == 1);
UChar c = substringFibers[0].characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
if (substringFiberCount == 1)
@@ -253,19 +253,19 @@ UString JSString::toString(ExecState* exec) const
return value(exec);
}
-inline StringObject* StringObject::create(ExecState* exec, JSString* string)
+inline StringObject* StringObject::create(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
{
- return new (exec) StringObject(exec->globalData(), exec->lexicalGlobalObject()->stringObjectStructure(), string);
+ return new (exec) StringObject(exec->globalData(), globalObject->stringObjectStructure(), string);
}
-JSObject* JSString::toObject(ExecState* exec) const
+JSObject* JSString::toObject(ExecState* exec, JSGlobalObject* globalObject) const
{
- return StringObject::create(exec, const_cast<JSString*>(this));
+ return StringObject::create(exec, globalObject, const_cast<JSString*>(this));
}
JSObject* JSString::toThisObject(ExecState* exec) const
{
- return StringObject::create(exec, const_cast<JSString*>(this));
+ return StringObject::create(exec, exec->lexicalGlobalObject(), const_cast<JSString*>(this));
}
bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index 3672300..9113d4a 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -349,7 +349,7 @@ namespace JSC {
JSValue replaceCharacter(ExecState*, UChar, const UString& replacement);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount, 0); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount, 0); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
@@ -402,7 +402,7 @@ namespace JSC {
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
@@ -468,7 +468,7 @@ namespace JSC {
inline JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c)
{
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1)));
}
@@ -478,7 +478,7 @@ namespace JSC {
JSGlobalData* globalData = &exec->globalData();
ASSERT(offset < static_cast<unsigned>(s.length()));
UChar c = s.characters()[offset];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, 1))));
}
@@ -513,7 +513,7 @@ namespace JSC {
return globalData->smallStrings.emptyString(globalData);
if (size == 1) {
UChar c = s.characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
return fixupVPtr(globalData, new (globalData) JSString(globalData, s));
@@ -521,7 +521,7 @@ namespace JSC {
inline JSString* jsStringWithFinalizer(ExecState* exec, const UString& s, JSStringFinalizerCallback callback, void* context)
{
- ASSERT(s.length() && (s.length() > 1 || s.characters()[0] > 0xFF));
+ ASSERT(s.length() && (s.length() > 1 || s.characters()[0] > maxSingleCharacterString));
JSGlobalData* globalData = &exec->globalData();
return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context));
}
@@ -548,7 +548,7 @@ namespace JSC {
return globalData->smallStrings.emptyString(globalData);
if (length == 1) {
UChar c = s.characters()[offset];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, length)), JSString::HasOtherOwner));
@@ -561,7 +561,7 @@ namespace JSC {
return globalData->smallStrings.emptyString(globalData);
if (size == 1) {
UChar c = s.characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
return fixupVPtr(globalData, new (globalData) JSString(globalData, s, JSString::HasOtherOwner));
diff --git a/Source/JavaScriptCore/runtime/JSTypeInfo.h b/Source/JavaScriptCore/runtime/JSTypeInfo.h
index fdcaf31..284d2b2 100644
--- a/Source/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/Source/JavaScriptCore/runtime/JSTypeInfo.h
@@ -46,7 +46,6 @@ namespace JSC {
static const unsigned IsJSFinalObject = 1 << 8;
class TypeInfo {
- friend class JIT;
public:
TypeInfo(JSType type, unsigned flags = 0)
: m_type(type)
@@ -72,6 +71,16 @@ namespace JSC {
unsigned flags() const { return m_flags; }
unsigned isFinal() const { return m_flags2 && (IsJSFinalObject >> 8); }
+ static ptrdiff_t flagsOffset()
+ {
+ return OBJECT_OFFSETOF(TypeInfo, m_flags);
+ }
+
+ static ptrdiff_t typeOffset()
+ {
+ return OBJECT_OFFSETOF(TypeInfo, m_type);
+ }
+
private:
unsigned char m_type;
unsigned char m_flags;
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index f4662db..d3ee89e 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -54,14 +54,14 @@ double JSValue::toIntegerPreserveNaN(ExecState* exec) const
return trunc(toNumber(exec));
}
-JSObject* JSValue::toObjectSlowCase(ExecState* exec) const
+JSObject* JSValue::toObjectSlowCase(ExecState* exec, JSGlobalObject* globalObject) const
{
ASSERT(!isCell());
if (isInt32() || isDouble())
- return constructNumber(exec, asValue());
+ return constructNumber(exec, globalObject, asValue());
if (isTrue() || isFalse())
- return constructBooleanFromImmediateBoolean(exec, asValue());
+ return constructBooleanFromImmediateBoolean(exec, globalObject, asValue());
ASSERT(isUndefinedOrNull());
throwError(exec, createNotAnObjectError(exec, *this));
@@ -73,9 +73,9 @@ JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
ASSERT(!isCell());
if (isInt32() || isDouble())
- return constructNumber(exec, asValue());
+ return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
if (isTrue() || isFalse())
- return constructBooleanFromImmediateBoolean(exec, asValue());
+ return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
ASSERT(isUndefinedOrNull());
return exec->globalThisValue();
}
@@ -84,9 +84,9 @@ JSObject* JSValue::synthesizeObject(ExecState* exec) const
{
ASSERT(!isCell());
if (isNumber())
- return constructNumber(exec, asValue());
+ return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
if (isBoolean())
- return constructBooleanFromImmediateBoolean(exec, asValue());
+ return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
ASSERT(isUndefinedOrNull());
throwError(exec, createNotAnObjectError(exec, *this));
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index b2e7a51..098123e 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -37,6 +37,7 @@ namespace JSC {
class Identifier;
class JSCell;
class JSGlobalData;
+ class JSGlobalObject;
class JSImmediate;
class JSObject;
class JSString;
@@ -52,11 +53,33 @@ namespace JSC {
enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
+
#if USE(JSVALUE32_64)
typedef int64_t EncodedJSValue;
#else
typedef void* EncodedJSValue;
#endif
+
+ union EncodedValueDescriptor {
+ EncodedJSValue asEncodedJSValue;
+#if USE(JSVALUE32_64)
+ double asDouble;
+#elif USE(JSVALUE64)
+ JSCell* ptr;
+#endif
+
+#if CPU(BIG_ENDIAN)
+ struct {
+ int32_t tag;
+ int32_t payload;
+ } asBits;
+#else
+ struct {
+ int32_t payload;
+ int32_t tag;
+ } asBits;
+#endif
+ };
double nonInlineNaN();
@@ -167,6 +190,7 @@ namespace JSC {
UString toString(ExecState*) const;
UString toPrimitiveString(ExecState*) const;
JSObject* toObject(ExecState*) const;
+ JSObject* toObject(ExecState*, JSGlobalObject*) const;
// Integer conversions.
double toInteger(ExecState*) const;
@@ -222,7 +246,7 @@ namespace JSC {
JSValue(HashTableDeletedValueTag);
inline const JSValue asValue() const { return *this; }
- JSObject* toObjectSlowCase(ExecState*) const;
+ JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
JSObject* toThisObjectSlowCase(ExecState*) const;
JSObject* synthesizePrototype(ExecState*) const;
@@ -239,28 +263,14 @@ namespace JSC {
enum { DeletedValueTag = 0xfffffff8 };
enum { LowestTag = DeletedValueTag };
-
+
uint32_t tag() const;
int32_t payload() const;
- union {
- EncodedJSValue asEncodedJSValue;
- double asDouble;
-#if CPU(BIG_ENDIAN)
- struct {
- int32_t tag;
- int32_t payload;
- } asBits;
-#else
- struct {
- int32_t payload;
- int32_t tag;
- } asBits;
-#endif
- } u;
-#else // USE(JSVALUE32_64)
+ EncodedValueDescriptor u;
+#elif USE(JSVALUE64)
JSCell* m_ptr;
-#endif // USE(JSVALUE32_64)
+#endif
};
#if USE(JSVALUE32_64)
@@ -392,9 +402,6 @@ namespace JSC {
{
JSValue v;
v.u.asEncodedJSValue = encodedJSValue;
-#if ENABLE(JSC_ZOMBIES)
- ASSERT(!v.isZombie());
-#endif
return v;
}
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index e94d277..891ada8 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -44,7 +44,7 @@ namespace JSC {
friend class JIT;
public:
- SymbolTable& symbolTable() const { return *d->symbolTable; }
+ SymbolTable& symbolTable() const { return *m_symbolTable; }
virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
@@ -54,39 +54,24 @@ namespace JSC {
virtual bool isVariableObject() const;
virtual bool isDynamicScope(bool& requiresDynamicChecks) const = 0;
- WriteBarrier<Unknown>& registerAt(int index) const { return d->registers[index]; }
+ WriteBarrier<Unknown>& registerAt(int index) const { return m_registers[index]; }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; }
+
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags;
- // Subclasses of JSVariableObject can subclass this struct to add data
- // without increasing their own size (since there's a hard limit on the
- // size of a JSCell).
- struct JSVariableObjectData {
- JSVariableObjectData(SymbolTable* symbolTable, Register* registers)
- : symbolTable(symbolTable)
- , registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
- {
- ASSERT(symbolTable);
- }
-
- SymbolTable* symbolTable; // Maps name -> offset from "r" in register file.
- WriteBarrier<Unknown>* registers; // "r" in the register file.
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
-
- private:
- JSVariableObjectData(const JSVariableObjectData&);
- JSVariableObjectData& operator=(const JSVariableObjectData&);
- };
-
- JSVariableObject(NonNullPassRefPtr<Structure> structure, JSVariableObjectData* data)
+
+ JSVariableObject(NonNullPassRefPtr<Structure> structure, SymbolTable* symbolTable, Register* registers)
: JSNonFinalObject(structure)
- , d(data) // Subclass owns this pointer.
+ , m_symbolTable(symbolTable)
+ , m_registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
{
+ ASSERT(m_symbolTable);
COMPILE_ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrier);
}
@@ -99,7 +84,9 @@ namespace JSC {
bool symbolTablePut(JSGlobalData&, const Identifier&, JSValue);
bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
- JSVariableObjectData* d;
+ SymbolTable* m_symbolTable; // Maps name -> offset from "r" in register file.
+ WriteBarrier<Unknown>* m_registers; // "r" in the register file.
+ OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
};
inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
@@ -161,9 +148,9 @@ namespace JSC {
inline void JSVariableObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray)
{
- ASSERT(registerArray != d->registerArray);
- d->registerArray = registerArray;
- d->registers = registers;
+ ASSERT(registerArray != m_registerArray);
+ m_registerArray = registerArray;
+ m_registers = registers;
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h
index 6d586df..63833e9 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h
@@ -30,19 +30,19 @@ namespace JSC {
// Number, Boolean and Date which are wrappers for primitive types.
class JSWrapperObject : public JSNonFinalObject {
protected:
- explicit JSWrapperObject(JSGlobalData&, NonNullPassRefPtr<Structure>);
+ explicit JSWrapperObject(NonNullPassRefPtr<Structure>);
public:
- JSValue internalValue() const { return m_internalValue.get(); }
+ JSValue internalValue() const;
void setInternalValue(JSGlobalData&, JSValue);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- static const unsigned AnonymousSlotCount = 1 + JSObject::AnonymousSlotCount;
+ static const unsigned StructureFlags = OverridesMarkChildren | JSNonFinalObject::StructureFlags;
private:
virtual void markChildren(MarkStack&);
@@ -50,10 +50,14 @@ namespace JSC {
WriteBarrier<Unknown> m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
+ inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure)
: JSNonFinalObject(structure)
{
- putAnonymousValue(globalData, 0, jsNull());
+ }
+
+ inline JSValue JSWrapperObject::internalValue() const
+ {
+ return m_internalValue.get();
}
inline void JSWrapperObject::setInternalValue(JSGlobalData& globalData, JSValue value)
@@ -61,7 +65,6 @@ namespace JSC {
ASSERT(value);
ASSERT(!value.isObject());
m_internalValue.set(globalData, this, value);
- putAnonymousValue(globalData, 0, value);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSZombie.cpp b/Source/JavaScriptCore/runtime/JSZombie.cpp
index c0c5f11..23cf135 100644
--- a/Source/JavaScriptCore/runtime/JSZombie.cpp
+++ b/Source/JavaScriptCore/runtime/JSZombie.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSZombie.h"
#include "ClassInfo.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#if ENABLE(JSC_ZOMBIES)
@@ -38,7 +39,7 @@ Structure* JSZombie::leakedZombieStructure() {
static Structure* structure = 0;
if (!structure) {
Structure::startIgnoringLeaks();
- structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0, &info).leakRef();
+ structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0, &s_info).leakRef();
Structure::stopIgnoringLeaks();
}
return structure;
diff --git a/Source/JavaScriptCore/runtime/JSZombie.h b/Source/JavaScriptCore/runtime/JSZombie.h
index 5fe6b6d..179ff53 100644
--- a/Source/JavaScriptCore/runtime/JSZombie.h
+++ b/Source/JavaScriptCore/runtime/JSZombie.h
@@ -66,9 +66,9 @@ public:
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, 0), AnonymousSlotCount, &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
index 4614a7c..3e205a1 100644
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
@@ -28,6 +28,11 @@
#include "JSGlobalData.h"
#include <setjmp.h>
#include <stdlib.h>
+#include <wtf/StdLibExtras.h>
+
+#if USE(PTHREAD_BASED_QT) && !defined(WTF_USE_PTHREADS)
+#define WTF_USE_PTHREADS 1
+#endif
#if OS(DARWIN)
@@ -74,12 +79,14 @@
#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
#include <signal.h>
#ifndef SA_RESTART
-#error MachineStackMarker requires SA_RESTART
+#error MachineThreads requires SA_RESTART
#endif
#endif
#endif
+using namespace WTF;
+
namespace JSC {
static inline void swapIfBackwards(void*& begin, void*& end)
@@ -113,7 +120,7 @@ static void pthreadSignalHandlerSuspendResume(int signo)
}
#endif
-class MachineStackMarker::Thread {
+class MachineThreads::Thread {
public:
Thread(pthread_t pthread, const PlatformThread& platThread, void* base)
: posixThread(pthread)
@@ -142,20 +149,20 @@ public:
#endif
-MachineStackMarker::MachineStackMarker(Heap* heap)
+MachineThreads::MachineThreads(Heap* heap)
: m_heap(heap)
#if ENABLE(JSC_MULTIPLE_THREADS)
, m_registeredThreads(0)
- , m_currentThreadRegistrar(0)
+ , m_threadSpecific(0)
#endif
{
}
-MachineStackMarker::~MachineStackMarker()
+MachineThreads::~MachineThreads()
{
#if ENABLE(JSC_MULTIPLE_THREADS)
- if (m_currentThreadRegistrar) {
- int error = pthread_key_delete(m_currentThreadRegistrar);
+ if (m_threadSpecific) {
+ int error = pthread_key_delete(m_threadSpecific);
ASSERT_UNUSED(error, !error);
}
@@ -181,24 +188,24 @@ static inline PlatformThread getCurrentPlatformThread()
#endif
}
-void MachineStackMarker::makeUsableFromMultipleThreads()
+void MachineThreads::makeUsableFromMultipleThreads()
{
- if (m_currentThreadRegistrar)
+ if (m_threadSpecific)
return;
- int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
+ int error = pthread_key_create(&m_threadSpecific, removeThread);
if (error)
CRASH();
}
-void MachineStackMarker::registerThread()
+void MachineThreads::addCurrentThread()
{
ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
- if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
+ if (!m_threadSpecific || pthread_getspecific(m_threadSpecific))
return;
- pthread_setspecific(m_currentThreadRegistrar, this);
+ pthread_setspecific(m_threadSpecific, this);
Thread* thread = new Thread(pthread_self(), getCurrentPlatformThread(), m_heap->globalData()->stack().origin());
MutexLocker lock(m_registeredThreadsMutex);
@@ -207,13 +214,13 @@ void MachineStackMarker::registerThread()
m_registeredThreads = thread;
}
-void MachineStackMarker::unregisterThread(void* p)
+void MachineThreads::removeThread(void* p)
{
if (p)
- static_cast<MachineStackMarker*>(p)->unregisterThread();
+ static_cast<MachineThreads*>(p)->removeCurrentThread();
}
-void MachineStackMarker::unregisterThread()
+void MachineThreads::removeCurrentThread()
{
pthread_t currentPosixThread = pthread_self();
@@ -240,21 +247,13 @@ void MachineStackMarker::unregisterThread()
#endif
-void NEVER_INLINE MachineStackMarker::markCurrentThreadConservativelyInternal(ConservativeSet& conservativeSet)
-{
- void* begin = m_heap->globalData()->stack().current();
- void* end = m_heap->globalData()->stack().origin();
- swapIfBackwards(begin, end);
- conservativeSet.add(begin, end);
-}
-
#if COMPILER(GCC)
#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
#else
#define REGISTER_BUFFER_ALIGNMENT
#endif
-void MachineStackMarker::markCurrentThreadConservatively(ConservativeSet& conservativeSet)
+void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, void* stackCurrent)
{
// setjmp forces volatile registers onto the stack
jmp_buf registers REGISTER_BUFFER_ALIGNMENT;
@@ -267,7 +266,15 @@ void MachineStackMarker::markCurrentThreadConservatively(ConservativeSet& conser
#pragma warning(pop)
#endif
- markCurrentThreadConservativelyInternal(conservativeSet);
+ void* registersBegin = &registers;
+ void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&registers + 1)));
+ swapIfBackwards(registersBegin, registersEnd);
+ conservativeRoots.add(registersBegin, registersEnd);
+
+ void* stackBegin = stackCurrent;
+ void* stackEnd = m_heap->globalData()->stack().origin();
+ swapIfBackwards(stackBegin, stackEnd);
+ conservativeRoots.add(stackBegin, stackEnd);
}
#if ENABLE(JSC_MULTIPLE_THREADS)
@@ -431,20 +438,19 @@ static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
#endif
}
-void MachineStackMarker::markOtherThreadConservatively(ConservativeSet& conservativeSet, Thread* thread)
+void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, Thread* thread)
{
suspendThread(thread->platformThread);
PlatformThreadRegisters regs;
size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
- // mark the thread's registers
- conservativeSet.add(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
+ conservativeRoots.add(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
void* stackPointer = otherThreadStackPointer(regs);
void* stackBase = thread->stackBase;
swapIfBackwards(stackPointer, stackBase);
- conservativeSet.add(stackPointer, stackBase);
+ conservativeRoots.add(stackPointer, stackBase);
resumeThread(thread->platformThread);
@@ -453,27 +459,27 @@ void MachineStackMarker::markOtherThreadConservatively(ConservativeSet& conserva
#endif
-void MachineStackMarker::markMachineStackConservatively(ConservativeSet& conservativeSet)
+void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, void* stackCurrent)
{
- markCurrentThreadConservatively(conservativeSet);
+ gatherFromCurrentThread(conservativeRoots, stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS)
- if (m_currentThreadRegistrar) {
+ if (m_threadSpecific) {
MutexLocker lock(m_registeredThreadsMutex);
#ifndef NDEBUG
- // Forbid malloc during the mark phase. Marking a thread suspends it, so
- // a malloc inside markChildren() would risk a deadlock with a thread that had been
- // suspended while holding the malloc lock.
+ // Forbid malloc during the gather phase. The gather phase suspends
+ // threads, so a malloc during gather would risk a deadlock with a
+ // thread that had been suspended while holding the malloc lock.
fastMallocForbid();
#endif
// It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
// and since this is a shared heap, they are real locks.
for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
if (!pthread_equal(thread->posixThread, pthread_self()))
- markOtherThreadConservatively(conservativeSet, thread);
+ gatherFromOtherThread(conservativeRoots, thread);
}
#ifndef NDEBUG
fastMallocAllow();
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.h b/Source/JavaScriptCore/runtime/MachineStackMarker.h
index 8afdb46..c814ac5 100644
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.h
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef MachineStackMarker_h
-#define MachineStackMarker_h
+#ifndef MachineThreads_h
+#define MachineThreads_h
#include <wtf/Noncopyable.h>
#include <wtf/ThreadingPrimitives.h>
@@ -32,32 +32,31 @@
namespace JSC {
class Heap;
- class ConservativeSet;
+ class ConservativeRoots;
- class MachineStackMarker {
- WTF_MAKE_NONCOPYABLE(MachineStackMarker);
+ class MachineThreads {
+ WTF_MAKE_NONCOPYABLE(MachineThreads);
public:
- MachineStackMarker(Heap*);
- ~MachineStackMarker();
+ MachineThreads(Heap*);
+ ~MachineThreads();
- void markMachineStackConservatively(ConservativeSet&);
+ void gatherConservativeRoots(ConservativeRoots&, void* stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS)
void makeUsableFromMultipleThreads();
- void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
+ void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
#endif
private:
- void markCurrentThreadConservatively(ConservativeSet&);
- void markCurrentThreadConservativelyInternal(ConservativeSet&);
+ void gatherFromCurrentThread(ConservativeRoots&, void* stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS)
class Thread;
- static void unregisterThread(void*);
+ static void removeThread(void*);
+ void removeCurrentThread();
- void unregisterThread();
- void markOtherThreadConservatively(ConservativeSet&, Thread*);
+ void gatherFromOtherThread(ConservativeRoots&, Thread*);
#endif
Heap* m_heap;
@@ -65,10 +64,10 @@ namespace JSC {
#if ENABLE(JSC_MULTIPLE_THREADS)
Mutex m_registeredThreadsMutex;
Thread* m_registeredThreads;
- pthread_key_t m_currentThreadRegistrar;
+ pthread_key_t m_threadSpecific;
#endif
};
} // namespace JSC
-#endif // MachineStackMarker_h
+#endif // MachineThreads_h
diff --git a/Source/JavaScriptCore/runtime/MarkStack.cpp b/Source/JavaScriptCore/runtime/MarkStack.cpp
index a350c35..e9d1b13 100644
--- a/Source/JavaScriptCore/runtime/MarkStack.cpp
+++ b/Source/JavaScriptCore/runtime/MarkStack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,14 @@
#include "config.h"
#include "MarkStack.h"
+#include "ConservativeSet.h"
+#include "Heap.h"
+#include "JSArray.h"
+#include "JSCell.h"
+#include "JSObject.h"
+#include "ScopeChain.h"
+#include "Structure.h"
+
namespace JSC {
size_t MarkStack::s_pageSize = 0;
@@ -37,4 +45,83 @@ void MarkStack::compact()
m_markSets.shrinkAllocation(s_pageSize);
}
+void MarkStack::append(ConservativeRoots& conservativeRoots)
+{
+ JSCell** roots = conservativeRoots.roots();
+ size_t size = conservativeRoots.size();
+ for (size_t i = 0; i < size; ++i)
+ internalAppend(roots[i]);
}
+
+inline void MarkStack::markChildren(JSCell* cell)
+{
+ ASSERT(Heap::isMarked(cell));
+ if (!cell->structure()->typeInfo().overridesMarkChildren()) {
+#ifdef NDEBUG
+ asObject(cell)->markChildrenDirect(*this);
+#else
+ ASSERT(!m_isCheckingForDefaultMarkViolation);
+ m_isCheckingForDefaultMarkViolation = true;
+ cell->markChildren(*this);
+ ASSERT(m_isCheckingForDefaultMarkViolation);
+ m_isCheckingForDefaultMarkViolation = false;
+#endif
+ return;
+ }
+ if (cell->vptr() == m_jsArrayVPtr) {
+ asArray(cell)->markChildrenDirect(*this);
+ return;
+ }
+ cell->markChildren(*this);
+}
+
+void MarkStack::drain()
+{
+#if !ASSERT_DISABLED
+ ASSERT(!m_isDraining);
+ m_isDraining = true;
+#endif
+ while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
+ while (!m_markSets.isEmpty() && m_values.size() < 50) {
+ ASSERT(!m_markSets.isEmpty());
+ MarkSet& current = m_markSets.last();
+ ASSERT(current.m_values);
+ JSValue* end = current.m_end;
+ ASSERT(current.m_values);
+ ASSERT(current.m_values != end);
+ findNextUnmarkedNullValue:
+ ASSERT(current.m_values != end);
+ JSValue value = *current.m_values;
+ current.m_values++;
+
+ JSCell* cell;
+ if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
+ if (current.m_values == end) {
+ m_markSets.removeLast();
+ continue;
+ }
+ goto findNextUnmarkedNullValue;
+ }
+
+ if (cell->structure()->typeInfo().type() < CompoundType) {
+ if (current.m_values == end) {
+ m_markSets.removeLast();
+ continue;
+ }
+ goto findNextUnmarkedNullValue;
+ }
+
+ if (current.m_values == end)
+ m_markSets.removeLast();
+
+ markChildren(cell);
+ }
+ while (!m_values.isEmpty())
+ markChildren(m_values.removeLast());
+ }
+#if !ASSERT_DISABLED
+ m_isDraining = false;
+#endif
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MarkStack.h b/Source/JavaScriptCore/runtime/MarkStack.h
index 0b7941e..7131917 100644
--- a/Source/JavaScriptCore/runtime/MarkStack.h
+++ b/Source/JavaScriptCore/runtime/MarkStack.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
#define MarkStack_h
#include "JSValue.h"
+#include "Register.h"
#include "WriteBarrier.h"
#include <wtf/Vector.h>
#include <wtf/Noncopyable.h>
@@ -34,6 +35,7 @@
namespace JSC {
+ class ConservativeRoots;
class JSGlobalData;
class Register;
@@ -50,7 +52,13 @@ namespace JSC {
#endif
{
}
-
+
+ ~MarkStack()
+ {
+ ASSERT(m_markSets.isEmpty());
+ ASSERT(m_values.isEmpty());
+ }
+
void deprecatedAppend(JSValue*);
void deprecatedAppend(JSCell**);
void deprecatedAppend(Register*);
@@ -70,17 +78,18 @@ namespace JSC {
if (count)
m_markSets.append(MarkSet(values, values + count, properties));
}
+
+ void append(ConservativeRoots&);
- inline void drain();
+ void drain();
void compact();
- ~MarkStack()
- {
- ASSERT(m_markSets.isEmpty());
- ASSERT(m_values.isEmpty());
- }
-
private:
+ friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
+ void append(JSValue*);
+ void append(JSValue*, size_t count);
+ void append(JSCell**);
+
void internalAppend(JSCell*);
void internalAppend(JSValue);
void markChildren(JSCell*);
@@ -196,7 +205,105 @@ namespace JSC {
bool m_isDraining;
#endif
};
+
+ inline void MarkStack::append(JSValue* slot, size_t count)
+ {
+ if (!count)
+ return;
+ m_markSets.append(MarkSet(slot, slot + count, NoNullValues));
+ }
+
+ template <typename T> inline void MarkStack::append(DeprecatedPtr<T>* slot)
+ {
+ internalAppend(*slot->slot());
+ }
-}
+ template <typename T> inline void MarkStack::append(WriteBarrierBase<T>* slot)
+ {
+ internalAppend(*slot->slot());
+ }
+
+ ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
+ {
+ ASSERT(value);
+ internalAppend(*value);
+ }
+
+ ALWAYS_INLINE void MarkStack::deprecatedAppend(JSValue* value)
+ {
+ ASSERT(value);
+ internalAppend(*value);
+ }
+
+ ALWAYS_INLINE void MarkStack::append(JSValue* value)
+ {
+ ASSERT(value);
+ internalAppend(*value);
+ }
+
+ ALWAYS_INLINE void MarkStack::append(JSCell** value)
+ {
+ ASSERT(value);
+ internalAppend(*value);
+ }
+
+ ALWAYS_INLINE void MarkStack::deprecatedAppend(Register* value)
+ {
+ ASSERT(value);
+ internalAppend(value->jsValue());
+ }
+
+ ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
+ {
+ ASSERT(value);
+ if (value.isCell())
+ internalAppend(value.asCell());
+ }
+
+ // Privileged class for marking JSValues directly. It is only safe to use
+ // this class to mark direct heap roots that are marked during every GC pass.
+ // All other references should be wrapped in WriteBarriers and marked through
+ // the MarkStack.
+ class HeapRootMarker {
+ private:
+ friend class Heap;
+ HeapRootMarker(MarkStack&);
+
+ public:
+ void mark(JSValue*);
+ void mark(JSValue*, size_t);
+ void mark(JSString**);
+ void mark(JSCell**);
+
+ private:
+ MarkStack& m_markStack;
+ };
+
+ inline HeapRootMarker::HeapRootMarker(MarkStack& markStack)
+ : m_markStack(markStack)
+ {
+ }
+
+ inline void HeapRootMarker::mark(JSValue* slot)
+ {
+ m_markStack.append(slot);
+ }
+
+ inline void HeapRootMarker::mark(JSValue* slot, size_t count)
+ {
+ m_markStack.append(slot, count);
+ }
+
+ inline void HeapRootMarker::mark(JSString** slot)
+ {
+ m_markStack.append(reinterpret_cast<JSCell**>(slot));
+ }
+
+ inline void HeapRootMarker::mark(JSCell** slot)
+ {
+ m_markStack.append(slot);
+ }
+
+} // namespace JSC
#endif
diff --git a/Source/JavaScriptCore/runtime/MarkedBlock.cpp b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
index 48dda4c..cae701f 100644
--- a/Source/JavaScriptCore/runtime/MarkedBlock.cpp
+++ b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
@@ -27,6 +27,8 @@
#include "MarkedBlock.h"
#include "JSCell.h"
+#include "JSObject.h"
+#include "JSZombie.h"
#include "ScopeChain.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/MarkedBlock.h b/Source/JavaScriptCore/runtime/MarkedBlock.h
index e80fe82..0e2b59c 100644
--- a/Source/JavaScriptCore/runtime/MarkedBlock.h
+++ b/Source/JavaScriptCore/runtime/MarkedBlock.h
@@ -24,6 +24,7 @@
#include <wtf/Bitmap.h>
#include <wtf/PageAllocationAligned.h>
+#include <wtf/StdLibExtras.h>
namespace JSC {
@@ -35,15 +36,6 @@ namespace JSC {
static const size_t KB = 1024;
- // Efficient implementation that takes advantage of powers of two.
- template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
- {
- COMPILE_ASSERT(divisor && !(divisor & (divisor - 1)), divisor_is_a_power_of_two);
-
- size_t remainderMask = divisor - 1;
- return (x + remainderMask) & ~remainderMask;
- }
-
class MarkedBlock {
public:
static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
@@ -109,7 +101,7 @@ namespace JSC {
inline size_t MarkedBlock::firstAtom()
{
- return roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize;
+ return WTF::roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize;
}
inline MarkedBlock::Atom* MarkedBlock::atoms()
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.cpp b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
index 15ab514..d9a1e42 100644
--- a/Source/JavaScriptCore/runtime/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
@@ -24,6 +24,7 @@
#include "JSCell.h"
#include "JSGlobalData.h"
#include "JSLock.h"
+#include "JSObject.h"
#include "ScopeChain.h"
namespace JSC {
@@ -35,7 +36,10 @@ MarkedSpace::MarkedSpace(JSGlobalData* globalData)
, m_highWaterMark(0)
, m_globalData(globalData)
{
- for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep)
+ for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
+ sizeClassFor(cellSize).cellSize = cellSize;
+
+ for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
sizeClassFor(cellSize).cellSize = cellSize;
}
@@ -148,7 +152,10 @@ void MarkedSpace::reset()
{
m_waterMark = 0;
- for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep)
+ for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
+ sizeClassFor(cellSize).reset();
+
+ for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
sizeClassFor(cellSize).reset();
BlockIterator end = m_blocks.end();
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.h b/Source/JavaScriptCore/runtime/MarkedSpace.h
index 2e88887..29a8cd0 100644
--- a/Source/JavaScriptCore/runtime/MarkedSpace.h
+++ b/Source/JavaScriptCore/runtime/MarkedSpace.h
@@ -32,8 +32,7 @@
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
-#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= MarkedSpace::maxCellSize, class_fits_in_cell)
-#define ASSERT_CLASS_FILLS_CELL(class) COMPILE_ASSERT(sizeof(class) == MarkedSpace::maxCellSize, class_fills_cell)
+#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) < MarkedSpace::maxCellSize, class_fits_in_cell)
namespace JSC {
@@ -48,7 +47,7 @@ namespace JSC {
WTF_MAKE_NONCOPYABLE(MarkedSpace);
public:
// Currently public for use in assertions.
- static const size_t maxCellSize = 64;
+ static const size_t maxCellSize = 1024;
static Heap* heap(JSCell*);
@@ -81,10 +80,15 @@ namespace JSC {
template<typename Functor> void forEach(Functor&);
private:
- // [ 8, 16... 64 ]
+ // [ 8, 16... 128 )
static const size_t preciseStep = MarkedBlock::atomSize;
- static const size_t preciseCutoff = maxCellSize;
- static const size_t preciseCount = preciseCutoff / preciseStep;
+ static const size_t preciseCutoff = 128;
+ static const size_t preciseCount = preciseCutoff / preciseStep - 1;
+
+ // [ 128, 256... 1024 )
+ static const size_t impreciseStep = preciseCutoff;
+ static const size_t impreciseCutoff = maxCellSize;
+ static const size_t impreciseCount = impreciseCutoff / impreciseStep - 1;
typedef HashSet<MarkedBlock*>::iterator BlockIterator;
@@ -106,6 +110,7 @@ namespace JSC {
void clearMarks(MarkedBlock*);
SizeClass m_preciseSizeClasses[preciseCount];
+ SizeClass m_impreciseSizeClasses[impreciseCount];
HashSet<MarkedBlock*> m_blocks;
size_t m_waterMark;
size_t m_highWaterMark;
diff --git a/Source/JavaScriptCore/runtime/MathObject.h b/Source/JavaScriptCore/runtime/MathObject.h
index 86e7951..26eaae0 100644
--- a/Source/JavaScriptCore/runtime/MathObject.h
+++ b/Source/JavaScriptCore/runtime/MathObject.h
@@ -34,9 +34,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 7949dd9..d8fda69 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -41,7 +41,7 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject*
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
- m_errorStructure = ErrorInstance::createStructure(prototype);
+ m_errorStructure = ErrorInstance::createStructure(exec->globalData(), prototype);
}
static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
index e4978cc..23f798e 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -35,9 +35,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
Structure* errorStructure() { return m_errorStructure.get(); }
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
index 3e4d6c7..aee143a 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -104,7 +104,7 @@ static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&)
// ECMA 15.7.1
static EncodedJSValue JSC_HOST_CALL constructWithNumberConstructor(ExecState* exec)
{
- NumberObject* object = new (exec) NumberObject(exec->globalData(), exec->lexicalGlobalObject()->numberObjectStructure());
+ NumberObject* object = new (exec) NumberObject(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->numberObjectStructure());
double n = exec->argumentCount() ? exec->argument(0).toNumber(exec) : 0;
object->setInternalValue(exec->globalData(), jsNumber(n));
return JSValue::encode(object);
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.h b/Source/JavaScriptCore/runtime/NumberConstructor.h
index aaf7c32..ab4507e 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.h
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.h
@@ -37,9 +37,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp
index 4408673..74b5e98 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.cpp
+++ b/Source/JavaScriptCore/runtime/NumberObject.cpp
@@ -31,8 +31,8 @@ ASSERT_CLASS_FITS_IN_CELL(NumberObject);
const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, 0 };
-NumberObject::NumberObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(globalData, structure)
+NumberObject::NumberObject(JSGlobalData&, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
}
@@ -42,9 +42,9 @@ JSValue NumberObject::getJSNumber()
return internalValue();
}
-NumberObject* constructNumber(ExecState* exec, JSValue number)
+NumberObject* constructNumber(ExecState* exec, JSGlobalObject* globalObject, JSValue number)
{
- NumberObject* object = new (exec) NumberObject(exec->globalData(), exec->lexicalGlobalObject()->numberObjectStructure());
+ NumberObject* object = new (exec) NumberObject(exec->globalData(), globalObject->numberObjectStructure());
object->setInternalValue(exec->globalData(), number);
return object;
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.h b/Source/JavaScriptCore/runtime/NumberObject.h
index 8a80382..90d0b26 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.h
+++ b/Source/JavaScriptCore/runtime/NumberObject.h
@@ -31,19 +31,16 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- protected:
- static const unsigned StructureFlags = JSWrapperObject::StructureFlags;
-
private:
virtual JSValue getJSNumber();
};
- NumberObject* constructNumber(ExecState*, JSValue);
+ NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 5080ef8..c642a5b 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -95,18 +95,18 @@ bool ObjectConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifi
}
// ECMA 15.2.2
-static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
+static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
JSValue arg = args.at(0);
if (arg.isUndefinedOrNull())
- return constructEmptyObject(exec);
- return arg.toObject(exec);
+ return constructEmptyObject(exec, globalObject);
+ return arg.toObject(exec, globalObject);
}
static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructObject(exec, args));
+ return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
@@ -118,7 +118,7 @@ ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructObject(exec, args));
+ return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
CallType ObjectConstructor::getCallData(CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.h b/Source/JavaScriptCore/runtime/ObjectConstructor.h
index 895f988..b7bfc1d 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.h
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.h
@@ -36,9 +36,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
index 85a3818..c000dc8 100644
--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -291,7 +291,7 @@ inline PropertyTable::~PropertyTable()
{
iterator end = this->end();
for (iterator iter = begin(); iter != end; ++iter)
- iter->key->ref();
+ iter->key->deref();
fastFree(m_index);
}
diff --git a/Source/JavaScriptCore/runtime/PropertyNameArray.cpp b/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
index 351ecc3..8efb406 100644
--- a/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "PropertyNameArray.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#include "Structure.h"
#include "StructureChain.h"
diff --git a/Source/JavaScriptCore/runtime/PutPropertySlot.h b/Source/JavaScriptCore/runtime/PutPropertySlot.h
index 4c9e0e6..69d1f8b 100644
--- a/Source/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PutPropertySlot.h
@@ -45,14 +45,14 @@ namespace JSC {
{
}
- void setExistingProperty(DeprecatedPtr<JSObject> base, size_t offset)
+ void setExistingProperty(JSObject* base, size_t offset)
{
m_type = ExistingProperty;
m_base = base;
m_offset = offset;
}
- void setNewProperty(DeprecatedPtr<JSObject> base, size_t offset)
+ void setNewProperty(JSObject* base, size_t offset)
{
m_type = NewProperty;
m_base = base;
@@ -60,7 +60,7 @@ namespace JSC {
}
Type type() const { return m_type; }
- JSObject* base() const { return m_base.get(); }
+ JSObject* base() const { return m_base; }
bool isStrictMode() const { return m_isStrictMode; }
bool isCacheable() const { return m_type != Uncachable; }
@@ -68,9 +68,10 @@ namespace JSC {
ASSERT(isCacheable());
return m_offset;
}
+
private:
Type m_type;
- DeprecatedPtr<JSObject> m_base;
+ JSObject* m_base;
size_t m_offset;
bool m_isStrictMode;
};
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 95ce5e9..25cb2d5 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -34,6 +34,38 @@
namespace JSC {
+RegExpFlags regExpFlags(const UString& string)
+{
+ RegExpFlags flags = NoFlags;
+
+ for (unsigned i = 0; i < string.length(); ++i) {
+ switch (string.characters()[i]) {
+ case 'g':
+ if (flags & FlagGlobal)
+ return InvalidFlags;
+ flags = static_cast<RegExpFlags>(flags | FlagGlobal);
+ break;
+
+ case 'i':
+ if (flags & FlagIgnoreCase)
+ return InvalidFlags;
+ flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
+ break;
+
+ case 'm':
+ if (flags & FlagMultiline)
+ return InvalidFlags;
+ flags = static_cast<RegExpFlags>(flags | FlagMultiline);
+ break;
+
+ default:
+ return InvalidFlags;
+ }
+ }
+
+ return flags;
+}
+
struct RegExpRepresentation {
#if ENABLE(YARR_JIT)
Yarr::YarrCodeBlock m_regExpJITCode;
@@ -41,9 +73,9 @@ struct RegExpRepresentation {
OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
};
-inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, const UString& flags)
+inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, RegExpFlags flags)
: m_patternString(patternString)
- , m_flagBits(0)
+ , m_flags(flags)
, m_constructionError(0)
, m_numSubpatterns(0)
#if ENABLE(REGEXP_TRACING)
@@ -52,17 +84,6 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, co
#endif
, m_representation(adoptPtr(new RegExpRepresentation))
{
- // NOTE: The global flag is handled on a case-by-case basis by functions like
- // String::match and RegExpObject::match.
- if (!flags.isNull()) {
- if (flags.find('g') != notFound)
- m_flagBits |= Global;
- if (flags.find('i') != notFound)
- m_flagBits |= IgnoreCase;
- if (flags.find('m') != notFound)
- m_flagBits |= Multiline;
- }
-
m_state = compile(globalData);
}
@@ -70,7 +91,7 @@ RegExp::~RegExp()
{
}
-PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, const UString& flags)
+PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, RegExpFlags flags)
{
RefPtr<RegExp> res = adoptRef(new RegExp(globalData, patternString, flags));
#if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h
index d99befb..000c33a 100644
--- a/Source/JavaScriptCore/runtime/RegExp.h
+++ b/Source/JavaScriptCore/runtime/RegExp.h
@@ -24,6 +24,7 @@
#include "UString.h"
#include "ExecutableAllocator.h"
+#include "RegExpKey.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
@@ -32,18 +33,20 @@ namespace JSC {
struct RegExpRepresentation;
class JSGlobalData;
+ RegExpFlags regExpFlags(const UString&);
+
class RegExp : public RefCounted<RegExp> {
public:
- static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+ static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, RegExpFlags);
~RegExp();
- bool global() const { return m_flagBits & Global; }
- bool ignoreCase() const { return m_flagBits & IgnoreCase; }
- bool multiline() const { return m_flagBits & Multiline; }
+ bool global() const { return m_flags & FlagGlobal; }
+ bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
+ bool multiline() const { return m_flags & FlagMultiline; }
const UString& pattern() const { return m_patternString; }
- bool isValid() const { return !m_constructionError; }
+ bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
const char* errorMessage() const { return m_constructionError; }
int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
@@ -54,7 +57,7 @@ namespace JSC {
#endif
private:
- RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+ RegExp(JSGlobalData* globalData, const UString& pattern, RegExpFlags);
enum RegExpState {
ParseError,
@@ -68,9 +71,8 @@ namespace JSC {
void matchCompareWithInterpreter(const UString&, int startOffset, int* offsetVector, int jitResult);
#endif
- enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
UString m_patternString;
- int m_flagBits;
+ RegExpFlags m_flags;
const char* m_constructionError;
unsigned m_numSubpatterns;
#if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp
index d101758..c96b047 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp
@@ -31,7 +31,7 @@
namespace JSC {
-PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags)
+PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, RegExpFlags flags)
{
if (patternString.length() < maxCacheablePatternLength) {
pair<RegExpCacheMap::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0);
@@ -43,7 +43,7 @@ PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, con
return create(patternString, flags, m_cacheMap.end());
}
-PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator)
+PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, RegExpFlags flags, RegExpCacheMap::iterator iterator)
{
RefPtr<RegExp> regExp = RegExp::create(m_globalData, patternString, flags);
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.h b/Source/JavaScriptCore/runtime/RegExpCache.h
index b5b637f..b4a6ae5 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.h
+++ b/Source/JavaScriptCore/runtime/RegExpCache.h
@@ -41,8 +41,8 @@ class RegExpCache {
typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap;
public:
- PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, const UString& flags);
- PassRefPtr<RegExp> create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator);
+ PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, RegExpFlags);
+ PassRefPtr<RegExp> create(const UString& patternString, RegExpFlags, RegExpCacheMap::iterator);
RegExpCache(JSGlobalData* globalData);
private:
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index c06fdc4..19b4b36 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -291,9 +291,9 @@ void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValu
{
asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
}
-
+
// ECMA 15.10.4
-JSObject* constructRegExp(ExecState* exec, const ArgList& args)
+JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
JSValue arg0 = args.at(0);
JSValue arg1 = args.at(1);
@@ -305,18 +305,28 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
}
UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
- UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
+ if (exec->hadException())
+ return 0;
+
+ RegExpFlags flags = NoFlags;
+ if (!arg1.isUndefined()) {
+ flags = regExpFlags(arg1.toString(exec));
+ if (exec->hadException())
+ return 0;
+ if (flags == InvalidFlags)
+ return throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+ }
RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
if (!regExp->isValid())
return throwError(exec, createSyntaxError(exec, regExp->errorMessage()));
- return new (exec) RegExpObject(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
+ return new (exec) RegExpObject(exec->lexicalGlobalObject(), globalObject->regExpStructure(), regExp.release());
}
static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructRegExp(exec, args));
+ return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
@@ -329,7 +339,7 @@ ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructRegExp(exec, args));
+ return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
CallType RegExpConstructor::getCallData(CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.h b/Source/JavaScriptCore/runtime/RegExpConstructor.h
index 8a8a54a..5e0b2b8 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.h
@@ -59,9 +59,9 @@ namespace JSC {
public:
RegExpConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, RegExpPrototype*);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -96,7 +96,7 @@ namespace JSC {
RegExpConstructor* asRegExpConstructor(JSValue);
- JSObject* constructRegExp(ExecState*, const ArgList&);
+ JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&);
inline RegExpConstructor* asRegExpConstructor(JSValue value)
{
diff --git a/Source/JavaScriptCore/runtime/RegExpKey.h b/Source/JavaScriptCore/runtime/RegExpKey.h
index cd1368d..b4847f9 100644
--- a/Source/JavaScriptCore/runtime/RegExpKey.h
+++ b/Source/JavaScriptCore/runtime/RegExpKey.h
@@ -25,63 +25,54 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "UString.h"
-#include <wtf/text/StringHash.h>
-
#ifndef RegExpKey_h
#define RegExpKey_h
+#include "UString.h"
+#include <wtf/text/StringHash.h>
+
namespace JSC {
+enum RegExpFlags {
+ NoFlags = 0,
+ FlagGlobal = 1,
+ FlagIgnoreCase = 2,
+ FlagMultiline = 4,
+ InvalidFlags = 8,
+ DeletedValueFlags = -1
+};
+
struct RegExpKey {
- int flagsValue;
+ RegExpFlags flagsValue;
RefPtr<StringImpl> pattern;
RegExpKey()
- : flagsValue(0)
+ : flagsValue(NoFlags)
{
}
- RegExpKey(int flags)
+ RegExpKey(RegExpFlags flags)
: flagsValue(flags)
{
}
- RegExpKey(int flags, const UString& pattern)
+ RegExpKey(RegExpFlags flags, const UString& pattern)
: flagsValue(flags)
, pattern(pattern.impl())
{
}
- RegExpKey(int flags, const PassRefPtr<StringImpl> pattern)
+ RegExpKey(RegExpFlags flags, const PassRefPtr<StringImpl> pattern)
: flagsValue(flags)
, pattern(pattern)
{
}
- RegExpKey(int flags, const RefPtr<StringImpl>& pattern)
+ RegExpKey(RegExpFlags flags, const RefPtr<StringImpl>& pattern)
: flagsValue(flags)
, pattern(pattern)
{
}
-
- RegExpKey(const UString& flags, const UString& pattern)
- : pattern(pattern.impl())
- {
- flagsValue = getFlagsValue(flags);
- }
-
- int getFlagsValue(const UString flags)
- {
- flagsValue = 0;
- if (flags.find('g') != notFound)
- flagsValue += 4;
- if (flags.find('i') != notFound)
- flagsValue += 2;
- if (flags.find('m') != notFound)
- flagsValue += 1;
- return flagsValue;
- }
};
inline bool operator==(const RegExpKey& a, const RegExpKey& b)
@@ -112,8 +103,8 @@ template<> struct DefaultHash<JSC::RegExpKey> {
};
template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> {
- static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = -1; }
- static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == -1; }
+ static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC::DeletedValueFlags; }
+ static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC::DeletedValueFlags; }
};
} // namespace WTF
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 5baf884..4b5028b 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -63,7 +63,7 @@ const ClassInfo RegExpObject::s_info = { "RegExp", &JSObjectWithGlobalObject::s_
RegExpObject::RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp)
: JSObjectWithGlobalObject(globalObject, structure)
- , d(adoptPtr(new RegExpObjectData(regExp, 0)))
+ , d(adoptPtr(new RegExpObjectData(regExp)))
{
ASSERT(inherits(&s_info));
}
@@ -72,6 +72,13 @@ RegExpObject::~RegExpObject()
{
}
+void RegExpObject::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+ if (UNLIKELY(!d->lastIndex.get().isInt32()))
+ markStack.append(&d->lastIndex);
+}
+
bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
@@ -104,7 +111,7 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&)
JSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&)
{
- return jsNumber(asRegExpObject(slotBase)->lastIndex());
+ return asRegExpObject(slotBase)->getLastIndex();
}
void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
@@ -114,7 +121,7 @@ void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue
void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
+ asRegExpObject(baseObject)->setLastIndex(exec->globalData(), value);
}
JSValue RegExpObject::test(ExecState* exec)
@@ -133,12 +140,7 @@ JSValue RegExpObject::exec(ExecState* exec)
bool RegExpObject::match(ExecState* exec)
{
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
-
- UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec);
- if (input.isNull()) {
- throwError(exec, createError(exec, makeUString("No input to ", toString(exec), ".")));
- return false;
- }
+ UString input = exec->argument(0).toString(exec);
if (!regExp()->global()) {
int position;
@@ -147,20 +149,32 @@ bool RegExpObject::match(ExecState* exec)
return position >= 0;
}
- if (d->lastIndex < 0 || d->lastIndex > input.length()) {
- d->lastIndex = 0;
- return false;
+ JSValue jsLastIndex = getLastIndex();
+ unsigned lastIndex;
+ if (LIKELY(jsLastIndex.isUInt32())) {
+ lastIndex = jsLastIndex.asUInt32();
+ if (lastIndex > input.length()) {
+ setLastIndex(0);
+ return false;
+ }
+ } else {
+ double doubleLastIndex = jsLastIndex.toInteger(exec);
+ if (doubleLastIndex < 0 || doubleLastIndex > input.length()) {
+ setLastIndex(0);
+ return false;
+ }
+ lastIndex = static_cast<unsigned>(doubleLastIndex);
}
int position;
int length = 0;
- regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
+ regExpConstructor->performMatch(d->regExp.get(), input, lastIndex, position, length);
if (position < 0) {
- d->lastIndex = 0;
+ setLastIndex(0);
return false;
}
- d->lastIndex = position + length;
+ setLastIndex(position + length);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h
index 1f89b84..fa2024d 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.h
+++ b/Source/JavaScriptCore/runtime/RegExpObject.h
@@ -28,14 +28,26 @@ namespace JSC {
class RegExpObject : public JSObjectWithGlobalObject {
public:
+ typedef JSObjectWithGlobalObject Base;
+
RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure>, NonNullPassRefPtr<RegExp>);
virtual ~RegExpObject();
void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; }
RegExp* regExp() const { return d->regExp.get(); }
- void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
- double lastIndex() const { return d->lastIndex; }
+ void setLastIndex(size_t lastIndex)
+ {
+ d->lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
+ }
+ void setLastIndex(JSGlobalData& globalData, JSValue lastIndex)
+ {
+ d->lastIndex.set(globalData, this, lastIndex);
+ }
+ JSValue getLastIndex() const
+ {
+ return d->lastIndex.get();
+ }
JSValue test(ExecState*);
JSValue exec(ExecState*);
@@ -46,28 +58,30 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags;
-
+ static const unsigned StructureFlags = OverridesMarkChildren | OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags;
+
private:
+ virtual void markChildren(MarkStack&);
+
bool match(ExecState*);
struct RegExpObjectData {
WTF_MAKE_FAST_ALLOCATED;
public:
- RegExpObjectData(NonNullPassRefPtr<RegExp> regExp, double lastIndex)
+ RegExpObjectData(NonNullPassRefPtr<RegExp> regExp)
: regExp(regExp)
- , lastIndex(lastIndex)
{
+ lastIndex.setWithoutWriteBarrier(jsNumber(0));
}
RefPtr<RegExp> regExp;
- double lastIndex;
+ WriteBarrier<Unknown> lastIndex;
};
#if COMPILER(MSVC)
friend void WTF::deleteOwnedPtr<RegExpObjectData>(RegExpObjectData*);
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 106006c..61747b1 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -48,11 +48,11 @@ static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
// ECMA 15.10.5
RegExpPrototype::RegExpPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
- : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", ""))
+ : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", NoFlags))
{
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
}
@@ -90,7 +90,17 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
regExp = asRegExpObject(arg0)->regExp();
} else {
UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec);
- UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ RegExpFlags flags = NoFlags;
+ if (!arg1.isUndefined()) {
+ flags = regExpFlags(arg1.toString(exec));
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ if (flags == InvalidFlags)
+ return throwVMError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+ }
regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
}
diff --git a/Source/JavaScriptCore/runtime/ScopeChain.h b/Source/JavaScriptCore/runtime/ScopeChain.h
index fbecd11..cb70a34 100644
--- a/Source/JavaScriptCore/runtime/ScopeChain.h
+++ b/Source/JavaScriptCore/runtime/ScopeChain.h
@@ -64,7 +64,7 @@ namespace JSC {
void print();
#endif
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
virtual void markChildren(MarkStack&);
private:
static const unsigned StructureFlags = OverridesMarkChildren;
@@ -100,7 +100,7 @@ namespace JSC {
bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
private:
- DeprecatedPtr<ScopeChainNode> m_node;
+ ScopeChainNode* m_node;
};
inline ScopeChainIterator ScopeChainNode::begin()
@@ -128,6 +128,17 @@ namespace JSC {
{
return scopeChain()->globalThis.get();
}
+
+ ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
+ {
+ return static_cast<ScopeChainNode*>(jsValue().asCell());
+ }
+
+ ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
+ {
+ *this = JSValue(scopeChain);
+ return *this;
+ }
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.cpp b/Source/JavaScriptCore/runtime/SmallStrings.cpp
index 9b193f5..ac67020 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/Source/JavaScriptCore/runtime/SmallStrings.cpp
@@ -33,8 +33,6 @@
namespace JSC {
-static const unsigned numCharactersToStore = 0x100;
-
static inline bool isMarked(JSCell* string)
{
return string && Heap::isMarked(string);
@@ -45,17 +43,22 @@ class SmallStringsStorage {
public:
SmallStringsStorage();
- StringImpl* rep(unsigned char character) { return m_reps[character].get(); }
+ StringImpl* rep(unsigned char character)
+ {
+ return m_reps[character].get();
+ }
private:
- RefPtr<StringImpl> m_reps[numCharactersToStore];
+ static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
+
+ RefPtr<StringImpl> m_reps[singleCharacterStringCount];
};
SmallStringsStorage::SmallStringsStorage()
{
UChar* characterBuffer = 0;
- RefPtr<StringImpl> baseString = StringImpl::createUninitialized(numCharactersToStore, characterBuffer);
- for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ RefPtr<StringImpl> baseString = StringImpl::createUninitialized(singleCharacterStringCount, characterBuffer);
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
characterBuffer[i] = i;
m_reps[i] = StringImpl::create(baseString, i, 1);
}
@@ -63,7 +66,7 @@ SmallStringsStorage::SmallStringsStorage()
SmallStrings::SmallStrings()
{
- COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
+ COMPILE_ASSERT(singleCharacterStringCount == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
clear();
}
@@ -71,7 +74,7 @@ SmallStrings::~SmallStrings()
{
}
-void SmallStrings::markChildren(MarkStack& markStack)
+void SmallStrings::markChildren(HeapRootMarker& heapRootMarker)
{
/*
Our hypothesis is that small strings are very common. So, we cache them
@@ -83,9 +86,9 @@ void SmallStrings::markChildren(MarkStack& markStack)
so, it's probably reasonable to mark the rest. If not, we clear the cache.
*/
- bool isAnyStringMarked = isMarked(m_emptyString.get());
- for (unsigned i = 0; i < numCharactersToStore && !isAnyStringMarked; ++i)
- isAnyStringMarked = isMarked(m_singleCharacterStrings[i].get());
+ bool isAnyStringMarked = isMarked(m_emptyString);
+ for (unsigned i = 0; i < singleCharacterStringCount && !isAnyStringMarked; ++i)
+ isAnyStringMarked = isMarked(m_singleCharacterStrings[i]);
if (!isAnyStringMarked) {
clear();
@@ -93,17 +96,17 @@ void SmallStrings::markChildren(MarkStack& markStack)
}
if (m_emptyString)
- markStack.append(&m_emptyString);
- for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ heapRootMarker.mark(&m_emptyString);
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
if (m_singleCharacterStrings[i])
- markStack.append(&m_singleCharacterStrings[i]);
+ heapRootMarker.mark(&m_singleCharacterStrings[i]);
}
}
void SmallStrings::clear()
{
m_emptyString = 0;
- for (unsigned i = 0; i < numCharactersToStore; ++i)
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i)
m_singleCharacterStrings[i] = 0;
}
@@ -112,7 +115,7 @@ unsigned SmallStrings::count() const
unsigned count = 0;
if (m_emptyString)
++count;
- for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
if (m_singleCharacterStrings[i])
++count;
}
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.h b/Source/JavaScriptCore/runtime/SmallStrings.h
index cd9c325..b54d020 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.h
+++ b/Source/JavaScriptCore/runtime/SmallStrings.h
@@ -33,13 +33,16 @@
namespace JSC {
+ class HeapRootMarker;
class JSGlobalData;
class JSString;
class MarkStack;
class SmallStringsStorage;
+ static const unsigned maxSingleCharacterString = 0xFF;
+
class SmallStrings {
- WTF_MAKE_NONCOPYABLE(SmallStrings); WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(SmallStrings);
public:
SmallStrings();
~SmallStrings();
@@ -48,30 +51,33 @@ namespace JSC {
{
if (!m_emptyString)
createEmptyString(globalData);
- return m_emptyString.get();
+ return m_emptyString;
}
+
JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
{
if (!m_singleCharacterStrings[character])
createSingleCharacterString(globalData, character);
- return m_singleCharacterStrings[character].get();
+ return m_singleCharacterStrings[character];
}
StringImpl* singleCharacterStringRep(unsigned char character);
- void markChildren(MarkStack&);
+ void markChildren(HeapRootMarker&);
void clear();
unsigned count() const;
- JSCell** singleCharacterStrings() { return m_singleCharacterStrings[0].slot(); }
+ JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
private:
+ static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
+
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
- DeprecatedPtr<JSString> m_emptyString;
- FixedArray<DeprecatedPtr<JSString>, 0x100> m_singleCharacterStrings;
+ JSString* m_emptyString;
+ JSString* m_singleCharacterStrings[singleCharacterStringCount];
OwnPtr<SmallStringsStorage> m_storage;
};
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index 5398f31..ed088e4 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -67,9 +67,10 @@ StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObje
// ECMA 15.5.2
static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec)
{
+ JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
if (!exec->argumentCount())
- return JSValue::encode(new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure()));
- return JSValue::encode(new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), exec->argument(0).toString(exec)));
+ return JSValue::encode(new (exec) StringObject(exec, globalObject->stringObjectStructure()));
+ return JSValue::encode(new (exec) StringObject(exec, globalObject->stringObjectStructure(), exec->argument(0).toString(exec)));
}
ConstructType StringConstructor::getConstructData(ConstructData& constructData)
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index 5fe7544..47e5860 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -30,21 +30,21 @@ ASSERT_CLASS_FITS_IN_CELL(StringObject);
const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0 };
StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsEmptyString(exec));
}
StringObject::StringObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure, JSString* string)
- : JSWrapperObject(globalData, structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(globalData, string);
}
StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsString(exec, string));
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index 99f9add..ae3376d 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -31,7 +31,7 @@ namespace JSC {
StringObject(ExecState*, NonNullPassRefPtr<Structure>);
StringObject(ExecState*, NonNullPassRefPtr<Structure>, const UString&);
- static StringObject* create(ExecState*, JSString*);
+ static StringObject* create(ExecState*, JSGlobalObject*, JSString*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
@@ -45,15 +45,15 @@ namespace JSC {
JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
StringObject(JSGlobalData&, NonNullPassRefPtr<Structure>, JSString*);
- };
+ };
StringObject* asStringObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index 0a44ed3..e4c7061 100644
--- a/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -33,7 +33,7 @@ namespace JSC {
static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string)
{
return new (exec) StringObjectThatMasqueradesAsUndefined(exec,
- createStructure(exec->lexicalGlobalObject()->stringPrototype()), string);
+ createStructure(exec->globalData(), exec->lexicalGlobalObject()->stringPrototype()), string);
}
private:
@@ -42,9 +42,9 @@ namespace JSC {
{
}
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index aa37122..a6bf4e6 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -604,9 +604,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
JSValue a0 = exec->argument(0);
- UString u = s;
RefPtr<RegExp> reg;
- RegExpObject* imp = 0;
if (a0.inherits(&RegExpObject::s_info))
reg = asRegExpObject(a0)->regExp();
else {
@@ -615,12 +613,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString());
+ reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), NoFlags);
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
int matchLength = 0;
- regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), s, 0, pos, matchLength);
if (!(reg->global())) {
// case without 'g' flag is handled like RegExp.prototype.exec
if (pos < 0)
@@ -630,15 +628,13 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
// return array of matches
MarkedArgumentBuffer list;
- int lastIndex = 0;
+ unsigned lastIndex = 0;
while (pos >= 0) {
- list.append(jsSubstring(exec, u, pos, matchLength));
+ list.append(jsSubstring(exec, s, pos, matchLength));
lastIndex = pos;
pos += matchLength == 0 ? 1 : matchLength;
- regExpConstructor->performMatch(reg.get(), u, pos, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), s, pos, pos, matchLength);
}
- if (imp)
- imp->setLastIndex(lastIndex);
if (list.isEmpty()) {
// if there are no matches at all, it's important to return
// Null instead of an empty array, because this matches
@@ -658,7 +654,6 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
JSValue a0 = exec->argument(0);
- UString u = s;
RefPtr<RegExp> reg;
if (a0.inherits(&RegExpObject::s_info))
reg = asRegExpObject(a0)->regExp();
@@ -668,12 +663,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString());
+ reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), NoFlags);
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
int matchLength = 0;
- regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), s, 0, pos, matchLength);
return JSValue::encode(jsNumber(pos));
}
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.h b/Source/JavaScriptCore/runtime/StringPrototype.h
index feea2e2..57def22 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.h
+++ b/Source/JavaScriptCore/runtime/StringPrototype.h
@@ -34,12 +34,18 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static const ClassInfo s_info;
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | StringObject::StructureFlags;
+
+ COMPILE_ASSERT(!StringObject::AnonymousSlotCount, StringPrototype_stomps_on_your_anonymous_slot);
+ static const unsigned AnonymousSlotCount = 1;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index bf27334..c9f900a 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -32,7 +32,6 @@
#include "PropertyMapHashTable.h"
#include "PropertyNameArray.h"
#include "Protect.h"
-#include "StructureChain.h"
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
#include "UString.h"
@@ -46,6 +45,7 @@ namespace JSC {
class MarkStack;
class PropertyNameArray;
class PropertyNameArrayData;
+ class StructureChain;
struct ClassInfo;
@@ -56,13 +56,18 @@ namespace JSC {
class Structure : public RefCounted<Structure> {
public:
- friend class JIT;
friend class StructureTransitionTable;
- static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
+ static PassRefPtr<Structure> create(JSGlobalData&, JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
{
return adoptRef(new Structure(prototype, typeInfo, anonymousSlotCount, classInfo));
}
+ enum VPtrStealingHackType { VPtrStealingHack };
+ static PassRefPtr<Structure> create(VPtrStealingHackType, const ClassInfo* classInfo)
+ {
+ return adoptRef(new Structure(jsNull(), TypeInfo(UnspecifiedType), 0, classInfo));
+ }
+
static void startIgnoringLeaks();
static void stopIgnoringLeaks();
@@ -102,6 +107,7 @@ namespace JSC {
DeprecatedPtr<Unknown>* storedPrototypeSlot() { return &m_prototype; }
JSValue prototypeForLookup(ExecState*) const;
StructureChain* prototypeChain(ExecState*) const;
+ DeprecatedPtr<StructureChain>* cachedPrototypeChainSlot() { return &m_cachedPrototypeChain; }
Structure* previousID() const { return m_previous.get(); }
@@ -140,6 +146,21 @@ namespace JSC {
static void initializeThreading();
+ static ptrdiff_t prototypeOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_prototype);
+ }
+
+ static ptrdiff_t typeInfoFlagsOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
+ }
+
+ static ptrdiff_t typeInfoTypeOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
+ }
+
private:
Structure(JSValue prototype, const TypeInfo&, unsigned anonymousSlotCount, const ClassInfo*);
Structure(const Structure*);
@@ -190,7 +211,7 @@ namespace JSC {
TypeInfo m_typeInfo;
DeprecatedPtr<Unknown> m_prototype;
- mutable RefPtr<StructureChain> m_cachedPrototypeChain;
+ mutable DeprecatedPtr<StructureChain> m_cachedPrototypeChain;
RefPtr<Structure> m_previous;
RefPtr<StringImpl> m_nameInPrevious;
diff --git a/Source/JavaScriptCore/runtime/StructureChain.cpp b/Source/JavaScriptCore/runtime/StructureChain.cpp
index e4523c3..4fa4a4b 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.cpp
+++ b/Source/JavaScriptCore/runtime/StructureChain.cpp
@@ -32,7 +32,8 @@
namespace JSC {
-StructureChain::StructureChain(Structure* head)
+StructureChain::StructureChain(NonNullPassRefPtr<Structure> structure, Structure* head)
+ : JSCell(structure.releaseRef())
{
size_t size = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
diff --git a/Source/JavaScriptCore/runtime/StructureChain.h b/Source/JavaScriptCore/runtime/StructureChain.h
index 816b66d..88592dc 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.h
+++ b/Source/JavaScriptCore/runtime/StructureChain.h
@@ -26,6 +26,8 @@
#ifndef StructureChain_h
#define StructureChain_h
+#include "JSCell.h"
+
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -35,15 +37,16 @@ namespace JSC {
class Structure;
- class StructureChain : public RefCounted<StructureChain> {
+ class StructureChain : public JSCell {
friend class JIT;
public:
- static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
+ static StructureChain* create(JSGlobalData& globalData, Structure* head) { return new (&globalData) StructureChain(globalData.structureChainStructure, head); }
RefPtr<Structure>* head() { return m_vector.get(); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype) { return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), 0, 0); }
private:
- StructureChain(Structure* head);
+ StructureChain(NonNullPassRefPtr<Structure>, Structure* head);
OwnArrayPtr<RefPtr<Structure> > m_vector;
};
diff --git a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
index 04d904d..d3867d4 100644
--- a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
+++ b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -101,7 +101,7 @@ static inline unsigned getCPUTime()
// use a relative time from first call in order to avoid an overflow
static double firstTime = currentTime();
- return (currentTime() - firstTime) * 1000;
+ return static_cast<unsigned> ((currentTime() - firstTime) * 1000);
#endif
}
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index 44840ad..af018a8 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -35,6 +35,7 @@ class JSGlobalData;
typedef enum { } Unknown;
typedef JSValue* HandleSlot;
+// FIXME: Remove all uses of this class.
template <class T> class DeprecatedPtr {
public:
DeprecatedPtr() : m_cell(0) { }
@@ -54,6 +55,7 @@ protected:
JSCell* m_cell;
};
+// FIXME: Remove all uses of this class.
template <> class DeprecatedPtr<Unknown> {
public:
DeprecatedPtr() { }
@@ -73,17 +75,23 @@ private:
JSValue m_value;
};
-template <typename T> struct WriteBarrierCheck {
+template <typename U, typename V> inline bool operator==(const DeprecatedPtr<U>& lhs, const DeprecatedPtr<V>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
+template <typename T> struct JSValueChecker {
static const bool IsJSValue = false;
};
-template <> struct WriteBarrierCheck<JSValue> {
+template <> struct JSValueChecker<JSValue> {
static const bool IsJSValue = true;
};
+// We have a separate base class with no constructors for use in Unions.
template <typename T> class WriteBarrierBase {
public:
- COMPILE_ASSERT(!WriteBarrierCheck<T>::IsJSValue, WriteBarrier_JSValue_is_invalid__use_unknown);
+ COMPILE_ASSERT(!JSValueChecker<T>::IsJSValue, WriteBarrier_JSValue_is_invalid__use_unknown);
void set(JSGlobalData&, const JSCell*, T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
T* get() const { return reinterpret_cast<T*>(m_cell); }
@@ -100,20 +108,10 @@ public:
void setWithoutWriteBarrier(T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
-protected:
+private:
JSCell* m_cell;
};
-template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
-public:
- WriteBarrier() { this->m_cell = 0; }
- WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
- {
- this->set(globalData, owner, value);
- }
-
-};
-
template <> class WriteBarrierBase<Unknown> {
public:
void set(JSGlobalData&, const JSCell*, JSValue value) { m_value = JSValue::encode(value); }
@@ -138,29 +136,41 @@ public:
operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
bool operator!() const { return !get(); }
-protected:
+private:
EncodedJSValue m_value;
};
+template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
+public:
+ WriteBarrier()
+ {
+ this->setWithoutWriteBarrier(0);
+ }
+
+ WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
+ {
+ this->set(globalData, owner, value);
+ }
+};
+
template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> {
public:
- WriteBarrier() { m_value = JSValue::encode(JSValue()); }
+ WriteBarrier()
+ {
+ this->setWithoutWriteBarrier(JSValue());
+ }
+
WriteBarrier(JSGlobalData& globalData, const JSCell* owner, JSValue value)
{
this->set(globalData, owner, value);
}
};
-template <typename U, typename V> inline bool operator==(const DeprecatedPtr<U>& lhs, const DeprecatedPtr<V>& rhs)
-{
- return lhs.get() == rhs.get();
-}
-
template <typename U, typename V> inline bool operator==(const WriteBarrierBase<U>& lhs, const WriteBarrierBase<V>& rhs)
{
return lhs.get() == rhs.get();
}
-}
+} // namespace JSC
#endif // WriteBarrier_h
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input.js b/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input.js
index 01c145c..26db14c 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input.js
@@ -50,40 +50,40 @@
testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.exec('2345')",
String(["2345"]), String(/\d+/.exec('2345')));
- // RegExp.input = "abcd12357efg"; /\d+/.exec()
+ // RegExp.input = "abcd12357efg"; /\d+/.exec(RegExp.input)
RegExp.input = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.exec()",
- String(["12357"]), String(/\d+/.exec()));
+ testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.exec(RegExp.input)",
+ String(["12357"]), String(/\d+/.exec(RegExp.input)));
- // RegExp.input = "abcd12357efg"; /[h-z]+/.exec()
+ // RegExp.input = "abcd12357efg"; /[h-z]+/.exec(RegExp.input)
RegExp.input = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /[h-z]+/.exec()",
- null, /[h-z]+/.exec());
+ testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /[h-z]+/.exec(RegExp.input)",
+ null, /[h-z]+/.exec(RegExp.input));
// RegExp.input = "abcd12357efg"; /\d+/.test('2345')
RegExp.input = "abcd12357efg";
testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.test('2345')",
true, /\d+/.test('2345'));
- // RegExp.input = "abcd12357efg"; /\d+/.test()
+ // RegExp.input = "abcd12357efg"; /\d+/.test(RegExp.input)
RegExp.input = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.test()",
- true, /\d+/.test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.test(RegExp.input)",
+ true, /\d+/.test(RegExp.input));
- // RegExp.input = "abcd12357efg"; (new RegExp('d+')).test()
+ // RegExp.input = "abcd12357efg"; (new RegExp('d+')).test(RegExp.input)
RegExp.input = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; (new RegExp('d+')).test()",
- true, (new RegExp('d+')).test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; (new RegExp('d+')).test(RegExp.input)",
+ true, (new RegExp('d+')).test(RegExp.input));
- // RegExp.input = "abcd12357efg"; /[h-z]+/.test()
+ // RegExp.input = "abcd12357efg"; /[h-z]+/.test(RegExp.input)
RegExp.input = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /[h-z]+/.test()",
- false, /[h-z]+/.test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /[h-z]+/.test(RegExp.input)",
+ false, /[h-z]+/.test(RegExp.input));
- // RegExp.input = "abcd12357efg"; (new RegExp('[h-z]+')).test()
+ // RegExp.input = "abcd12357efg"; (new RegExp('[h-z]+')).test(RegExp.input)
RegExp.input = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; (new RegExp('[h-z]+')).test()",
- false, (new RegExp('[h-z]+')).test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; (new RegExp('[h-z]+')).test(RegExp.input)",
+ false, (new RegExp('[h-z]+')).test(RegExp.input));
function test()
{
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input_as_array.js b/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input_as_array.js
index a1ed113..9afdb14 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input_as_array.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_2/regexp/RegExp_input_as_array.js
@@ -50,40 +50,40 @@
testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.exec('2345')",
String(["2345"]), String(/\d+/.exec('2345')));
- // RegExp['$_'] = "abcd12357efg"; /\d+/.exec()
+ // RegExp['$_'] = "abcd12357efg"; /\d+/.exec(RegExp.input)
RegExp['$_'] = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.exec()",
- String(["12357"]), String(/\d+/.exec()));
+ testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.exec(RegExp.input)",
+ String(["12357"]), String(/\d+/.exec(RegExp.input)));
- // RegExp['$_'] = "abcd12357efg"; /[h-z]+/.exec()
+ // RegExp['$_'] = "abcd12357efg"; /[h-z]+/.exec(RegExp.input)
RegExp['$_'] = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.exec()",
- null, /[h-z]+/.exec());
+ testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.exec(RegExp.input)",
+ null, /[h-z]+/.exec(RegExp.input));
// RegExp['$_'] = "abcd12357efg"; /\d+/.test('2345')
RegExp['$_'] = "abcd12357efg";
testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.test('2345')",
true, /\d+/.test('2345'));
- // RegExp['$_'] = "abcd12357efg"; /\d+/.test()
+ // RegExp['$_'] = "abcd12357efg"; /\d+/.test(RegExp.input)
RegExp['$_'] = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.test()",
- true, /\d+/.test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.test(RegExp.input)",
+ true, /\d+/.test(RegExp.input));
- // RegExp['$_'] = "abcd12357efg"; /[h-z]+/.test()
+ // RegExp['$_'] = "abcd12357efg"; /[h-z]+/.test(RegExp.input)
RegExp['$_'] = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.test()",
- false, /[h-z]+/.test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.test(RegExp.input)",
+ false, /[h-z]+/.test(RegExp.input));
- // RegExp['$_'] = "abcd12357efg"; (new RegExp('\d+')).test()
+ // RegExp['$_'] = "abcd12357efg"; (new RegExp('\d+')).test(RegExp.input)
RegExp['$_'] = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; (new RegExp('\d+')).test()",
- true, (new RegExp('\d+')).test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; (new RegExp('\d+')).test(RegExp.input)",
+ true, (new RegExp('\d+')).test(RegExp.input));
- // RegExp['$_'] = "abcd12357efg"; (new RegExp('[h-z]+')).test()
+ // RegExp['$_'] = "abcd12357efg"; (new RegExp('[h-z]+')).test(RegExp.input)
RegExp['$_'] = "abcd12357efg";
- testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; (new RegExp('[h-z]+')).test()",
- false, (new RegExp('[h-z]+')).test());
+ testcases[count++] = new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; (new RegExp('[h-z]+')).test(RegExp.input)",
+ false, (new RegExp('[h-z]+')).test(RegExp.input));
function test()
{
diff --git a/Source/JavaScriptCore/wtf/Assertions.cpp b/Source/JavaScriptCore/wtf/Assertions.cpp
index 3c4fc77..77e30c1 100644
--- a/Source/JavaScriptCore/wtf/Assertions.cpp
+++ b/Source/JavaScriptCore/wtf/Assertions.cpp
@@ -24,6 +24,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// The vprintf_stderr_common function triggers this error in the Mac build.
+// Feel free to remove this pragma if this file builds on Mac.
+// According to http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas
+// we need to place this directive before any data or functions are defined.
+#pragma GCC diagnostic ignored "-Wmissing-format-attribute"
+
#include "config.h"
#include "Assertions.h"
diff --git a/Source/JavaScriptCore/wtf/Assertions.h b/Source/JavaScriptCore/wtf/Assertions.h
index 13ece31..1d108e4 100644
--- a/Source/JavaScriptCore/wtf/Assertions.h
+++ b/Source/JavaScriptCore/wtf/Assertions.h
@@ -142,14 +142,14 @@ typedef struct {
WTFLogChannelState state;
} WTFLogChannel;
-void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
-void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
-void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
-void WTFReportBacktrace();
-void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
-void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
-void WTFLog(WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
-void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
+WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
+WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
+WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
+WTF_EXPORT_PRIVATE void WTFReportBacktrace();
+WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
+WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
+WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
+WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
#ifdef __cplusplus
}
diff --git a/Source/JavaScriptCore/wtf/Atomics.h b/Source/JavaScriptCore/wtf/Atomics.h
index 1d190a3..1ebd487 100644
--- a/Source/JavaScriptCore/wtf/Atomics.h
+++ b/Source/JavaScriptCore/wtf/Atomics.h
@@ -78,7 +78,7 @@
namespace WTF {
#if OS(WINDOWS)
-#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
+#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
@@ -89,7 +89,7 @@ inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(r
#endif
#elif OS(DARWIN)
-#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
+#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }
inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }
@@ -100,7 +100,7 @@ inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(add
inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }
#elif COMPILER(GCC) && !CPU(SPARC64) && !OS(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
-#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
+#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }
inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }
@@ -109,7 +109,7 @@ inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_
} // namespace WTF
-#if USE(LOCKFREE_THREADSAFESHARED)
+#if USE(LOCKFREE_THREADSAFEREFCOUNTED)
using WTF::atomicDecrement;
using WTF::atomicIncrement;
#endif
diff --git a/Source/JavaScriptCore/wtf/CMakeLists.txt b/Source/JavaScriptCore/wtf/CMakeLists.txt
index c27b2e5..304be73 100644
--- a/Source/JavaScriptCore/wtf/CMakeLists.txt
+++ b/Source/JavaScriptCore/wtf/CMakeLists.txt
@@ -30,6 +30,7 @@ SET(WTF_HEADERS
HashSet.h
HashTable.h
HashTraits.h
+ HexNumber.h
ListHashSet.h
ListRefPtr.h
Locker.h
@@ -76,7 +77,7 @@ SET(WTF_HEADERS
TCSpinLock.h
TCSystemAlloc.h
ThreadIdentifierDataPthreads.h
- ThreadSafeShared.h
+ ThreadSafeRefCounted.h
ThreadSpecific.h
Threading.h
ThreadingPrimitives.h
diff --git a/Source/JavaScriptCore/wtf/CrossThreadRefCounted.h b/Source/JavaScriptCore/wtf/CrossThreadRefCounted.h
index 8b65977..9d093ee 100644
--- a/Source/JavaScriptCore/wtf/CrossThreadRefCounted.h
+++ b/Source/JavaScriptCore/wtf/CrossThreadRefCounted.h
@@ -38,10 +38,10 @@
namespace WTF {
- // Used to allowing sharing data across classes and threads (like ThreadedSafeShared).
+ // Used to allowing sharing data across classes and threads (like ThreadSafeRefCounted).
//
- // Why not just use ThreadSafeShared?
- // ThreadSafeShared can have a significant perf impact when used in low level classes
+ // Why not just use ThreadSafeRefCounted?
+ // ThreadSafeRefCounted can have a significant perf impact when used in low level classes
// (like UString) that get ref/deref'ed a lot. This class has the benefit of doing fast ref
// counts like RefPtr whenever possible, but it has the downside that you need to copy it
// to use it on another thread.
@@ -72,7 +72,7 @@ namespace WTF {
}
private:
- CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
+ CrossThreadRefCounted(T* data, ThreadSafeRefCountedBase* threadedCounter)
: m_threadSafeRefCounter(threadedCounter)
, m_data(data)
#ifndef NDEBUG
@@ -97,7 +97,7 @@ namespace WTF {
#endif
RefCountedBase m_refCounter;
- ThreadSafeSharedBase* m_threadSafeRefCounter;
+ ThreadSafeRefCountedBase* m_threadSafeRefCounter;
T* m_data;
#ifndef NDEBUG
ThreadIdentifier m_threadId;
@@ -154,7 +154,7 @@ namespace WTF {
if (m_threadSafeRefCounter)
m_threadSafeRefCounter->ref();
else
- m_threadSafeRefCounter = new ThreadSafeSharedBase(2);
+ m_threadSafeRefCounter = new ThreadSafeRefCountedBase(2);
return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter));
}
diff --git a/Source/JavaScriptCore/wtf/DateMath.cpp b/Source/JavaScriptCore/wtf/DateMath.cpp
index 062cc1b..70c0cf4 100644
--- a/Source/JavaScriptCore/wtf/DateMath.cpp
+++ b/Source/JavaScriptCore/wtf/DateMath.cpp
@@ -75,6 +75,9 @@
#include "Assertions.h"
#include "ASCIICType.h"
#include "CurrentTime.h"
+#if USE(JSC)
+#include "JSObject.h"
+#endif
#include "MathExtras.h"
#if USE(JSC)
#include "ScopeChain.h"
@@ -924,8 +927,10 @@ static double parseDateFromNullTerminatedCharacters(const char* dateString, bool
}
}
- // The year may be after the time but before the time zone.
- if (year <= 0) {
+ // The year may be after the time but before the time zone, but don't
+ // confuse a time zone specificed as an offset from UTC (e.g. +0100) with a
+ // four-digit year.
+ if (year <= 0 && *dateString != '+' && *dateString != '-') {
if (!parseLong(dateString, &newPosStr, 10, &year))
year = 0;
dateString = newPosStr;
diff --git a/Source/JavaScriptCore/wtf/ExportMacros.h b/Source/JavaScriptCore/wtf/ExportMacros.h
new file mode 100644
index 0000000..3fadd37
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/ExportMacros.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file handles shared library symbol export decorations. It is recommended
+ * that all WebKit projects use these definitions so that symbol exports work
+ * properly on all platforms and compilers that WebKit builds under.
+ */
+
+#ifndef ExportMacros_h
+#define ExportMacros_h
+
+#include "Platform.h"
+
+#if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !COMPILER(GCC)
+#define WTF_EXPORT __declspec(dllexport)
+#define WTF_IMPORT __declspec(dllimport)
+#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__)
+#define WTF_EXPORT __attribute__((visibility("default")))
+#define WTF_IMPORT WTF_EXPORT
+#else
+#define WTF_EXPORT
+#define WTF_IMPORT
+#endif
+
+#endif /* ExportMacros_h */
diff --git a/Source/JavaScriptCore/wtf/HexNumber.h b/Source/JavaScriptCore/wtf/HexNumber.h
new file mode 100644
index 0000000..8fd6032
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/HexNumber.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef HexNumber_h
+#define HexNumber_h
+
+#include <wtf/text/StringConcatenate.h>
+
+namespace WTF {
+
+enum HexConversionMode {
+ Lowercase,
+ Uppercase
+};
+
+namespace Internal {
+
+static const char* hexDigitsForMode(HexConversionMode mode)
+{
+ static const char lowerHexDigits[17] = "0123456789abcdef";
+ static const char upperHexDigits[17] = "0123456789ABCDEF";
+ return mode == Lowercase ? lowerHexDigits : upperHexDigits;
+}
+
+}; // namespace Internal
+
+template<typename T>
+inline void appendByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase)
+{
+ const char* hexDigits = Internal::hexDigitsForMode(mode);
+ destination.append(hexDigits[byte >> 4]);
+ destination.append(hexDigits[byte & 0xF]);
+}
+
+template<typename T>
+inline void placeByteAsHexCompressIfPossible(unsigned char byte, T& destination, unsigned& index, HexConversionMode mode = Uppercase)
+{
+ const char* hexDigits = Internal::hexDigitsForMode(mode);
+ if (byte >= 0x10)
+ destination[index++] = hexDigits[byte >> 4];
+ destination[index++] = hexDigits[byte & 0xF];
+}
+
+template<typename T>
+inline void placeByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase)
+{
+ const char* hexDigits = Internal::hexDigitsForMode(mode);
+ *destination++ = hexDigits[byte >> 4];
+ *destination++ = hexDigits[byte & 0xF];
+}
+
+template<typename T>
+inline void appendUnsignedAsHex(unsigned number, T& destination, HexConversionMode mode = Uppercase)
+{
+ const char* hexDigits = Internal::hexDigitsForMode(mode);
+ Vector<UChar, 8> result;
+ do {
+ result.prepend(hexDigits[number % 16]);
+ number >>= 4;
+ } while (number > 0);
+
+ destination.append(result.data(), result.size());
+}
+
+// Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the conversion.
+template<typename T>
+inline void appendUnsignedAsHexFixedSize(unsigned number, T& destination, unsigned desiredDigits, HexConversionMode mode = Uppercase)
+{
+ ASSERT(desiredDigits);
+
+ const char* hexDigits = Internal::hexDigitsForMode(mode);
+ Vector<UChar, 8> result;
+ do {
+ result.prepend(hexDigits[number % 16]);
+ number >>= 4;
+ } while (result.size() < desiredDigits);
+
+ ASSERT(result.size() == desiredDigits);
+ destination.append(result.data(), result.size());
+}
+
+} // namespace WTF
+
+using WTF::appendByteAsHex;
+using WTF::appendUnsignedAsHex;
+using WTF::appendUnsignedAsHexFixedSize;
+using WTF::placeByteAsHex;
+using WTF::placeByteAsHexCompressIfPossible;
+using WTF::Lowercase;
+
+#endif // HexNumber_h
diff --git a/Source/JavaScriptCore/wtf/MathExtras.h b/Source/JavaScriptCore/wtf/MathExtras.h
index ec27f5f..66e557f 100644
--- a/Source/JavaScriptCore/wtf/MathExtras.h
+++ b/Source/JavaScriptCore/wtf/MathExtras.h
@@ -90,7 +90,7 @@ inline bool isfinite(double x) { return finite(x) && !isnand(x); }
inline bool isinf(double x) { return !finite(x) && !isnand(x); }
#endif
#ifndef signbit
-inline bool signbit(double x) { return x < 0.0; } // FIXME: Wrong for negative 0.
+inline bool signbit(double x) { return copysign(1.0, x) < 0; }
#endif
#endif
@@ -106,7 +106,7 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x
#endif
-#if COMPILER(MSVC) || COMPILER(RVCT)
+#if COMPILER(MSVC) || (COMPILER(RVCT) && !(RVCT_VERSION_AT_LEAST(3, 0, 0, 0)))
// We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss.
static double round(double num)
@@ -233,7 +233,12 @@ inline int clampToPositiveInteger(float d)
return static_cast<int>(std::max<float>(std::min(d, maxIntAsFloat), 0));
}
-#if !COMPILER(MSVC) && !COMPILER(WINSCW) && !(COMPILER(RVCT) && (OS(SYMBIAN) || PLATFORM(BREWMP)))
+inline int clampToInteger(unsigned value)
+{
+ return static_cast<int>(std::min(value, static_cast<unsigned>(std::numeric_limits<int>::max())));
+}
+
+#if !COMPILER(MSVC) && !COMPILER(WINSCW) && !(COMPILER(RVCT) && (OS(SYMBIAN) || PLATFORM(BREWMP))) && !OS(SOLARIS)
using std::isfinite;
using std::isinf;
using std::isnan;
diff --git a/Source/JavaScriptCore/wtf/MessageQueue.h b/Source/JavaScriptCore/wtf/MessageQueue.h
index 7c18a0c..2b774fb 100644
--- a/Source/JavaScriptCore/wtf/MessageQueue.h
+++ b/Source/JavaScriptCore/wtf/MessageQueue.h
@@ -41,7 +41,7 @@ namespace WTF {
enum MessageQueueWaitResult {
MessageQueueTerminated, // Queue was destroyed while waiting for message.
MessageQueueTimeout, // Timeout was specified and it expired.
- MessageQueueMessageReceived, // A message was successfully received and returned.
+ MessageQueueMessageReceived // A message was successfully received and returned.
};
// The queue takes ownership of messages and transfer it to the new owner
diff --git a/Source/JavaScriptCore/wtf/Platform.h b/Source/JavaScriptCore/wtf/Platform.h
index f4fdbcb..aee03e6 100644
--- a/Source/JavaScriptCore/wtf/Platform.h
+++ b/Source/JavaScriptCore/wtf/Platform.h
@@ -114,6 +114,11 @@
#define WTF_COMPILER_INTEL 1
#endif
+/* COMPILER(SUNCC) */
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+#define WTF_COMPILER_SUNCC 1
+#endif
+
/* ==== CPU() - the target CPU architecture ==== */
/* This also defines CPU(BIG_ENDIAN) or CPU(MIDDLE_ENDIAN) or neither, as appropriate. */
@@ -565,7 +570,11 @@
#define WTF_USE_MERSENNE_TWISTER_19937 1
#endif
-#if (PLATFORM(GTK) || PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && OS(DARWIN) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
+#if PLATFORM(QT) && OS(UNIX) && !OS(SYMBIAN) && !OS(DARWIN)
+#define WTF_USE_PTHREAD_BASED_QT 1
+#endif
+
+#if (PLATFORM(GTK) || PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && (OS(DARWIN) || USE(PTHREAD_BASED_QT)) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
#define ENABLE_JSC_MULTIPLE_THREADS 1
#endif
@@ -598,10 +607,6 @@
#define WTF_USE_ICU_UNICODE 1
#endif
-#if !PLATFORM(CHROMIUM) /* Chromium controls this macro with a gyp define */
-#define WTF_USE_BUILTIN_UTF8_CODEC 1
-#endif
-
#if PLATFORM(MAC) && !PLATFORM(IOS)
#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && CPU(X86_64)
#define WTF_USE_PLUGIN_HOST_PROCESS 1
@@ -963,6 +968,10 @@
#define ENABLE_GEOLOCATION 0
#endif
+#if !defined(ENABLE_GESTURE_RECOGNIZER)
+#define ENABLE_GESTURE_RECOGNIZER 0
+#endif
+
#if !defined(ENABLE_NOTIFICATIONS)
#define ENABLE_NOTIFICATIONS 0
#endif
@@ -1022,6 +1031,13 @@
#define ENABLE_JIT 1
#endif
+/* Currently only implemented for JSVALUE64, only tested on PLATFORM(MAC) */
+#if ENABLE(JIT) && USE(JSVALUE64) && PLATFORM(MAC)
+#define ENABLE_DFG_JIT 1
+/* Enabled with restrictions to circumvent known performance regressions. */
+#define ENABLE_DFG_JIT_RESTRICTIONS 1
+#endif
+
/* Ensure that either the JIT or the interpreter has been enabled. */
#if !defined(ENABLE_INTERPRETER) && !ENABLE(JIT)
#define ENABLE_INTERPRETER 1
@@ -1145,6 +1161,10 @@
#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1
#endif
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+#define WTF_USE_AVFOUNDATION 1
+#endif
+
#if COMPILER(GCC)
#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
#else
@@ -1184,4 +1204,10 @@
#include "GTypedefs.h"
#endif
+/* FIXME: This define won't be needed once #27551 is fully landed. However,
+ since most ports try to support sub-project independence, adding new headers
+ to WTF causes many ports to break, and so this way we can address the build
+ breakages one port at a time. */
+#define WTF_USE_EXPORT_MACROS 0
+
#endif /* WTF_Platform_h */
diff --git a/Source/JavaScriptCore/wtf/RefCounted.h b/Source/JavaScriptCore/wtf/RefCounted.h
index da178b2..12b670e 100644
--- a/Source/JavaScriptCore/wtf/RefCounted.h
+++ b/Source/JavaScriptCore/wtf/RefCounted.h
@@ -59,6 +59,12 @@ public:
#endif
}
+ // Helper for generating JIT code. Please do not use for non-JIT purposes.
+ const int* addressOfCount() const
+ {
+ return &m_refCount;
+ }
+
protected:
RefCountedBase()
: m_refCount(1)
@@ -93,12 +99,6 @@ protected:
return false;
}
- // Helper for generating JIT code. Please do not use for non-JIT purposes.
- int* addressOfCount()
- {
- return &m_refCount;
- }
-
#ifndef NDEBUG
bool deletionHasBegun() const
{
diff --git a/Source/JavaScriptCore/wtf/StdLibExtras.h b/Source/JavaScriptCore/wtf/StdLibExtras.h
index 4bb0076..0dacb91 100644
--- a/Source/JavaScriptCore/wtf/StdLibExtras.h
+++ b/Source/JavaScriptCore/wtf/StdLibExtras.h
@@ -114,6 +114,53 @@ inline size_t bitCount(unsigned bits)
template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))[Size];
#define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array))
+// Efficient implementation that takes advantage of powers of two.
+template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
+{
+ COMPILE_ASSERT(divisor && !(divisor & (divisor - 1)), divisor_is_a_power_of_two);
+
+ size_t remainderMask = divisor - 1;
+ return (x + remainderMask) & ~remainderMask;
+}
+
+// Binary search algorithm, calls extractKey on pre-sorted elements in array,
+// compares result with key (KeyTypes should be comparable with '--', '<', '>').
+// Optimized for cases where the array contains the key, checked by assertions.
+template<typename ArrayType, typename KeyType, KeyType(*extractKey)(ArrayType*)>
+inline ArrayType* binarySearch(ArrayType* array, size_t size, KeyType key)
+{
+ // The array must contain at least one element (pre-condition, array does conatin key).
+ // If the array only contains one element, no need to do the comparison.
+ while (size > 1) {
+ // Pick an element to check, half way through the array, and read the value.
+ int pos = (size - 1) >> 1;
+ KeyType val = extractKey(&array[pos]);
+
+ // If the key matches, success!
+ if (val == key)
+ return &array[pos];
+ // The item we are looking for is smaller than the item being check; reduce the value of 'size',
+ // chopping off the right hand half of the array.
+ else if (key < val)
+ size = pos;
+ // Discard all values in the left hand half of the array, up to and including the item at pos.
+ else {
+ size -= (pos + 1);
+ array += (pos + 1);
+ }
+
+ // 'size' should never reach zero.
+ ASSERT(size);
+ }
+
+ // If we reach this point we've chopped down to one element, no need to check it matches
+ ASSERT(size == 1);
+ ASSERT(key == extractKey(&array[0]));
+ return &array[0];
+}
+
} // namespace WTF
+using WTF::binarySearch;
+
#endif // WTF_StdLibExtras_h
diff --git a/Source/JavaScriptCore/wtf/StringHasher.h b/Source/JavaScriptCore/wtf/StringHasher.h
index a84b2c4..5a2c36c 100644
--- a/Source/JavaScriptCore/wtf/StringHasher.h
+++ b/Source/JavaScriptCore/wtf/StringHasher.h
@@ -88,7 +88,7 @@ public:
return result;
}
- template<typename T, UChar Converter(T)> static inline unsigned createHash(const T* data, unsigned length)
+ template<typename T, UChar Converter(T)> static inline unsigned computeHash(const T* data, unsigned length)
{
StringHasher hasher;
bool rem = length & 1;
@@ -105,7 +105,7 @@ public:
return hasher.hash();
}
- template<typename T, UChar Converter(T)> static inline unsigned createHash(const T* data)
+ template<typename T, UChar Converter(T)> static inline unsigned computeHash(const T* data)
{
StringHasher hasher;
@@ -125,26 +125,26 @@ public:
return hasher.hash();
}
- template<typename T> static inline unsigned createHash(const T* data, unsigned length)
+ template<typename T> static inline unsigned computeHash(const T* data, unsigned length)
{
- return createHash<T, defaultCoverter>(data, length);
+ return computeHash<T, defaultCoverter>(data, length);
}
- template<typename T> static inline unsigned createHash(const T* data)
+ template<typename T> static inline unsigned computeHash(const T* data)
{
- return createHash<T, defaultCoverter>(data);
+ return computeHash<T, defaultCoverter>(data);
}
- template<size_t length> static inline unsigned createBlobHash(const void* data)
+ template<size_t length> static inline unsigned hashMemory(const void* data)
{
COMPILE_ASSERT(!(length % 4), length_must_be_a_multible_of_four);
- return createHash<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar));
+ return computeHash<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar));
}
- static inline unsigned createBlobHash(const void* data, unsigned size)
+ static inline unsigned hashMemory(const void* data, unsigned size)
{
ASSERT(!(size % 2));
- return createHash<UChar>(static_cast<const UChar*>(data), size / sizeof(UChar));
+ return computeHash<UChar>(static_cast<const UChar*>(data), size / sizeof(UChar));
}
private:
@@ -173,4 +173,6 @@ private:
} // namespace WTF
+using WTF::StringHasher;
+
#endif // WTF_StringHasher_h
diff --git a/Source/JavaScriptCore/wtf/ThreadSafeShared.h b/Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h
index a6a1cf2..c9beec4 100644
--- a/Source/JavaScriptCore/wtf/ThreadSafeShared.h
+++ b/Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h
@@ -56,8 +56,8 @@
* DEALINGS IN THE SOFTWARE.
*/
-#ifndef ThreadSafeShared_h
-#define ThreadSafeShared_h
+#ifndef ThreadSafeRefCounted_h
+#define ThreadSafeRefCounted_h
#include "Platform.h"
@@ -66,17 +66,18 @@
namespace WTF {
-class ThreadSafeSharedBase {
- WTF_MAKE_NONCOPYABLE(ThreadSafeSharedBase); WTF_MAKE_FAST_ALLOCATED;
+class ThreadSafeRefCountedBase {
+ WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedBase);
+ WTF_MAKE_FAST_ALLOCATED;
public:
- ThreadSafeSharedBase(int initialRefCount = 1)
+ ThreadSafeRefCountedBase(int initialRefCount = 1)
: m_refCount(initialRefCount)
{
}
void ref()
{
-#if USE(LOCKFREE_THREADSAFESHARED)
+#if USE(LOCKFREE_THREADSAFEREFCOUNTED)
atomicIncrement(&m_refCount);
#else
MutexLocker locker(m_mutex);
@@ -91,7 +92,7 @@ public:
int refCount() const
{
-#if !USE(LOCKFREE_THREADSAFESHARED)
+#if !USE(LOCKFREE_THREADSAFEREFCOUNTED)
MutexLocker locker(m_mutex);
#endif
return static_cast<int const volatile &>(m_refCount);
@@ -101,7 +102,7 @@ protected:
// Returns whether the pointer should be freed or not.
bool derefBase()
{
-#if USE(LOCKFREE_THREADSAFESHARED)
+#if USE(LOCKFREE_THREADSAFEREFCOUNTED)
if (atomicDecrement(&m_refCount) <= 0)
return true;
#else
@@ -122,12 +123,12 @@ private:
friend class CrossThreadRefCounted;
int m_refCount;
-#if !USE(LOCKFREE_THREADSAFESHARED)
+#if !USE(LOCKFREE_THREADSAFEREFCOUNTED)
mutable Mutex m_mutex;
#endif
};
-template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {
+template<class T> class ThreadSafeRefCounted : public ThreadSafeRefCountedBase {
public:
void deref()
{
@@ -136,13 +137,13 @@ public:
}
protected:
- ThreadSafeShared()
+ ThreadSafeRefCounted()
{
}
};
} // namespace WTF
-using WTF::ThreadSafeShared;
+using WTF::ThreadSafeRefCounted;
-#endif // ThreadSafeShared_h
+#endif // ThreadSafeRefCounted_h
diff --git a/Source/JavaScriptCore/wtf/Threading.h b/Source/JavaScriptCore/wtf/Threading.h
index 044365f..b6f8c24 100644
--- a/Source/JavaScriptCore/wtf/Threading.h
+++ b/Source/JavaScriptCore/wtf/Threading.h
@@ -67,7 +67,7 @@
#include <wtf/Locker.h>
#include <wtf/MainThread.h>
#include <wtf/Noncopyable.h>
-#include <wtf/ThreadSafeShared.h>
+#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/ThreadingPrimitives.h>
// For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc).
diff --git a/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp b/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp
index aa63f33..0ffcfe2 100644
--- a/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp
+++ b/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp
@@ -55,6 +55,10 @@
#include <wtf/PassOwnPtr.h>
#endif
+#if OS(MAC_OS_X) && !defined(BUILDING_ON_LEOPARD)
+#include <objc/objc-auto.h>
+#endif
+
namespace WTF {
typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
@@ -190,6 +194,12 @@ void initializeCurrentThreadInternal(const char* threadName)
UNUSED_PARAM(threadName);
#endif
+#if OS(MAC_OS_X) && !defined(BUILDING_ON_LEOPARD)
+ // All threads that potentially use APIs above the BSD layer must be registered with the Objective-C
+ // garbage collector in case API implementations use garbage-collected memory.
+ objc_registerThreadWithCollector();
+#endif
+
ThreadIdentifier id = identifierByPthreadHandle(pthread_self());
ASSERT(id);
ThreadIdentifierData::initialize(id);
diff --git a/Source/JavaScriptCore/wtf/Vector.h b/Source/JavaScriptCore/wtf/Vector.h
index 2fb4114..b26857c 100644
--- a/Source/JavaScriptCore/wtf/Vector.h
+++ b/Source/JavaScriptCore/wtf/Vector.h
@@ -40,7 +40,7 @@ namespace WTF {
using std::max;
// WTF_ALIGN_OF / WTF_ALIGNED
- #if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW)
+ #if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW) || COMPILER(SUNCC)
#define WTF_ALIGN_OF(type) __alignof__(type)
#define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n)))
#elif COMPILER(MSVC)
@@ -566,6 +566,7 @@ namespace WTF {
T& last() { return at(size() - 1); }
const T& last() const { return at(size() - 1); }
+ template<typename U> bool contains(const U&) const;
template<typename U> size_t find(const U&) const;
template<typename U> size_t reverseFind(const U&) const;
@@ -745,6 +746,13 @@ namespace WTF {
template<typename T, size_t inlineCapacity>
template<typename U>
+ bool Vector<T, inlineCapacity>::contains(const U& value) const
+ {
+ return find(value) != notFound;
+ }
+
+ template<typename T, size_t inlineCapacity>
+ template<typename U>
size_t Vector<T, inlineCapacity>::find(const U& value) const
{
for (size_t i = 0; i < size(); ++i) {
diff --git a/Source/JavaScriptCore/wtf/text/AtomicString.cpp b/Source/JavaScriptCore/wtf/text/AtomicString.cpp
index e0a866d..eb0dbbb 100644
--- a/Source/JavaScriptCore/wtf/text/AtomicString.cpp
+++ b/Source/JavaScriptCore/wtf/text/AtomicString.cpp
@@ -87,7 +87,7 @@ static inline PassRefPtr<StringImpl> addToStringTable(const T& value)
struct CStringTranslator {
static unsigned hash(const char* c)
{
- return StringImpl::computeHash(c);
+ return StringHasher::computeHash(c);
}
static bool equal(StringImpl* r, const char* s)
@@ -142,7 +142,7 @@ static inline bool equal(StringImpl* string, const UChar* characters, unsigned l
// FIXME: perhaps we should have a more abstract macro that indicates when
// going 4 bytes at a time is unsafe
-#if CPU(ARM) || CPU(SH4) || CPU(MIPS)
+#if CPU(ARM) || CPU(SH4) || CPU(MIPS) || CPU(SPARC)
const UChar* stringCharacters = string->characters();
for (unsigned i = 0; i != length; ++i) {
if (*stringCharacters++ != *characters++)
@@ -176,7 +176,7 @@ bool operator==(const AtomicString& string, const Vector<UChar>& vector)
struct UCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
- return StringImpl::computeHash(buf.s, buf.length);
+ return StringHasher::computeHash(buf.s, buf.length);
}
static bool equal(StringImpl* const& str, const UCharBuffer& buf)
@@ -201,7 +201,7 @@ struct HashAndCharacters {
struct HashAndCharactersTranslator {
static unsigned hash(const HashAndCharacters& buffer)
{
- ASSERT(buffer.hash == StringImpl::computeHash(buffer.characters, buffer.length));
+ ASSERT(buffer.hash == StringHasher::computeHash(buffer.characters, buffer.length));
return buffer.hash;
}
diff --git a/Source/JavaScriptCore/wtf/text/StringConcatenate.h b/Source/JavaScriptCore/wtf/text/StringConcatenate.h
index 92a2d06..7fa7d2c 100644
--- a/Source/JavaScriptCore/wtf/text/StringConcatenate.h
+++ b/Source/JavaScriptCore/wtf/text/StringConcatenate.h
@@ -89,6 +89,34 @@ private:
};
template<>
+class StringTypeAdapter<const UChar*> {
+public:
+ StringTypeAdapter<const UChar*>(const UChar* buffer)
+ : m_buffer(buffer)
+ {
+ size_t len = 0;
+ while (m_buffer[len] != UChar(0))
+ len++;
+
+ if (len > std::numeric_limits<unsigned>::max())
+ CRASH();
+
+ m_length = len;
+ }
+
+ unsigned length() { return m_length; }
+
+ void writeTo(UChar* destination)
+ {
+ memcpy(destination, m_buffer, static_cast<size_t>(m_length) * sizeof(UChar));
+ }
+
+private:
+ const UChar* m_buffer;
+ unsigned m_length;
+};
+
+template<>
class StringTypeAdapter<const char*> {
public:
StringTypeAdapter<const char*>(const char* buffer)
diff --git a/Source/JavaScriptCore/wtf/text/StringHash.h b/Source/JavaScriptCore/wtf/text/StringHash.h
index d7aabdb..80193a6 100644
--- a/Source/JavaScriptCore/wtf/text/StringHash.h
+++ b/Source/JavaScriptCore/wtf/text/StringHash.h
@@ -104,7 +104,7 @@ namespace WTF {
static unsigned hash(const UChar* data, unsigned length)
{
- return StringHasher::createHash<UChar, foldCase<UChar> >(data, length);
+ return StringHasher::computeHash<UChar, foldCase<UChar> >(data, length);
}
static unsigned hash(StringImpl* str)
@@ -114,7 +114,7 @@ namespace WTF {
static unsigned hash(const char* data, unsigned length)
{
- return StringHasher::createHash<char, foldCase<char> >(data, length);
+ return StringHasher::computeHash<char, foldCase<char> >(data, length);
}
static bool equal(const StringImpl* a, const StringImpl* b)
diff --git a/Source/JavaScriptCore/wtf/text/StringImpl.h b/Source/JavaScriptCore/wtf/text/StringImpl.h
index a08427b..81911b3 100644
--- a/Source/JavaScriptCore/wtf/text/StringImpl.h
+++ b/Source/JavaScriptCore/wtf/text/StringImpl.h
@@ -136,7 +136,7 @@ private:
{
ASSERT(!isStatic());
ASSERT(!m_hash);
- ASSERT(hash == computeHash(m_data, m_length));
+ ASSERT(hash == StringHasher::computeHash(m_data, m_length));
m_hash = hash;
}
@@ -235,11 +235,8 @@ public:
m_refCountAndFlags &= ~s_refCountFlagIsAtomic;
}
- unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
+ unsigned hash() const { if (!m_hash) m_hash = StringHasher::computeHash(m_data, m_length); return m_hash; }
unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
- static unsigned computeHash(const UChar* data, unsigned length) { return WTF::StringHasher::createHash<UChar>(data, length); }
- static unsigned computeHash(const char* data, unsigned length) { return WTF::StringHasher::createHash<char>(data, length); }
- static unsigned computeHash(const char* data) { return WTF::StringHasher::createHash<char>(data); }
ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; }
diff --git a/Source/JavaScriptCore/wtf/unicode/UTF8.cpp b/Source/JavaScriptCore/wtf/unicode/UTF8.cpp
index 4c3738b..6981fe4 100644
--- a/Source/JavaScriptCore/wtf/unicode/UTF8.cpp
+++ b/Source/JavaScriptCore/wtf/unicode/UTF8.cpp
@@ -319,7 +319,7 @@ static inline unsigned calculateStringHashAndLengthFromUTF8Internal(const char*
if (!data)
return 0;
- WTF::StringHasher stringHasher;
+ StringHasher stringHasher;
dataLength = 0;
utf16Length = 0;
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
index 37d44f7..d8c5d27 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
@@ -1234,6 +1234,10 @@ public:
if (input.checkInput(currentTerm().checkInputCount))
MATCH_NEXT();
BACKTRACK();
+
+ case ByteTerm::TypeUncheckInput:
+ input.uncheckInput(currentTerm().checkInputCount);
+ MATCH_NEXT();
}
// We should never fall-through to here.
@@ -1354,6 +1358,10 @@ public:
case ByteTerm::TypeCheckInput:
input.uncheckInput(currentTerm().checkInputCount);
BACKTRACK();
+
+ case ByteTerm::TypeUncheckInput:
+ input.checkInput(currentTerm().checkInputCount);
+ BACKTRACK();
}
ASSERT_NOT_REACHED();
@@ -1453,6 +1461,11 @@ public:
m_bodyDisjunction->terms.append(ByteTerm::CheckInput(count));
}
+ void uncheckInput(unsigned count)
+ {
+ m_bodyDisjunction->terms.append(ByteTerm::UncheckInput(count));
+ }
+
void assertionBOL(int inputPosition)
{
m_bodyDisjunction->terms.append(ByteTerm::BOL(inputPosition));
@@ -1849,10 +1862,21 @@ public:
ASSERT(currentCountAlreadyChecked >= static_cast<unsigned>(term.inputPosition));
int positiveInputOffset = currentCountAlreadyChecked - term.inputPosition;
+ int uncheckAmount = positiveInputOffset - term.parentheses.disjunction->m_minimumSize;
+
+ if (uncheckAmount > 0) {
+ uncheckInput(uncheckAmount);
+ currentCountAlreadyChecked -= uncheckAmount;
+ } else
+ uncheckAmount = 0;
atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invert(), term.frameLocation, alternativeFrameLocation);
emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, positiveInputOffset, true);
atomParentheticalAssertionEnd(0, term.frameLocation, term.quantityCount, term.quantityType);
+ if (uncheckAmount) {
+ checkInput(uncheckAmount);
+ currentCountAlreadyChecked += uncheckAmount;
+ }
break;
}
}
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.h b/Source/JavaScriptCore/yarr/YarrInterpreter.h
index eea5266..a9f4d48 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.h
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.h
@@ -70,6 +70,7 @@ struct ByteTerm {
TypeParentheticalAssertionBegin,
TypeParentheticalAssertionEnd,
TypeCheckInput,
+ TypeUncheckInput,
} type;
union {
struct {
@@ -205,6 +206,13 @@ struct ByteTerm {
return term;
}
+ static ByteTerm UncheckInput(unsigned count)
+ {
+ ByteTerm term(TypeUncheckInput);
+ term.checkInputCount = count;
+ return term;
+ }
+
static ByteTerm EOL(int inputPos)
{
ByteTerm term(TypeAssertionEOL);
diff --git a/Source/JavaScriptCore/yarr/YarrJIT.cpp b/Source/JavaScriptCore/yarr/YarrJIT.cpp
index e34e6f4..bc61a6e 100644
--- a/Source/JavaScriptCore/yarr/YarrJIT.cpp
+++ b/Source/JavaScriptCore/yarr/YarrJIT.cpp
@@ -157,7 +157,7 @@ class YarrGenerator : private MacroAssembler {
}
Jump unicodeFail;
if (charClass->m_matchesUnicode.size() || charClass->m_rangesUnicode.size()) {
- Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));
+ Jump isAscii = branch32(LessThanOrEqual, character, TrustedImm32(0x7f));
if (charClass->m_matchesUnicode.size()) {
for (unsigned i = 0; i < charClass->m_matchesUnicode.size(); ++i) {
@@ -207,9 +207,9 @@ class YarrGenerator : private MacroAssembler {
}
if (unsigned countAZaz = matchesAZaz.size()) {
- or32(Imm32(32), character);
+ or32(TrustedImm32(32), character);
for (unsigned i = 0; i < countAZaz; ++i)
- matchDest.append(branch32(Equal, character, Imm32(matchesAZaz[i])));
+ matchDest.append(branch32(Equal, character, TrustedImm32(matchesAZaz[i])));
}
}
@@ -265,14 +265,14 @@ class YarrGenerator : private MacroAssembler {
poke(reg, frameLocation);
}
- void storeToFrame(Imm32 imm, unsigned frameLocation)
+ void storeToFrame(TrustedImm32 imm, unsigned frameLocation)
{
poke(imm, frameLocation);
}
DataLabelPtr storeToFrameWithPatch(unsigned frameLocation)
{
- return storePtrWithPatch(ImmPtr(0), Address(stackPointerRegister, frameLocation * sizeof(void*)));
+ return storePtrWithPatch(TrustedImmPtr(0), Address(stackPointerRegister, frameLocation * sizeof(void*)));
}
void loadFromFrame(unsigned frameLocation, RegisterID reg)
@@ -1109,11 +1109,11 @@ class YarrGenerator : private MacroAssembler {
if (m_term.quantityType == QuantifierGreedy) {
// If this is -1 we have now tested with both with and without the parens.
generator->loadFromFrame(parenthesesFrameLocation, indexTemporary);
- m_backtrack.jumpToBacktrack(generator, generator->branch32(Equal, indexTemporary, Imm32(-1)));
+ m_backtrack.jumpToBacktrack(generator, generator->branch32(Equal, indexTemporary, TrustedImm32(-1)));
} else if (m_term.quantityType == QuantifierNonGreedy) {
// If this is -1 we have now tested with both with and without the parens.
generator->loadFromFrame(parenthesesFrameLocation, indexTemporary);
- generator->branch32(Equal, indexTemporary, Imm32(-1)).linkTo(m_nonGreedyTryParentheses, generator);
+ generator->branch32(Equal, indexTemporary, TrustedImm32(-1)).linkTo(m_nonGreedyTryParentheses, generator);
}
if (!m_doDirectBacktrack)
@@ -1126,10 +1126,10 @@ class YarrGenerator : private MacroAssembler {
m_withinBacktrackJumps.link(generator);
if (m_term.capture())
- generator->store32(Imm32(-1), Address(output, (m_term.parentheses.subpatternId << 1) * sizeof(int)));
+ generator->store32(TrustedImm32(-1), Address(output, (m_term.parentheses.subpatternId << 1) * sizeof(int)));
if (m_term.quantityType == QuantifierGreedy) {
- generator->storeToFrame(Imm32(-1), parenthesesFrameLocation);
+ generator->storeToFrame(TrustedImm32(-1), parenthesesFrameLocation);
generator->jump().linkTo(m_fallThrough, generator);
nextBacktrackFallThrough = false;
} else if (!nextBacktrackFallThrough)
@@ -1271,7 +1271,7 @@ class YarrGenerator : private MacroAssembler {
if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
readCharacter(state.inputOffset(), character);
- or32(Imm32(32), character);
+ or32(TrustedImm32(32), character);
state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
} else {
ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
@@ -1316,13 +1316,13 @@ class YarrGenerator : private MacroAssembler {
Label loop(this);
if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
load16(BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), character);
- or32(Imm32(32), character);
+ or32(TrustedImm32(32), character);
state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
} else {
ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
state.jumpToBacktrack(this, branch16(NotEqual, BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), Imm32(ch)));
}
- add32(Imm32(1), countRegister);
+ add32(TrustedImm32(1), countRegister);
branch32(NotEqual, countRegister, index).linkTo(loop, this);
}
@@ -1333,22 +1333,22 @@ class YarrGenerator : private MacroAssembler {
PatternTerm& term = state.term();
UChar ch = term.patternCharacter;
- move(Imm32(0), countRegister);
+ move(TrustedImm32(0), countRegister);
JumpList failures;
Label loop(this);
failures.append(atEndOfInput());
if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
readCharacter(state.inputOffset(), character);
- or32(Imm32(32), character);
+ or32(TrustedImm32(32), character);
failures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
} else {
ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
failures.append(jumpIfCharNotEquals(ch, state.inputOffset()));
}
- add32(Imm32(1), countRegister);
- add32(Imm32(1), index);
+ add32(TrustedImm32(1), countRegister);
+ add32(TrustedImm32(1), index);
if (term.quantityCount != quantifyInfinite) {
branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
failures.append(jump());
@@ -1358,8 +1358,8 @@ class YarrGenerator : private MacroAssembler {
Label backtrackBegin(this);
loadFromFrame(term.frameLocation, countRegister);
state.jumpToBacktrack(this, branchTest32(Zero, countRegister));
- sub32(Imm32(1), countRegister);
- sub32(Imm32(1), index);
+ sub32(TrustedImm32(1), countRegister);
+ sub32(TrustedImm32(1), index);
failures.link(this);
@@ -1375,7 +1375,7 @@ class YarrGenerator : private MacroAssembler {
PatternTerm& term = state.term();
UChar ch = term.patternCharacter;
- move(Imm32(0), countRegister);
+ move(TrustedImm32(0), countRegister);
Jump firstTimeDoNothing = jump();
@@ -1391,15 +1391,15 @@ class YarrGenerator : private MacroAssembler {
branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail);
if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
readCharacter(state.inputOffset(), character);
- or32(Imm32(32), character);
+ or32(TrustedImm32(32), character);
branch32(NotEqual, character, Imm32(Unicode::toLower(ch))).linkTo(hardFail, this);
} else {
ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
jumpIfCharNotEquals(ch, state.inputOffset()).linkTo(hardFail, this);
}
- add32(Imm32(1), countRegister);
- add32(Imm32(1), index);
+ add32(TrustedImm32(1), countRegister);
+ add32(TrustedImm32(1), index);
firstTimeDoNothing.link(this);
storeToFrame(countRegister, term.frameLocation);
@@ -1445,7 +1445,7 @@ class YarrGenerator : private MacroAssembler {
matchDest.link(this);
}
- add32(Imm32(1), countRegister);
+ add32(TrustedImm32(1), countRegister);
branch32(NotEqual, countRegister, index).linkTo(loop, this);
}
@@ -1455,7 +1455,7 @@ class YarrGenerator : private MacroAssembler {
const RegisterID countRegister = regT1;
PatternTerm& term = state.term();
- move(Imm32(0), countRegister);
+ move(TrustedImm32(0), countRegister);
JumpList failures;
Label loop(this);
@@ -1472,8 +1472,8 @@ class YarrGenerator : private MacroAssembler {
matchDest.link(this);
}
- add32(Imm32(1), countRegister);
- add32(Imm32(1), index);
+ add32(TrustedImm32(1), countRegister);
+ add32(TrustedImm32(1), index);
if (term.quantityCount != quantifyInfinite) {
branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
failures.append(jump());
@@ -1483,8 +1483,8 @@ class YarrGenerator : private MacroAssembler {
Label backtrackBegin(this);
loadFromFrame(term.frameLocation, countRegister);
state.jumpToBacktrack(this, branchTest32(Zero, countRegister));
- sub32(Imm32(1), countRegister);
- sub32(Imm32(1), index);
+ sub32(TrustedImm32(1), countRegister);
+ sub32(TrustedImm32(1), index);
failures.link(this);
@@ -1499,7 +1499,7 @@ class YarrGenerator : private MacroAssembler {
const RegisterID countRegister = regT1;
PatternTerm& term = state.term();
- move(Imm32(0), countRegister);
+ move(TrustedImm32(0), countRegister);
Jump firstTimeDoNothing = jump();
@@ -1524,8 +1524,8 @@ class YarrGenerator : private MacroAssembler {
matchDest.link(this);
}
- add32(Imm32(1), countRegister);
- add32(Imm32(1), index);
+ add32(TrustedImm32(1), countRegister);
+ add32(TrustedImm32(1), index);
firstTimeDoNothing.link(this);
storeToFrame(countRegister, term.frameLocation);
@@ -1669,7 +1669,7 @@ class YarrGenerator : private MacroAssembler {
if (term.quantityType == QuantifierGreedy)
storeToFrame(index, parenthesesFrameLocation);
else if (term.quantityType == QuantifierNonGreedy) {
- storeToFrame(Imm32(-1), parenthesesFrameLocation);
+ storeToFrame(TrustedImm32(-1), parenthesesFrameLocation);
nonGreedySkipParentheses = jump();
nonGreedyTryParentheses = label();
storeToFrame(index, parenthesesFrameLocation);
@@ -2140,7 +2140,7 @@ class YarrGenerator : private MacroAssembler {
if (m_pattern.m_body->m_callFrameSize)
addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
- move(Imm32(-1), returnRegister);
+ move(TrustedImm32(-1), returnRegister);
generateReturn();