Changeset 39428 in webkit for trunk/JavaScriptCore/jit/JITCall.cpp
- Timestamp:
- Dec 21, 2008, 5:00:07 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JITCall.cpp
r39371 r39428 41 41 #endif 42 42 43 #define __ m_assembler.44 45 43 using namespace std; 46 44 … … 52 50 // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive 53 51 // match). Reset the check so it no longer matches. 54 reinterpret_cast<void**>(callLinkInfo->hotPathBegin)[-1] = asPointer(JSImmediate::impossibleValue());52 DataLabelPtr::repatch(callLinkInfo->hotPathBegin, JSImmediate::impossibleValue()); 55 53 } 56 54 … … 63 61 calleeCodeBlock->addCaller(callLinkInfo); 64 62 65 reinterpret_cast<void**>(callLinkInfo->hotPathBegin)[-1] = callee;66 ctiRepatchCallByReturnAddress(callLinkInfo->hotPathOther, ctiCode);63 DataLabelPtr::repatch(callLinkInfo->hotPathBegin, callee); 64 Jump::repatch(callLinkInfo->hotPathOther, ctiCode); 67 65 } 68 66 69 67 // repatch the instruction that jumps out to the cold path, so that we only try to link once. 70 void* repatchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + repatchOffsetOpCallC all);71 ctiRepatchCallByReturnAddress(repatchCheck, callLinkInfo->coldPathOther);68 void* repatchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + repatchOffsetOpCallCompareToJump); 69 Jump::repatch(repatchCheck, callLinkInfo->coldPathOther); 72 70 } 73 71 … … 194 192 #else 195 193 196 typedef X86Assembler::JmpSrc JmpSrc;197 typedef X86Assembler::JmpDst JmpDst;198 199 194 static void unreachable() 200 195 { … … 211 206 212 207 // Handle eval 213 J mpSrcwasEval;208 Jump wasEval; 214 209 if (opcodeID == op_call_eval) { 215 210 emitGetVirtualRegister(callee, X86::ecx); … … 217 212 218 213 emitCTICall(Interpreter::cti_op_call_eval); 219 __ cmpl_ir(asInteger(JSImmediate::impossibleValue()), X86::eax); 220 wasEval = __ jne(); 214 wasEval = jnePtr(X86::eax, ImmPtr(JSImmediate::impossibleValue())); 221 215 } 222 216 … … 224 218 // This deliberately leaves the callee in ecx, used when setting up the stack frame below 225 219 emitGetVirtualRegister(callee, X86::ecx); 226 __ cmpl_ir_force32(asInteger(JSImmediate::impossibleValue()), X86::ecx);227 J mpDst addressOfLinkedFunctionCheck = __ label();228 addSlowCase( __ jne());229 ASSERT( X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck, __ label()) == repatchOffsetOpCallCall);220 DataLabelPtr addressOfLinkedFunctionCheck; 221 Jump jumpToSlow = jnePtrWithRepatch(X86::ecx, addressOfLinkedFunctionCheck, ImmPtr(JSImmediate::impossibleValue())); 222 addSlowCase(jumpToSlow); 223 ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == repatchOffsetOpCallCompareToJump); 230 224 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; 231 225 … … 246 240 // Fast version of stack frame initialization, directly relative to edi. 247 241 // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee 248 __ movl_i32m(asInteger(noValue()), (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)), X86::edi);249 __ movl_rm(X86::ecx, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)), X86::edi);250 __ movl_mr(FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node), X86::ecx, X86::edx); // newScopeChain251 __ movl_i32m(argCount, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)), X86::edi);252 __ movl_rm(X86::edi, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)), X86::edi);253 __ movl_rm(X86::edx, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register)), X86::edi);254 __ addl_ir(registerOffset * sizeof(Register), X86::edi);242 storePtr(ImmPtr(noValue()), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)))); 243 storePtr(X86::ecx, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)))); 244 loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain 245 store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); 246 storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); 247 storePtr(X86::edx, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register)))); 248 addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister); 255 249 256 250 // Call to the callee … … 258 252 259 253 if (opcodeID == op_call_eval) 260 __ link(wasEval, __ label());254 wasEval.link(this); 261 255 262 256 // Put the return value in dst. In the interpreter, op_ret does this. … … 264 258 265 259 #if ENABLE(CODEBLOCK_SAMPLING) 266 __ movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_interpreter->sampler()->codeBlockSlot());260 storePtr(ImmPtr(m_codeBlock), m_interpreter->sampler()->codeBlockSlot()); 267 261 #endif 268 262 } … … 284 278 285 279 // Fast check for JS function. 286 __ testl_i32r(JSImmediate::TagMask, X86::ecx); 287 JmpSrc callLinkFailNotObject = __ jne(); 288 __ cmpl_im(reinterpret_cast<unsigned>(m_interpreter->m_jsFunctionVptr), 0, X86::ecx); 289 JmpSrc callLinkFailNotJSFunction = __ jne(); 280 Jump callLinkFailNotObject = jnz32(X86::ecx, Imm32(JSImmediate::TagMask)); 281 Jump callLinkFailNotJSFunction = jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr)); 290 282 291 283 // First, in the case of a construct, allocate the new object. … … 296 288 } 297 289 298 __ movl_i32r(argCount, X86::edx);290 move(Imm32(argCount), X86::edx); 299 291 300 292 // Speculatively roll the callframe, assuming argCount will match the arity. 301 __ movl_rm(X86::edi, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)), X86::edi);302 __ addl_ir(registerOffset * static_cast<int>(sizeof(Register)), X86::edi);293 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)))); 294 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister); 303 295 304 296 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = 305 297 emitNakedCall(m_interpreter->m_ctiVirtualCallPreLink); 306 298 307 JmpSrc storeResultForFirstRun = __ jmp(); 308 299 Jump storeResultForFirstRun = jump(); 300 301 // FIXME: this label can be removed, since it is a fixed offset from 'callReturnLocation'. 309 302 // This is the address for the cold path *after* the first run (which tries to link the call). 310 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = __ label();303 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = Label(this); 311 304 312 305 // The arguments have been set up on the hot path for op_call_eval … … 317 310 318 311 // Check for JSFunctions. 319 __ testl_i32r(JSImmediate::TagMask, X86::ecx); 320 JmpSrc isNotObject = __ jne(); 321 __ cmpl_im(reinterpret_cast<unsigned>(m_interpreter->m_jsFunctionVptr), 0, X86::ecx); 322 JmpSrc isJSFunction = __ je(); 312 Jump isNotObject = jnzPtr(X86::ecx, Imm32(JSImmediate::TagMask)); 313 Jump isJSFunction = jePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr)); 323 314 324 315 // This handles host functions 325 JmpDst notJSFunctionlabel = __ label(); 326 __ link(isNotObject, notJSFunctionlabel); 327 __ link(callLinkFailNotObject, notJSFunctionlabel); 328 __ link(callLinkFailNotJSFunction, notJSFunctionlabel); 316 isNotObject.link(this); 317 callLinkFailNotObject.link(this); 318 callLinkFailNotJSFunction.link(this); 329 319 emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction)); 330 J mpSrc wasNotJSFunction = __ jmp();320 Jump wasNotJSFunction = jump(); 331 321 332 322 // Next, handle JSFunctions... 333 __ link(isJSFunction, __ label());323 isJSFunction.link(this); 334 324 335 325 // First, in the case of a construct, allocate the new object. … … 341 331 342 332 // Speculatively roll the callframe, assuming argCount will match the arity. 343 __ movl_rm(X86::edi, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)), X86::edi);344 __ addl_ir(registerOffset * static_cast<int>(sizeof(Register)), X86::edi);345 __ movl_i32r(argCount, X86::edx);333 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register)))); 334 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister); 335 move(Imm32(argCount), X86::edx); 346 336 347 337 emitNakedCall(m_interpreter->m_ctiVirtualCall); 348 338 349 339 // Put the return value in dst. In the interpreter, op_ret does this. 350 JmpDst storeResult = __ label(); 351 __ link(wasNotJSFunction, storeResult); 352 __ link(storeResultForFirstRun, storeResult); 340 wasNotJSFunction.link(this); 341 storeResultForFirstRun.link(this); 353 342 emitPutVirtualRegister(dst); 354 343 355 344 #if ENABLE(CODEBLOCK_SAMPLING) 356 __ movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_interpreter->sampler()->codeBlockSlot());345 storePtr(ImmPtr(m_codeBlock), m_interpreter->sampler()->codeBlockSlot()); 357 346 #endif 358 347 }
Note:
See TracChangeset
for help on using the changeset viewer.