diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
commit | dd91e772430dc294e3bf478c119ef8d43c0a3358 (patch) | |
tree | 6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | |
parent | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff) |
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 143 |
1 files changed, 105 insertions, 38 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index 8578337f5..7bcb44576 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -83,7 +83,7 @@ GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex) void SpeculativeJIT::useChildren(Node& node) { - if (node.op & NodeHasVarArgs) { + if (node.flags & NodeHasVarArgs) { for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) use(m_jit.graph().m_varArgChildren[childIdx]); } else { @@ -365,12 +365,15 @@ void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeUse valueU bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction) { - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); + ASSERT(node.adjustedRefCount() == 1); nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; @@ -383,15 +386,15 @@ bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::Relationa bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert) { - if (!invert && (isKnownNumeric(node.child1().index()) || isKnownNumeric(node.child2().index()))) - return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq); - - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); + ASSERT(node.adjustedRefCount() == 1); nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; @@ -765,7 +768,6 @@ FPRTemporary::FPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1) } #endif -#ifndef NDEBUG void ValueSource::dump(FILE* out) const { switch (kind()) { @@ -792,7 +794,6 @@ void ValueSource::dump(FILE* out) const break; } } -#endif void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition) { @@ -873,8 +874,10 @@ void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNo bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation) { // Fused compare & branch. - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); + // detectPeepHoleBranch currently only permits the branch to be the very next node, // so can be no intervening nodes to also reference the compare. ASSERT(node.adjustedRefCount() == 1); @@ -898,6 +901,7 @@ bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::Relationa } else nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; } @@ -915,12 +919,9 @@ void SpeculativeJIT::compileMovHint(Node& node) void SpeculativeJIT::compile(BasicBlock& block) { ASSERT(m_compileOkay); - ASSERT(m_compileIndex == block.begin); - if (!block.isReachable) { - m_compileIndex = block.end; + if (!block.isReachable) return; - } m_blockHeads[m_block] = m_jit.label(); #if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK) @@ -930,7 +931,7 @@ void SpeculativeJIT::compile(BasicBlock& block) ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments()); for (size_t i = 0; i < m_arguments.size(); ++i) { NodeIndex nodeIndex = block.variablesAtHead.argument(i); - if (nodeIndex == NoNode) + if (nodeIndex == NoNode || m_jit.graph().argumentIsCaptured(i)) m_arguments[i] = ValueSource(ValueInRegisterFile); else m_arguments[i] = ValueSource::forPrediction(at(nodeIndex).variableAccessData()->prediction()); @@ -942,7 +943,7 @@ void SpeculativeJIT::compile(BasicBlock& block) ASSERT(m_variables.size() == block.variablesAtHead.numberOfLocals()); for (size_t i = 0; i < m_variables.size(); ++i) { NodeIndex nodeIndex = block.variablesAtHead.local(i); - if (nodeIndex == NoNode) + if (nodeIndex == NoNode || m_jit.graph().localIsCaptured(i)) m_variables[i] = ValueSource(ValueInRegisterFile); else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat()) m_variables[i] = ValueSource(DoubleInRegisterFile); @@ -955,12 +956,13 @@ void SpeculativeJIT::compile(BasicBlock& block) if (DFG_ENABLE_EDGE_CODE_VERIFICATION) { JITCompiler::Jump verificationSucceeded = - m_jit.branch32(JITCompiler::Equal, GPRInfo::regT0, Imm32(m_block)); + m_jit.branch32(JITCompiler::Equal, GPRInfo::regT0, TrustedImm32(m_block)); m_jit.breakpoint(); verificationSucceeded.link(&m_jit); } - for (; m_compileIndex < block.end; ++m_compileIndex) { + for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) { + m_compileIndex = block[m_indexInBlock]; Node& node = at(m_compileIndex); m_codeOriginForOSR = node.codeOrigin; if (!node.shouldGenerate()) { @@ -1005,7 +1007,6 @@ void SpeculativeJIT::compile(BasicBlock& block) compile(node); if (!m_compileOkay) { m_compileOkay = true; - m_compileIndex = block.end; clearGenerationInfo(); return; } @@ -1045,7 +1046,7 @@ void SpeculativeJIT::compile(BasicBlock& block) #endif // Make sure that the abstract state is rematerialized for the next node. - m_state.execute(m_compileIndex); + m_state.execute(m_indexInBlock); if (node.shouldGenerate()) checkConsistency(); @@ -1232,7 +1233,7 @@ bool SpeculativeJIT::compile() checkArgumentTypes(); if (DFG_ENABLE_EDGE_CODE_VERIFICATION) - m_jit.move(Imm32(0), GPRInfo::regT0); + m_jit.move(TrustedImm32(0), GPRInfo::regT0); ASSERT(!m_compileIndex); for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) @@ -1258,7 +1259,7 @@ void SpeculativeJIT::createOSREntries() } m_osrEntryHeads.append(m_jit.label()); - m_jit.move(Imm32(blockIndex), GPRInfo::regT0); + m_jit.move(TrustedImm32(blockIndex), GPRInfo::regT0); m_jit.jump().linkTo(m_blockHeads[blockIndex], &m_jit); } } @@ -2318,8 +2319,14 @@ void SpeculativeJIT::compileArithSub(Node& node) if (nodeCanTruncateInteger(node.arithNodeFlags())) { m_jit.move(op1.gpr(), result.gpr()); m_jit.sub32(Imm32(imm2), result.gpr()); - } else + } else { +#if ENABLE(JIT_CONSTANT_BLINDING) + GPRTemporary scratch(this); + speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr(), scratch.gpr())); +#else speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); +#endif + } integerResult(result.gpr(), m_compileIndex); return; @@ -2365,6 +2372,34 @@ void SpeculativeJIT::compileArithSub(Node& node) doubleResult(result.fpr(), m_compileIndex); } +void SpeculativeJIT::compileArithNegate(Node& node) +{ + if (m_jit.graph().negateShouldSpeculateInteger(node)) { + SpeculateIntegerOperand op1(this, node.child1()); + GPRTemporary result(this); + + m_jit.move(op1.gpr(), result.gpr()); + + if (nodeCanTruncateInteger(node.arithNodeFlags())) + m_jit.neg32(result.gpr()); + else { + speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr())); + if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) + speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, result.gpr())); + } + + integerResult(result.gpr(), m_compileIndex); + return; + } + + SpeculateDoubleOperand op1(this, node.child1()); + FPRTemporary result(this); + + m_jit.negateDouble(op1.fpr(), result.fpr()); + + doubleResult(result.fpr(), m_compileIndex); +} + void SpeculativeJIT::compileArithMul(Node& node) { if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) { @@ -2456,8 +2491,9 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSVal { JSValueOperand op1(this, value); - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); Node& branchNode = at(branchNodeIndex); BlockIndex taken = branchNode.takenBlockIndex(); BlockIndex notTaken = branchNode.notTakenBlockIndex(); @@ -2493,6 +2529,7 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSVal use(node.child1()); use(node.child2()); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; } @@ -2504,18 +2541,18 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSVal GPRReg resultGPR = result.gpr(); m_jit.move(MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(ValueFalse)), resultGPR); MacroAssembler::Jump notEqual = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant)))); - m_jit.or32(MacroAssembler::Imm32(1), resultGPR); + m_jit.or32(MacroAssembler::TrustedImm32(1), resultGPR); notEqual.link(&m_jit); jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean); #else GPRReg op1PayloadGPR = op1.payloadGPR(); GPRReg op1TagGPR = op1.tagGPR(); GPRReg resultGPR = result.gpr(); - m_jit.move(Imm32(0), resultGPR); + m_jit.move(TrustedImm32(0), resultGPR); MacroAssembler::JumpList notEqual; notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, MacroAssembler::Imm32(constant.tag()))); notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1PayloadGPR, MacroAssembler::Imm32(constant.payload()))); - m_jit.move(Imm32(1), resultGPR); + m_jit.move(TrustedImm32(1), resultGPR); notEqual.link(&m_jit); booleanResult(resultGPR, m_compileIndex); #endif @@ -2543,11 +2580,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node) // 2) If the operands are predicted integer, do an integer comparison. if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) { - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); compilePeepHoleIntegerBranch(node, branchNodeIndex, MacroAssembler::Equal); use(node.child1()); use(node.child2()); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; } @@ -2558,11 +2597,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node) // 3) If the operands are predicted double, do a double comparison. if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) { - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); compilePeepHoleDoubleBranch(node, branchNodeIndex, MacroAssembler::DoubleEqual); use(node.child1()); use(node.child2()); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; } @@ -2574,11 +2615,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node) // or array comparison. if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) { - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); compilePeepHoleObjectEquality(node, branchNodeIndex, &JSFinalObject::s_info, isFinalObjectPrediction); use(node.child1()); use(node.child2()); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; } @@ -2587,11 +2630,13 @@ bool SpeculativeJIT::compileStrictEq(Node& node) } if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) { - NodeIndex branchNodeIndex = detectPeepHoleBranch(); - if (branchNodeIndex != NoNode) { + unsigned branchIndexInBlock = detectPeepHoleBranch(); + if (branchIndexInBlock != UINT_MAX) { + NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock); compilePeepHoleObjectEquality(node, branchNodeIndex, &JSArray::s_info, isArrayPrediction); use(node.child1()); use(node.child2()); + m_indexInBlock = branchIndexInBlock; m_compileIndex = branchNodeIndex; return true; } @@ -2691,6 +2736,28 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node) storageResult(storageReg, m_compileIndex); } +void SpeculativeJIT::compileNewFunctionNoCheck(Node& node) +{ + GPRResult result(this); + GPRReg resultGPR = result.gpr(); + flushRegisters(); + callOperation( + operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex())); + cellResult(resultGPR, m_compileIndex); +} + +void SpeculativeJIT::compileNewFunctionExpression(Node& node) +{ + GPRResult result(this); + GPRReg resultGPR = result.gpr(); + flushRegisters(); + callOperation( + operationNewFunctionExpression, + resultGPR, + m_jit.codeBlock()->functionExpr(node.functionExprIndex())); + cellResult(resultGPR, m_compileIndex); +} + } } // namespace JSC::DFG #endif |