Changeset 90602 in webkit
- Timestamp:
- Jul 7, 2011 4:54:57 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r90601 r90602 1 2011-07-07 Filip Pizlo <fpizlo@apple.com> 2 3 DFG JIT does not implement op_construct. 4 https://bugs.webkit.org/show_bug.cgi?id=64066 5 6 Reviewed by Gavin Barraclough. 7 8 * dfg/DFGAliasTracker.h: 9 (JSC::DFG::AliasTracker::recordConstruct): 10 * dfg/DFGByteCodeParser.cpp: 11 (JSC::DFG::ByteCodeParser::addCall): 12 (JSC::DFG::ByteCodeParser::parseBlock): 13 * dfg/DFGJITCodeGenerator.cpp: 14 (JSC::DFG::JITCodeGenerator::emitCall): 15 * dfg/DFGNode.h: 16 * dfg/DFGNonSpeculativeJIT.cpp: 17 (JSC::DFG::NonSpeculativeJIT::compile): 18 * dfg/DFGOperations.cpp: 19 * dfg/DFGOperations.h: 20 * dfg/DFGRepatch.cpp: 21 (JSC::DFG::dfgLinkFor): 22 * dfg/DFGRepatch.h: 23 * dfg/DFGSpeculativeJIT.cpp: 24 (JSC::DFG::SpeculativeJIT::compile): 25 1 26 2011-07-07 Filip Pizlo <fpizlo@apple.com> 2 27 -
trunk/Source/JavaScriptCore/dfg/DFGAliasTracker.h
r90529 r90602 108 108 } 109 109 110 void recordConstruct(NodeIndex construct) 111 { 112 ASSERT_UNUSED(construct, m_graph[construct].op == Construct); 113 m_candidateAliasGetByVal = NoNode; 114 } 115 110 116 private: 111 117 // This method returns true for arguments: -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r90533 r90602 411 411 m_graph.m_varArgChildren.append(child); 412 412 m_numPassedVarArgs++; 413 } 414 415 NodeIndex addCall(Interpreter* interpreter, Instruction* currentInstruction, NodeType op) 416 { 417 addVarArgChild(get(currentInstruction[1].u.operand)); 418 int argCount = currentInstruction[2].u.operand; 419 int registerOffset = currentInstruction[3].u.operand; 420 int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize; 421 for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++) 422 addVarArgChild(get(argIdx)); 423 NodeIndex call = addToGraph(Node::VarArg, op); 424 Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call); 425 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) 426 set(putInstruction[1].u.operand, call); 427 if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots) 428 m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount; 429 return call; 413 430 } 414 431 … … 1102 1119 1103 1120 case op_call: { 1104 addVarArgChild(get(currentInstruction[1].u.operand)); 1105 int argCount = currentInstruction[2].u.operand; 1106 int registerOffset = currentInstruction[3].u.operand; 1107 int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize; 1108 for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++) 1109 addVarArgChild(get(argIdx)); 1110 NodeIndex call = addToGraph(Node::VarArg, Call); 1121 NodeIndex call = addCall(interpreter, currentInstruction, Call); 1111 1122 aliases.recordCall(call); 1112 Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);1113 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)1114 set(putInstruction[1].u.operand, call);1115 if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)1116 m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;1117 1123 NEXT_OPCODE(op_call); 1124 } 1125 1126 case op_construct: { 1127 NodeIndex construct = addCall(interpreter, currentInstruction, Construct); 1128 aliases.recordConstruct(construct); 1129 NEXT_OPCODE(op_construct); 1118 1130 } 1119 1131 1120 1132 case op_call_put_result: { 1121 #if !ASSERT_DISABLED1122 Instruction* callInstruction = currentInstruction - OPCODE_LENGTH(op_call);1123 ASSERT(interpreter->getOpcodeID(callInstruction->u.opcode) == op_call);1124 #endif1125 1133 NEXT_OPCODE(op_call_put_result); 1126 1134 } -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
r90529 r90602 471 471 void JITCodeGenerator::emitCall(Node& node) 472 472 { 473 P_DFGOperation_E slowCallFunction; 474 bool isCall; 475 476 if (node.op == Call) { 477 slowCallFunction = operationLinkCall; 478 isCall = true; 479 } else { 480 ASSERT(node.op == Construct); 481 slowCallFunction = operationLinkConstruct; 482 isCall = false; 483 } 484 473 485 NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()]; 474 486 JSValueOperand callee(this, calleeNodeIndex); … … 502 514 } 503 515 504 switch (node.op) { 505 case Call: 506 m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee)); 507 break; 508 509 default: 510 ASSERT_NOT_REACHED(); 511 } 516 m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee)); 512 517 513 518 flushRegisters(); … … 519 524 JITCompiler::Jump slowPath; 520 525 521 switch (node.op) { 522 case Call: 523 slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue()))); 524 m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR); 525 m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain)); 526 break; 527 528 default: 529 ASSERT_NOT_REACHED(); 530 } 526 slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue()))); 527 m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR); 528 m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain)); 531 529 532 530 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister); … … 540 538 541 539 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 542 JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck( operationLinkCall, m_jit.graph()[m_compileIndex].exceptionInfo);540 JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, m_jit.graph()[m_compileIndex].exceptionInfo); 543 541 m_jit.move(Imm32(numArgs), GPRInfo::regT1); 544 542 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister); … … 551 549 jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly); 552 550 553 m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo);551 m_jit.addJSCall(fastCall, slowCall, targetToCheck, isCall, m_jit.graph()[m_compileIndex].exceptionInfo); 554 552 } 555 553 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r90529 r90602 143 143 /* Calls. */\ 144 144 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 145 macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 145 146 \ 146 147 /* Nodes for misc operations. */\ -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
r90529 r90602 1069 1069 1070 1070 case Call: 1071 case Construct: 1071 1072 emitCall(node); 1072 1073 break; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r90529 r90602 432 432 } 433 433 434 static void* handleHostCall(ExecState* execCallee, JSValue callee )434 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind) 435 435 { 436 436 ExecState* exec = execCallee->callerFrame(); 437 437 JSGlobalData* globalData = &exec->globalData(); 438 CallData callData; 439 CallType callType = getCallData(callee, callData); 440 441 ASSERT(callType != CallTypeJS); 442 443 if (callType == CallTypeHost) { 444 if (!globalData->interpreter->registerFile().grow(execCallee->registers())) { 445 globalData->exception = createStackOverflowError(exec); 446 return 0; 447 } 438 if (kind == CodeForCall) { 439 CallData callData; 440 CallType callType = getCallData(callee, callData); 441 442 ASSERT(callType != CallTypeJS); 443 444 if (callType == CallTypeHost) { 445 if (!globalData->interpreter->registerFile().grow(execCallee->registers())) { 446 globalData->exception = createStackOverflowError(exec); 447 return 0; 448 } 448 449 449 execCallee->setScopeChain(exec->scopeChain());450 execCallee->setScopeChain(exec->scopeChain()); 450 451 451 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));452 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); 452 453 453 if (globalData->exception) 454 return 0; 455 return reinterpret_cast<void*>(getHostCallReturnValue); 456 } 457 458 ASSERT(callType == CallTypeNone); 454 if (globalData->exception) 455 return 0; 456 return reinterpret_cast<void*>(getHostCallReturnValue); 457 } 458 459 ASSERT(callType == CallTypeNone); 460 } else { 461 ASSERT(kind == CodeForConstruct); 462 463 ConstructData constructData; 464 ConstructType constructType = getConstructData(callee, constructData); 465 466 ASSERT(constructType = ConstructTypeJS); 467 468 if (constructType == ConstructTypeHost) { 469 if (!globalData->interpreter->registerFile().grow(execCallee->registers())) { 470 globalData->exception = createStackOverflowError(exec); 471 return 0; 472 } 473 474 execCallee->setScopeChain(exec->scopeChain()); 475 476 globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); 477 478 if (globalData->exception) 479 return 0; 480 return reinterpret_cast<void*>(getHostCallReturnValue); 481 } 482 483 ASSERT(constructType == ConstructTypeNone); 484 } 459 485 exec->globalData().exception = createNotAFunctionError(exec, callee); 460 486 return 0; 461 487 } 462 488 463 void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr); 464 FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall); 465 void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress) 489 inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind) 466 490 { 467 491 ExecState* exec = execCallee->callerFrame(); … … 470 494 JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue); 471 495 if (!calleeAsFunctionCell) 472 return handleHostCall(execCallee, calleeAsValue );496 return handleHostCall(execCallee, calleeAsValue, kind); 473 497 JSFunction* callee = asFunction(calleeAsFunctionCell); 474 498 ExecutableBase* executable = callee->executable(); … … 477 501 CodeBlock* codeBlock = 0; 478 502 if (executable->isHostFunction()) 479 codePtr = executable->generatedJITCodeFor Call().addressForCall();503 codePtr = executable->generatedJITCodeFor(kind).addressForCall(); 480 504 else { 481 505 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 482 JSObject* error = functionExecutable->compileFor Call(exec, callee->scope());506 JSObject* error = functionExecutable->compileFor(exec, callee->scope(), kind); 483 507 if (error) { 484 508 globalData->exception = createStackOverflowError(exec); 485 509 return 0; 486 510 } 487 codeBlock = &functionExecutable->generatedBytecodeFor Call();511 codeBlock = &functionExecutable->generatedBytecodeFor(kind); 488 512 if (execCallee->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters)) 489 codePtr = functionExecutable->generatedJITCodeFor Call().addressForCall();513 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall(); 490 514 else 491 codePtr = functionExecutable->generatedJITCode ForCallWithArityCheck();515 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); 492 516 execCallee->setScopeChain(callee->scope()); 493 517 } … … 496 520 callLinkInfo.setSeen(); 497 521 else 498 dfgLink Call(execCallee, callLinkInfo, codeBlock, callee, codePtr);522 dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); 499 523 return codePtr.executableAddress(); 500 524 } 501 525 502 void* operationVirtualCall(ExecState* execCallee) 526 void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr); 527 FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall); 528 void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress) 529 { 530 return linkFor(execCallee, returnAddress, CodeForCall); 531 } 532 533 void* operationLinkConstructWithReturnAddress(ExecState*, ReturnAddressPtr); 534 FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkConstruct); 535 void* operationLinkConstructWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress) 536 { 537 return linkFor(execCallee, returnAddress, CodeForConstruct); 538 } 539 540 inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) 503 541 { 504 542 ExecState* exec = execCallee->callerFrame(); … … 507 545 JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue); 508 546 if (UNLIKELY(!calleeAsFunctionCell)) 509 return handleHostCall(execCallee, calleeAsValue );547 return handleHostCall(execCallee, calleeAsValue, kind); 510 548 511 549 JSFunction* function = asFunction(calleeAsFunctionCell); 512 550 ExecutableBase* executable = function->executable(); 513 if (UNLIKELY(!executable->hasJITCodeFor Call())) {551 if (UNLIKELY(!executable->hasJITCodeFor(kind))) { 514 552 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 515 553 JSObject* error = functionExecutable->compileForCall(exec, function->scope()); … … 520 558 } 521 559 execCallee->setScopeChain(function->scopeUnchecked()); 522 return executable->generatedJITCodeForCallWithArityCheck().executableAddress(); 560 return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress(); 561 } 562 563 void* operationVirtualCall(ExecState* execCallee) 564 { 565 return virtualFor(execCallee, CodeForCall); 566 } 567 568 void* operationVirtualConstruct(ExecState* execCallee) 569 { 570 return virtualFor(execCallee, CodeForConstruct); 523 571 } 524 572 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r90529 r90602 49 49 typedef void (*V_DFGOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*); 50 50 typedef double (*D_DFGOperation_DD)(double, double); 51 typedef void *(*P_DFGOperation_E)(ExecState*); 51 52 52 53 // These routines are provide callbacks out to C++ implementations of operations too complex to JIT. … … 84 85 void* operationVirtualCall(ExecState*); 85 86 void* operationLinkCall(ExecState*); 87 void* operationVirtualConstruct(ExecState*); 88 void* operationLinkConstruct(ExecState*); 86 89 87 90 // This method is used to lookup an exception hander, keyed by faultLocation, which is -
trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp
r90601 r90602 514 514 } 515 515 516 void dfgLink Call(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr)516 void dfgLinkFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr, CodeSpecializationKind kind) 517 517 { 518 518 CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock(); … … 526 526 } 527 527 528 repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall); 528 if (kind == CodeForCall) { 529 repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall); 530 return; 531 } 532 ASSERT(kind == CodeForConstruct); 533 repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualConstruct); 529 534 } 530 535 -
trunk/Source/JavaScriptCore/dfg/DFGRepatch.h
r90529 r90602 38 38 void dfgBuildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&); 39 39 void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind); 40 void dfgLink Call(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr);40 void dfgLinkFor(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr, CodeSpecializationKind); 41 41 42 42 } } // namespace JSC::DFG -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r90529 r90602 1146 1146 1147 1147 case Call: 1148 case Construct: 1148 1149 emitCall(node); 1149 1150 break;
Note: See TracChangeset
for help on using the changeset viewer.