diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index f17e2d7e4..6c6615716 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -119,11 +119,8 @@ JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind) return speculationWatchpoint(kind, JSValueSource(), NoNode); } -void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery) +void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecovery) { - ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes); - speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail); - #if !ASSERT_DISABLED if (!valueRecovery) { // Check that the preceding node was a SetLocal with the same code origin. @@ -155,6 +152,10 @@ void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValu ASSERT(setLocal->codeOrigin == at(m_compileIndex).codeOrigin); Node* nextNode = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock + 1)); + if (nextNode->op() == Jump && nextNode->codeOrigin == at(m_compileIndex).codeOrigin) { + // We're at an inlined return. Use a backward speculation instead. + return; + } ASSERT(nextNode->codeOrigin != at(m_compileIndex).codeOrigin); OSRExit& exit = m_jit.codeBlock()->lastOSRExit(); @@ -167,6 +168,28 @@ void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValu new ValueRecoveryOverride(setLocal->local(), valueRecovery)); } +JumpReplacementWatchpoint* SpeculativeJIT::forwardSpeculationWatchpoint(ExitKind kind) +{ + JumpReplacementWatchpoint* result = speculationWatchpoint(kind); + convertLastOSRExitToForward(); + return result; +} + +JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpointWithConditionalDirection(ExitKind kind, bool isForward) +{ + JumpReplacementWatchpoint* result = speculationWatchpoint(kind); + if (isForward) + convertLastOSRExitToForward(); + return result; +} + +void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery) +{ + ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes); + speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail); + convertLastOSRExitToForward(valueRecovery); +} + void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery) { ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes); @@ -246,6 +269,24 @@ void SpeculativeJIT::clearGenerationInfo() m_fprs = RegisterBank<FPRInfo>(); } +void SpeculativeJIT::speculateArray(Edge edge, GPRReg baseReg) +{ + AbstractValue& arrayValue = m_state.forNode(edge); + if (arrayValue.m_currentKnownStructure.hasSingleton() + && arrayValue.m_currentKnownStructure.singleton()->classInfo() == &JSArray::s_info) + return; + + GPRTemporary temp(this); + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSCell::structureOffset()), temp.gpr()); + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branchPtr( + MacroAssembler::NotEqual, + MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()), + MacroAssembler::TrustedImmPtr(&JSArray::s_info))); +} + GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex) { Node& node = m_jit.graph()[nodeIndex]; @@ -1220,7 +1261,7 @@ void SpeculativeJIT::compile(BasicBlock& block) valueSource = ValueSource(DoubleInRegisterFile); else if (isInt32Speculation(argumentPosition.prediction())) valueSource = ValueSource(Int32InRegisterFile); - else if (isArraySpeculation(argumentPosition.prediction()) || isCellSpeculation(argumentPosition.prediction())) + else if (isCellSpeculation(argumentPosition.prediction())) valueSource = ValueSource(CellInRegisterFile); else if (isBooleanSpeculation(argumentPosition.prediction())) valueSource = ValueSource(BooleanInRegisterFile); @@ -1343,12 +1384,7 @@ void SpeculativeJIT::checkArgumentTypes() #if USE(JSVALUE64) if (isInt32Speculation(predictedType)) speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister)); - else if (isArraySpeculation(predictedType)) { - GPRTemporary temp(this); - m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr()); - speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister)); - speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); - } else if (isBooleanSpeculation(predictedType)) { + else if (isBooleanSpeculation(predictedType)) { GPRTemporary temp(this); m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr()); m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), temp.gpr()); @@ -1403,13 +1439,7 @@ void SpeculativeJIT::checkArgumentTypes() #else if (isInt32Speculation(predictedType)) speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag))); - else if (isArraySpeculation(predictedType)) { - GPRTemporary temp(this); - m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr()); - speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag))); - m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr()); - speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); - } else if (isBooleanSpeculation(predictedType)) + else if (isBooleanSpeculation(predictedType)) speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag))); else if (isInt8ArraySpeculation(predictedType)) { GPRTemporary temp(this); @@ -1591,7 +1621,6 @@ void SpeculativeJIT::compileGetByValOnString(Node& node) GPRReg storageReg = storage.gpr(); if (!isStringSpeculation(m_state.forNode(node.child1()).m_type)) { - ASSERT(!(at(node.child1()).prediction() & SpecString)); terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); noResult(m_compileIndex); return; @@ -3037,22 +3066,12 @@ bool SpeculativeJIT::compileStrictEq(Node& node) void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node) { - if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) { - terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); - return; - } + ASSERT(at(node.child1()).prediction()); + ASSERT(at(node.child2()).shouldSpeculateInteger()); SpeculateCellOperand base(this, node.child1()); GPRReg baseReg = base.gpr(); - SpeculatedType basePrediction = at(node.child2()).prediction(); - if (!(basePrediction & SpecInt32) && basePrediction) { - ASSERT_NOT_REACHED(); - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); - noResult(m_compileIndex); - return; - } - GPRTemporary storage(this); GPRReg storageReg = storage.gpr(); if (at(node.child1()).shouldSpeculateArguments()) { @@ -3113,8 +3132,7 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node) speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo))); m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg); } else { - if (!isArraySpeculation(m_state.forNode(node.child1()).m_type)) - speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); + speculateArray(node.child1(), baseReg); m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg); } storageResult(storageReg, m_compileIndex); |