Changeset 90423 in webkit
- Timestamp:
- Jul 5, 2011 5:56:49 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r90421 r90423 1 2011-07-05 Filip Pizlo <fpizlo@apple.com> 2 3 DFG JIT does not implement op_call. 4 https://bugs.webkit.org/show_bug.cgi?id=63858 5 6 Reviewed by Gavin Barraclough. 7 8 * bytecode/CodeBlock.cpp: 9 (JSC::CodeBlock::unlinkCalls): 10 * bytecode/CodeBlock.h: 11 (JSC::CodeBlock::setNumberOfCallLinkInfos): 12 (JSC::CodeBlock::numberOfCallLinkInfos): 13 * bytecompiler/BytecodeGenerator.cpp: 14 (JSC::BytecodeGenerator::emitCall): 15 (JSC::BytecodeGenerator::emitConstruct): 16 * dfg/DFGAliasTracker.h: 17 (JSC::DFG::AliasTracker::lookupGetByVal): 18 (JSC::DFG::AliasTracker::recordCall): 19 (JSC::DFG::AliasTracker::equalIgnoringLaterNumericConversion): 20 * dfg/DFGByteCodeParser.cpp: 21 (JSC::DFG::ByteCodeParser::ByteCodeParser): 22 (JSC::DFG::ByteCodeParser::getLocal): 23 (JSC::DFG::ByteCodeParser::getArgument): 24 (JSC::DFG::ByteCodeParser::toInt32): 25 (JSC::DFG::ByteCodeParser::addToGraph): 26 (JSC::DFG::ByteCodeParser::addVarArgChild): 27 (JSC::DFG::ByteCodeParser::predictInt32): 28 (JSC::DFG::ByteCodeParser::parseBlock): 29 (JSC::DFG::ByteCodeParser::processPhiStack): 30 (JSC::DFG::ByteCodeParser::allocateVirtualRegisters): 31 * dfg/DFGGraph.cpp: 32 (JSC::DFG::Graph::opName): 33 (JSC::DFG::Graph::dump): 34 (JSC::DFG::Graph::refChildren): 35 * dfg/DFGGraph.h: 36 * dfg/DFGJITCodeGenerator.cpp: 37 (JSC::DFG::JITCodeGenerator::useChildren): 38 (JSC::DFG::JITCodeGenerator::emitCall): 39 * dfg/DFGJITCodeGenerator.h: 40 (JSC::DFG::JITCodeGenerator::addressOfCallData): 41 * dfg/DFGJITCompiler.cpp: 42 (JSC::DFG::JITCompiler::compileFunction): 43 * dfg/DFGJITCompiler.h: 44 (JSC::DFG::CallRecord::CallRecord): 45 (JSC::DFG::JITCompiler::notifyCall): 46 (JSC::DFG::JITCompiler::appendCallWithFastExceptionCheck): 47 (JSC::DFG::JITCompiler::addJSCall): 48 (JSC::DFG::JITCompiler::PropertyAccessRecord::PropertyAccessRecord): 49 (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord): 50 * dfg/DFGNode.h: 51 (JSC::DFG::Node::Node): 52 (JSC::DFG::Node::child1): 53 (JSC::DFG::Node::child2): 54 (JSC::DFG::Node::child3): 55 (JSC::DFG::Node::firstChild): 56 (JSC::DFG::Node::numChildren): 57 * dfg/DFGNonSpeculativeJIT.cpp: 58 (JSC::DFG::NonSpeculativeJIT::basicArithOp): 59 (JSC::DFG::NonSpeculativeJIT::compare): 60 (JSC::DFG::NonSpeculativeJIT::compile): 61 * dfg/DFGOperations.cpp: 62 * dfg/DFGOperations.h: 63 * dfg/DFGRepatch.cpp: 64 (JSC::DFG::dfgLinkCall): 65 * dfg/DFGRepatch.h: 66 * dfg/DFGSpeculativeJIT.cpp: 67 (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch): 68 (JSC::DFG::SpeculativeJIT::compilePeepHoleCall): 69 (JSC::DFG::SpeculativeJIT::compile): 70 * dfg/DFGSpeculativeJIT.h: 71 (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch): 72 * interpreter/CallFrame.h: 73 (JSC::ExecState::calleeAsValue): 74 * jit/JIT.cpp: 75 (JSC::JIT::JIT): 76 (JSC::JIT::privateCompileMainPass): 77 (JSC::JIT::privateCompileSlowCases): 78 (JSC::JIT::privateCompile): 79 (JSC::JIT::linkCall): 80 (JSC::JIT::linkConstruct): 81 * jit/JITCall.cpp: 82 (JSC::JIT::compileOpCall): 83 * jit/JITCode.h: 84 (JSC::JITCode::JITCode): 85 (JSC::JITCode::jitType): 86 (JSC::JITCode::HostFunction): 87 * runtime/JSFunction.h: 88 * runtime/JSGlobalData.h: 89 1 90 2011-07-05 Oliver Hunt <oliver@apple.com> 2 91 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r90415 r90423 44 44 #include <wtf/StringExtras.h> 45 45 46 #if ENABLE(DFG_JIT) 47 #include "DFGOperations.h" 48 #endif 49 46 50 #define DUMP_CODE_BLOCK_STATISTICS 0 47 51 48 52 namespace JSC { 53 54 #if ENABLE(DFG_JIT) 55 using namespace DFG; 56 #endif 49 57 50 58 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) … … 1740 1748 if (!m_callLinkInfos[i].isLinked()) 1741 1749 continue; 1742 repatchBuffer.relink(m_callLinkInfos[i].callReturnLocation, m_callLinkInfos[i].isCall ? m_globalData->jitStubs->ctiVirtualCallLink() : m_globalData->jitStubs->ctiVirtualConstructLink()); 1750 if (getJITCode().jitType() == JITCode::DFGJIT) { 1751 #if ENABLE(DFG_JIT) 1752 repatchBuffer.relink(CodeLocationCall(m_callLinkInfos[i].callReturnLocation), operationLinkCall); 1753 #else 1754 ASSERT_NOT_REACHED(); 1755 #endif 1756 } else 1757 repatchBuffer.relink(CodeLocationNearCall(m_callLinkInfos[i].callReturnLocation), m_callLinkInfos[i].isCall ? m_globalData->jitStubs->ctiVirtualCallLink() : m_globalData->jitStubs->ctiVirtualConstructLink()); 1743 1758 m_callLinkInfos[i].unlink(); 1744 1759 } -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r89954 r90423 103 103 } 104 104 105 CodeLocation NearCall callReturnLocation;105 CodeLocationLabel callReturnLocation; // it's a near call in the old JIT, or a normal call in DFG 106 106 CodeLocationDataLabelPtr hotPathBegin; 107 107 CodeLocationNearCall hotPathOther; … … 379 379 bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset); 380 380 381 void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); } 381 382 size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); } 382 void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }383 383 CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; } 384 384 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r90371 r90423 1753 1753 emitExpressionInfo(divot, startOffset, endOffset); 1754 1754 1755 #if ENABLE(JIT)1756 m_codeBlock->addCallLinkInfo();1757 #endif1758 1759 1755 // Emit call. 1760 1756 emitOpcode(opcodeID); … … 1869 1865 1870 1866 emitExpressionInfo(divot, startOffset, endOffset); 1871 1872 #if ENABLE(JIT)1873 m_codeBlock->addCallLinkInfo();1874 #endif1875 1867 1876 1868 emitOpcode(op_construct); -
trunk/Source/JavaScriptCore/dfg/DFGAliasTracker.h
r89611 r90423 61 61 // integer index (this is good enough; the speculative path will only generate 62 62 // optimized accesses to handle integer subscripts). 63 if (possibleAlias.child1 == base && equalIgnoringLaterNumericConversion(possibleAlias.child2, property))63 if (possibleAlias.child1() == base && equalIgnoringLaterNumericConversion(possibleAlias.child2(), property)) 64 64 return m_candidateAliasGetByVal; 65 65 } … … 95 95 m_candidateAliasGetByVal = NoNode; 96 96 } 97 98 void recordCall(NodeIndex call) 99 { 100 ASSERT_UNUSED(call, m_graph[call].op == Call); 101 m_candidateAliasGetByVal = NoNode; 102 } 97 103 98 104 private: … … 107 113 return true; 108 114 Node& node2 = m_graph[op2]; 109 return (node2.op == ValueToNumber || node2.op == ValueToInt32) && op1 == node2.child1 ;115 return (node2.op == ValueToNumber || node2.op == ValueToInt32) && op1 == node2.child1(); 110 116 } 111 117 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r90371 r90423 63 63 , m_numLocals(codeBlock->m_numCalleeRegisters) 64 64 , m_preservedVars(codeBlock->m_numVars) 65 , m_parameterSlots(0) 66 , m_numPassedVarArgs(0) 65 67 { 66 68 } … … 125 127 return nodeIndex; 126 128 ASSERT(node.op == SetLocal); 127 return node.child1 ;129 return node.child1(); 128 130 } 129 131 … … 156 158 return nodeIndex; 157 159 ASSERT(node.op == SetLocal); 158 return node.child1 ;160 return node.child1(); 159 161 } 160 162 … … 192 194 193 195 if (node.op == UInt32ToNumber) 194 return node.child1 ;196 return node.child1(); 195 197 196 198 // Check for numeric constants boxed as JSValues. … … 383 385 return resultIndex; 384 386 } 387 388 NodeIndex addToGraph(Node::VarArgTag, NodeType op) 389 { 390 NodeIndex resultIndex = (NodeIndex)m_graph.size(); 391 m_graph.append(Node(Node::VarArg, op, m_currentIndex, m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs)); 392 393 m_numPassedVarArgs = 0; 394 395 if (op & NodeMustGenerate) 396 m_graph.ref(resultIndex); 397 return resultIndex; 398 } 399 void addVarArgChild(NodeIndex child) 400 { 401 m_graph.m_varArgChildren.append(child); 402 m_numPassedVarArgs++; 403 } 385 404 386 405 void predictArray(NodeIndex nodeIndex) … … 397 416 398 417 if (nodePtr->op == ValueToNumber) 399 nodePtr = &m_graph[nodePtr->child1 ];418 nodePtr = &m_graph[nodePtr->child1()]; 400 419 401 420 if (nodePtr->op == ValueToInt32) 402 nodePtr = &m_graph[nodePtr->child1 ];421 nodePtr = &m_graph[nodePtr->child1()]; 403 422 404 423 if (nodePtr->op == GetLocal) … … 454 473 // temporaries that persist across blocks (dues to ?:, &&, ||, etc). 455 474 unsigned m_preservedVars; 475 // The number of slots (in units of sizeof(Register)) that we need to 476 // preallocate for calls emanating from this frame. This includes the 477 // size of the CallFrame, only if this is not a leaf function. (I.e. 478 // this is 0 if and only if this function is a leaf.) 479 unsigned m_parameterSlots; 480 // The number of var args passed to the next var arg node. 481 unsigned m_numPassedVarArgs; 456 482 457 483 struct PhiStackEntry { … … 1040 1066 LAST_OPCODE(op_ret); 1041 1067 } 1068 1069 case op_call: { 1070 addVarArgChild(get(currentInstruction[1].u.operand)); 1071 int argCount = currentInstruction[2].u.operand; 1072 int registerOffset = currentInstruction[3].u.operand; 1073 int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize; 1074 for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++) 1075 addVarArgChild(get(argIdx)); 1076 NodeIndex call = addToGraph(Node::VarArg, Call); 1077 aliases.recordCall(call); 1078 Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call); 1079 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) 1080 set(putInstruction[1].u.operand, call); 1081 if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots) 1082 m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount; 1083 NEXT_OPCODE(op_call); 1084 } 1085 1086 case op_call_put_result: { 1087 #if !ASSERT_DISABLED 1088 Instruction* callInstruction = currentInstruction - OPCODE_LENGTH(op_call); 1089 ASSERT(interpreter->getOpcodeID(callInstruction->u.opcode) == op_call); 1090 #endif 1091 NEXT_OPCODE(op_call_put_result); 1092 } 1042 1093 1043 1094 default: … … 1072 1123 phiStack.append(PhiStackEntry(predecessorBlock, valueInPredecessor, varNo)); 1073 1124 } else if (m_graph[valueInPredecessor].op == GetLocal) 1074 valueInPredecessor = m_graph[valueInPredecessor].child1 ;1125 valueInPredecessor = m_graph[valueInPredecessor].child1(); 1075 1126 ASSERT(m_graph[valueInPredecessor].op == SetLocal || m_graph[valueInPredecessor].op == Phi); 1076 1127 … … 1078 1129 m_graph.ref(valueInPredecessor); 1079 1130 1080 if (phiNode.child1 == NoNode) {1081 phiNode.child 1 = valueInPredecessor;1131 if (phiNode.child1() == NoNode) { 1132 phiNode.children.fixed.child1 = valueInPredecessor; 1082 1133 continue; 1083 1134 } 1084 if (phiNode.child2 == NoNode) {1085 phiNode.child 2 = valueInPredecessor;1135 if (phiNode.child2() == NoNode) { 1136 phiNode.children.fixed.child2 = valueInPredecessor; 1086 1137 continue; 1087 1138 } 1088 if (phiNode.child3 == NoNode) {1089 phiNode.child 3 = valueInPredecessor;1139 if (phiNode.child3() == NoNode) { 1140 phiNode.children.fixed.child3 = valueInPredecessor; 1090 1141 continue; 1091 1142 } … … 1096 1147 m_graph.ref(newPhi); 1097 1148 1098 newPhiNode.child 1 = phiNode.child1;1099 newPhiNode.child 2 = phiNode.child2;1100 newPhiNode.child 3 = phiNode.child3;1101 1102 phiNode.child 1 = newPhi;1103 phiNode.child 1 = valueInPredecessor;1104 phiNode.child 3 = NoNode;1149 newPhiNode.children.fixed.child1 = phiNode.child1(); 1150 newPhiNode.children.fixed.child2 = phiNode.child2(); 1151 newPhiNode.children.fixed.child3 = phiNode.child3(); 1152 1153 phiNode.children.fixed.child1 = newPhi; 1154 phiNode.children.fixed.child1 = valueInPredecessor; 1155 phiNode.children.fixed.child3 = NoNode; 1105 1156 } 1106 1157 } … … 1130 1181 for (size_t i = 0; i < sizeExcludingPhiNodes; ++i) { 1131 1182 Node& node = m_graph[i]; 1183 1132 1184 if (!node.shouldGenerate()) 1133 1185 continue; 1134 1186 1135 1187 // GetLocal nodes are effectively phi nodes in the graph, referencing 1136 1188 // results from prior blocks. … … 1140 1192 // order so that if a child is on its last use, and a 1141 1193 // VirtualRegister is freed, then it may be reused for node. 1142 scoreBoard.use(node.child1); 1143 scoreBoard.use(node.child2); 1144 scoreBoard.use(node.child3); 1194 if (node.op & NodeHasVarArgs) { 1195 for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) 1196 scoreBoard.use(m_graph.m_varArgChildren[childIdx]); 1197 } else { 1198 scoreBoard.use(node.child1()); 1199 scoreBoard.use(node.child2()); 1200 scoreBoard.use(node.child3()); 1201 } 1145 1202 } 1146 1203 … … 1158 1215 // for the function (and checked for on entry). Since we perform a new and 1159 1216 // different allocation of temporaries, more registers may now be required. 1160 unsigned calleeRegisters = scoreBoard.allocatedCount() + m_preservedVars ;1217 unsigned calleeRegisters = scoreBoard.allocatedCount() + m_preservedVars + m_parameterSlots; 1161 1218 if ((unsigned)m_codeBlock->m_numCalleeRegisters < calleeRegisters) 1162 1219 m_codeBlock->m_numCalleeRegisters = calleeRegisters; -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r89611 r90423 42 42 }; 43 43 44 const char *Graph::opName(NodeType op) 45 { 46 return dfgOpNames[op & NodeIdMask]; 47 } 48 44 49 void Graph::dump(NodeIndex nodeIndex, CodeBlock* codeBlock) 45 50 { … … 76 81 else 77 82 printf("-"); 78 printf(">\t%s(", dfgOpNames[op & NodeIdMask]); 79 if (node.child1 != NoNode) 80 printf("@%u", node.child1); 81 if (node.child2 != NoNode) 82 printf(", @%u", node.child2); 83 if (node.child3 != NoNode) 84 printf(", @%u", node.child3); 85 bool hasPrinted = node.child1 != NoNode; 83 printf(">\t%s(", opName(op)); 84 bool hasPrinted; 85 if (op & NodeHasVarArgs) { 86 for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) { 87 if (hasPrinted) 88 printf(", "); 89 else 90 hasPrinted = true; 91 printf("@%u", m_varArgChildren[childIdx]); 92 } 93 } else { 94 if (node.child1() != NoNode) 95 printf("@%u", node.child1()); 96 if (node.child2() != NoNode) 97 printf(", @%u", node.child2()); 98 if (node.child3() != NoNode) 99 printf(", @%u", node.child3()); 100 hasPrinted = node.child1() != NoNode; 101 } 86 102 87 103 if (node.hasVarNumber()) { … … 139 155 Node& node = at(op); 140 156 141 if (node.child1 == NoNode) { 142 ASSERT(node.child2 == NoNode && node.child3 == NoNode); 143 return; 157 if (node.op & NodeHasVarArgs) { 158 for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) 159 ref(m_varArgChildren[childIdx]); 160 } else { 161 if (node.child1() == NoNode) { 162 ASSERT(node.child2() == NoNode && node.child3() == NoNode); 163 return; 164 } 165 ref(node.child1()); 166 167 if (node.child2() == NoNode) { 168 ASSERT(node.child3() == NoNode); 169 return; 170 } 171 ref(node.child2()); 172 173 if (node.child3() == NoNode) 174 return; 175 ref(node.child3()); 144 176 } 145 ref(node.child1);146 147 if (node.child2 == NoNode) {148 ASSERT(node.child3 == NoNode);149 return;150 }151 ref(node.child2);152 153 if (node.child3 == NoNode)154 return;155 ref(node.child3);156 177 } 157 178 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r84860 r90423 161 161 } 162 162 163 #ifndef NDEBUG 164 static const char *opName(NodeType); 165 #endif 166 163 167 Vector< OwnPtr<BasicBlock> , 8> m_blocks; 168 Vector<NodeIndex, 16> m_varArgChildren; 164 169 private: 165 170 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
r90193 r90423 301 301 void JITCodeGenerator::useChildren(Node& node) 302 302 { 303 NodeIndex child1 = node.child1; 304 if (child1 == NoNode) { 305 ASSERT(node.child2 == NoNode && node.child3 == NoNode); 306 return; 307 } 308 use(child1); 309 310 NodeIndex child2 = node.child2; 311 if (child2 == NoNode) { 312 ASSERT(node.child3 == NoNode); 313 return; 314 } 315 use(child2); 316 317 NodeIndex child3 = node.child3; 318 if (child3 == NoNode) 319 return; 320 use(child3); 303 if (node.op & NodeHasVarArgs) { 304 for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) 305 use(m_jit.graph().m_varArgChildren[childIdx]); 306 } else { 307 NodeIndex child1 = node.child1(); 308 if (child1 == NoNode) { 309 ASSERT(node.child2() == NoNode && node.child3() == NoNode); 310 return; 311 } 312 use(child1); 313 314 NodeIndex child2 = node.child2(); 315 if (child2 == NoNode) { 316 ASSERT(node.child3() == NoNode); 317 return; 318 } 319 use(child2); 320 321 NodeIndex child3 = node.child3(); 322 if (child3 == NoNode) 323 return; 324 use(child3); 325 } 321 326 } 322 327 … … 424 429 425 430 m_jit.addPropertyAccess(functionCall, checkImmToCall, callToCheck, callToStore, callToSlowCase, callToDone, static_cast<int8_t>(baseGPR), static_cast<int8_t>(valueGPR), static_cast<int8_t>(scratchGPR)); 431 } 432 433 void JITCodeGenerator::emitCall(Node& node, GPRReg targetGPR) 434 { 435 // the call instruction's first child is either the function (normal call) or the 436 // receiver (method call). subsequent children are the arguments. 437 int numArgs = node.numChildren() - 1; 438 439 // amount of stuff (in units of sizeof(Register)) that we need to place at the 440 // top of the JS stack. 441 int callDataSize = 0; 442 443 // first there are the arguments 444 callDataSize += numArgs; 445 446 // and then there is the call frame header 447 callDataSize += RegisterFile::CallFrameHeaderSize; 448 449 m_jit.storePtr(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(numArgs))), addressOfCallData(RegisterFile::ArgumentCount)); 450 m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame)); 451 452 for (int argIdx = 0; argIdx < numArgs; argIdx++) { 453 JSValueOperand arg(this, m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx]); 454 GPRReg argGPR = arg.gpr(); 455 456 m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx)); 457 } 458 459 switch (node.op) { 460 case Call: 461 m_jit.storePtr(targetGPR, addressOfCallData(RegisterFile::Callee)); 462 break; 463 464 default: 465 ASSERT_NOT_REACHED(); 466 } 467 468 flushRegisters(); 469 470 GPRResult result(this); 471 GPRReg resultGPR = result.gpr(); 472 473 JITCompiler::DataLabelPtr targetToCheck; 474 JITCompiler::Jump slowPath; 475 476 switch (node.op) { 477 case Call: 478 slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, targetGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue()))); 479 m_jit.loadPtr(MacroAssembler::Address(targetGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR); 480 m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain)); 481 break; 482 483 default: 484 ASSERT_NOT_REACHED(); 485 } 486 487 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister); 488 489 JITCompiler::Call fastCall = m_jit.nearCall(); 490 m_jit.notifyCall(fastCall, m_jit.graph()[m_compileIndex].exceptionInfo); 491 492 JITCompiler::Jump done = m_jit.jump(); 493 494 slowPath.link(&m_jit); 495 496 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 497 JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(operationLinkCall, m_jit.graph()[m_compileIndex].exceptionInfo); 498 m_jit.move(Imm32(numArgs), GPRInfo::regT1); 499 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister); 500 m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), m_jit.graph()[m_compileIndex].exceptionInfo); 501 502 done.link(&m_jit); 503 504 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 505 506 jsValueResult(resultGPR, m_compileIndex); 507 508 m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo); 426 509 } 427 510 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r90193 r90423 523 523 void cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); 524 524 void cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); 525 526 MacroAssembler::Address addressOfCallData(int idx) 527 { 528 return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register))); 529 } 530 531 void emitCall(Node&, GPRReg targetGPR); 525 532 526 533 // Called once a node has completed code generation but prior to setting -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r90324 r90423 295 295 m_calls.clear(); 296 296 m_propertyAccesses.clear(); 297 m_jsCalls.clear(); 297 298 rewindToLabel(speculativePathBegin); 298 299 … … 370 371 371 372 // Link all calls out from the JIT code to their respective functions. 372 for (unsigned i = 0; i < m_calls.size(); ++i) 373 linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function); 373 for (unsigned i = 0; i < m_calls.size(); ++i) { 374 if (m_calls[i].m_function.value()) 375 linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function); 376 } 374 377 375 378 if (m_codeBlock->needsCallReturnIndices()) { 376 379 m_codeBlock->callReturnIndexVector().reserveCapacity(exceptionCheckCount); 377 380 for (unsigned i = 0; i < m_calls.size(); ++i) { 378 if (m_calls[i].m_ exceptionCheck.isSet()) {381 if (m_calls[i].m_handlesExceptions) { 379 382 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call); 380 383 unsigned exceptionInfo = m_calls[i].m_exceptionInfo; … … 397 400 info.u.unset.scratchGPR = m_propertyAccesses[i].m_scratchGPR; 398 401 } 399 402 403 m_codeBlock->setNumberOfCallLinkInfos(m_jsCalls.size()); 404 for (unsigned i = 0; i < m_jsCalls.size(); ++i) { 405 CallLinkInfo& info = m_codeBlock->callLinkInfo(i); 406 info.isCall = m_jsCalls[i].m_isCall; 407 info.callReturnLocation = CodeLocationLabel(linkBuffer.locationOf(m_jsCalls[i].m_slowCall)); 408 info.hotPathBegin = linkBuffer.locationOf(m_jsCalls[i].m_targetToCheck); 409 info.hotPathOther = linkBuffer.locationOfNearCall(m_jsCalls[i].m_fastCall); 410 } 411 400 412 // FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs. 401 413 linkBuffer.link(callRegisterFileCheck, cti_register_file_check); … … 403 415 404 416 entryWithArityCheck = linkBuffer.locationOf(arityCheck); 405 entry = linkBuffer.finalizeCode();417 entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT); 406 418 } 407 419 -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r90324 r90423 66 66 : m_call(call) 67 67 , m_function(function) 68 , m_handlesExceptions(false) 68 69 { 69 70 } … … 75 76 , m_exceptionCheck(exceptionCheck) 76 77 , m_exceptionInfo(exceptionInfo) 78 , m_handlesExceptions(true) 79 { 80 } 81 82 // Constructor for a call that may cause exceptions, but which are handled 83 // through some mechanism other than the in-line exception handler. 84 CallRecord(MacroAssembler::Call call, FunctionPtr function, ExceptionInfo exceptionInfo) 85 : m_call(call) 86 , m_function(function) 87 , m_exceptionInfo(exceptionInfo) 88 , m_handlesExceptions(true) 77 89 { 78 90 } … … 82 94 MacroAssembler::Jump m_exceptionCheck; 83 95 ExceptionInfo m_exceptionInfo; 96 bool m_handlesExceptions; 84 97 }; 85 98 … … 159 172 return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); 160 173 } 174 175 // Notify the JIT of a call that does not require linking. 176 void notifyCall(Call call, unsigned exceptionInfo) 177 { 178 m_calls.append(CallRecord(call, FunctionPtr(), exceptionInfo)); 179 } 161 180 162 181 // Add a call out from JIT code, without an exception check. … … 172 191 Call functionCall = call(); 173 192 Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception)); 193 m_calls.append(CallRecord(functionCall, function, exceptionCheck, exceptionInfo)); 194 return functionCall; 195 } 196 197 // Add a call out from JIT code, with a fast exception check that tests if the return value is zero. 198 Call appendCallWithFastExceptionCheck(const FunctionPtr& function, unsigned exceptionInfo) 199 { 200 Call functionCall = call(); 201 Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR); 174 202 m_calls.append(CallRecord(functionCall, function, exceptionCheck, exceptionInfo)); 175 203 return functionCall; … … 240 268 m_propertyAccesses.append(PropertyAccessRecord(functionCall, deltaCheckImmToCall, deltaCallToStructCheck, deltaCallToLoadOrStore, deltaCallToSlowCase, deltaCallToDone, baseGPR, valueGPR, scratchGPR)); 241 269 } 270 271 void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, bool isCall, unsigned exceptionInfo) 272 { 273 m_jsCalls.append(JSCallRecord(fastCall, slowCall, targetToCheck, isCall, exceptionInfo)); 274 } 242 275 243 276 private: … … 262 295 263 296 struct PropertyAccessRecord { 264 PropertyAccessRecord( JITCompiler::Call functionCall, int8_t deltaCheckImmToCall, int8_t deltaCallToStructCheck, int8_t deltaCallToLoadOrStore, int8_t deltaCallToSlowCase, int8_t deltaCallToDone, int8_t baseGPR, int8_t valueGPR, int8_t scratchGPR)297 PropertyAccessRecord(Call functionCall, int8_t deltaCheckImmToCall, int8_t deltaCallToStructCheck, int8_t deltaCallToLoadOrStore, int8_t deltaCallToSlowCase, int8_t deltaCallToDone, int8_t baseGPR, int8_t valueGPR, int8_t scratchGPR) 265 298 : m_functionCall(functionCall) 266 299 , m_deltaCheckImmToCall(deltaCheckImmToCall) … … 285 318 int8_t m_scratchGPR; 286 319 }; 320 321 struct JSCallRecord { 322 JSCallRecord(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, bool isCall, unsigned exceptionInfo) 323 : m_fastCall(fastCall) 324 , m_slowCall(slowCall) 325 , m_targetToCheck(targetToCheck) 326 , m_isCall(isCall) 327 , m_exceptionInfo(exceptionInfo) 328 { 329 } 330 331 Call m_fastCall; 332 Call m_slowCall; 333 DataLabelPtr m_targetToCheck; 334 bool m_isCall; 335 unsigned m_exceptionInfo; 336 }; 287 337 288 338 Vector<PropertyAccessRecord, 4> m_propertyAccesses; 339 Vector<JSCallRecord, 4> m_jsCalls; 289 340 }; 290 341 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r90371 r90423 77 77 #define NodeIsBranch 0x80000 78 78 #define NodeIsTerminal 0x100000 79 #define NodeHasVarArgs 0x200000 79 80 80 81 // These values record the result type of the node (as checked by NodeResultMask, above), 0 for no result. … … 139 140 macro(CompareStrictEq, NodeResultJS) \ 140 141 \ 142 /* Calls. */\ 143 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 144 \ 141 145 /* Nodes for misc operations. */\ 142 146 macro(Breakpoint, NodeMustGenerate) \ … … 178 182 // Node represents a single operation in the data flow graph. 179 183 struct Node { 184 enum VarArgTag { VarArg }; 185 180 186 // Construct a node with up to 3 children, no immediate value. 181 187 Node(NodeType op, ExceptionInfo exceptionInfo, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode) 182 188 : op(op) 183 189 , exceptionInfo(exceptionInfo) 184 , child1(child1)185 , child2(child2)186 , child3(child3)187 190 , m_virtualRegister(InvalidVirtualRegister) 188 191 , m_refCount(0) 189 192 { 193 ASSERT(!(op & NodeHasVarArgs)); 194 children.fixed.child1 = child1; 195 children.fixed.child2 = child2; 196 children.fixed.child3 = child3; 190 197 } 191 198 … … 194 201 : op(op) 195 202 , exceptionInfo(exceptionInfo) 196 , child1(child1)197 , child2(child2)198 , child3(child3)199 203 , m_virtualRegister(InvalidVirtualRegister) 200 204 , m_refCount(0) 201 205 , m_opInfo(imm.m_value) 202 206 { 207 ASSERT(!(op & NodeHasVarArgs)); 208 children.fixed.child1 = child1; 209 children.fixed.child2 = child2; 210 children.fixed.child3 = child3; 203 211 } 204 212 … … 207 215 : op(op) 208 216 , exceptionInfo(exceptionInfo) 209 , child1(child1)210 , child2(child2)211 , child3(child3)212 217 , m_virtualRegister(InvalidVirtualRegister) 213 218 , m_refCount(0) … … 215 220 , m_opInfo2(imm2.m_value) 216 221 { 222 ASSERT(!(op & NodeHasVarArgs)); 223 children.fixed.child1 = child1; 224 children.fixed.child2 = child2; 225 children.fixed.child3 = child3; 226 } 227 228 // Construct a node with a variable number of children and no immediate values. 229 Node(VarArgTag, NodeType op, ExceptionInfo exceptionInfo, unsigned firstChild, unsigned numChildren) 230 : op(op) 231 , exceptionInfo(exceptionInfo) 232 , m_virtualRegister(InvalidVirtualRegister) 233 , m_refCount(0) 234 { 235 ASSERT(op & NodeHasVarArgs); 236 children.variable.firstChild = firstChild; 237 children.variable.numChildren = numChildren; 217 238 } 218 239 … … 355 376 return mustGenerate() ? m_refCount - 1 : m_refCount; 356 377 } 357 378 379 NodeIndex child1() 380 { 381 ASSERT(!(op & NodeHasVarArgs)); 382 return children.fixed.child1; 383 } 384 385 NodeIndex child2() 386 { 387 ASSERT(!(op & NodeHasVarArgs)); 388 return children.fixed.child2; 389 } 390 391 NodeIndex child3() 392 { 393 ASSERT(!(op & NodeHasVarArgs)); 394 return children.fixed.child3; 395 } 396 397 unsigned firstChild() 398 { 399 ASSERT(op & NodeHasVarArgs); 400 return children.variable.firstChild; 401 } 402 403 unsigned numChildren() 404 { 405 ASSERT(op & NodeHasVarArgs); 406 return children.variable.numChildren; 407 } 408 358 409 // This enum value describes the type of the node. 359 410 NodeType op; … … 361 412 ExceptionInfo exceptionInfo; 362 413 // References to up to 3 children (0 for no child). 363 NodeIndex child1, child2, child3; 414 union { 415 struct { 416 NodeIndex child1, child2, child3; 417 } fixed; 418 struct { 419 unsigned firstChild; 420 unsigned numChildren; 421 } variable; 422 } children; 364 423 365 424 private: -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
r90371 r90423 266 266 void NonSpeculativeJIT::basicArithOp(NodeType op, Node &node) 267 267 { 268 JSValueOperand arg1(this, node.child1 );269 JSValueOperand arg2(this, node.child2 );268 JSValueOperand arg1(this, node.child1()); 269 JSValueOperand arg2(this, node.child2()); 270 270 271 271 GPRReg arg1GPR = arg1.gpr(); … … 278 278 JITCompiler::JumpList slowPath; 279 279 280 if (!isKnownInteger(node.child1 ))280 if (!isKnownInteger(node.child1())) 281 281 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister)); 282 if (!isKnownInteger(node.child2 ))282 if (!isKnownInteger(node.child2())) 283 283 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister)); 284 284 … … 347 347 // FIXME: should do some peephole to fuse compare/branch 348 348 349 JSValueOperand arg1(this, node.child1 );350 JSValueOperand arg2(this, node.child2 );349 JSValueOperand arg1(this, node.child1()); 350 JSValueOperand arg2(this, node.child2()); 351 351 GPRReg arg1GPR = arg1.gpr(); 352 352 GPRReg arg2GPR = arg2.gpr(); … … 357 357 JITCompiler::JumpList slowPath; 358 358 359 if (!isKnownInteger(node.child1 ))359 if (!isKnownInteger(node.child1())) 360 360 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister)); 361 if (!isKnownInteger(node.child2 ))361 if (!isKnownInteger(node.child2())) 362 362 slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister)); 363 363 … … 398 398 switch (op) { 399 399 case ConvertThis: { 400 JSValueOperand thisValue(this, node.child1 );400 JSValueOperand thisValue(this, node.child1()); 401 401 GPRReg thisGPR = thisValue.gpr(); 402 402 flushRegisters(); … … 425 425 426 426 case SetLocal: { 427 JSValueOperand value(this, node.child1 );427 JSValueOperand value(this, node.child1()); 428 428 m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local())); 429 429 noResult(m_compileIndex); … … 434 434 case BitOr: 435 435 case BitXor: 436 if (isInt32Constant(node.child1 )) {437 IntegerOperand op2(this, node.child2 );436 if (isInt32Constant(node.child1())) { 437 IntegerOperand op2(this, node.child2()); 438 438 GPRTemporary result(this, op2); 439 439 440 bitOp(op, valueOfInt32Constant(node.child1 ), op2.gpr(), result.gpr());440 bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr()); 441 441 442 442 integerResult(result.gpr(), m_compileIndex); 443 } else if (isInt32Constant(node.child2 )) {444 IntegerOperand op1(this, node.child1 );443 } else if (isInt32Constant(node.child2())) { 444 IntegerOperand op1(this, node.child1()); 445 445 GPRTemporary result(this, op1); 446 446 447 bitOp(op, valueOfInt32Constant(node.child2 ), op1.gpr(), result.gpr());447 bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr()); 448 448 449 449 integerResult(result.gpr(), m_compileIndex); 450 450 } else { 451 IntegerOperand op1(this, node.child1 );452 IntegerOperand op2(this, node.child2 );451 IntegerOperand op1(this, node.child1()); 452 IntegerOperand op2(this, node.child2()); 453 453 GPRTemporary result(this, op1, op2); 454 454 … … 464 464 case BitLShift: 465 465 case BitURShift: 466 if (isInt32Constant(node.child2 )) {467 IntegerOperand op1(this, node.child1 );466 if (isInt32Constant(node.child2())) { 467 IntegerOperand op1(this, node.child1()); 468 468 GPRTemporary result(this, op1); 469 469 470 int shiftAmount = valueOfInt32Constant(node.child2 ) & 0x1f;470 int shiftAmount = valueOfInt32Constant(node.child2()) & 0x1f; 471 471 // Shifts by zero should have been optimized out of the graph! 472 472 ASSERT(shiftAmount); … … 476 476 } else { 477 477 // Do not allow shift amount to be used as the result, MacroAssembler does not permit this. 478 IntegerOperand op1(this, node.child1 );479 IntegerOperand op2(this, node.child2 );478 IntegerOperand op1(this, node.child1()); 479 IntegerOperand op2(this, node.child2()); 480 480 GPRTemporary result(this, op1); 481 481 … … 489 489 490 490 case UInt32ToNumber: { 491 IntegerOperand op1(this, node.child1 );491 IntegerOperand op1(this, node.child1()); 492 492 FPRTemporary boxer(this); 493 493 GPRTemporary result(this, op1); … … 514 514 515 515 case ValueToInt32: { 516 ASSERT(!isInt32Constant(node.child1 ));517 518 if (isKnownInteger(node.child1 )) {519 IntegerOperand op1(this, node.child1 );516 ASSERT(!isInt32Constant(node.child1())); 517 518 if (isKnownInteger(node.child1())) { 519 IntegerOperand op1(this, node.child1()); 520 520 GPRTemporary result(this, op1); 521 521 m_jit.move(op1.gpr(), result.gpr()); … … 524 524 } 525 525 526 GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1 ].virtualRegister()];526 GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1()].virtualRegister()]; 527 527 if ((childInfo.registerFormat() | DataFormatJS) == DataFormatJSDouble) { 528 DoubleOperand op1(this, node.child1 );528 DoubleOperand op1(this, node.child1()); 529 529 GPRTemporary result(this); 530 530 numberToInt32(op1.fpr(), result.gpr()); … … 533 533 } 534 534 535 JSValueOperand op1(this, node.child1 );535 JSValueOperand op1(this, node.child1()); 536 536 GPRTemporary result(this, op1); 537 537 valueToInt32(op1, result.gpr()); … … 541 541 542 542 case ValueToNumber: { 543 ASSERT(!isInt32Constant(node.child1 ));544 ASSERT(!isDoubleConstant(node.child1 ));545 546 if (isKnownNumeric(node.child1 )) {547 JSValueOperand op1(this, node.child1 );543 ASSERT(!isInt32Constant(node.child1())); 544 ASSERT(!isDoubleConstant(node.child1())); 545 546 if (isKnownNumeric(node.child1())) { 547 JSValueOperand op1(this, node.child1()); 548 548 GPRTemporary result(this, op1); 549 549 m_jit.move(op1.gpr(), result.gpr()); … … 552 552 } 553 553 554 JSValueOperand op1(this, node.child1 );554 JSValueOperand op1(this, node.child1()); 555 555 GPRTemporary result(this); 556 556 valueToNumber(op1, result.gpr()); … … 561 561 case ValueAdd: 562 562 case ArithAdd: { 563 if (isInt32Constant(node.child1 )) {564 knownConstantArithOp(op, node.child2 , node.child1, true);563 if (isInt32Constant(node.child1())) { 564 knownConstantArithOp(op, node.child2(), node.child1(), true); 565 565 break; 566 566 } 567 567 568 if (isInt32Constant(node.child2 )) {569 knownConstantArithOp(op, node.child1 , node.child2, false);568 if (isInt32Constant(node.child2())) { 569 knownConstantArithOp(op, node.child1(), node.child2(), false); 570 570 break; 571 571 } … … 576 576 577 577 case ArithSub: { 578 if (isInt32Constant(node.child2 )) {579 knownConstantArithOp(ArithSub, node.child1 , node.child2, false);578 if (isInt32Constant(node.child2())) { 579 knownConstantArithOp(ArithSub, node.child1(), node.child2(), false); 580 580 break; 581 581 } … … 591 591 592 592 case ArithDiv: { 593 DoubleOperand op1(this, node.child1 );594 DoubleOperand op2(this, node.child2 );593 DoubleOperand op1(this, node.child1()); 594 DoubleOperand op2(this, node.child2()); 595 595 FPRTemporary result(this, op1); 596 596 FPRReg op1FPR = op1.fpr(); … … 605 605 606 606 case ArithMod: { 607 JSValueOperand op1(this, node.child1 );608 JSValueOperand op2(this, node.child2 );607 JSValueOperand op1(this, node.child1()); 608 JSValueOperand op2(this, node.child2()); 609 609 GPRTemporary eax(this, X86Registers::eax); 610 610 GPRTemporary edx(this, X86Registers::edx); … … 624 624 JITCompiler::Jump modByZero; 625 625 626 if (!isKnownInteger(node.child1 ))626 if (!isKnownInteger(node.child1())) 627 627 firstOpNotInt = m_jit.branchPtr(MacroAssembler::Below, op1GPR, GPRInfo::tagTypeNumberRegister); 628 if (!isKnownInteger(node.child2 ))628 if (!isKnownInteger(node.child2())) 629 629 secondOpNotInt = m_jit.branchPtr(MacroAssembler::Below, op2GPR, GPRInfo::tagTypeNumberRegister); 630 630 … … 656 656 done.append(m_jit.jump()); 657 657 658 if (!isKnownInteger(node.child1 )) {658 if (!isKnownInteger(node.child1())) { 659 659 firstOpNotInt.link(&m_jit); 660 660 661 661 JITCompiler::Jump secondOpNotInt2; 662 662 663 if (!isKnownInteger(node.child2 ))663 if (!isKnownInteger(node.child2())) 664 664 secondOpNotInt2 = m_jit.branchPtr(MacroAssembler::Below, op2GPR, GPRInfo::tagTypeNumberRegister); 665 665 … … 667 667 m_jit.convertInt32ToDouble(op2GPR, op2FPR); 668 668 669 if (!isKnownInteger(node.child2 )) {669 if (!isKnownInteger(node.child2())) { 670 670 JITCompiler::Jump gotSecondOp = m_jit.jump(); 671 671 … … 683 683 } 684 684 685 if (!isKnownInteger(node.child2 )) {685 if (!isKnownInteger(node.child2())) { 686 686 secondOpNotInt.link(&m_jit); 687 687 … … 691 691 } 692 692 693 if (!isKnownInteger(node.child1 ))693 if (!isKnownInteger(node.child1())) 694 694 gotDoubleArgs.link(&m_jit); 695 695 696 if (!isKnownInteger(node.child1 ) || !isKnownInteger(node.child2)) {696 if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) { 697 697 silentSpillAllRegisters(X86Registers::edx); 698 698 setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(op1FPR, op2FPR); … … 709 709 710 710 case LogicalNot: { 711 JSValueOperand arg1(this, node.child1 );711 JSValueOperand arg1(this, node.child1()); 712 712 GPRTemporary result(this); 713 713 … … 758 758 759 759 case GetByVal: { 760 JSValueOperand base(this, node.child1 );761 JSValueOperand property(this, node.child2 );760 JSValueOperand base(this, node.child1()); 761 JSValueOperand property(this, node.child2()); 762 762 763 763 GPRTemporary storage(this); … … 810 810 case PutByVal: 811 811 case PutByValAlias: { 812 JSValueOperand arg1(this, node.child1 );813 JSValueOperand arg2(this, node.child2 );814 JSValueOperand arg3(this, node.child3 );812 JSValueOperand arg1(this, node.child1()); 813 JSValueOperand arg2(this, node.child2()); 814 JSValueOperand arg3(this, node.child3()); 815 815 GPRReg arg1GPR = arg1.gpr(); 816 816 GPRReg arg2GPR = arg2.gpr(); … … 826 826 827 827 case GetById: { 828 JSValueOperand base(this, node.child1 );828 JSValueOperand base(this, node.child1()); 829 829 GPRReg baseGPR = base.gpr(); 830 830 GPRTemporary result(this, base); … … 840 840 841 841 case PutById: { 842 JSValueOperand base(this, node.child1 );843 JSValueOperand value(this, node.child2 );842 JSValueOperand base(this, node.child1()); 843 JSValueOperand value(this, node.child2()); 844 844 GPRTemporary scratch(this); 845 845 GPRReg valueGPR = value.gpr(); … … 855 855 856 856 case PutByIdDirect: { 857 JSValueOperand base(this, node.child1 );858 JSValueOperand value(this, node.child2 );857 JSValueOperand base(this, node.child1()); 858 JSValueOperand value(this, node.child2()); 859 859 GPRTemporary scratch(this); 860 860 GPRReg valueGPR = value.gpr(); … … 881 881 882 882 case PutGlobalVar: { 883 JSValueOperand value(this, node.child1 );883 JSValueOperand value(this, node.child1()); 884 884 GPRTemporary globalObject(this); 885 885 GPRTemporary scratch(this); … … 908 908 909 909 case Branch: { 910 JSValueOperand value(this, node.child1 );910 JSValueOperand value(this, node.child1()); 911 911 GPRReg valueGPR = value.gpr(); 912 912 flushRegisters(); … … 937 937 938 938 // Return the result in returnValueGPR. 939 JSValueOperand op1(this, node.child1 );939 JSValueOperand op1(this, node.child1()); 940 940 m_jit.move(op1.gpr(), GPRInfo::returnValueGPR); 941 941 … … 953 953 954 954 case CheckHasInstance: { 955 JSValueOperand base(this, node.child1 );955 JSValueOperand base(this, node.child1()); 956 956 GPRTemporary structure(this); 957 957 … … 981 981 982 982 case InstanceOf: { 983 JSValueOperand value(this, node.child1 );984 JSValueOperand base(this, node.child2 );985 JSValueOperand prototype(this, node.child3 );983 JSValueOperand value(this, node.child1()); 984 JSValueOperand base(this, node.child2()); 985 JSValueOperand prototype(this, node.child3()); 986 986 GPRTemporary scratch(this, base); 987 987 … … 1052 1052 ASSERT_NOT_REACHED(); 1053 1053 #endif 1054 break; 1055 1056 case Call: 1057 JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]); 1058 GPRReg calleeGPR = callee.gpr(); 1059 emitCall(node, calleeGPR); 1060 break; 1054 1061 } 1055 1062 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r90401 r90423 43 43 "jmp _" STRINGIZE(function) "WithReturnAddress" "\n" \ 44 44 ); 45 #define FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi) 45 46 #define FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx) 46 47 #define FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8) … … 398 399 } 399 400 401 EncodedJSValue getHostCallReturnValue(); 402 EncodedJSValue getHostCallReturnValueWithExecState(ExecState*); 403 404 asm ( 405 ".globl _" STRINGIZE(getHostCallReturnValue) "\n" 406 "_" STRINGIZE(getHostCallReturnValue) ":" "\n" 407 "mov -40(%r13), %r13\n" 408 "mov %r13, %rdi\n" 409 "jmp _" STRINGIZE(getHostCallReturnValueWithExecState) "\n" 410 ); 411 412 EncodedJSValue getHostCallReturnValueWithExecState(ExecState* exec) 413 { 414 return JSValue::encode(exec->globalData().hostCallReturnValue); 415 } 416 417 static void* handleHostCall(ExecState* execCallee, JSValue callee) 418 { 419 ExecState* exec = execCallee->callerFrame(); 420 JSGlobalData* globalData = &exec->globalData(); 421 CallData callData; 422 CallType callType = getCallData(callee, callData); 423 424 ASSERT(callType != CallTypeJS); 425 426 if (callType == CallTypeHost) { 427 if (!globalData->interpreter->registerFile().grow(execCallee->registers())) { 428 globalData->exception = createStackOverflowError(exec); 429 return 0; 430 } 431 432 execCallee->setScopeChain(exec->scopeChain()); 433 434 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); 435 436 if (globalData->exception) 437 return 0; 438 return reinterpret_cast<void*>(getHostCallReturnValue); 439 } 440 441 ASSERT(callType == CallTypeNone); 442 exec->globalData().exception = createNotAFunctionError(exec, callee); 443 return 0; 444 } 445 446 void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr); 447 FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall); 448 void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress) 449 { 450 ExecState* exec = execCallee->callerFrame(); 451 JSGlobalData* globalData = &exec->globalData(); 452 JSValue calleeAsValue = execCallee->calleeAsValue(); 453 JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue); 454 if (!calleeAsFunctionCell) 455 return handleHostCall(execCallee, calleeAsValue); 456 JSFunction* callee = asFunction(calleeAsFunctionCell); 457 ExecutableBase* executable = callee->executable(); 458 459 MacroAssemblerCodePtr codePtr; 460 CodeBlock* codeBlock = 0; 461 if (executable->isHostFunction()) 462 codePtr = executable->generatedJITCodeForCall().addressForCall(); 463 else { 464 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 465 JSObject* error = functionExecutable->compileForCall(exec, callee->scope()); 466 if (error) { 467 globalData->exception = createStackOverflowError(exec); 468 return 0; 469 } 470 codeBlock = &functionExecutable->generatedBytecodeForCall(); 471 if (execCallee->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters)) 472 codePtr = functionExecutable->generatedJITCodeForCall().addressForCall(); 473 else 474 codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck(); 475 execCallee->setScopeChain(callee->scope()); 476 } 477 CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress); 478 if (!callLinkInfo.seenOnce()) 479 callLinkInfo.setSeen(); 480 else 481 dfgLinkCall(execCallee, callLinkInfo, codeBlock, callee, codePtr); 482 return codePtr.executableAddress(); 483 } 484 485 void* operationVirtualCall(ExecState* execCallee) 486 { 487 ExecState* exec = execCallee->callerFrame(); 488 JSGlobalData* globalData = &exec->globalData(); 489 JSValue calleeAsValue = execCallee->calleeAsValue(); 490 JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue); 491 if (!calleeAsFunctionCell) 492 return handleHostCall(execCallee, calleeAsValue); 493 494 JSFunction* function = asFunction(calleeAsFunctionCell); 495 ExecutableBase* executable = function->executable(); 496 if (executable->isHostFunction()) 497 return executable->generatedJITCodeForCall().addressForCall().executableAddress(); 498 499 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 500 JSObject* error = functionExecutable->compileForCall(exec, function->scope()); 501 if (error) { 502 exec->globalData().exception = error; 503 return 0; 504 } 505 execCallee->setScopeChain(function->scope()); 506 return functionExecutable->generatedJITCodeForCallWithArityCheck().executableAddress(); 507 } 508 400 509 EncodedJSValue operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, EncodedJSValue encodedPrototype) 401 510 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r90371 r90423 81 81 bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 82 82 bool operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 83 void* operationVirtualCall(ExecState*); 84 void* operationLinkCall(ExecState*); 83 85 84 86 // This method is used to lookup an exception hander, keyed by faultLocation, which is -
trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp
r90193 r90423 376 376 } 377 377 378 void dfgLinkCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr) 379 { 380 CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock(); 381 382 RepatchBuffer repatchBuffer(callerCodeBlock); 383 384 if (!calleeCodeBlock || static_cast<int>(exec->argumentCountIncludingThis()) == calleeCodeBlock->m_numParameters) { 385 ASSERT(!callLinkInfo.isLinked()); 386 callLinkInfo.callee.set(exec->callerFrame()->globalData(), callLinkInfo.hotPathBegin, callerCodeBlock->ownerExecutable(), callee); 387 repatchBuffer.relink(callLinkInfo.hotPathOther, codePtr); 388 } 389 390 repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall); 391 } 392 378 393 } } // namespace JSC::DFG 379 394 -
trunk/Source/JavaScriptCore/dfg/DFGRepatch.h
r90035 r90423 37 37 void dfgBuildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&); 38 38 void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind); 39 void dfgLinkCall(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr); 39 40 40 41 } } // namespace JSC::DFG -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r90371 r90423 364 364 } 365 365 366 if (isInt32Constant(node.child1 )) {367 int32_t imm = valueOfInt32Constant(node.child1 );368 SpeculateIntegerOperand op2(this, node.child2 );366 if (isInt32Constant(node.child1())) { 367 int32_t imm = valueOfInt32Constant(node.child1()); 368 SpeculateIntegerOperand op2(this, node.child2()); 369 369 addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken); 370 } else if (isInt32Constant(node.child2 )) {371 SpeculateIntegerOperand op1(this, node.child1 );372 int32_t imm = valueOfInt32Constant(node.child2 );370 } else if (isInt32Constant(node.child2())) { 371 SpeculateIntegerOperand op1(this, node.child1()); 372 int32_t imm = valueOfInt32Constant(node.child2()); 373 373 addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken); 374 374 } else { 375 SpeculateIntegerOperand op1(this, node.child1 );376 SpeculateIntegerOperand op2(this, node.child2 );375 SpeculateIntegerOperand op1(this, node.child1()); 376 SpeculateIntegerOperand op2(this, node.child2()); 377 377 addBranch(m_jit.branch32(condition, op1.gpr(), op2.gpr()), taken); 378 378 } … … 399 399 } 400 400 401 JSValueOperand op1(this, node.child1 );402 JSValueOperand op2(this, node.child2 );401 JSValueOperand op1(this, node.child1()); 402 JSValueOperand op2(this, node.child2()); 403 403 GPRReg op1GPR = op1.gpr(); 404 404 GPRReg op2GPR = op2.gpr(); … … 424 424 ASSERT(node.adjustedRefCount() == 1); 425 425 426 if (shouldSpeculateInteger(node.child1 , node.child2))426 if (shouldSpeculateInteger(node.child1(), node.child2())) 427 427 compilePeepHoleIntegerBranch(node, branchNodeIndex, condition); 428 428 else 429 429 compilePeepHoleCall(node, branchNodeIndex, operation); 430 430 431 use(node.child1 );432 use(node.child2 );431 use(node.child1()); 432 use(node.child2()); 433 433 m_compileIndex = branchNodeIndex; 434 434 return true; … … 436 436 437 437 // Normal case, not fused to branch. 438 SpeculateIntegerOperand op1(this, node.child1 );439 SpeculateIntegerOperand op2(this, node.child2 );438 SpeculateIntegerOperand op1(this, node.child1()); 439 SpeculateIntegerOperand op2(this, node.child2()); 440 440 GPRTemporary result(this, op1, op2); 441 441 … … 483 483 switch (m_jit.graph().getPrediction(node.local())) { 484 484 case PredictInt32: { 485 SpeculateIntegerOperand value(this, node.child1 );485 SpeculateIntegerOperand value(this, node.child1()); 486 486 m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local())); 487 487 noResult(m_compileIndex); … … 489 489 } 490 490 case PredictArray: { 491 SpeculateCellOperand cell(this, node.child1 );491 SpeculateCellOperand cell(this, node.child1()); 492 492 m_jit.storePtr(cell.gpr(), JITCompiler::addressFor(node.local())); 493 493 noResult(m_compileIndex); … … 496 496 497 497 default: { 498 JSValueOperand value(this, node.child1 );498 JSValueOperand value(this, node.child1()); 499 499 m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local())); 500 500 noResult(m_compileIndex); … … 508 508 case BitOr: 509 509 case BitXor: 510 if (isInt32Constant(node.child1 )) {511 SpeculateIntegerOperand op2(this, node.child2 );510 if (isInt32Constant(node.child1())) { 511 SpeculateIntegerOperand op2(this, node.child2()); 512 512 GPRTemporary result(this, op2); 513 513 514 bitOp(op, valueOfInt32Constant(node.child1 ), op2.gpr(), result.gpr());514 bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr()); 515 515 516 516 integerResult(result.gpr(), m_compileIndex); 517 } else if (isInt32Constant(node.child2 )) {518 SpeculateIntegerOperand op1(this, node.child1 );517 } else if (isInt32Constant(node.child2())) { 518 SpeculateIntegerOperand op1(this, node.child1()); 519 519 GPRTemporary result(this, op1); 520 520 521 bitOp(op, valueOfInt32Constant(node.child2 ), op1.gpr(), result.gpr());521 bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr()); 522 522 523 523 integerResult(result.gpr(), m_compileIndex); 524 524 } else { 525 SpeculateIntegerOperand op1(this, node.child1 );526 SpeculateIntegerOperand op2(this, node.child2 );525 SpeculateIntegerOperand op1(this, node.child1()); 526 SpeculateIntegerOperand op2(this, node.child2()); 527 527 GPRTemporary result(this, op1, op2); 528 528 … … 538 538 case BitLShift: 539 539 case BitURShift: 540 if (isInt32Constant(node.child2 )) {541 SpeculateIntegerOperand op1(this, node.child1 );540 if (isInt32Constant(node.child2())) { 541 SpeculateIntegerOperand op1(this, node.child1()); 542 542 GPRTemporary result(this, op1); 543 543 544 shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2 ) & 0x1f, result.gpr());544 shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr()); 545 545 546 546 integerResult(result.gpr(), m_compileIndex); 547 547 } else { 548 548 // Do not allow shift amount to be used as the result, MacroAssembler does not permit this. 549 SpeculateIntegerOperand op1(this, node.child1 );550 SpeculateIntegerOperand op2(this, node.child2 );549 SpeculateIntegerOperand op1(this, node.child1()); 550 SpeculateIntegerOperand op2(this, node.child2()); 551 551 GPRTemporary result(this, op1); 552 552 … … 560 560 561 561 case UInt32ToNumber: { 562 IntegerOperand op1(this, node.child1 );562 IntegerOperand op1(this, node.child1()); 563 563 GPRTemporary result(this, op1); 564 564 … … 572 572 573 573 case ValueToInt32: { 574 SpeculateIntegerOperand op1(this, node.child1 );574 SpeculateIntegerOperand op1(this, node.child1()); 575 575 GPRTemporary result(this, op1); 576 576 m_jit.move(op1.gpr(), result.gpr()); … … 580 580 581 581 case ValueToNumber: { 582 if (isInteger(node.child1 )) {583 SpeculateIntegerOperand op1(this, node.child1 );582 if (isInteger(node.child1())) { 583 SpeculateIntegerOperand op1(this, node.child1()); 584 584 GPRTemporary result(this, op1); 585 585 m_jit.move(op1.gpr(), result.gpr()); … … 587 587 break; 588 588 } 589 SpeculateDoubleOperand op1(this, node.child1 );589 SpeculateDoubleOperand op1(this, node.child1()); 590 590 FPRTemporary result(this, op1); 591 591 m_jit.moveDouble(op1.fpr(), result.fpr()); … … 596 596 case ValueAdd: 597 597 case ArithAdd: { 598 if (shouldSpeculateInteger(node.child1 , node.child2)) {599 if (isInt32Constant(node.child1 )) {600 int32_t imm1 = valueOfInt32Constant(node.child1 );601 SpeculateIntegerOperand op2(this, node.child2 );598 if (shouldSpeculateInteger(node.child1(), node.child2())) { 599 if (isInt32Constant(node.child1())) { 600 int32_t imm1 = valueOfInt32Constant(node.child1()); 601 SpeculateIntegerOperand op2(this, node.child2()); 602 602 GPRTemporary result(this); 603 603 … … 608 608 } 609 609 610 if (isInt32Constant(node.child2 )) {611 SpeculateIntegerOperand op1(this, node.child1 );612 int32_t imm2 = valueOfInt32Constant(node.child2 );610 if (isInt32Constant(node.child2())) { 611 SpeculateIntegerOperand op1(this, node.child1()); 612 int32_t imm2 = valueOfInt32Constant(node.child2()); 613 613 GPRTemporary result(this); 614 614 … … 619 619 } 620 620 621 SpeculateIntegerOperand op1(this, node.child1 );622 SpeculateIntegerOperand op2(this, node.child2 );621 SpeculateIntegerOperand op1(this, node.child1()); 622 SpeculateIntegerOperand op2(this, node.child2()); 623 623 GPRTemporary result(this, op1, op2); 624 624 … … 639 639 } 640 640 641 SpeculateDoubleOperand op1(this, node.child1 );642 SpeculateDoubleOperand op2(this, node.child2 );641 SpeculateDoubleOperand op1(this, node.child1()); 642 SpeculateDoubleOperand op2(this, node.child2()); 643 643 FPRTemporary result(this, op1, op2); 644 644 … … 652 652 653 653 case ArithSub: { 654 if (shouldSpeculateInteger(node.child1 , node.child2)) {655 if (isInt32Constant(node.child2 )) {656 SpeculateIntegerOperand op1(this, node.child1 );657 int32_t imm2 = valueOfInt32Constant(node.child2 );654 if (shouldSpeculateInteger(node.child1(), node.child2())) { 655 if (isInt32Constant(node.child2())) { 656 SpeculateIntegerOperand op1(this, node.child1()); 657 int32_t imm2 = valueOfInt32Constant(node.child2()); 658 658 GPRTemporary result(this); 659 659 … … 664 664 } 665 665 666 SpeculateIntegerOperand op1(this, node.child1 );667 SpeculateIntegerOperand op2(this, node.child2 );666 SpeculateIntegerOperand op1(this, node.child1()); 667 SpeculateIntegerOperand op2(this, node.child2()); 668 668 GPRTemporary result(this); 669 669 … … 674 674 } 675 675 676 SpeculateDoubleOperand op1(this, node.child1 );677 SpeculateDoubleOperand op2(this, node.child2 );676 SpeculateDoubleOperand op1(this, node.child1()); 677 SpeculateDoubleOperand op2(this, node.child2()); 678 678 FPRTemporary result(this, op1); 679 679 … … 687 687 688 688 case ArithMul: { 689 if (shouldSpeculateInteger(node.child1 , node.child2)) {690 SpeculateIntegerOperand op1(this, node.child1 );691 SpeculateIntegerOperand op2(this, node.child2 );689 if (shouldSpeculateInteger(node.child1(), node.child2())) { 690 SpeculateIntegerOperand op1(this, node.child1()); 691 SpeculateIntegerOperand op2(this, node.child2()); 692 692 GPRTemporary result(this); 693 693 … … 705 705 } 706 706 707 SpeculateDoubleOperand op1(this, node.child1 );708 SpeculateDoubleOperand op2(this, node.child2 );707 SpeculateDoubleOperand op1(this, node.child1()); 708 SpeculateDoubleOperand op2(this, node.child2()); 709 709 FPRTemporary result(this, op1, op2); 710 710 … … 719 719 720 720 case ArithDiv: { 721 SpeculateDoubleOperand op1(this, node.child1 );722 SpeculateDoubleOperand op2(this, node.child2 );721 SpeculateDoubleOperand op1(this, node.child1()); 722 SpeculateDoubleOperand op2(this, node.child2()); 723 723 FPRTemporary result(this, op1); 724 724 … … 732 732 733 733 case ArithMod: { 734 SpeculateIntegerOperand op1(this, node.child1 );735 SpeculateIntegerOperand op2(this, node.child2 );734 SpeculateIntegerOperand op1(this, node.child1()); 735 SpeculateIntegerOperand op2(this, node.child2()); 736 736 GPRTemporary eax(this, X86Registers::eax); 737 737 GPRTemporary edx(this, X86Registers::edx); … … 760 760 761 761 case LogicalNot: { 762 JSValueOperand value(this, node.child1 );762 JSValueOperand value(this, node.child1()); 763 763 GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add). 764 764 … … 799 799 800 800 case CompareStrictEq: { 801 SpeculateIntegerOperand op1(this, node.child1 );802 SpeculateIntegerOperand op2(this, node.child2 );801 SpeculateIntegerOperand op1(this, node.child1()); 802 SpeculateIntegerOperand op2(this, node.child2()); 803 803 GPRTemporary result(this, op1, op2); 804 804 … … 812 812 813 813 case GetByVal: { 814 NodeIndex alias = node.child3 ;814 NodeIndex alias = node.child3(); 815 815 if (alias != NoNode) { 816 816 // FIXME: result should be able to reuse child1, child2. Should have an 'UnusedOperand' type. 817 JSValueOperand aliasedValue(this, node.child3 );817 JSValueOperand aliasedValue(this, node.child3()); 818 818 GPRTemporary result(this, aliasedValue); 819 819 m_jit.move(aliasedValue.gpr(), result.gpr()); … … 822 822 } 823 823 824 SpeculateCellOperand base(this, node.child1 );825 SpeculateStrictInt32Operand property(this, node.child2 );824 SpeculateCellOperand base(this, node.child1()); 825 SpeculateStrictInt32Operand property(this, node.child2()); 826 826 GPRTemporary storage(this); 827 827 … … 836 836 // Check that base is an array, and that property is contained within m_vector (< m_vectorLength). 837 837 // If we have predicted the base to be type array, we can skip the check. 838 Node& baseNode = m_jit.graph()[node.child1 ];838 Node& baseNode = m_jit.graph()[node.child1()]; 839 839 if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray) 840 840 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); … … 853 853 854 854 case PutByVal: { 855 SpeculateCellOperand base(this, node.child1 );856 SpeculateStrictInt32Operand property(this, node.child2 );857 JSValueOperand value(this, node.child3 );855 SpeculateCellOperand base(this, node.child1()); 856 SpeculateStrictInt32Operand property(this, node.child2()); 857 JSValueOperand value(this, node.child3()); 858 858 GPRTemporary scratch(this); 859 859 … … 868 868 // Check that base is an array, and that property is contained within m_vector (< m_vectorLength). 869 869 // If we have predicted the base to be type array, we can skip the check. 870 Node& baseNode = m_jit.graph()[node.child1 ];870 Node& baseNode = m_jit.graph()[node.child1()]; 871 871 if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray) 872 872 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); … … 910 910 911 911 case PutByValAlias: { 912 SpeculateCellOperand base(this, node.child1 );913 SpeculateStrictInt32Operand property(this, node.child2 );914 JSValueOperand value(this, node.child3 );912 SpeculateCellOperand base(this, node.child1()); 913 SpeculateStrictInt32Operand property(this, node.child2()); 914 JSValueOperand value(this, node.child3()); 915 915 GPRTemporary scratch(this); 916 916 … … 942 942 943 943 case Branch: { 944 JSValueOperand value(this, node.child1 );944 JSValueOperand value(this, node.child1()); 945 945 GPRReg valueReg = value.gpr(); 946 946 … … 978 978 979 979 // Return the result in returnValueGPR. 980 JSValueOperand op1(this, node.child1 );980 JSValueOperand op1(this, node.child1()); 981 981 m_jit.move(op1.gpr(), GPRInfo::returnValueGPR); 982 982 … … 994 994 995 995 case ConvertThis: { 996 SpeculateCellOperand thisValue(this, node.child1 );996 SpeculateCellOperand thisValue(this, node.child1()); 997 997 GPRTemporary temp(this); 998 998 … … 1005 1005 1006 1006 case GetById: { 1007 SpeculateCellOperand base(this, node.child1 );1007 SpeculateCellOperand base(this, node.child1()); 1008 1008 GPRTemporary result(this, base); 1009 1009 … … 1017 1017 1018 1018 case PutById: { 1019 SpeculateCellOperand base(this, node.child1 );1020 JSValueOperand value(this, node.child2 );1019 SpeculateCellOperand base(this, node.child1()); 1020 JSValueOperand value(this, node.child2()); 1021 1021 GPRTemporary scratch(this); 1022 1022 … … 1028 1028 1029 1029 case PutByIdDirect: { 1030 SpeculateCellOperand base(this, node.child1 );1031 JSValueOperand value(this, node.child2 );1030 SpeculateCellOperand base(this, node.child1()); 1031 JSValueOperand value(this, node.child2()); 1032 1032 GPRTemporary scratch(this); 1033 1033 … … 1050 1050 1051 1051 case PutGlobalVar: { 1052 JSValueOperand value(this, node.child1 );1052 JSValueOperand value(this, node.child1()); 1053 1053 GPRTemporary globalObject(this); 1054 1054 GPRTemporary scratch(this); … … 1069 1069 1070 1070 case CheckHasInstance: { 1071 SpeculateCellOperand base(this, node.child1 );1071 SpeculateCellOperand base(this, node.child1()); 1072 1072 GPRTemporary structure(this); 1073 1073 … … 1081 1081 1082 1082 case InstanceOf: { 1083 SpeculateCellOperand value(this, node.child1 );1083 SpeculateCellOperand value(this, node.child1()); 1084 1084 // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance. 1085 SpeculateCellOperand prototype(this, node.child3 );1085 SpeculateCellOperand prototype(this, node.child3()); 1086 1086 1087 1087 GPRTemporary scratch(this); … … 1126 1126 ASSERT_NOT_REACHED(); 1127 1127 #endif 1128 break; 1129 1130 case Call: 1131 JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]); 1132 GPRReg calleeGPR = callee.gpr(); 1133 emitCall(node, calleeGPR); 1134 break; 1128 1135 } 1129 1136 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r90371 r90423 153 153 // Check if the lastNode is a branch on this node. 154 154 Node& lastNode = m_jit.graph()[lastNodeIndex]; 155 return lastNode.op == Branch && lastNode.child1 == m_compileIndex ? lastNodeIndex : NoNode;155 return lastNode.op == Branch && lastNode.child1() == m_compileIndex ? lastNodeIndex : NoNode; 156 156 } 157 157 -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r86727 r90423 39 39 class ExecState : private Register { 40 40 public: 41 JSValue calleeAsValue() const { return this[RegisterFile::Callee].jsValue(); } 41 42 JSObject* callee() const { return this[RegisterFile::Callee].function(); } 42 43 CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); } -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r90414 r90423 75 75 , m_codeBlock(codeBlock) 76 76 , m_labels(codeBlock ? codeBlock->instructions().size() : 0) 77 , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)78 77 , m_bytecodeOffset((unsigned)-1) 79 78 #if USE(JSVALUE32_64) … … 356 355 } 357 356 358 ASSERT(m_callLinkInfoIndex == m_c odeBlock->numberOfCallLinkInfos());357 ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size()); 359 358 360 359 #ifndef NDEBUG … … 465 464 466 465 ASSERT(m_propertyAccessInstructionIndex == m_propertyAccessCompilationInfo.size()); 467 ASSERT(m_callLinkInfoIndex == m_c odeBlock->numberOfCallLinkInfos());466 ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size()); 468 467 469 468 #ifndef NDEBUG … … 589 588 info.hotPathBegin = patchBuffer.locationOf(m_propertyAccessCompilationInfo[i].hotPathBegin); 590 589 } 590 m_codeBlock->setNumberOfCallLinkInfos(m_callStructureStubCompilationInfo.size()); 591 591 for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) { 592 592 CallLinkInfo& info = m_codeBlock->callLinkInfo(i); 593 593 info.isCall = m_callStructureStubCompilationInfo[i].isCall; 594 info.callReturnLocation = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation);594 info.callReturnLocation = CodeLocationLabel(patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation)); 595 595 info.hotPathBegin = patchBuffer.locationOf(m_callStructureStubCompilationInfo[i].hotPathBegin); 596 596 info.hotPathOther = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].hotPathOther); … … 607 607 *functionEntryArityCheck = patchBuffer.locationOf(arityCheck); 608 608 609 return patchBuffer.finalizeCode();609 return JITCode(patchBuffer.finalizeCode(), JITCode::BaselineJIT); 610 610 } 611 611 … … 624 624 // patch the call so we do not continue to try to link. 625 625 if (kind == CodeForCall) { 626 repatchBuffer.relink( callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());626 repatchBuffer.relink(CodeLocationNearCall(callLinkInfo->callReturnLocation), globalData->jitStubs->ctiVirtualCall()); 627 627 return; 628 628 } 629 629 630 630 ASSERT(kind == CodeForConstruct); 631 repatchBuffer.relink( callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct());631 repatchBuffer.relink(CodeLocationNearCall(callLinkInfo->callReturnLocation), globalData->jitStubs->ctiVirtualConstruct()); 632 632 } 633 633 -
trunk/Source/JavaScriptCore/jit/JITCall.cpp
r89885 r90423 133 133 addSlowCase(jumpToSlow); 134 134 ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump); 135 136 ASSERT(m_callStructureStubCompilationInfo.size() == callLinkInfoIndex); 137 m_callStructureStubCompilationInfo.append(StructureStubCompilationInfo()); 135 138 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; 136 139 m_callStructureStubCompilationInfo[callLinkInfoIndex].isCall = opcodeID != op_construct; -
trunk/Source/JavaScriptCore/jit/JITCode.h
r86883 r90423 38 38 class JSGlobalData; 39 39 class RegisterFile; 40 40 41 41 class JITCode { 42 42 typedef MacroAssemblerCodeRef CodeRef; 43 43 typedef MacroAssemblerCodePtr CodePtr; 44 44 public: 45 enum JITType { HostCallThunk, BaselineJIT, DFGJIT }; 46 45 47 JITCode() 46 48 { 47 49 } 48 50 49 JITCode(const CodeRef ref )51 JITCode(const CodeRef ref, JITType jitType) 50 52 : m_ref(ref) 53 , m_jitType(jitType) 51 54 { 52 55 } … … 94 97 return m_ref.m_executablePool.get(); 95 98 } 99 100 JITType jitType() 101 { 102 return m_jitType; 103 } 96 104 97 105 // Host functions are a bit special; they have a m_code pointer but they … … 99 107 static JITCode HostFunction(CodePtr code) 100 108 { 101 return JITCode(code.dataLocation(), 0, 0 );109 return JITCode(code.dataLocation(), 0, 0, HostCallThunk); 102 110 } 103 111 … … 109 117 110 118 private: 111 JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size )119 JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size, JITType jitType) 112 120 : m_ref(code, executablePool, size) 121 , m_jitType(jitType) 113 122 { 114 123 } 115 124 116 125 CodeRef m_ref; 126 JITType m_jitType; 117 127 }; 118 128 -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r87826 r90423 36 36 class NativeExecutable; 37 37 class VPtrHackExecutable; 38 namespace DFG { 39 class JITCodeGenerator; 40 } 38 41 39 42 EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*); … … 41 44 class JSFunction : public JSObjectWithGlobalObject { 42 45 friend class JIT; 46 friend class DFG::JITCodeGenerator; 43 47 friend class JSGlobalData; 44 48 -
trunk/Source/JavaScriptCore/runtime/JSGlobalData.h
r88473 r90423 235 235 #if ENABLE(JIT) 236 236 ReturnAddressPtr exceptionLocation; 237 JSValue hostCallReturnValue; 237 238 #endif 238 239
Note: See TracChangeset
for help on using the changeset viewer.