WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
116889.patch (text/plain), 113.39 KB, created by
Michael Saboff
on 2013-05-28 16:41:41 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Michael Saboff
Created:
2013-05-28 16:41:41 PDT
Size:
113.39 KB
patch
obsolete
>Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 150843) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -612,6 +612,7 @@ > 651122FD14046A4C002B101D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; }; > 651122FE14046A4C002B101D /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; }; > 6511230714046B0A002B101D /* testRegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651122E5140469BA002B101D /* testRegExp.cpp */; }; >+ 6519976E17443D68007393CE /* CommonSlowPaths.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6519976C17443548007393CE /* CommonSlowPaths.cpp */; }; > 65303D641447B9E100D3F904 /* ParserTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 65303D631447B9E100D3F904 /* ParserTokens.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; }; > 7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -1581,6 +1582,7 @@ > 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypeInfo.h; sourceTree = "<group>"; }; > 651122E5140469BA002B101D /* testRegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testRegExp.cpp; sourceTree = "<group>"; }; > 6511230514046A4C002B101D /* testRegExp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testRegExp; sourceTree = BUILT_PRODUCTS_DIR; }; >+ 6519976C17443548007393CE /* CommonSlowPaths.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommonSlowPaths.cpp; sourceTree = "<group>"; }; > 65303D631447B9E100D3F904 /* ParserTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserTokens.h; sourceTree = "<group>"; }; > 65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyNameArray.cpp; sourceTree = "<group>"; }; > 65400C100A69BAF200509887 /* PropertyNameArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PropertyNameArray.h; sourceTree = "<group>"; }; >@@ -1590,6 +1592,7 @@ > 65621E6C089E859700760F35 /* PropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = PropertySlot.h; sourceTree = "<group>"; tabWidth = 8; }; > 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilationInfo.h; path = dfg/DFGOSRExitCompilationInfo.h; sourceTree = "<group>"; }; > 65987F2F16828A7E003C2F8D /* UnusedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedPointer.h; sourceTree = "<group>"; }; >+ 65AC83F1174C17AE0011D8AB /* SlowPathCall.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SlowPathCall.h; sourceTree = "<group>"; }; > 65C02FBB0637462A003E7EE6 /* Protect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Protect.h; sourceTree = "<group>"; tabWidth = 8; }; > 65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; }; > 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; }; >@@ -2285,6 +2288,7 @@ > 1429D92C0ED22D7000B89619 /* jit */ = { > isa = PBXGroup; > children = ( >+ 65AC83F1174C17AE0011D8AB /* SlowPathCall.h */, > 0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */, > 0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */, > 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */, >@@ -2613,6 +2617,7 @@ > 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = { > isa = PBXGroup; > children = ( >+ 6519976C17443548007393CE /* CommonSlowPaths.cpp */, > BCF605110E203EF800B9A64D /* ArgList.cpp */, > BCF605120E203EF800B9A64D /* ArgList.h */, > BC257DE50E1F51C50016B6C9 /* Arguments.cpp */, >@@ -4108,6 +4113,7 @@ > isa = PBXSourcesBuildPhase; > buildActionMask = 2147483647; > files = ( >+ 6519976E17443D68007393CE /* CommonSlowPaths.cpp in Sources */, > 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */, > 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */, > 147F39BE107EC37600427A48 /* Arguments.cpp in Sources */, >Index: Source/JavaScriptCore/interpreter/Interpreter.cpp >=================================================================== >--- Source/JavaScriptCore/interpreter/Interpreter.cpp (revision 150843) >+++ Source/JavaScriptCore/interpreter/Interpreter.cpp (working copy) >@@ -713,7 +713,7 @@ void Interpreter::getStackTrace(Vector<S > void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSObject* error) > { > VM* vm = &callFrame->vm(); >- ASSERT(callFrame == vm->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec()); >+// ASSERT(callFrame == vm->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec()); > if (error->hasProperty(callFrame, vm->propertyNames->stack)) > return; > >Index: Source/JavaScriptCore/jit/JIT.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JIT.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JIT.cpp (working copy) >@@ -46,6 +46,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckS > #include "RepatchBuffer.h" > #include "ResultType.h" > #include "SamplingTool.h" >+#include "SlowPathCall.h" > #include <wtf/CryptographicallyRandomNumber.h> > > using namespace std; >@@ -156,39 +157,33 @@ void JIT::emitTimeoutCheck() > > #if USE(JSVALUE32_64) > #define DEFINE_BINARY_OP(name) \ >- case name: { \ >- JITStubCall stubCall(this, cti_##name); \ >- stubCall.addArgument(currentInstruction[2].u.operand); \ >- stubCall.addArgument(currentInstruction[3].u.operand); \ >- stubCall.call(currentInstruction[1].u.operand); \ >- NEXT_OPCODE(name); \ >+ case op_##name: { \ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_##name); \ >+ slowPathCall.call(); \ >+ NEXT_OPCODE(op_##name); \ > } > > #define DEFINE_UNARY_OP(name) \ >- case name: { \ >- JITStubCall stubCall(this, cti_##name); \ >- stubCall.addArgument(currentInstruction[2].u.operand); \ >- stubCall.call(currentInstruction[1].u.operand); \ >- NEXT_OPCODE(name); \ >+ case op_##name: { \ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_##name); \ >+ slowPathCall.call(); \ >+ NEXT_OPCODE(op_##name); \ > } > > #else // USE(JSVALUE32_64) > > #define DEFINE_BINARY_OP(name) \ >- case name: { \ >- JITStubCall stubCall(this, cti_##name); \ >- stubCall.addArgument(currentInstruction[2].u.operand, regT2); \ >- stubCall.addArgument(currentInstruction[3].u.operand, regT2); \ >- stubCall.call(currentInstruction[1].u.operand); \ >- NEXT_OPCODE(name); \ >+ case op_##name: { \ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_##name); \ >+ slowPathCall.call(); \ >+ NEXT_OPCODE(op_##name); \ > } > > #define DEFINE_UNARY_OP(name) \ >- case name: { \ >- JITStubCall stubCall(this, cti_##name); \ >- stubCall.addArgument(currentInstruction[2].u.operand, regT2); \ >- stubCall.call(currentInstruction[1].u.operand); \ >- NEXT_OPCODE(name); \ >+ case op_##name: { \ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_##name); \ >+ slowPathCall.call(); \ >+ NEXT_OPCODE(op_##name); \ > } > #endif // USE(JSVALUE32_64) > >@@ -244,15 +239,15 @@ void JIT::privateCompileMainPass() > } > > switch (opcodeID) { >- DEFINE_BINARY_OP(op_del_by_val) >- DEFINE_BINARY_OP(op_in) >- DEFINE_BINARY_OP(op_less) >- DEFINE_BINARY_OP(op_lesseq) >- DEFINE_BINARY_OP(op_greater) >- DEFINE_BINARY_OP(op_greatereq) >- DEFINE_UNARY_OP(op_is_function) >- DEFINE_UNARY_OP(op_is_object) >- DEFINE_UNARY_OP(op_typeof) >+ DEFINE_BINARY_OP(del_by_val) >+ DEFINE_BINARY_OP(in) >+ DEFINE_BINARY_OP(less) >+ DEFINE_BINARY_OP(lesseq) >+ DEFINE_BINARY_OP(greater) >+ DEFINE_BINARY_OP(greatereq) >+ DEFINE_UNARY_OP(is_function) >+ DEFINE_UNARY_OP(is_object) >+ DEFINE_UNARY_OP(typeof) > > DEFINE_OP(op_add) > DEFINE_OP(op_bitand) >Index: Source/JavaScriptCore/jit/JIT.h >=================================================================== >--- Source/JavaScriptCore/jit/JIT.h (revision 150843) >+++ Source/JavaScriptCore/jit/JIT.h (working copy) >@@ -283,6 +283,7 @@ namespace JSC { > void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction); > > class JIT : private JSInterfaceJIT { >+ friend class JITSlowPathCall; > friend class JITStubCall; > friend struct PropertyStubCompilationInfo; > >@@ -608,7 +609,7 @@ namespace JSC { > > void emitTagAsBoolImmediate(RegisterID reg); > void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); >- void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase); >+ void compileBinaryArithOpSlowCase(Instruction*, OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase); > > void compileGetByIdHotPath(int baseVReg, Identifier*); > void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier*, Vector<SlowCaseEntry>::iterator&); >Index: Source/JavaScriptCore/jit/JITArithmetic32_64.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITArithmetic32_64.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JITArithmetic32_64.cpp (working copy) >@@ -39,6 +39,7 @@ > #include "Operations.h" > #include "ResultType.h" > #include "SamplingTool.h" >+#include "SlowPathCall.h" > > #ifndef NDEBUG > #include <stdio.h> >@@ -80,9 +81,9 @@ void JIT::emitSlow_op_negate(Instruction > linkSlowCase(iter); // 0x7fffffff check > linkSlowCase(iter); // double check > >- JITStubCall stubCall(this, cti_op_negate); >- stubCall.addArgument(regT1, regT0); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_negate); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_compareAndJump(OpcodeID opcode, unsigned op1, unsigned op2, unsigned target, RelationalCondition condition) >@@ -198,10 +199,9 @@ void JIT::emitSlow_op_lshift(Instruction > linkSlowCase(iter); // int32 check > linkSlowCase(iter); // int32 check > >- JITStubCall stubCall(this, cti_op_lshift); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // RightShift (>>) and UnsignedRightShift (>>>) helper >@@ -296,10 +296,9 @@ void JIT::emitRightShiftSlowCase(Instruc > linkSlowCase(iter); // Can't represent unsigned result as an immediate > } > >- JITStubCall stubCall(this, isUnsigned ? cti_op_urshift : cti_op_rshift); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, isUnsigned ? slow_path_urshift : slow_path_rshift); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // RightShift (>>) >@@ -361,10 +360,9 @@ void JIT::emitSlow_op_bitand(Instruction > linkSlowCase(iter); // int32 check > linkSlowCase(iter); // int32 check > >- JITStubCall stubCall(this, cti_op_bitand); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitand); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // BitOr (|) >@@ -402,10 +400,9 @@ void JIT::emitSlow_op_bitor(Instruction* > linkSlowCase(iter); // int32 check > linkSlowCase(iter); // int32 check > >- JITStubCall stubCall(this, cti_op_bitor); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitor); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // BitXor (^) >@@ -443,10 +440,9 @@ void JIT::emitSlow_op_bitxor(Instruction > linkSlowCase(iter); // int32 check > linkSlowCase(iter); // int32 check > >- JITStubCall stubCall(this, cti_op_bitxor); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitxor); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_op_inc(Instruction* currentInstruction) >@@ -506,10 +502,9 @@ void JIT::emit_op_add(Instruction* curre > > if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) { > addSlowCase(); >- JITStubCall stubCall(this, cti_op_add); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > return; > } > >@@ -611,10 +606,9 @@ void JIT::emitSlow_op_add(Instruction* c > } > } > >- JITStubCall stubCall(this, cti_op_add); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // Subtraction (-) >@@ -689,7 +683,6 @@ void JIT::emitSub32Constant(unsigned dst > void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned dst = currentInstruction[1].u.operand; >- unsigned op1 = currentInstruction[2].u.operand; > unsigned op2 = currentInstruction[3].u.operand; > OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); > >@@ -715,10 +708,9 @@ void JIT::emitSlow_op_sub(Instruction* c > } > } > >- JITStubCall stubCall(this, cti_op_sub); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_sub); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes types, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters, bool op2IsInRegisters) >@@ -1022,11 +1014,9 @@ void JIT::emitSlow_op_mul(Instruction* c > } > } > >- Label jitStubCall(this); >- JITStubCall stubCall(this, cti_op_mul); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_mul); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // Division (/) >@@ -1097,8 +1087,7 @@ void JIT::emit_op_div(Instruction* curre > void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned dst = currentInstruction[1].u.operand; >- unsigned op1 = currentInstruction[2].u.operand; >- unsigned op2 = currentInstruction[3].u.operand; >+ > OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); > > if (!supportsFloatingPoint()) >@@ -1113,10 +1102,9 @@ void JIT::emitSlow_op_div(Instruction* c > } > } > >- JITStubCall stubCall(this, cti_op_div); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_div); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > // Mod (%) >@@ -1152,10 +1140,9 @@ void JIT::emit_op_mod(Instruction* curre > numeratorPositive.link(this); > emitStoreInt32(dst, regT1, (op1 == dst || op2 == dst)); > #else >- JITStubCall stubCall(this, cti_op_mod); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_mod); >+ slowPathCall.call(); >+ emitLoad(result, regT1, regT0, callFrameRegister); > #endif > } > >@@ -1163,17 +1150,14 @@ void JIT::emitSlow_op_mod(Instruction* c > { > #if CPU(X86) || CPU(X86_64) > unsigned result = currentInstruction[1].u.operand; >- unsigned op1 = currentInstruction[2].u.operand; >- unsigned op2 = currentInstruction[3].u.operand; > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_mod); >- stubCall.addArgument(op1); >- stubCall.addArgument(op2); >- stubCall.call(result); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_mod); >+ slowPathCall.call(); >+ emitLoad(result, regT1, regT0, callFrameRegister); > #else > UNUSED_PARAM(currentInstruction); > UNUSED_PARAM(iter); >Index: Source/JavaScriptCore/jit/JITArithmetic.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITArithmetic.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JITArithmetic.cpp (working copy) >@@ -38,6 +38,7 @@ > #include "Operations.h" > #include "ResultType.h" > #include "SamplingTool.h" >+#include "SlowPathCall.h" > > #ifndef NDEBUG > #include <stdio.h> >@@ -219,14 +220,14 @@ void JIT::emit_op_negate(Instruction* cu > > void JIT::emitSlow_op_negate(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { >- unsigned dst = currentInstruction[1].u.operand; >+ unsigned result = currentInstruction[1].u.operand; > > linkSlowCase(iter); // 0x7fffffff check > linkSlowCase(iter); // double check > >- JITStubCall stubCall(this, cti_op_negate); >- stubCall.addArgument(regT0); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_negate); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > void JIT::emit_op_lshift(Instruction* currentInstruction) >@@ -249,17 +250,12 @@ void JIT::emit_op_lshift(Instruction* cu > void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned result = currentInstruction[1].u.operand; >- unsigned op1 = currentInstruction[2].u.operand; >- unsigned op2 = currentInstruction[3].u.operand; > >- UNUSED_PARAM(op1); >- UNUSED_PARAM(op2); > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_lshift); >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT2); >- stubCall.call(result); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > void JIT::emit_op_rshift(Instruction* currentInstruction) >@@ -303,31 +299,25 @@ void JIT::emitSlow_op_rshift(Instruction > unsigned op1 = currentInstruction[2].u.operand; > unsigned op2 = currentInstruction[3].u.operand; > >- JITStubCall stubCall(this, cti_op_rshift); >+ UNUSED_PARAM(op1); > >- if (isOperandConstantImmediateInt(op2)) { >+ if (isOperandConstantImmediateInt(op2)) > linkSlowCase(iter); >- stubCall.addArgument(regT0); >- stubCall.addArgument(op2, regT2); >- } else { >+ >+ else { > if (supportsFloatingPointTruncate()) { > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); >- // We're reloading op1 to regT0 as we can no longer guarantee that >- // we have not munged the operand. It may have already been shifted >- // correctly, but it still will not have been tagged. >- stubCall.addArgument(op1, regT0); >- stubCall.addArgument(regT2); > } else { > linkSlowCase(iter); > linkSlowCase(iter); >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT2); > } > } > >- stubCall.call(result); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_rshift); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > void JIT::emit_op_urshift(Instruction* currentInstruction) >@@ -418,10 +408,9 @@ void JIT::emitSlow_op_urshift(Instructio > linkSlowCase(iter); // Can't represent unsigned result as an immediate > } > >- JITStubCall stubCall(this, cti_op_urshift); >- stubCall.addArgument(op1, regT0); >- stubCall.addArgument(op2, regT1); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_urshift); >+ slowPathCall.call(); >+ emitGetVirtualRegister(dst, regT0); > } > > void JIT::emit_compareAndJump(OpcodeID, unsigned op1, unsigned op2, unsigned target, RelationalCondition condition) >@@ -607,26 +596,12 @@ void JIT::emit_op_bitand(Instruction* cu > void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned result = currentInstruction[1].u.operand; >- unsigned op1 = currentInstruction[2].u.operand; >- unsigned op2 = currentInstruction[3].u.operand; > > linkSlowCase(iter); >- if (isOperandConstantImmediateInt(op1)) { >- JITStubCall stubCall(this, cti_op_bitand); >- stubCall.addArgument(op1, regT2); >- stubCall.addArgument(regT0); >- stubCall.call(result); >- } else if (isOperandConstantImmediateInt(op2)) { >- JITStubCall stubCall(this, cti_op_bitand); >- stubCall.addArgument(regT0); >- stubCall.addArgument(op2, regT2); >- stubCall.call(result); >- } else { >- JITStubCall stubCall(this, cti_op_bitand); >- stubCall.addArgument(op1, regT2); >- stubCall.addArgument(regT1); >- stubCall.call(result); >- } >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitand); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > void JIT::emit_op_inc(Instruction* currentInstruction) >@@ -644,13 +619,11 @@ void JIT::emitSlow_op_inc(Instruction* c > { > unsigned srcDst = currentInstruction[1].u.operand; > >- Jump notImm = getSlowCase(iter); > linkSlowCase(iter); >+ linkSlowCase(iter); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_inc); >+ slowPathCall.call(); > emitGetVirtualRegister(srcDst, regT0); >- notImm.link(this); >- JITStubCall stubCall(this, cti_op_inc); >- stubCall.addArgument(regT0); >- stubCall.call(srcDst); > } > > void JIT::emit_op_dec(Instruction* currentInstruction) >@@ -668,13 +641,11 @@ void JIT::emitSlow_op_dec(Instruction* c > { > unsigned srcDst = currentInstruction[1].u.operand; > >- Jump notImm = getSlowCase(iter); > linkSlowCase(iter); >+ linkSlowCase(iter); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_dec); >+ slowPathCall.call(); > emitGetVirtualRegister(srcDst, regT0); >- notImm.link(this); >- JITStubCall stubCall(this, cti_op_dec); >- stubCall.addArgument(regT0); >- stubCall.call(srcDst); > } > > /* ------------------------------ BEGIN: OP_MOD ------------------------------ */ >@@ -719,10 +690,9 @@ void JIT::emitSlow_op_mod(Instruction* c > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_mod); >- stubCall.addArgument(regT3); >- stubCall.addArgument(regT2); >- stubCall.call(result); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_mod); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > #else // CPU(X86) || CPU(X86_64) >@@ -733,10 +703,12 @@ void JIT::emit_op_mod(Instruction* curre > unsigned op1 = currentInstruction[2].u.operand; > unsigned op2 = currentInstruction[3].u.operand; > >- JITStubCall stubCall(this, cti_op_mod); >- stubCall.addArgument(op1, regT2); >- stubCall.addArgument(op2, regT2); >- stubCall.call(result); >+ UNUSED_PARAM(op1); >+ UNUSED_PARAM(op2); >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_mod); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) >@@ -796,7 +768,7 @@ void JIT::compileBinaryArithOp(OpcodeID > emitFastArithIntToImmNoCheck(regT0, regT0); > } > >-void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned result, unsigned op1, unsigned op2, OperandTypes types, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase) >+void JIT::compileBinaryArithOpSlowCase(Instruction* currentInstruction, OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned result, unsigned op1, unsigned op2, OperandTypes types, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase) > { > // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset. > COMPILE_ASSERT(((TagTypeNumber + DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0); >@@ -815,17 +787,12 @@ void JIT::compileBinaryArithOpSlowCase(O > linkSlowCase(iter); // Integer overflow case - we could handle this in JIT code, but this is likely rare. > if (opcodeID == op_mul && !op1HasImmediateIntFastCase && !op2HasImmediateIntFastCase) // op_mul has an extra slow case to handle 0 * negative number. > linkSlowCase(iter); >- emitGetVirtualRegister(op1, regT0); > > Label stubFunctionCall(this); >- JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul); >- if (op1HasImmediateIntFastCase || op2HasImmediateIntFastCase) { >- emitGetVirtualRegister(op1, regT0); >- emitGetVirtualRegister(op2, regT1); >- } >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT1); >- stubCall.call(result); >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, opcodeID == op_add ? slow_path_add : opcodeID == op_sub ? slow_path_sub : slow_path_mul); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > Jump end = jump(); > > if (op1HasImmediateIntFastCase) { >@@ -893,11 +860,8 @@ void JIT::emit_op_add(Instruction* curre > OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); > > if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) { >- addSlowCase(); >- JITStubCall stubCall(this, cti_op_add); >- stubCall.addArgument(op1, regT2); >- stubCall.addArgument(op2, regT2); >- stubCall.call(result); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add); >+ slowPathCall.call(); > return; > } > >@@ -931,7 +895,7 @@ void JIT::emitSlow_op_add(Instruction* c > > bool op1HasImmediateIntFastCase = isOperandConstantImmediateInt(op1); > bool op2HasImmediateIntFastCase = !op1HasImmediateIntFastCase && isOperandConstantImmediateInt(op2); >- compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types, op1HasImmediateIntFastCase, op2HasImmediateIntFastCase); >+ compileBinaryArithOpSlowCase(currentInstruction, op_add, iter, result, op1, op2, types, op1HasImmediateIntFastCase, op2HasImmediateIntFastCase); > } > > void JIT::emit_op_mul(Instruction* currentInstruction) >@@ -976,7 +940,7 @@ void JIT::emitSlow_op_mul(Instruction* c > > bool op1HasImmediateIntFastCase = isOperandConstantImmediateInt(op1) && getConstantOperandImmediateInt(op1) > 0; > bool op2HasImmediateIntFastCase = !op1HasImmediateIntFastCase && isOperandConstantImmediateInt(op2) && getConstantOperandImmediateInt(op2) > 0; >- compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types, op1HasImmediateIntFastCase, op2HasImmediateIntFastCase); >+ compileBinaryArithOpSlowCase(currentInstruction, op_mul, iter, result, op1, op2, types, op1HasImmediateIntFastCase, op2HasImmediateIntFastCase); > } > > void JIT::emit_op_div(Instruction* currentInstruction) >@@ -1082,10 +1046,9 @@ void JIT::emitSlow_op_div(Instruction* c > linkSlowCase(iter); > } > // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. >- JITStubCall stubCall(this, cti_op_div); >- stubCall.addArgument(op1, regT2); >- stubCall.addArgument(op2, regT2); >- stubCall.call(result); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_div); >+ slowPathCall.call(); >+ emitGetVirtualRegister(result, regT0); > } > > void JIT::emit_op_sub(Instruction* currentInstruction) >@@ -1106,7 +1069,7 @@ void JIT::emitSlow_op_sub(Instruction* c > unsigned op2 = currentInstruction[3].u.operand; > OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); > >- compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types, false, false); >+ compileBinaryArithOpSlowCase(currentInstruction, op_sub, iter, result, op1, op2, types, false, false); > } > > /* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */ >Index: Source/JavaScriptCore/jit/JITExceptions.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITExceptions.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JITExceptions.cpp (working copy) >@@ -37,6 +37,74 @@ > > namespace JSC { > >+static bool getExceptionLocation(VM* vm, CallFrame* callFrame, unsigned& bytecodeOffset) >+{ >+ UNUSED_PARAM(vm); >+ bytecodeOffset = 0; >+ ASSERT(!callFrame->hasHostCallFrameFlag()); >+ CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag(); >+ bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame(); >+ >+ if (!callFrame || !callFrame->codeBlock()) >+ return false; >+ >+ CodeBlock* codeBlock = callFrame->codeBlock(); >+ >+#if ENABLE(JIT) || ENABLE(LLINT) >+ if (!callFrame->hasReturnPC()) >+ callframeIsHost = true; >+#endif >+#if ENABLE(DFG_JIT) >+ if (callFrame->isInlineCallFrame()) >+ callframeIsHost = false; >+#endif >+ >+ if (callframeIsHost) { >+ // Don't need to deal with inline callframes here as by definition we haven't >+ // inlined a call with an intervening native call frame. >+#if ENABLE(JIT) || ENABLE(LLINT) >+#if ENABLE(DFG_JIT) >+ if (codeBlock && JITCode::isOptimizingJIT(codeBlock->jitType())) { >+ unsigned codeOriginIndex = callFrame->codeOriginIndexForDFG(); >+ bytecodeOffset = codeBlock->codeOrigin(codeOriginIndex).bytecodeIndex; >+ } else >+#endif >+ bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode(); >+#endif >+ } else { >+#if ENABLE(JIT) || ENABLE(LLINT) >+#if ENABLE(DFG_JIT) >+ if (callFrame->isInlineCallFrame()) { >+ InlineCallFrame* icf = callFrame->inlineCallFrame(); >+ bytecodeOffset = icf->caller.bytecodeIndex; >+ if (InlineCallFrame* parentCallFrame = icf->caller.inlineCallFrame) { >+ FunctionExecutable* executable = static_cast<FunctionExecutable*>(parentCallFrame->executable.get()); >+ CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(parentCallFrame->isCall ? CodeForCall : CodeForConstruct); >+ ASSERT(newCodeBlock); >+ ASSERT(newCodeBlock->instructionCount() > bytecodeOffset); >+ codeBlock = newCodeBlock; >+ } >+ } else if (codeBlock && JITCode::isOptimizingJIT(codeBlock->jitType())) { >+ CodeOrigin origin; >+ if (!codeBlock->codeOriginForReturn(callFrame->returnPC(), origin)) >+ RELEASE_ASSERT_NOT_REACHED(); >+ bytecodeOffset = origin.bytecodeIndex; >+ if (InlineCallFrame* icf = origin.inlineCallFrame) { >+ FunctionExecutable* executable = static_cast<FunctionExecutable*>(icf->executable.get()); >+ CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(icf->isCall ? CodeForCall : CodeForConstruct); >+ ASSERT(newCodeBlock); >+ ASSERT(newCodeBlock->instructionCount() > bytecodeOffset); >+ codeBlock = newCodeBlock; >+ } >+ } else >+#endif >+ bytecodeOffset = codeBlock->bytecodeOffset(callFrame, callFrame->returnPC()); >+#endif >+ } >+ >+ return true; >+} >+ > ExceptionHandler genericThrow(VM* vm, ExecState* callFrame, JSValue exceptionValue, unsigned vPCIndex) > { > RELEASE_ASSERT(exceptionValue); >@@ -58,10 +126,19 @@ ExceptionHandler genericThrow(VM* vm, Ex > vm->targetInterpreterPCForThrow = catchPCForInterpreter; > > RELEASE_ASSERT(catchRoutine); >- ExceptionHandler exceptionHandler = { catchRoutine, callFrame }; >+ ExceptionHandler exceptionHandler = { callFrame, catchRoutine}; > return exceptionHandler; > } > >+ExceptionHandler jitThrowNew(VM* vm, ExecState* callFrame, JSValue exceptionValue) >+{ >+ unsigned bytecodeOffset = 0; >+ if (!getExceptionLocation(vm, callFrame, bytecodeOffset)) >+ bytecodeOffset = 0; >+ >+ return genericThrow(vm, callFrame, exceptionValue, bytecodeOffset); >+} >+ > ExceptionHandler jitThrow(VM* vm, ExecState* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation) > { > return genericThrow(vm, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation)); >Index: Source/JavaScriptCore/jit/JITExceptions.h >=================================================================== >--- Source/JavaScriptCore/jit/JITExceptions.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITExceptions.h (working copy) >@@ -40,12 +40,14 @@ class VM; > // for the throwing and handling exceptions. > > struct ExceptionHandler { >- void* catchRoutine; >+ // > ExecState* callFrame; >+ void* catchRoutine; > }; > > ExceptionHandler genericThrow(VM*, ExecState*, JSValue exceptionValue, unsigned vPCIndex); > >+ExceptionHandler jitThrowNew(VM*, ExecState*, JSValue exceptionValue); > ExceptionHandler jitThrow(VM*, ExecState*, JSValue exceptionValue, ReturnAddressPtr faultLocation); > > } // namespace JSC >Index: Source/JavaScriptCore/jit/JITOpcodes32_64.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (working copy) >@@ -38,6 +38,7 @@ > #include "JSPropertyNameIterator.h" > #include "JSVariableObject.h" > #include "LinkBuffer.h" >+#include "SlowPathCall.h" > > namespace JSC { > >@@ -167,14 +168,9 @@ JIT::CodeRef JIT::privateCompileCTINativ > > move(TrustedImmPtr(&vm->exceptionLocation), regT2); > storePtr(regT1, regT2); >- poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); >- >- storePtr(callFrameRegister, &m_vm->topCallFrame); >- // Set the return address. >- move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1); >- restoreReturnAddressBeforeReturn(regT1); > >- ret(); >+ move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampolineSlowpath).value()), regT1); >+ jump(regT1); > > // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. > LinkBuffer patchBuffer(*m_vm, this, GLOBAL_THUNK_ID); >@@ -433,17 +429,15 @@ void JIT::emitSlow_op_to_primitive(Instr > > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_to_primitive); >- stubCall.addArgument(regT1, regT0); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_primitive); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_op_strcat(Instruction* currentInstruction) > { >- JITStubCall stubCall(this, cti_op_strcat); >- stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand)); >- stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_strcat); >+ slowPathCall.call(); > } > > void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction) >@@ -471,13 +465,12 @@ void JIT::emit_op_not(Instruction* curre > void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned dst = currentInstruction[1].u.operand; >- unsigned src = currentInstruction[2].u.operand; > > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_not); >- stubCall.addArgument(src); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_not); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_op_jfalse(Instruction* currentInstruction) >@@ -750,17 +743,14 @@ void JIT::emit_op_stricteq(Instruction* > void JIT::emitSlow_op_stricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned dst = currentInstruction[1].u.operand; >- unsigned src1 = currentInstruction[2].u.operand; >- unsigned src2 = currentInstruction[3].u.operand; > > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_stricteq); >- stubCall.addArgument(src1); >- stubCall.addArgument(src2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_stricteq); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_op_nstricteq(Instruction* currentInstruction) >@@ -771,17 +761,14 @@ void JIT::emit_op_nstricteq(Instruction* > void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > unsigned dst = currentInstruction[1].u.operand; >- unsigned src1 = currentInstruction[2].u.operand; >- unsigned src2 = currentInstruction[3].u.operand; > > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_nstricteq); >- stubCall.addArgument(src1); >- stubCall.addArgument(src2); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_nstricteq); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_op_eq_null(Instruction* currentInstruction) >@@ -1001,9 +988,9 @@ void JIT::emitSlow_op_to_number(Instruct > > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_to_number); >- stubCall.addArgument(regT1, regT0); >- stubCall.call(dst); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_number); >+ slowPathCall.call(); >+ emitLoad(dst, regT1, regT0, callFrameRegister); > } > > void JIT::emit_op_push_name_scope(Instruction* currentInstruction) >@@ -1137,9 +1124,8 @@ void JIT::emit_op_create_arguments(Instr > > Jump argsCreated = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag)); > >- JITStubCall(this, cti_op_create_arguments).call(); >- emitStore(dst, regT1, regT0); >- emitStore(unmodifiedArgumentsRegister(dst), regT1, regT0); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_arguments); >+ slowPathCall.call(); > > argsCreated.link(this); > } >@@ -1183,9 +1169,8 @@ void JIT::emitSlow_op_create_this(Instru > linkSlowCase(iter); // doesn't have an allocation profile > linkSlowCase(iter); // allocation failed > >- JITStubCall stubCall(this, cti_op_create_this); >- stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_this); >+ slowPathCall.call(); > } > > void JIT::emit_op_to_this(Instruction* currentInstruction) >@@ -1205,13 +1190,10 @@ void JIT::emit_op_to_this(Instruction* c > > void JIT::emitSlow_op_to_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { >- unsigned thisRegister = currentInstruction[1].u.operand; >- > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_to_this); >- stubCall.addArgument(regT3, regT2); >- stubCall.call(thisRegister); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_this); >+ slowPathCall.call(); > } > > void JIT::emit_op_profile_will_call(Instruction* currentInstruction) >@@ -1282,9 +1264,9 @@ void JIT::emitSlow_op_get_argument_by_va > > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall(this, cti_op_create_arguments).call(); >- emitStore(arguments, regT1, regT0); >- emitStore(unmodifiedArgumentsRegister(arguments), regT1, regT0); >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_arguments); >+ slowPathCall.call(); > > skipArgumentsCreation.link(this); > JITStubCall stubCall(this, cti_op_get_by_val_generic); >Index: Source/JavaScriptCore/jit/JITOpcodes.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITOpcodes.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JITOpcodes.cpp (working copy) >@@ -38,6 +38,7 @@ > #include "JSFunction.h" > #include "JSPropertyNameIterator.h" > #include "LinkBuffer.h" >+#include "SlowPathCall.h" > > namespace JSC { > >@@ -360,10 +361,9 @@ void JIT::emit_op_to_primitive(Instructi > > void JIT::emit_op_strcat(Instruction* currentInstruction) > { >- JITStubCall stubCall(this, cti_op_strcat); >- stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand)); >- stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_strcat); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction) >@@ -938,9 +938,9 @@ void JIT::emitSlow_op_create_this(Instru > linkSlowCase(iter); // doesn't have an allocation profile > linkSlowCase(iter); // allocation failed > >- JITStubCall stubCall(this, cti_op_create_this); >- stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_this); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emit_op_profile_will_call(Instruction* currentInstruction) >@@ -964,27 +964,28 @@ void JIT::emitSlow_op_to_this(Instructio > { > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_to_this); >- stubCall.addArgument(regT1); >- stubCall.call(currentInstruction[1].u.operand); >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_this); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_to_primitive); >- stubCall.addArgument(regT0); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_primitive); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > linkSlowCase(iter); >- xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), regT0); >- JITStubCall stubCall(this, cti_op_not); >- stubCall.addArgument(regT0); >- stubCall.call(currentInstruction[1].u.operand); >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_not); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) >@@ -1008,19 +1009,15 @@ void JIT::emitSlow_op_jtrue(Instruction* > void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_bitxor); >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT1); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitxor); >+ slowPathCall.call(); > } > > void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) > { > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_bitor); >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT1); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitor); >+ slowPathCall.call(); > } > > void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) >@@ -1051,10 +1048,9 @@ void JIT::emitSlow_op_stricteq(Instructi > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_stricteq); >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT1); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_stricteq); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) >@@ -1062,10 +1058,9 @@ void JIT::emitSlow_op_nstricteq(Instruct > linkSlowCase(iter); > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall stubCall(this, cti_op_nstricteq); >- stubCall.addArgument(regT0); >- stubCall.addArgument(regT1); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_nstricteq); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) >@@ -1123,9 +1118,9 @@ void JIT::emitSlow_op_to_number(Instruct > { > linkSlowCase(iter); > >- JITStubCall stubCall(this, cti_op_to_number); >- stubCall.addArgument(regT0); >- stubCall.call(currentInstruction[1].u.operand); >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_number); >+ slowPathCall.call(); >+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); > } > > void JIT::emit_op_get_arguments_length(Instruction* currentInstruction) >@@ -1184,10 +1179,10 @@ void JIT::emitSlow_op_get_argument_by_va > > linkSlowCase(iter); > linkSlowCase(iter); >- JITStubCall(this, cti_op_create_arguments).call(); >- emitPutVirtualRegister(arguments); >- emitPutVirtualRegister(unmodifiedArgumentsRegister(arguments)); >- >+ >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_arguments); >+ slowPathCall.call(); >+ > skipArgumentsCreation.link(this); > JITStubCall stubCall(this, cti_op_get_by_val_generic); > stubCall.addArgument(arguments, regT2); >Index: Source/JavaScriptCore/jit/JITStubCall.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubCall.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubCall.h (working copy) >@@ -26,6 +26,7 @@ > #ifndef JITStubCall_h > #define JITStubCall_h > >+#include "CommonSlowPaths.h" > #include "MacroAssemblerCodeRef.h" > > #if ENABLE(JIT) >@@ -37,6 +38,7 @@ namespace JSC { > JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >+ , m_pc(0) > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(Cell) > #endif >@@ -47,6 +49,7 @@ namespace JSC { > JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >+ , m_pc(0) > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(Cell) > #endif >@@ -57,7 +60,8 @@ namespace JSC { > JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >-#if USE(JSVALUE32_64) || !ASSERT_DISABLED >+ , m_pc(0) >+#if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(VoidPtr) > #endif > , m_stackIndex(JITSTACKFRAME_ARGS_INDEX) >@@ -67,6 +71,7 @@ namespace JSC { > JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >+ , m_pc(0) > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(Int) > #endif >@@ -77,6 +82,7 @@ namespace JSC { > JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >+ , m_pc(0) > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(Int) > #endif >@@ -87,6 +93,7 @@ namespace JSC { > JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >+ , m_pc(0) > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(Void) > #endif >@@ -97,6 +104,7 @@ namespace JSC { > JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) > : m_jit(jit) > , m_stub(stub) >+ , m_pc(0) > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > , m_returnType(Value) > #endif >@@ -104,8 +112,29 @@ namespace JSC { > { > } > >+ JITStubCall(JIT* jit, SlowPathReturnType (JIT_STUB *stub)(ExecState* exec, Instruction* pc)) >+ : m_jit(jit) >+ , m_stub(stub) >+ , m_pc(0) >+#if USE(JSVALUE32_64) || !ASSERT_DISABLED >+ , m_returnType(Void) >+#endif >+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX) >+ { >+ } >+ > // Arguments are added first to last. > >+ void setPC(Instruction* pc) >+ { >+ m_pc = pc; >+ } >+ >+ void setReturnTypeInt() >+ { >+ m_returnType = Int; >+ } >+ > void skipArgument() > { > m_stackIndex += stackIndexStep; >@@ -291,6 +320,7 @@ namespace JSC { > > JIT* m_jit; > FunctionPtr m_stub; >+ Instruction* m_pc; > #if USE(JSVALUE32_64) || !ASSERT_DISABLED > enum { Void, VoidPtr, Int, Value, Cell } m_returnType; > #endif >Index: Source/JavaScriptCore/jit/JITStubs.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITStubs.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubs.cpp (working copy) >@@ -69,6 +69,7 @@ > #include "Register.h" > #include "RepatchBuffer.h" > #include "SamplingTool.h" >+#include "SlowPathCall.h" > #include "Strong.h" > #include "StructureRareDataInlines.h" > #include <wtf/StdLibExtras.h> >@@ -2649,6 +2650,12 @@ DEFINE_STUB_FUNCTION(void*, vm_throw) > return handler.callFrame; > } > >+ExceptionHandler JIT_STUB cti_vm_throw_slowpath(CallFrame* callFrame) >+{ >+ VM* vm = callFrame->codeBlock()->vm(); >+ return jitThrowNew(vm, callFrame, vm->exception); >+} >+ > DEFINE_STUB_FUNCTION(EncodedJSValue, to_object) > { > STUB_INIT_STACK_FRAME(stackFrame); >Index: Source/JavaScriptCore/jit/JITStubs.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubs.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubs.h (working copy) >@@ -32,6 +32,7 @@ > > #include "CallData.h" > #include "Intrinsic.h" >+#include "JITExceptions.h" > #include "LowLevelInterpreter.h" > #include "MacroAssemblerCodeRef.h" > #include "Register.h" >@@ -306,6 +307,7 @@ struct JITStackFrame { > #endif > > extern "C" void ctiVMThrowTrampoline(); >+extern "C" void ctiVMThrowTrampolineSlowpath(); > extern "C" void ctiOpThrowNotCaught(); > extern "C" EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*); > #if ENABLE(DFG_JIT) >@@ -445,6 +447,7 @@ void* JIT_STUB cti_vm_lazyLinkCall(STUB_ > void* JIT_STUB cti_vm_lazyLinkClosureCall(STUB_ARGS_DECLARATION) WTF_INTERNAL; > void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL; > void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL; >+ExceptionHandler JIT_STUB cti_vm_throw_slowpath(CallFrame*) REFERENCED_FROM_ASM WTF_INTERNAL; > } // extern "C" > > #elif ENABLE(LLINT_C_LOOP) >Index: Source/JavaScriptCore/jit/JITStubsARM.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubsARM.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubsARM.h (working copy) >@@ -92,6 +92,21 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" " > "bx lr" "\n" > ); > >+asm ( >+".text" "\n" >+".globl " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+HIDE_SYMBOL(ctiVMThrowTrampolineSlowpath) "\n" >+INLINE_ARM_FUNCTION(ctiVMThrowTrampolineSlowpath) >+SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) ":" "\n" >+ "mov r0, r5" "\n" >+ "bl " SYMBOL_STRING(cti_vm_throw_slowpath) "\n" >+ // When cti_vm_throw_slowpath returns, r0 has callFrame and r1 has handler address >+ "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n" >+ "ldmia sp!, {r4-r6, r8-r11, lr}" "\n" >+ "add sp, sp, #12" "\n" >+ "bx r1" "\n" >+); >+ > #define DEFINE_STUB_FUNCTION(rtype, op) \ > extern "C" { \ > rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \ >Index: Source/JavaScriptCore/jit/JITStubsARMv7.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubsARMv7.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubsARMv7.h (working copy) >@@ -123,6 +123,30 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" > asm ( > ".text" "\n" > ".align 2" "\n" >+".globl " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+HIDE_SYMBOL(ctiVMThrowTrampolineSlowpath) "\n" >+".thumb" "\n" >+".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampolineSlowpath) "\n" >+SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) ":" "\n" >+ "mov r0, r5" "\n" >+ "bl " LOCAL_REFERENCE(cti_vm_throw_slowpath) "\n" >+ // When cti_vm_throw_slowpath returns, r0 has callFrame and r1 has handler address >+ "ldr r11, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R11_OFFSET) "]" "\n" >+ "ldr r10, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R10_OFFSET) "]" "\n" >+ "ldr r9, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R9_OFFSET) "]" "\n" >+ "ldr r8, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R8_OFFSET) "]" "\n" >+ "ldr r7, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R7_OFFSET) "]" "\n" >+ "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n" >+ "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n" >+ "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n" >+ "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n" >+ "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n" >+ "bx r1" "\n" >+); >+ >+asm ( >+".text" "\n" >+".align 2" "\n" > ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" > HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" > ".thumb" "\n" >Index: Source/JavaScriptCore/jit/JITStubsMIPS.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubsMIPS.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubsMIPS.h (working copy) >@@ -134,6 +134,40 @@ asm ( > ".set noreorder" "\n" > ".set nomacro" "\n" > ".set nomips16" "\n" >+".globl " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+".ent " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) ":" "\n" >+#if WTF_MIPS_PIC >+".set macro" "\n" >+".cpload $31" "\n" >+ "la $25," SYMBOL_STRING(cti_vm_throw_slowpath) "\n" >+".set nomacro" "\n" >+ "bal " SYMBOL_STRING(cti_vm_throw_slowpath) "\n" >+ "move $4,$16" "\n" >+#else >+ "jal " SYMBOL_STRING(cti_vm_throw_slowpath) "\n" >+ "move $4,$16" "\n" >+#endif >+ // When cti_vm_throw_slowpath returns, v0 has callFrame and v1 has handler address >+ "lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n" >+ "lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n" >+ "lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n" >+ "lw $19," STRINGIZE_VALUE_OF(PRESERVED_S3_OFFSET) "($29)" "\n" >+ "lw $20," STRINGIZE_VALUE_OF(PRESERVED_S4_OFFSET) "($29)" "\n" >+ "lw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n" >+ "jr $3" "\n" >+ "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n" >+".set reorder" "\n" >+".set macro" "\n" >+".end " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+); >+ >+asm ( >+".text" "\n" >+".align 2" "\n" >+".set noreorder" "\n" >+".set nomacro" "\n" >+".set nomips16" "\n" > ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" > ".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" > SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" >Index: Source/JavaScriptCore/jit/JITStubsSH4.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubsSH4.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubsSH4.h (working copy) >@@ -99,6 +99,31 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" > ); > > asm volatile ( >+".globl " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+HIDE_SYMBOL(ctiVMThrowTrampolineSlowpath) "\n" >+SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) ":" "\n" >+ "mov.l .L2"SYMBOL_STRING(cti_vm_throw_slowpath)",r0" "\n" >+ "mov r15, r4" "\n" >+ "mov.l @(r0,r12),r11" "\n" >+ "jsr @r11" "\n" >+ // When cti_vm_throw_slowpath returns, r0 has callFrame and r1 has handler address >+ "nop" "\n" >+ "add #60, r15" "\n" >+ "mov.l @r15+,r10" "\n" >+ "mov.l @r15+,r11" "\n" >+ "mov.l @r15+,r13" "\n" >+ "lds.l @r15+,pr" "\n" >+ "mov.l @r15+,r14" "\n" >+ "mov.l @r15+,r8" "\n" >+ "add #12, r15" "\n" >+ "mov r0, r4" "\n" >+ "jmp @r1" "\n" >+ "nop" "\n" >+ ".align 2" "\n" >+ ".L2"SYMBOL_STRING(cti_vm_throw_slowpath)":.long " SYMBOL_STRING(cti_vm_throw_slowpath)"@GOT \n" >+); >+ >+asm volatile ( > ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" > HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" > SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" >Index: Source/JavaScriptCore/jit/JITStubsX86.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubsX86.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubsX86.h (working copy) >@@ -86,6 +86,16 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" > ); > > asm ( >+".globl " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+HIDE_SYMBOL(ctiVMThrowTrampolineSlowpath) "\n" >+SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) ":" "\n" >+ "movl %edi, %ecx" "\n" >+ "call " LOCAL_REFERENCE(cti_vm_throw_slowpath) "\n" >+ // When cti_vm_throw_slowpath returns, eax has callFrame and edx has handler address >+ "jmp *%edx" "\n" >+); >+ >+asm ( > ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" > HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" > SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" >@@ -213,6 +223,22 @@ extern "C" { > } > } > >+ __declspec(naked) void ctiVMThrowTrampolineSlowpath() >+ { >+ __asm { >+ mov ecx, edi; >+ call cti_vm_throw_slowpath; >+ // When cti_vm_throw_slowpath returns, eax has callFrame and edx has handler address >+ add esp, 0x3c; >+ pop ebx; >+ pop edi; >+ pop esi; >+ pop ebp; >+ jmp edx >+ ret; >+ } >+ } >+ > __declspec(naked) void ctiOpThrowNotCaught() > { > __asm { >Index: Source/JavaScriptCore/jit/JITStubsX86_64.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubsX86_64.h (revision 150843) >+++ Source/JavaScriptCore/jit/JITStubsX86_64.h (working copy) >@@ -99,6 +99,16 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" > ); > > asm ( >+".globl " SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) "\n" >+HIDE_SYMBOL(ctiVMThrowTrampolineSlowpath) "\n" >+SYMBOL_STRING(ctiVMThrowTrampolineSlowpath) ":" "\n" >+ "movq %r13, %rdi" "\n" >+ "call " LOCAL_REFERENCE(cti_vm_throw_slowpath) "\n" >+ // When cti_vm_throw_slowpath returns, rax has callFrame and rdx has handler address >+ "jmp *%rdx" "\n" >+); >+ >+asm ( > ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" > HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" > SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" >Index: Source/JavaScriptCore/jit/JSInterfaceJIT.h >=================================================================== >--- Source/JavaScriptCore/jit/JSInterfaceJIT.h (revision 150843) >+++ Source/JavaScriptCore/jit/JSInterfaceJIT.h (working copy) >@@ -59,8 +59,10 @@ namespace JSC { > static const RegisterID cachedResultRegister = X86Registers::eax; > #if !OS(WINDOWS) > static const RegisterID firstArgumentRegister = X86Registers::edi; >+ static const RegisterID secondArgumentRegister = X86Registers::esi; > #else > static const RegisterID firstArgumentRegister = X86Registers::ecx; >+ static const RegisterID secondArgumentRegister = X86Registers::edx; > #endif > > #if ENABLE(VALUE_PROFILER) >@@ -89,6 +91,7 @@ namespace JSC { > // On x86 we always use fastcall conventions = but on > // OS X if might make more sense to just use regparm. > static const RegisterID firstArgumentRegister = X86Registers::ecx; >+ static const RegisterID secondArgumentRegister = X86Registers::edx; > > static const RegisterID bucketCounterRegister = X86Registers::esi; > static const RegisterID callFrameRegister = X86Registers::edi; >@@ -106,6 +109,7 @@ namespace JSC { > static const RegisterID returnValueRegister = ARMRegisters::r0; > static const RegisterID cachedResultRegister = ARMRegisters::r0; > static const RegisterID firstArgumentRegister = ARMRegisters::r0; >+ static const RegisterID secondArgumentRegister = ARMRegisters::r1; > > #if ENABLE(VALUE_PROFILER) > static const RegisterID bucketCounterRegister = ARMRegisters::r7; >@@ -128,6 +132,7 @@ namespace JSC { > static const RegisterID returnValueRegister = MIPSRegisters::v0; > static const RegisterID cachedResultRegister = MIPSRegisters::v0; > static const RegisterID firstArgumentRegister = MIPSRegisters::a0; >+ static const RegisterID secondArgumentRegister = MIPSRegisters::a1; > > #if ENABLE(VALUE_PROFILER) > static const RegisterID bucketCounterRegister = MIPSRegisters::s3; >@@ -164,6 +169,7 @@ namespace JSC { > static const RegisterID regT6 = SH4Registers::r6; > static const RegisterID regT7 = SH4Registers::r7; > static const RegisterID firstArgumentRegister =regT4; >+ static const RegisterID secondArgumentRegister =regT4; > > static const RegisterID returnValueRegister = SH4Registers::r0; > static const RegisterID cachedResultRegister = SH4Registers::r0; >Index: Source/JavaScriptCore/jit/SlowPathCall.h >=================================================================== >--- Source/JavaScriptCore/jit/SlowPathCall.h (revision 0) >+++ Source/JavaScriptCore/jit/SlowPathCall.h (revision 0) >@@ -0,0 +1,100 @@ >+/* >+ * Copyright (C) 2013 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 SlowPathCall_h >+#define SlowPathCall_h >+ >+#include "CommonSlowPaths.h" >+#include "MacroAssemblerCodeRef.h" >+ >+#if ENABLE(JIT) >+ >+namespace JSC { >+ >+class JITSlowPathCall { >+public: >+ JITSlowPathCall(JIT* jit, Instruction* pc, SlowPathReturnType (SLOW_PATH *stub)(ExecState* exec, Instruction* pc)) >+ : m_jit(jit) >+ , m_stub(stub) >+ , m_pc(pc) >+ { >+ } >+ >+ JIT::Call call() >+ { >+#if ENABLE(OPCODE_SAMPLING) >+ if (m_jit->m_bytecodeOffset != (unsigned)-1) >+ m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeOffset, true); >+#endif >+ m_jit->updateTopCallFrame(); >+#if CPU(X86) && USE(JSVALUE32_64) >+ m_jit->addPtr(MacroAssembler::TrustedImm32(-8), MacroAssembler::stackPointerRegister); >+ m_jit->push(JIT::TrustedImm32(JIT::TrustedImmPtr(m_pc))); >+ m_jit->push(JIT::callFrameRegister); >+#else >+ m_jit->move(JIT::callFrameRegister, JIT::firstArgumentRegister); >+ m_jit->move(JIT::TrustedImmPtr(m_pc), JIT::secondArgumentRegister); >+#endif >+ JIT::Call call = m_jit->call(); >+ m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeOffset, m_stub.value())); >+ >+#if CPU(X86) && USE(JSVALUE32_64) >+ m_jit->addPtr(MacroAssembler::TrustedImm32(16), MacroAssembler::stackPointerRegister); >+#endif >+ >+#if ENABLE(OPCODE_SAMPLING) >+ if (m_jit->m_bytecodeOffset != (unsigned)-1) >+ m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeOffset, false); >+#endif >+ >+#if USE(JSVALUE32_64) >+ m_jit->unmap(); >+#else >+ m_jit->killLastResultRegister(); >+#endif >+ >+#if USE(JSVALUE32_64) >+ JIT::Jump noException = m_jit->branch32(JIT::Equal, JIT::AbsoluteAddress(reinterpret_cast<char*>(&m_jit->m_codeBlock->vm()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), JIT::TrustedImm32(JSValue::EmptyValueTag)); >+#else >+ JIT::Jump noException = m_jit->branchTest64(JIT::Zero, JIT::AbsoluteAddress(&m_jit->m_codeBlock->vm()->exception)); >+#endif >+ m_jit->move(JIT::TrustedImmPtr(FunctionPtr(ctiVMThrowTrampolineSlowpath).value()), JIT::regT1); >+ m_jit->jump(JIT::regT1); >+ noException.link(m_jit); >+ >+ return call; >+ } >+ >+private: >+ JIT* m_jit; >+ FunctionPtr m_stub; >+ Instruction* m_pc; >+}; >+ >+} // namespace JS >+ >+#endif // ENABLE(JIT) >+ >+#endif // SlowPathCall_h >Index: Source/JavaScriptCore/jit/ThunkGenerators.cpp >=================================================================== >--- Source/JavaScriptCore/jit/ThunkGenerators.cpp (revision 150843) >+++ Source/JavaScriptCore/jit/ThunkGenerators.cpp (working copy) >@@ -395,17 +395,14 @@ static MacroAssemblerCodeRef nativeForGe > > // Grab the return address. > jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT1); >- >+ > jit.move(JSInterfaceJIT::TrustedImmPtr(&vm->exceptionLocation), JSInterfaceJIT::regT2); > jit.storePtr(JSInterfaceJIT::regT1, JSInterfaceJIT::regT2); >- jit.poke(JSInterfaceJIT::callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); > > jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame); >- // Set the return address. >- jit.move(JSInterfaceJIT::TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), JSInterfaceJIT::regT1); >- jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT1); > >- jit.ret(); >+ jit.move(JSInterfaceJIT::TrustedImmPtr(FunctionPtr(ctiVMThrowTrampolineSlowpath).value()), JSInterfaceJIT::regT1); >+ jit.jump(JSInterfaceJIT::regT1); > > LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID); > return FINALIZE_CODE(patchBuffer, ("native %s trampoline", toCString(kind).data())); >Index: Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (revision 150843) >+++ Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (working copy) >@@ -428,34 +428,6 @@ LLINT_SLOW_PATH_DECL(stack_check) > LLINT_END_IMPL(); > } > >-LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck) >-{ >- LLINT_BEGIN(); >- ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall); >- if (!newExec) { >- ReturnAddressPtr returnPC = exec->returnPC(); >- exec = exec->callerFrame(); >- vm.exception = createStackOverflowError(exec); >- interpreterThrowInCaller(exec, returnPC); >- LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); >- } >- LLINT_RETURN_TWO(0, newExec); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck) >-{ >- LLINT_BEGIN(); >- ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct); >- if (!newExec) { >- ReturnAddressPtr returnPC = exec->returnPC(); >- exec = exec->callerFrame(); >- vm.exception = createStackOverflowError(exec); >- interpreterThrowInCaller(exec, returnPC); >- LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); >- } >- LLINT_RETURN_TWO(0, newExec); >-} >- > LLINT_SLOW_PATH_DECL(slow_path_create_activation) > { > LLINT_BEGIN(); >@@ -467,42 +439,6 @@ LLINT_SLOW_PATH_DECL(slow_path_create_ac > LLINT_RETURN(JSValue(activation)); > } > >-LLINT_SLOW_PATH_DECL(slow_path_create_arguments) >-{ >- LLINT_BEGIN(); >- JSValue arguments = JSValue(Arguments::create(vm, exec)); >- LLINT_CHECK_EXCEPTION(); >- exec->uncheckedR(pc[1].u.operand) = arguments; >- exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments; >- LLINT_END(); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_create_this) >-{ >- LLINT_BEGIN(); >- JSFunction* constructor = jsCast<JSFunction*>(LLINT_OP(2).jsValue().asCell()); >- >-#if !ASSERT_DISABLED >- ConstructData constructData; >- ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS); >-#endif >- >- size_t inlineCapacity = pc[3].u.operand; >- Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure(); >- LLINT_RETURN(constructEmptyObject(exec, structure)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_to_this) >-{ >- LLINT_BEGIN(); >- JSValue v1 = LLINT_OP(1).jsValue(); >-#if ENABLE(VALUE_PROFILER) >- pc[OPCODE_LENGTH(op_to_this) - 1].u.profile->m_buckets[0] = >- JSValue::encode(v1.structureOrUndefined()); >-#endif >- LLINT_RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode)); >-} >- > LLINT_SLOW_PATH_DECL(slow_path_new_object) > { > LLINT_BEGIN(); >@@ -536,187 +472,6 @@ LLINT_SLOW_PATH_DECL(slow_path_new_regex > LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp)); > } > >-LLINT_SLOW_PATH_DECL(slow_path_not) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_eq) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_neq) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_stricteq) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_nstricteq) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_less) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_lesseq) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_greater) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_greatereq) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_pre_inc) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_pre_dec) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_to_number) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_negate) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_add) >-{ >- LLINT_BEGIN(); >- JSValue v1 = LLINT_OP_C(2).jsValue(); >- JSValue v2 = LLINT_OP_C(3).jsValue(); >- >-#if LLINT_SLOW_PATH_TRACING >- dataLog("Trying to add ", v1, " to ", v2, ".\n"); >-#endif >- >- if (v1.isString() && !v2.isObject()) >- LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec))); >- >- if (v1.isNumber() && v2.isNumber()) >- LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber())); >- >- LLINT_RETURN(jsAddSlowCase(exec, v1, v2)); >-} >- >-// The following arithmetic and bitwise operations need to be sure to run >-// toNumber() on their operands in order. (A call to toNumber() is idempotent >-// if an exception is already set on the ExecState.) >- >-LLINT_SLOW_PATH_DECL(slow_path_mul) >-{ >- LLINT_BEGIN(); >- double a = LLINT_OP_C(2).jsValue().toNumber(exec); >- double b = LLINT_OP_C(3).jsValue().toNumber(exec); >- LLINT_RETURN(jsNumber(a * b)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_sub) >-{ >- LLINT_BEGIN(); >- double a = LLINT_OP_C(2).jsValue().toNumber(exec); >- double b = LLINT_OP_C(3).jsValue().toNumber(exec); >- LLINT_RETURN(jsNumber(a - b)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_div) >-{ >- LLINT_BEGIN(); >- double a = LLINT_OP_C(2).jsValue().toNumber(exec); >- double b = LLINT_OP_C(3).jsValue().toNumber(exec); >- LLINT_RETURN(jsNumber(a / b)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_mod) >-{ >- LLINT_BEGIN(); >- double a = LLINT_OP_C(2).jsValue().toNumber(exec); >- double b = LLINT_OP_C(3).jsValue().toNumber(exec); >- LLINT_RETURN(jsNumber(fmod(a, b))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_lshift) >-{ >- LLINT_BEGIN(); >- int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec); >- uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec); >- LLINT_RETURN(jsNumber(a << (b & 31))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_rshift) >-{ >- LLINT_BEGIN(); >- int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec); >- uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec); >- LLINT_RETURN(jsNumber(a >> (b & 31))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_urshift) >-{ >- LLINT_BEGIN(); >- uint32_t a = LLINT_OP_C(2).jsValue().toUInt32(exec); >- uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec); >- LLINT_RETURN(jsNumber(a >> (b & 31))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_bitand) >-{ >- LLINT_BEGIN(); >- int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec); >- int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec); >- LLINT_RETURN(jsNumber(a & b)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_bitor) >-{ >- LLINT_BEGIN(); >- int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec); >- int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec); >- LLINT_RETURN(jsNumber(a | b)); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_bitxor) >-{ >- LLINT_BEGIN(); >- int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec); >- int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec); >- LLINT_RETURN(jsNumber(a ^ b)); >-} >- > LLINT_SLOW_PATH_DECL(slow_path_check_has_instance) > { > LLINT_BEGIN(); >@@ -743,30 +498,6 @@ LLINT_SLOW_PATH_DECL(slow_path_instanceo > LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto))); > } > >-LLINT_SLOW_PATH_DECL(slow_path_typeof) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue())); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_is_object) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(jsIsObjectType(exec, LLINT_OP_C(2).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_is_function) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue()))); >-} >- >-LLINT_SLOW_PATH_DECL(slow_path_in) >-{ >- LLINT_BEGIN(); >- LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()))); >-} >- > LLINT_SLOW_PATH_DECL(slow_path_resolve) > { > LLINT_BEGIN(); >Index: Source/JavaScriptCore/llint/LLIntSlowPaths.h >=================================================================== >--- Source/JavaScriptCore/llint/LLIntSlowPaths.h (revision 150843) >+++ Source/JavaScriptCore/llint/LLIntSlowPaths.h (working copy) >@@ -26,6 +26,7 @@ > #ifndef LLIntSlowPaths_h > #define LLIntSlowPaths_h > >+#include "CommonSlowPaths.h" > #include <wtf/Platform.h> > #include <wtf/StdLibExtras.h> > >@@ -38,57 +39,6 @@ struct Instruction; > > namespace LLInt { > >-#if USE(JSVALUE64) >-// According to C++ rules, a type used for the return signature of function with C linkage (i.e. >-// 'extern "C"') needs to be POD; hence putting any constructors into it could cause either compiler >-// warnings, or worse, a change in the ABI used to return these types. >-struct SlowPathReturnType { >- void* a; >- ExecState* b; >-}; >- >-inline SlowPathReturnType encodeResult(void* a, ExecState* b) >-{ >- SlowPathReturnType result; >- result.a = a; >- result.b = b; >- return result; >-} >- >-inline void decodeResult(SlowPathReturnType result, void*& a, ExecState*& b) >-{ >- a = result.a; >- b = result.b; >-} >- >-#else // USE(JSVALUE32_64) >-typedef int64_t SlowPathReturnType; >- >-typedef union { >- struct { >- void* a; >- ExecState* b; >- } pair; >- int64_t i; >-} SlowPathReturnTypeEncoding; >- >-inline SlowPathReturnType encodeResult(void* a, ExecState* b) >-{ >- SlowPathReturnTypeEncoding u; >- u.pair.a = a; >- u.pair.b = b; >- return u.i; >-} >- >-inline void decodeResult(SlowPathReturnType result, void*& a, ExecState*& b) >-{ >- SlowPathReturnTypeEncoding u; >- u.i = result; >- a = u.pair.a; >- b = u.pair.b; >-} >-#endif // USE(JSVALUE32_64) >- > extern "C" SlowPathReturnType llint_trace_operand(ExecState*, Instruction*, int fromWhere, int operand); > extern "C" SlowPathReturnType llint_trace_value(ExecState*, Instruction*, int fromWhere, int operand); > >@@ -113,47 +63,14 @@ LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_fu > LLINT_SLOW_PATH_HIDDEN_DECL(loop_osr); > LLINT_SLOW_PATH_HIDDEN_DECL(replace); > LLINT_SLOW_PATH_HIDDEN_DECL(stack_check); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_activation); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_arguments); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_this); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_this); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_object); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_array); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_array_with_size); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_array_buffer); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_regexp); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_not); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_eq); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_neq); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_stricteq); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_nstricteq); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_less); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_lesseq); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_greater); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_greatereq); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pre_inc); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pre_dec); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_number); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_negate); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_add); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_mul); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_sub); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_div); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_mod); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_lshift); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_rshift); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_urshift); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_bitand); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_bitor); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_bitxor); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_check_has_instance); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_typeof); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_is_object); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_is_function); >-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_base); > LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_base); >Index: Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >=================================================================== >--- Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (revision 150843) >+++ Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (working copy) >@@ -352,7 +352,7 @@ _llint_op_create_arguments: > traceExecution() > loadi 4[PC], t0 > bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone >- callSlowPath(_llint_slow_path_create_arguments) >+ callSlowPath(_slow_path_create_arguments) > .opCreateArgumentsDone: > dispatch(2) > >@@ -371,7 +371,7 @@ _llint_op_create_this: > dispatch(4) > > .opCreateThisSlow: >- callSlowPath(_llint_slow_path_create_this) >+ callSlowPath(_slow_path_create_this) > dispatch(4) > > >@@ -398,7 +398,7 @@ _llint_op_to_this: > dispatch(3) > > .opToThisSlow: >- callSlowPath(_llint_slow_path_to_this) >+ callSlowPath(_slow_path_to_this) > dispatch(3) > > >@@ -440,7 +440,7 @@ _llint_op_not: > dispatch(3) > > .opNotSlow: >- callSlowPath(_llint_slow_path_not) >+ callSlowPath(_slow_path_not) > dispatch(3) > > >@@ -460,7 +460,7 @@ _llint_op_eq: > dispatch(4) > > .opEqSlow: >- callSlowPath(_llint_slow_path_eq) >+ callSlowPath(_slow_path_eq) > dispatch(4) > > >@@ -507,7 +507,7 @@ _llint_op_neq: > dispatch(4) > > .opNeqSlow: >- callSlowPath(_llint_slow_path_neq) >+ callSlowPath(_slow_path_neq) > dispatch(4) > > >@@ -564,12 +564,12 @@ end > > _llint_op_stricteq: > traceExecution() >- strictEq(macro (left, right, result) cieq left, right, result end, _llint_slow_path_stricteq) >+ strictEq(macro (left, right, result) cieq left, right, result end, _slow_path_stricteq) > > > _llint_op_nstricteq: > traceExecution() >- strictEq(macro (left, right, result) cineq left, right, result end, _llint_slow_path_nstricteq) >+ strictEq(macro (left, right, result) cineq left, right, result end, _slow_path_nstricteq) > > > _llint_op_inc: >@@ -582,7 +582,7 @@ _llint_op_inc: > dispatch(2) > > .opIncSlow: >- callSlowPath(_llint_slow_path_pre_inc) >+ callSlowPath(_slow_path_inc) > dispatch(2) > > >@@ -596,7 +596,7 @@ _llint_op_dec: > dispatch(2) > > .opDecSlow: >- callSlowPath(_llint_slow_path_pre_dec) >+ callSlowPath(_slow_path_dec) > dispatch(2) > > >@@ -613,7 +613,7 @@ _llint_op_to_number: > dispatch(3) > > .opToNumberSlow: >- callSlowPath(_llint_slow_path_to_number) >+ callSlowPath(_slow_path_to_number) > dispatch(3) > > >@@ -636,7 +636,7 @@ _llint_op_negate: > dispatch(3) > > .opNegateSlow: >- callSlowPath(_llint_slow_path_negate) >+ callSlowPath(_slow_path_negate) > dispatch(3) > > >@@ -697,7 +697,7 @@ _llint_op_add: > binaryOp( > macro (left, right, slow) baddio left, right, slow end, > macro (left, right) addd left, right end, >- _llint_slow_path_add) >+ _slow_path_add) > > > _llint_op_mul: >@@ -715,7 +715,7 @@ _llint_op_mul: > storei scratch, PayloadOffset[cfr, index, 8] > end, > macro (left, right) muld left, right end, >- _llint_slow_path_mul) >+ _slow_path_mul) > > > _llint_op_sub: >@@ -723,7 +723,7 @@ _llint_op_sub: > binaryOp( > macro (left, right, slow) bsubio left, right, slow end, > macro (left, right) subd left, right end, >- _llint_slow_path_sub) >+ _slow_path_sub) > > > _llint_op_div: >@@ -742,7 +742,7 @@ _llint_op_div: > .done: > end, > macro (left, right) divd left, right end, >- _llint_slow_path_div) >+ _slow_path_div) > > > macro bitOp(operation, slowPath, advance) >@@ -767,7 +767,7 @@ _llint_op_lshift: > traceExecution() > bitOp( > macro (left, right, slow) lshifti left, right end, >- _llint_slow_path_lshift, >+ _slow_path_lshift, > 4) > > >@@ -775,7 +775,7 @@ _llint_op_rshift: > traceExecution() > bitOp( > macro (left, right, slow) rshifti left, right end, >- _llint_slow_path_rshift, >+ _slow_path_rshift, > 4) > > >@@ -786,7 +786,7 @@ _llint_op_urshift: > urshifti left, right > bilt right, 0, slow > end, >- _llint_slow_path_urshift, >+ _slow_path_urshift, > 4) > > >@@ -794,7 +794,7 @@ _llint_op_bitand: > traceExecution() > bitOp( > macro (left, right, slow) andi left, right end, >- _llint_slow_path_bitand, >+ _slow_path_bitand, > 5) > > >@@ -802,7 +802,7 @@ _llint_op_bitxor: > traceExecution() > bitOp( > macro (left, right, slow) xori left, right end, >- _llint_slow_path_bitxor, >+ _slow_path_bitxor, > 5) > > >@@ -810,7 +810,7 @@ _llint_op_bitor: > traceExecution() > bitOp( > macro (left, right, slow) ori left, right end, >- _llint_slow_path_bitor, >+ _slow_path_bitor, > 5) > > >@@ -1671,7 +1671,7 @@ _llint_op_to_primitive: > dispatch(3) > > .opToPrimitiveSlowCase: >- callSlowPath(_llint_slow_path_to_primitive) >+ callSlowPath(_slow_path_to_primitive) > dispatch(3) > > >Index: Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >=================================================================== >--- Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (revision 150843) >+++ Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (working copy) >@@ -234,7 +234,7 @@ _llint_op_create_arguments: > traceExecution() > loadisFromInstruction(1, t0) > bqneq [cfr, t0, 8], ValueEmpty, .opCreateArgumentsDone >- callSlowPath(_llint_slow_path_create_arguments) >+ callSlowPath(_slow_path_create_arguments) > .opCreateArgumentsDone: > dispatch(2) > >@@ -252,7 +252,7 @@ _llint_op_create_this: > dispatch(4) > > .opCreateThisSlow: >- callSlowPath(_llint_slow_path_create_this) >+ callSlowPath(_slow_path_create_this) > dispatch(4) > > >@@ -278,7 +278,7 @@ _llint_op_to_this: > dispatch(3) > > .opToThisSlow: >- callSlowPath(_llint_slow_path_to_this) >+ callSlowPath(_slow_path_to_this) > dispatch(3) > > >@@ -318,7 +318,7 @@ _llint_op_not: > dispatch(3) > > .opNotSlow: >- callSlowPath(_llint_slow_path_not) >+ callSlowPath(_slow_path_not) > dispatch(3) > > >@@ -342,13 +342,13 @@ end > _llint_op_eq: > equalityComparison( > macro (left, right, result) cieq left, right, result end, >- _llint_slow_path_eq) >+ _slow_path_eq) > > > _llint_op_neq: > equalityComparison( > macro (left, right, result) cineq left, right, result end, >- _llint_slow_path_neq) >+ _slow_path_neq) > > > macro equalNullComparison() >@@ -417,13 +417,13 @@ end > _llint_op_stricteq: > strictEq( > macro (left, right, result) cqeq left, right, result end, >- _llint_slow_path_stricteq) >+ _slow_path_stricteq) > > > _llint_op_nstricteq: > strictEq( > macro (left, right, result) cqneq left, right, result end, >- _llint_slow_path_nstricteq) >+ _slow_path_nstricteq) > > > macro preOp(arithmeticOperation, slowPath) >@@ -444,13 +444,13 @@ end > _llint_op_inc: > preOp( > macro (value, slow) baddio 1, value, slow end, >- _llint_slow_path_pre_inc) >+ _slow_path_inc) > > > _llint_op_dec: > preOp( > macro (value, slow) bsubio 1, value, slow end, >- _llint_slow_path_pre_dec) >+ _slow_path_dec) > > > _llint_op_to_number: >@@ -465,7 +465,7 @@ _llint_op_to_number: > dispatch(3) > > .opToNumberSlow: >- callSlowPath(_llint_slow_path_to_number) >+ callSlowPath(_slow_path_to_number) > dispatch(3) > > >@@ -487,7 +487,7 @@ _llint_op_negate: > dispatch(3) > > .opNegateSlow: >- callSlowPath(_llint_slow_path_negate) >+ callSlowPath(_slow_path_negate) > dispatch(3) > > >@@ -555,7 +555,7 @@ _llint_op_add: > binaryOp( > macro (left, right, slow) baddio left, right, slow end, > macro (left, right) addd left, right end, >- _llint_slow_path_add) >+ _slow_path_add) > > > _llint_op_mul: >@@ -573,7 +573,7 @@ _llint_op_mul: > storeq t3, [cfr, index, 8] > end, > macro (left, right) muld left, right end, >- _llint_slow_path_mul) >+ _slow_path_mul) > > > _llint_op_sub: >@@ -581,7 +581,7 @@ _llint_op_sub: > binaryOp( > macro (left, right, slow) bsubio left, right, slow end, > macro (left, right) subd left, right end, >- _llint_slow_path_sub) >+ _slow_path_sub) > > > _llint_op_div: >@@ -605,7 +605,7 @@ _llint_op_div: > storeq t0, [cfr, index, 8] > end, > macro (left, right) divd left, right end, >- _llint_slow_path_div) >+ _slow_path_div) > > > macro bitOp(operation, slowPath, advance) >@@ -630,7 +630,7 @@ _llint_op_lshift: > traceExecution() > bitOp( > macro (left, right, slow) lshifti left, right end, >- _llint_slow_path_lshift, >+ _slow_path_lshift, > 4) > > >@@ -638,7 +638,7 @@ _llint_op_rshift: > traceExecution() > bitOp( > macro (left, right, slow) rshifti left, right end, >- _llint_slow_path_rshift, >+ _slow_path_rshift, > 4) > > >@@ -649,7 +649,7 @@ _llint_op_urshift: > urshifti left, right > bilt right, 0, slow > end, >- _llint_slow_path_urshift, >+ _slow_path_urshift, > 4) > > >@@ -657,7 +657,7 @@ _llint_op_bitand: > traceExecution() > bitOp( > macro (left, right, slow) andi left, right end, >- _llint_slow_path_bitand, >+ _slow_path_bitand, > 5) > > >@@ -665,7 +665,7 @@ _llint_op_bitxor: > traceExecution() > bitOp( > macro (left, right, slow) xori left, right end, >- _llint_slow_path_bitxor, >+ _slow_path_bitxor, > 5) > > >@@ -673,7 +673,7 @@ _llint_op_bitor: > traceExecution() > bitOp( > macro (left, right, slow) ori left, right end, >- _llint_slow_path_bitor, >+ _slow_path_bitor, > 5) > > >@@ -1502,7 +1502,7 @@ _llint_op_to_primitive: > dispatch(3) > > .opToPrimitiveSlowCase: >- callSlowPath(_llint_slow_path_to_primitive) >+ callSlowPath(_slow_path_to_primitive) > dispatch(3) > > >Index: Source/JavaScriptCore/llint/LowLevelInterpreter.asm >=================================================================== >--- Source/JavaScriptCore/llint/LowLevelInterpreter.asm (revision 150843) >+++ Source/JavaScriptCore/llint/LowLevelInterpreter.asm (working copy) >@@ -431,12 +431,12 @@ _llint_function_for_construct_prologue: > > _llint_function_for_call_arity_check: > prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call) >- functionArityCheck(.functionForCallBegin, _llint_slow_path_call_arityCheck) >+ functionArityCheck(.functionForCallBegin, _slow_path_call_arityCheck) > > > _llint_function_for_construct_arity_check: > prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct) >- functionArityCheck(.functionForConstructBegin, _llint_slow_path_construct_arityCheck) >+ functionArityCheck(.functionForConstructBegin, _slow_path_construct_arityCheck) > > > # Value-representation-specific code. >@@ -474,55 +474,55 @@ _llint_op_new_regexp: > > _llint_op_less: > traceExecution() >- callSlowPath(_llint_slow_path_less) >+ callSlowPath(_slow_path_less) > dispatch(4) > > > _llint_op_lesseq: > traceExecution() >- callSlowPath(_llint_slow_path_lesseq) >+ callSlowPath(_slow_path_lesseq) > dispatch(4) > > > _llint_op_greater: > traceExecution() >- callSlowPath(_llint_slow_path_greater) >+ callSlowPath(_slow_path_greater) > dispatch(4) > > > _llint_op_greatereq: > traceExecution() >- callSlowPath(_llint_slow_path_greatereq) >+ callSlowPath(_slow_path_greatereq) > dispatch(4) > > > _llint_op_mod: > traceExecution() >- callSlowPath(_llint_slow_path_mod) >+ callSlowPath(_slow_path_mod) > dispatch(4) > > > _llint_op_typeof: > traceExecution() >- callSlowPath(_llint_slow_path_typeof) >+ callSlowPath(_slow_path_typeof) > dispatch(3) > > > _llint_op_is_object: > traceExecution() >- callSlowPath(_llint_slow_path_is_object) >+ callSlowPath(_slow_path_is_object) > dispatch(3) > > > _llint_op_is_function: > traceExecution() >- callSlowPath(_llint_slow_path_is_function) >+ callSlowPath(_slow_path_is_function) > dispatch(3) > > > _llint_op_in: > traceExecution() >- callSlowPath(_llint_slow_path_in) >+ callSlowPath(_slow_path_in) > dispatch(4) > > macro getPutToBaseOperationField(scratch, scratch1, fieldOffset, fieldGetter) >@@ -1131,7 +1131,7 @@ _llint_generic_return_point: > > _llint_op_strcat: > traceExecution() >- callSlowPath(_llint_slow_path_strcat) >+ callSlowPath(_slow_path_strcat) > dispatch(4) > > >Index: Source/JavaScriptCore/llint/LowLevelInterpreter.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LowLevelInterpreter.cpp (revision 150843) >+++ Source/JavaScriptCore/llint/LowLevelInterpreter.cpp (working copy) >@@ -36,6 +36,7 @@ > #include "LLIntCLoop.h" > #include "LLIntSlowPaths.h" > #include "Operations.h" >+#include "SlowPaths.h" > #include "VMInspector.h" > #include <wtf/Assertions.h> > #include <wtf/MathExtras.h> >Index: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (revision 0) >+++ Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (revision 0) >@@ -0,0 +1,477 @@ >+/* >+ * Copyright (C) 2011, 2012, 2013 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 "CommonSlowPaths.h" >+ >+#if ENABLE(JIT) || ENABLE(LLINT) >+ >+#include "Arguments.h" >+#include "ArrayConstructor.h" >+#include "CallFrame.h" >+#include "CodeProfiling.h" >+#include "GetterSetter.h" >+#include "HostCallReturnValue.h" >+#include "Interpreter.h" >+#include "JIT.h" >+#include "JITDriver.h" >+#include "JITStubs.h" >+#include "JSActivation.h" >+#include "JSCJSValue.h" >+#include "JSGlobalObjectFunctions.h" >+#include "JSNameScope.h" >+#include "JSPropertyNameIterator.h" >+#include "JSString.h" >+#include "JSWithScope.h" >+#include "LLIntCommon.h" >+#include "LLIntExceptions.h" >+#include "LowLevelInterpreter.h" >+#include "ObjectConstructor.h" >+#include "Operations.h" >+#include "StructureRareDataInlines.h" >+#include <wtf/StringPrintStream.h> >+ >+namespace JSC { >+ >+#define BEGIN_NO_SET_PC() \ >+ VM& vm = exec->vm(); \ >+ NativeCallFrameTracer tracer(&vm, exec) >+ >+#ifndef NDEBUG >+#define SET_PC_FOR_STUBS() do { \ >+ exec->codeBlock()->bytecodeOffset(pc); \ >+ exec->setCurrentVPC(pc + 1); \ >+ } while (false) >+#else >+#define SET_PC_FOR_STUBS() do { \ >+ exec->setCurrentVPC(pc + 1); \ >+ } while (false) >+#endif >+ >+#define BEGIN() \ >+ BEGIN_NO_SET_PC(); \ >+ SET_PC_FOR_STUBS() >+ >+#define OP(index) (exec->uncheckedR(pc[index].u.operand)) >+#define OP_C(index) (exec->r(pc[index].u.operand)) >+ >+#define RETURN_TWO(first, second) do { \ >+ return encodeResult(first, second); \ >+ } while (false) >+ >+#define END_IMPL() RETURN_TWO(pc, exec) >+ >+#define THROW(exceptionToThrow) do { \ >+ vm.exception = (exceptionToThrow); \ >+ pc = LLInt::returnToThrow(exec, pc); \ >+ END_IMPL(); \ >+ } while (false) >+ >+#define CHECK_EXCEPTION() do { \ >+ if (UNLIKELY(vm.exception)) { \ >+ pc = LLInt::returnToThrow(exec, pc); \ >+ END_IMPL(); \ >+ } \ >+ } while (false) >+ >+#define END() do { \ >+ CHECK_EXCEPTION(); \ >+ END_IMPL(); \ >+ } while (false) >+ >+#define BRANCH(opcode, condition) do { \ >+ bool bCondition = (condition); \ >+ CHECK_EXCEPTION(); \ >+ if (bCondition) \ >+ pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \ >+ else \ >+ pc += OPCODE_LENGTH(opcode); \ >+ END_IMPL(); \ >+ } while (false) >+ >+#define RETURN(value) do { \ >+ JSValue rReturnValue = (value); \ >+ CHECK_EXCEPTION(); \ >+ OP(1) = rReturnValue; \ >+ END_IMPL(); \ >+ } while (false) >+ >+#if ENABLE(VALUE_PROFILER) >+#define RETURN_PROFILED(opcode, value) do { \ >+ JSValue rpPeturnValue = (value); \ >+ CHECK_EXCEPTION(); \ >+ OP(1) = rpPeturnValue; \ >+ PROFILE_VALUE(opcode, rpPeturnValue); \ >+ END_IMPL(); \ >+ } while (false) >+ >+#define PROFILE_VALUE(opcode, value) do { \ >+ pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \ >+ JSValue::encode(value); \ >+ } while (false) >+ >+#else // ENABLE(VALUE_PROFILER) >+#define RETURN_PROFILED(opcode, value) RETURN(value) >+ >+#define PROFILE_VALUE(opcode, value) do { } while (false) >+ >+#endif // ENABLE(VALUE_PROFILER) >+ >+#define CALL_END_IMPL(exec, callTarget) RETURN_TWO((callTarget), (exec)) >+ >+#define CALL_THROW(exec, pc, exceptionToThrow) do { \ >+ ExecState* ctExec = (exec); \ >+ Instruction* ctPC = (pc); \ >+ vm.exception = (exceptionToThrow); \ >+ CALL_END_IMPL(ctExec, LLInt::callToThrow(ctExec, ctPC)); \ >+ } while (false) >+ >+#define CALL_CHECK_EXCEPTION(exec, pc) do { \ >+ ExecState* cceExec = (exec); \ >+ Instruction* ccePC = (pc); \ >+ if (UNLIKELY(vm.exception)) \ >+ CALL_END_IMPL(cceExec, LLInt::callToThrow(cceExec, ccePC)); \ >+ } while (false) >+ >+#define CALL_RETURN(exec, pc, callTarget) do { \ >+ ExecState* crExec = (exec); \ >+ Instruction* crPC = (pc); \ >+ void* crCallTarget = (callTarget); \ >+ CALL_CHECK_EXCEPTION(crExec->callerFrame(), crPC); \ >+ CALL_END_IMPL(crExec, crCallTarget); \ >+ } while (false) >+ >+SLOW_PATH_DECL(slow_path_call_arityCheck) >+{ >+ BEGIN(); >+ ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall); >+ if (!newExec) { >+ ReturnAddressPtr returnPC = exec->returnPC(); >+ exec = exec->callerFrame(); >+ vm.exception = createStackOverflowError(exec); >+ LLInt::interpreterThrowInCaller(exec, returnPC); >+ RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); >+ } >+ RETURN_TWO(0, newExec); >+} >+ >+SLOW_PATH_DECL(slow_path_construct_arityCheck) >+{ >+ BEGIN(); >+ ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct); >+ if (!newExec) { >+ ReturnAddressPtr returnPC = exec->returnPC(); >+ exec = exec->callerFrame(); >+ vm.exception = createStackOverflowError(exec); >+ LLInt::interpreterThrowInCaller(exec, returnPC); >+ RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); >+ } >+ RETURN_TWO(0, newExec); >+} >+ >+SLOW_PATH_DECL(slow_path_create_arguments) >+{ >+ BEGIN(); >+ JSValue arguments = JSValue(Arguments::create(vm, exec)); >+ CHECK_EXCEPTION(); >+ exec->uncheckedR(pc[1].u.operand) = arguments; >+ exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments; >+ END(); >+} >+ >+SLOW_PATH_DECL(slow_path_create_this) >+{ >+ BEGIN(); >+ JSFunction* constructor = jsCast<JSFunction*>(OP(2).jsValue().asCell()); >+ >+#if !ASSERT_DISABLED >+ ConstructData constructData; >+ ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS); >+#endif >+ >+ size_t inlineCapacity = pc[3].u.operand; >+ Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure(); >+ RETURN(constructEmptyObject(exec, structure)); >+} >+ >+SLOW_PATH_DECL(slow_path_to_this) >+{ >+ BEGIN(); >+ JSValue v1 = OP(1).jsValue(); >+#if ENABLE(VALUE_PROFILER) >+ pc[OPCODE_LENGTH(op_to_this) - 1].u.profile->m_buckets[0] = >+ JSValue::encode(v1.structureOrUndefined()); >+#endif >+ RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode)); >+} >+ >+SLOW_PATH_DECL(slow_path_not) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(!OP_C(2).jsValue().toBoolean(exec))); >+} >+ >+SLOW_PATH_DECL(slow_path_eq) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(JSValue::equal(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_neq) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(!JSValue::equal(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_stricteq) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(JSValue::strictEqual(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_nstricteq) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(!JSValue::strictEqual(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_less) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(jsLess<true>(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_lesseq) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(jsLessEq<true>(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_greater) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(jsLess<false>(exec, OP_C(3).jsValue(), OP_C(2).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_greatereq) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(jsLessEq<false>(exec, OP_C(3).jsValue(), OP_C(2).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_inc) >+{ >+ BEGIN(); >+ RETURN(jsNumber(OP(1).jsValue().toNumber(exec) + 1)); >+} >+ >+SLOW_PATH_DECL(slow_path_dec) >+{ >+ BEGIN(); >+ RETURN(jsNumber(OP(1).jsValue().toNumber(exec) - 1)); >+} >+ >+SLOW_PATH_DECL(slow_path_to_number) >+{ >+ BEGIN(); >+ RETURN(jsNumber(OP_C(2).jsValue().toNumber(exec))); >+} >+ >+SLOW_PATH_DECL(slow_path_negate) >+{ >+ BEGIN(); >+ RETURN(jsNumber(-OP_C(2).jsValue().toNumber(exec))); >+} >+ >+SLOW_PATH_DECL(slow_path_add) >+{ >+ BEGIN(); >+ JSValue v1 = OP_C(2).jsValue(); >+ JSValue v2 = OP_C(3).jsValue(); >+ >+#if 1 // LLINT_SLOW_PATH_TRACING >+ dataLog("Trying to add ", v1, " to ", v2, ".\n"); >+#endif >+ >+ if (v1.isString() && !v2.isObject()) >+ RETURN(jsString(exec, asString(v1), v2.toString(exec))); >+ >+ if (v1.isNumber() && v2.isNumber()) >+ RETURN(jsNumber(v1.asNumber() + v2.asNumber())); >+ >+ RETURN(jsAddSlowCase(exec, v1, v2)); >+} >+ >+// The following arithmetic and bitwise operations need to be sure to run >+// toNumber() on their operands in order. (A call to toNumber() is idempotent >+// if an exception is already set on the ExecState.) >+ >+SLOW_PATH_DECL(slow_path_mul) >+{ >+ BEGIN(); >+ double a = OP_C(2).jsValue().toNumber(exec); >+ double b = OP_C(3).jsValue().toNumber(exec); >+ RETURN(jsNumber(a * b)); >+} >+ >+SLOW_PATH_DECL(slow_path_sub) >+{ >+ BEGIN(); >+ double a = OP_C(2).jsValue().toNumber(exec); >+ double b = OP_C(3).jsValue().toNumber(exec); >+ RETURN(jsNumber(a - b)); >+} >+ >+SLOW_PATH_DECL(slow_path_div) >+{ >+ BEGIN(); >+ double a = OP_C(2).jsValue().toNumber(exec); >+ double b = OP_C(3).jsValue().toNumber(exec); >+ RETURN(jsNumber(a / b)); >+} >+ >+SLOW_PATH_DECL(slow_path_mod) >+{ >+ BEGIN(); >+ double a = OP_C(2).jsValue().toNumber(exec); >+ double b = OP_C(3).jsValue().toNumber(exec); >+ RETURN(jsNumber(fmod(a, b))); >+} >+ >+SLOW_PATH_DECL(slow_path_lshift) >+{ >+ BEGIN(); >+ int32_t a = OP_C(2).jsValue().toInt32(exec); >+ uint32_t b = OP_C(3).jsValue().toUInt32(exec); >+ RETURN(jsNumber(a << (b & 31))); >+} >+ >+SLOW_PATH_DECL(slow_path_rshift) >+{ >+ BEGIN(); >+ int32_t a = OP_C(2).jsValue().toInt32(exec); >+ uint32_t b = OP_C(3).jsValue().toUInt32(exec); >+ RETURN(jsNumber(a >> (b & 31))); >+} >+ >+SLOW_PATH_DECL(slow_path_urshift) >+{ >+ BEGIN(); >+ uint32_t a = OP_C(2).jsValue().toUInt32(exec); >+ uint32_t b = OP_C(3).jsValue().toUInt32(exec); >+ RETURN(jsNumber(a >> (b & 31))); >+} >+ >+SLOW_PATH_DECL(slow_path_bitand) >+{ >+ BEGIN(); >+ int32_t a = OP_C(2).jsValue().toInt32(exec); >+ int32_t b = OP_C(3).jsValue().toInt32(exec); >+ RETURN(jsNumber(a & b)); >+} >+ >+SLOW_PATH_DECL(slow_path_bitor) >+{ >+ BEGIN(); >+ int32_t a = OP_C(2).jsValue().toInt32(exec); >+ int32_t b = OP_C(3).jsValue().toInt32(exec); >+ RETURN(jsNumber(a | b)); >+} >+ >+SLOW_PATH_DECL(slow_path_bitxor) >+{ >+ BEGIN(); >+ int32_t a = OP_C(2).jsValue().toInt32(exec); >+ int32_t b = OP_C(3).jsValue().toInt32(exec); >+ RETURN(jsNumber(a ^ b)); >+} >+ >+SLOW_PATH_DECL(slow_path_typeof) >+{ >+ BEGIN(); >+ RETURN(jsTypeStringForValue(exec, OP_C(2).jsValue())); >+} >+ >+SLOW_PATH_DECL(slow_path_is_object) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(jsIsObjectType(exec, OP_C(2).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_is_function) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(jsIsFunctionType(OP_C(2).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_in) >+{ >+ BEGIN(); >+ RETURN(jsBoolean(CommonSlowPaths::opIn(exec, OP_C(2).jsValue(), OP_C(3).jsValue()))); >+} >+ >+SLOW_PATH_DECL(slow_path_del_by_val) >+{ >+ BEGIN(); >+ JSValue baseValue = OP_C(2).jsValue(); >+ JSObject* baseObject = baseValue.toObject(exec); >+ >+ JSValue subscript = OP_C(3).jsValue(); >+ >+ bool couldDelete; >+ >+ uint32_t i; >+ if (subscript.getUInt32(i)) >+ couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i); >+ else if (isName(subscript)) >+ couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName()); >+ else { >+ CHECK_EXCEPTION(); >+ Identifier property(exec, subscript.toString(exec)->value(exec)); >+ CHECK_EXCEPTION(); >+ couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property); >+ } >+ >+ if (!couldDelete && exec->codeBlock()->isStrictMode()) >+ THROW(createTypeError(exec, "Unable to delete property.")); >+ >+ RETURN(jsBoolean(couldDelete)); >+} >+ >+SLOW_PATH_DECL(slow_path_strcat) >+{ >+ BEGIN(); >+ RETURN(jsString(exec, &OP(2), pc[3].u.operand)); >+} >+ >+SLOW_PATH_DECL(slow_path_to_primitive) >+{ >+ BEGIN(); >+ RETURN(OP_C(2).jsValue().toPrimitive(exec)); >+} >+ >+} // namespace JSC >+ >+#endif // ENABLE(JIT) || ENABLE(LLINT) >Index: Source/JavaScriptCore/runtime/CommonSlowPaths.h >=================================================================== >--- Source/JavaScriptCore/runtime/CommonSlowPaths.h (revision 150843) >+++ Source/JavaScriptCore/runtime/CommonSlowPaths.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. >+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -29,8 +29,10 @@ > #include "CodeBlock.h" > #include "CodeSpecializationKind.h" > #include "ExceptionHelpers.h" >-#include "JSArray.h" > #include "NameInstance.h" >+#include <wtf/Platform.h> >+ >+#if ENABLE(JIT) || ENABLE(LLINT) > > namespace JSC { > >@@ -97,6 +99,109 @@ inline bool opIn(ExecState* exec, JSValu > return baseObj->hasProperty(exec, property); > } > >-} } // namespace JSC::CommonSlowPaths >+} // namespace CommonSlowPaths >+ >+class ExecState; >+struct Instruction; >+ >+#if USE(JSVALUE64) >+// According to C++ rules, a type used for the return signature of function with C linkage (i.e. >+// 'extern "C"') needs to be POD; hence putting any constructors into it could cause either compiler >+// warnings, or worse, a change in the ABI used to return these types. >+struct SlowPathReturnType { >+ void* a; >+ ExecState* b; >+}; >+ >+inline SlowPathReturnType encodeResult(void* a, ExecState* b) >+{ >+ SlowPathReturnType result; >+ result.a = a; >+ result.b = b; >+ return result; >+} >+ >+inline void decodeResult(SlowPathReturnType result, void*& a, ExecState*& b) >+{ >+ a = result.a; >+ b = result.b; >+} >+ >+#else // USE(JSVALUE32_64) >+typedef int64_t SlowPathReturnType; >+ >+typedef union { >+ struct { >+ void* a; >+ ExecState* b; >+ } pair; >+ int64_t i; >+} SlowPathReturnTypeEncoding; >+ >+inline SlowPathReturnType encodeResult(void* a, ExecState* b) >+{ >+ SlowPathReturnTypeEncoding u; >+ u.pair.a = a; >+ u.pair.b = b; >+ return u.i; >+} >+ >+inline void decodeResult(SlowPathReturnType result, void*& a, ExecState*& b) >+{ >+ SlowPathReturnTypeEncoding u; >+ u.i = result; >+ a = u.pair.a; >+ b = u.pair.b; >+} >+#endif // USE(JSVALUE32_64) >+ >+#define SLOW_PATH >+ >+#define SLOW_PATH_DECL(name) \ >+extern "C" SlowPathReturnType SLOW_PATH name(ExecState* exec, Instruction* pc) >+ >+#define SLOW_PATH_HIDDEN_DECL(name) \ >+SLOW_PATH_DECL(name) WTF_INTERNAL >+ >+SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck); >+SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck); >+SLOW_PATH_HIDDEN_DECL(slow_path_create_arguments); >+SLOW_PATH_HIDDEN_DECL(slow_path_create_this); >+SLOW_PATH_HIDDEN_DECL(slow_path_to_this); >+SLOW_PATH_HIDDEN_DECL(slow_path_not); >+SLOW_PATH_HIDDEN_DECL(slow_path_eq); >+SLOW_PATH_HIDDEN_DECL(slow_path_neq); >+SLOW_PATH_HIDDEN_DECL(slow_path_stricteq); >+SLOW_PATH_HIDDEN_DECL(slow_path_nstricteq); >+SLOW_PATH_HIDDEN_DECL(slow_path_less); >+SLOW_PATH_HIDDEN_DECL(slow_path_lesseq); >+SLOW_PATH_HIDDEN_DECL(slow_path_greater); >+SLOW_PATH_HIDDEN_DECL(slow_path_greatereq); >+SLOW_PATH_HIDDEN_DECL(slow_path_inc); >+SLOW_PATH_HIDDEN_DECL(slow_path_dec); >+SLOW_PATH_HIDDEN_DECL(slow_path_to_number); >+SLOW_PATH_HIDDEN_DECL(slow_path_negate); >+SLOW_PATH_HIDDEN_DECL(slow_path_add); >+SLOW_PATH_HIDDEN_DECL(slow_path_mul); >+SLOW_PATH_HIDDEN_DECL(slow_path_sub); >+SLOW_PATH_HIDDEN_DECL(slow_path_div); >+SLOW_PATH_HIDDEN_DECL(slow_path_mod); >+SLOW_PATH_HIDDEN_DECL(slow_path_lshift); >+SLOW_PATH_HIDDEN_DECL(slow_path_rshift); >+SLOW_PATH_HIDDEN_DECL(slow_path_urshift); >+SLOW_PATH_HIDDEN_DECL(slow_path_bitand); >+SLOW_PATH_HIDDEN_DECL(slow_path_bitor); >+SLOW_PATH_HIDDEN_DECL(slow_path_bitxor); >+SLOW_PATH_HIDDEN_DECL(slow_path_typeof); >+SLOW_PATH_HIDDEN_DECL(slow_path_is_object); >+SLOW_PATH_HIDDEN_DECL(slow_path_is_function); >+SLOW_PATH_HIDDEN_DECL(slow_path_in); >+SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val); >+SLOW_PATH_HIDDEN_DECL(slow_path_strcat); >+SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive); >+ >+} // namespace JSC >+ >+#endif // ENABLE(JIT) || ENABLE(LLINT) > > #endif // CommonSlowPaths_h >Index: Source/JavaScriptCore/runtime/JSCJSValue.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSCJSValue.h (revision 150843) >+++ Source/JavaScriptCore/runtime/JSCJSValue.h (working copy) >@@ -111,6 +111,7 @@ inline uint32_t toUInt32(double number) > class JSValue { > friend struct EncodedJSValueHashTraits; > friend class JIT; >+ friend class JITSlowPathCall; > friend class JITStubs; > friend class JITStubCall; > friend class JSInterfaceJIT;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 116889
:
203095
|
203106
|
203289
|
203617
|
204074