Changeset 108908 in webkit
- Timestamp:
- Feb 25, 2012, 3:05:38 PM (14 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r108907 r108908 1 2012-02-25 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should support activations and nested functions 4 https://bugs.webkit.org/show_bug.cgi?id=79554 5 6 Reviewed by Oliver Hunt. 7 8 Wrote the simplest possible implementation of activations. Big speed-up on 9 code that uses activations, no speed-up on major benchmarks (SunSpider, V8, 10 Kraken) because they do not appear to have sufficient coverage over code 11 that uses activations. 12 13 * bytecode/PredictedType.cpp: 14 (JSC::predictionToString): 15 (JSC::predictionFromValue): 16 * bytecode/PredictedType.h: 17 (JSC): 18 (JSC::isEmptyPrediction): 19 * dfg/DFGAbstractState.cpp: 20 (JSC::DFG::AbstractState::execute): 21 * dfg/DFGByteCodeParser.cpp: 22 (JSC::DFG::ByteCodeParser::ByteCodeParser): 23 (ByteCodeParser): 24 (JSC::DFG::ByteCodeParser::parseBlock): 25 (JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary): 26 (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): 27 (JSC::DFG::ByteCodeParser::parse): 28 * dfg/DFGCapabilities.h: 29 (JSC::DFG::canCompileOpcode): 30 (JSC::DFG::canInlineOpcode): 31 * dfg/DFGGraph.h: 32 (JSC::DFG::Graph::needsActivation): 33 * dfg/DFGNode.h: 34 (DFG): 35 (JSC::DFG::Node::storageAccessDataIndex): 36 (Node): 37 (JSC::DFG::Node::hasFunctionDeclIndex): 38 (JSC::DFG::Node::functionDeclIndex): 39 (JSC::DFG::Node::hasFunctionExprIndex): 40 (JSC::DFG::Node::functionExprIndex): 41 * dfg/DFGOperations.cpp: 42 * dfg/DFGOperations.h: 43 * dfg/DFGPredictionPropagationPhase.cpp: 44 (JSC::DFG::PredictionPropagationPhase::propagate): 45 * dfg/DFGSpeculativeJIT.cpp: 46 (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck): 47 (DFG): 48 (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression): 49 * dfg/DFGSpeculativeJIT.h: 50 (JSC::DFG::SpeculativeJIT::callOperation): 51 * dfg/DFGSpeculativeJIT32_64.cpp: 52 (JSC::DFG::SpeculativeJIT::compile): 53 * dfg/DFGSpeculativeJIT64.cpp: 54 (JSC::DFG::SpeculativeJIT::compile): 55 1 56 2012-02-25 Benjamin Poulain <benjamin@webkit.org> 2 57 -
trunk/Source/JavaScriptCore/bytecode/PredictedType.cpp
r108677 r108908 154 154 isTop = false; 155 155 156 if (isTop) 157 return "Top"; 156 if (isTop) { 157 ptr = description; 158 ptr.strcat("Top"); 159 } 160 161 if (value & PredictEmpty) 162 ptr.strcat("Empty"); 158 163 159 164 *ptr++ = 0; … … 222 227 PredictedType predictionFromValue(JSValue value) 223 228 { 229 if (value.isEmpty()) 230 return PredictEmpty; 224 231 if (value.isInt32()) 225 232 return PredictInt32; -
trunk/Source/JavaScriptCore/bytecode/PredictedType.h
r106590 r108908 62 62 static const PredictedType PredictNumber = 0x00070000; // It's either an Int32 or a Double. 63 63 static const PredictedType PredictBoolean = 0x00080000; // It's definitely a Boolean. 64 static const PredictedType PredictOther = 0x40000000; // It's definitely none of the above. 65 static const PredictedType PredictTop = 0x7fffffff; // It can be any of the above. 64 static const PredictedType PredictOther = 0x08000000; // It's definitely none of the above. 65 static const PredictedType PredictTop = 0x0fffffff; // It can be any of the above. 66 static const PredictedType PredictEmpty = 0x10000000; // It's definitely an empty value marker. 67 static const PredictedType PredictEmptyOrTop = 0x1fffffff; // It can be any of the above. 66 68 static const PredictedType FixedIndexedStorageMask = PredictByteArray | PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array; 67 69 … … 218 220 } 219 221 222 inline bool isEmptyPrediction(PredictedType value) 223 { 224 return value == PredictEmpty; 225 } 226 220 227 const char* predictionToString(PredictedType value); 221 228 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r108842 r108908 724 724 725 725 case NewObject: 726 forNode(nodeIndex).set(m_codeBlock->globalObject ()->emptyObjectStructure());726 forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->emptyObjectStructure()); 727 727 m_haveStructures = true; 728 728 break; 729 729 730 case CreateActivation: 731 forNode(nodeIndex).set(m_graph.m_globalData.activationStructure.get()); 732 m_haveStructures = true; 733 break; 734 735 case TearOffActivation: 736 // Does nothing that is user-visible. 737 break; 738 739 case NewFunction: 740 case NewFunctionExpression: 741 case NewFunctionNoCheck: 742 forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure()); 743 break; 744 730 745 case GetCallee: 731 746 forNode(nodeIndex).set(PredictFunction); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r108842 r108908 67 67 , m_inlineStackTop(0) 68 68 , m_haveBuiltOperandMaps(false) 69 , m_emptyJSValueIndex(UINT_MAX) 69 70 { 70 71 ASSERT(m_profiledBlock); … … 948 949 // Mapping between values and constant numbers. 949 950 JSValueMap m_jsValueMap; 951 // Index of the empty value, or UINT_MAX if there is no mapping. This is a horrible 952 // work-around for the fact that JSValueMap can't handle "empty" values. 953 unsigned m_emptyJSValueIndex; 950 954 951 955 // Cache of code blocks that we've generated bytecode for. … … 2223 2227 NEXT_OPCODE(op_loop_hint); 2224 2228 } 2229 2230 case op_init_lazy_reg: { 2231 set(currentInstruction[1].u.operand, getJSConstantForValue(JSValue())); 2232 NEXT_OPCODE(op_init_lazy_reg); 2233 } 2234 2235 case op_create_activation: { 2236 set(currentInstruction[1].u.operand, addToGraph(CreateActivation, get(currentInstruction[1].u.operand))); 2237 NEXT_OPCODE(op_create_activation); 2238 } 2239 2240 case op_tear_off_activation: { 2241 // This currently ignores arguments because we don't support them yet. 2242 addToGraph(TearOffActivation, get(currentInstruction[1].u.operand)); 2243 NEXT_OPCODE(op_tear_off_activation); 2244 } 2245 2246 case op_new_func: { 2247 if (!currentInstruction[3].u.operand) { 2248 set(currentInstruction[1].u.operand, 2249 addToGraph(NewFunctionNoCheck, OpInfo(currentInstruction[2].u.operand))); 2250 } else { 2251 set(currentInstruction[1].u.operand, 2252 addToGraph( 2253 NewFunction, 2254 OpInfo(currentInstruction[2].u.operand), 2255 get(currentInstruction[1].u.operand))); 2256 } 2257 NEXT_OPCODE(op_new_func); 2258 } 2259 2260 case op_new_func_exp: { 2261 set(currentInstruction[1].u.operand, 2262 addToGraph(NewFunctionExpression, OpInfo(currentInstruction[2].u.operand))); 2263 NEXT_OPCODE(op_new_func_exp); 2264 } 2225 2265 2226 2266 default: … … 2475 2515 for (size_t i = 0; i < m_codeBlock->numberOfIdentifiers(); ++i) 2476 2516 m_identifierMap.add(m_codeBlock->identifier(i).impl(), i); 2477 for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i) 2478 m_jsValueMap.add(JSValue::encode(m_codeBlock->getConstant(i + FirstConstantRegisterIndex)), i + FirstConstantRegisterIndex); 2517 for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i) { 2518 JSValue value = m_codeBlock->getConstant(i + FirstConstantRegisterIndex); 2519 if (!value) 2520 m_emptyJSValueIndex = i + FirstConstantRegisterIndex; 2521 else 2522 m_jsValueMap.add(JSValue::encode(value), i + FirstConstantRegisterIndex); 2523 } 2479 2524 2480 2525 m_haveBuiltOperandMaps = true; … … 2526 2571 for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) { 2527 2572 JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex); 2573 if (!value) { 2574 if (byteCodeParser->m_emptyJSValueIndex == UINT_MAX) { 2575 byteCodeParser->m_emptyJSValueIndex = byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex; 2576 byteCodeParser->m_codeBlock->addConstant(JSValue()); 2577 byteCodeParser->m_constants.append(ConstantRecord()); 2578 } 2579 m_constantRemap[i] = byteCodeParser->m_emptyJSValueIndex; 2580 continue; 2581 } 2528 2582 pair<JSValueMap::iterator, bool> result = byteCodeParser->m_jsValueMap.add(JSValue::encode(value), byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex); 2529 2583 if (result.second) { … … 2653 2707 // We should be pretending that the code has an activation. 2654 2708 ASSERT(m_graph.needsActivation()); 2655 #else2656 // For now we should never see code that needs activations.2657 ASSERT(!m_graph.needsActivation());2658 2709 #endif 2659 2710 -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h
r108866 r108908 155 155 case op_construct: 156 156 case op_new_regexp: 157 case op_init_lazy_reg: 158 case op_create_activation: 159 case op_tear_off_activation: 160 case op_new_func: 161 case op_new_func_exp: 157 162 return true; 158 163 … … 180 185 // Inlining doesn't correctly remap regular expression operands. 181 186 case op_new_regexp: 187 return false; 188 189 // We don't support inlining code that creates activations or has nested functions. 190 case op_init_lazy_reg: 191 case op_create_activation: 192 case op_tear_off_activation: 193 case op_new_func: 194 case op_new_func_exp: 182 195 return false; 183 196 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r108842 r108908 311 311 return true; 312 312 #else 313 return m_codeBlock-> ownerExecutable()->needsActivation() && m_codeBlock->codeType() != GlobalCode;313 return m_codeBlock->needsFullScopeChain() && m_codeBlock->codeType() != GlobalCode; 314 314 #endif 315 315 } -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r108842 r108908 292 292 macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \ 293 293 \ 294 /* Nodes used for activations. Activation support works by having it anchored at */\ 295 /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\ 296 /* being threaded with each other. */\ 297 macro(CreateActivation, NodeResultJS) \ 298 macro(TearOffActivation, NodeMustGenerate) \ 299 \ 300 /* Nodes for creating functions. */\ 301 macro(NewFunctionNoCheck, NodeResultJS) \ 302 macro(NewFunction, NodeResultJS) \ 303 macro(NewFunctionExpression, NodeResultJS) \ 304 \ 294 305 /* Block terminals. */\ 295 306 macro(Jump, NodeMustGenerate | NodeIsTerminal | NodeIsJump) \ … … 776 787 unsigned storageAccessDataIndex() 777 788 { 789 ASSERT(hasStorageAccessData()); 790 return m_opInfo; 791 } 792 793 bool hasFunctionDeclIndex() 794 { 795 return op == NewFunction 796 || op == NewFunctionNoCheck; 797 } 798 799 unsigned functionDeclIndex() 800 { 801 ASSERT(hasFunctionDeclIndex()); 802 return m_opInfo; 803 } 804 805 bool hasFunctionExprIndex() 806 { 807 return op == NewFunctionExpression; 808 } 809 810 unsigned functionExprIndex() 811 { 812 ASSERT(hasFunctionExprIndex()); 778 813 return m_opInfo; 779 814 } -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r108444 r108908 34 34 #include "InlineASM.h" 35 35 #include "Interpreter.h" 36 #include "JSActivation.h" 36 37 #include "JSByteArray.h" 37 38 #include "JSGlobalData.h" 39 #include "JSStaticScopeObject.h" 38 40 #include "Operations.h" 39 41 … … 973 975 974 976 return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp)); 977 } 978 979 JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec) 980 { 981 JSGlobalData& globalData = exec->globalData(); 982 JSActivation* activation = JSActivation::create( 983 globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable())); 984 exec->setScopeChain(exec->scopeChain()->push(activation)); 985 return activation; 986 } 987 988 void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activation) 989 { 990 ASSERT(activation); 991 ASSERT(activation->inherits(&JSActivation::s_info)); 992 static_cast<JSActivation*>(activation)->tearOff(exec->globalData()); 993 } 994 995 JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable) 996 { 997 ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info)); 998 return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scopeChain()); 999 } 1000 1001 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell) 1002 { 1003 ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info)); 1004 FunctionExecutable* functionExecutable = 1005 static_cast<FunctionExecutable*>(functionExecutableAsCell); 1006 JSFunction *function = functionExecutable->make(exec, exec->scopeChain()); 1007 if (!functionExecutable->name().isNull()) { 1008 JSStaticScopeObject* functionScopeObject = 1009 JSStaticScopeObject::create( 1010 exec, functionExecutable->name(), function, ReadOnly | DontDelete); 1011 function->setScope(exec->globalData(), function->scope()->push(functionScopeObject)); 1012 } 1013 return function; 975 1014 } 976 1015 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r107485 r108908 90 90 typedef double DFG_OPERATION (*D_DFGOperation_EJ)(ExecState*, EncodedJSValue); 91 91 typedef void* DFG_OPERATION (*P_DFGOperation_E)(ExecState*); 92 typedef void DFG_OPERATION (V_DFGOperation_EC)(ExecState*, JSCell*); 92 93 93 94 // These routines are provide callbacks out to C++ implementations of operations too complex to JIT. … … 146 147 void* DFG_OPERATION operationVirtualConstruct(ExecState*); 147 148 void* DFG_OPERATION operationLinkConstruct(ExecState*); 149 JSCell* DFG_OPERATION operationCreateActivation(ExecState*); 150 void DFG_OPERATION operationTearOffActivation(ExecState*, JSCell*); 151 JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*); 152 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*); 148 153 149 154 // This method is used to lookup an exception hander, keyed by faultLocation, which is -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r108842 r108908 398 398 } 399 399 400 case CreateActivation: { 401 changed |= setPrediction(PredictObjectOther); 402 break; 403 } 404 405 case NewFunction: 406 case NewFunctionNoCheck: 407 case NewFunctionExpression: { 408 changed |= setPrediction(PredictFunction); 409 break; 410 } 411 400 412 case GetArrayLength: 401 413 case GetByteArrayLength: … … 440 452 case PutStructure: 441 453 case PutByOffset: 454 case TearOffActivation: 442 455 break; 443 456 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r108842 r108908 2690 2690 } 2691 2691 2692 void SpeculativeJIT::compileNewFunctionNoCheck(Node& node) 2693 { 2694 GPRResult result(this); 2695 GPRReg resultGPR = result.gpr(); 2696 flushRegisters(); 2697 callOperation( 2698 operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex())); 2699 cellResult(resultGPR, m_compileIndex); 2700 } 2701 2702 void SpeculativeJIT::compileNewFunctionExpression(Node& node) 2703 { 2704 GPRResult result(this); 2705 GPRReg resultGPR = result.gpr(); 2706 flushRegisters(); 2707 callOperation( 2708 operationNewFunctionExpression, 2709 resultGPR, 2710 m_jit.codeBlock()->functionExpr(node.functionExprIndex())); 2711 cellResult(resultGPR, m_compileIndex); 2712 } 2713 2692 2714 } } // namespace JSC::DFG 2693 2715 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r108842 r108908 1161 1161 return appendCallWithExceptionCheckSetResult(operation, result); 1162 1162 } 1163 JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell) 1164 { 1165 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell)); 1166 return appendCallWithExceptionCheckSetResult(operation, result); 1167 } 1163 1168 JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell) 1164 1169 { … … 1195 1200 m_jit.setupArgumentsWithExecState(arg1, arg2); 1196 1201 return appendCallWithExceptionCheckSetResult(operation, result); 1202 } 1203 JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1) 1204 { 1205 m_jit.setupArgumentsWithExecState(arg1); 1206 return appendCallWithExceptionCheck(operation); 1197 1207 } 1198 1208 JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer) … … 1329 1339 return appendCallWithExceptionCheckSetResult(operation, result); 1330 1340 } 1341 JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell) 1342 { 1343 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell)); 1344 return appendCallWithExceptionCheckSetResult(operation, result); 1345 } 1331 1346 JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell) 1332 1347 { … … 1363 1378 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag); 1364 1379 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1380 } 1381 JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1) 1382 { 1383 m_jit.setupArgumentsWithExecState(arg1); 1384 return appendCallWithExceptionCheck(operation); 1365 1385 } 1366 1386 JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer) … … 1714 1734 void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements); 1715 1735 void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements); 1736 void compileNewFunctionNoCheck(Node& node); 1737 void compileNewFunctionExpression(Node& node); 1716 1738 1717 1739 // It is acceptable to have structure be equal to scratch, so long as you're fine -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r108842 r108908 3489 3489 } 3490 3490 3491 case CreateActivation: { 3492 JSValueOperand value(this, node.child1()); 3493 GPRTemporary result(this, value); 3494 3495 GPRReg valueTagGPR = value.tagGPR(); 3496 GPRReg valuePayloadGPR = value.payloadGPR(); 3497 GPRReg resultGPR = result.gpr(); 3498 3499 m_jit.move(valuePayloadGPR, resultGPR); 3500 3501 JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag)); 3502 3503 silentSpillAllRegisters(resultGPR); 3504 callOperation(operationCreateActivation, resultGPR); 3505 silentFillAllRegisters(resultGPR); 3506 3507 alreadyCreated.link(&m_jit); 3508 3509 cellResult(resultGPR, m_compileIndex); 3510 break; 3511 } 3512 3513 case TearOffActivation: { 3514 JSValueOperand value(this, node.child1()); 3515 GPRTemporary result(this, value); 3516 3517 GPRReg valueTagGPR = value.tagGPR(); 3518 GPRReg valuePayloadGPR = value.payloadGPR(); 3519 3520 JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag)); 3521 3522 silentSpillAllRegisters(InvalidGPRReg); 3523 callOperation(operationTearOffActivation, valuePayloadGPR); 3524 silentFillAllRegisters(InvalidGPRReg); 3525 3526 notCreated.link(&m_jit); 3527 3528 noResult(m_compileIndex); 3529 break; 3530 } 3531 3532 case NewFunctionNoCheck: 3533 compileNewFunctionNoCheck(node); 3534 break; 3535 3536 case NewFunction: { 3537 JSValueOperand value(this, node.child1()); 3538 GPRTemporary result(this, value); 3539 3540 GPRReg valueTagGPR = value.tagGPR(); 3541 GPRReg valuePayloadGPR = value.payloadGPR(); 3542 GPRReg resultGPR = result.gpr(); 3543 3544 m_jit.move(valuePayloadGPR, resultGPR); 3545 3546 JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag)); 3547 3548 silentSpillAllRegisters(resultGPR); 3549 callOperation( 3550 operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex())); 3551 silentFillAllRegisters(resultGPR); 3552 3553 alreadyCreated.link(&m_jit); 3554 3555 cellResult(resultGPR, m_compileIndex); 3556 break; 3557 } 3558 3559 case NewFunctionExpression: 3560 compileNewFunctionExpression(node); 3561 break; 3562 3491 3563 case ForceOSRExit: { 3492 3564 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r108842 r108908 3452 3452 break; 3453 3453 } 3454 3455 case CreateActivation: { 3456 JSValueOperand value(this, node.child1()); 3457 GPRTemporary result(this, value); 3458 3459 GPRReg valueGPR = value.gpr(); 3460 GPRReg resultGPR = result.gpr(); 3461 3462 m_jit.move(valueGPR, resultGPR); 3463 3464 JITCompiler::Jump alreadyCreated = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR); 3465 3466 silentSpillAllRegisters(resultGPR); 3467 callOperation(operationCreateActivation, resultGPR); 3468 silentFillAllRegisters(resultGPR); 3469 3470 alreadyCreated.link(&m_jit); 3471 3472 cellResult(resultGPR, m_compileIndex); 3473 break; 3474 } 3475 3476 case TearOffActivation: { 3477 JSValueOperand value(this, node.child1()); 3478 GPRReg valueGPR = value.gpr(); 3479 3480 JITCompiler::Jump notCreated = m_jit.branchTestPtr(JITCompiler::Zero, valueGPR); 3481 3482 silentSpillAllRegisters(InvalidGPRReg); 3483 callOperation(operationTearOffActivation, valueGPR); 3484 silentFillAllRegisters(InvalidGPRReg); 3485 3486 notCreated.link(&m_jit); 3487 3488 noResult(m_compileIndex); 3489 break; 3490 } 3491 3492 case NewFunctionNoCheck: 3493 compileNewFunctionNoCheck(node); 3494 break; 3495 3496 case NewFunction: { 3497 JSValueOperand value(this, node.child1()); 3498 GPRTemporary result(this, value); 3499 3500 GPRReg valueGPR = value.gpr(); 3501 GPRReg resultGPR = result.gpr(); 3502 3503 m_jit.move(valueGPR, resultGPR); 3504 3505 JITCompiler::Jump alreadyCreated = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR); 3506 3507 silentSpillAllRegisters(resultGPR); 3508 callOperation( 3509 operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex())); 3510 silentFillAllRegisters(resultGPR); 3511 3512 alreadyCreated.link(&m_jit); 3513 3514 cellResult(resultGPR, m_compileIndex); 3515 break; 3516 } 3517 3518 case NewFunctionExpression: 3519 compileNewFunctionExpression(node); 3520 break; 3454 3521 3455 3522 case ForceOSRExit: {
Note:
See TracChangeset
for help on using the changeset viewer.