diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp | 103 |
1 files changed, 38 insertions, 65 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp index da6583c70..7b43c5cfc 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp @@ -1062,7 +1062,7 @@ void SpeculativeJIT::emitCall(Node& node) } template<bool strict> -GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat) +GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat, SpeculationDirection direction) { #if DFG_ENABLE(DEBUG_VERBOSE) dataLogF("SpecInt@%d ", nodeIndex); @@ -1075,7 +1075,7 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& switch (info.registerFormat()) { case DataFormatNone: { if ((node.hasConstant() && !isInt32Constant(nodeIndex)) || info.spillFormat() == DataFormatDouble) { - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); returnFormat = DataFormatInteger; return allocate(); } @@ -1126,7 +1126,7 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& GPRReg gpr = info.gpr(); m_gprs.lock(gpr); if (!isInt32Speculation(type)) - speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister)); + speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister), direction); info.fillJSValue(*m_stream, gpr, DataFormatJSInteger); // If !strict we're done, return. if (!strict) { @@ -1183,7 +1183,7 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& case DataFormatBoolean: case DataFormatJSCell: case DataFormatJSBoolean: { - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); returnFormat = DataFormatInteger; return allocate(); } @@ -1197,20 +1197,20 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& } } -GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat) +GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat, SpeculationDirection direction) { - return fillSpeculateIntInternal<false>(nodeIndex, returnFormat); + return fillSpeculateIntInternal<false>(nodeIndex, returnFormat, direction); } GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex) { DataFormat mustBeDataFormatInteger; - GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger); + GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger, BackwardSpeculation); ASSERT(mustBeDataFormatInteger == DataFormatInteger); return result; } -FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) +FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirection direction) { #if DFG_ENABLE(DEBUG_VERBOSE) dataLogF("SpecDouble@%d ", nodeIndex); @@ -1244,7 +1244,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) info.fillDouble(*m_stream, fpr); return fpr; } - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return fprAllocate(); } @@ -1287,7 +1287,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) ASSERT_NOT_REACHED(); case DataFormatCell: - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return fprAllocate(); case DataFormatJSCell: @@ -1301,7 +1301,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); if (!isNumberSpeculation(type)) - speculationCheck(BadType, JSValueRegs(jsValueGpr), nodeIndex, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister)); + speculationCheck(BadType, JSValueRegs(jsValueGpr), nodeIndex, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister), direction); // First, if we get here we have a double encoded as a JSValue m_jit.move(jsValueGpr, tempGpr); @@ -1364,7 +1364,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) } } -GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpeculation) +GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirection direction) { #if DFG_ENABLE(DEBUG_VERBOSE) dataLogF("SpecCell@%d ", nodeIndex); @@ -1377,7 +1377,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpec switch (info.registerFormat()) { case DataFormatNone: { if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) { - terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return allocate(); } @@ -1391,7 +1391,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpec info.fillJSValue(*m_stream, gpr, DataFormatJSCell); return gpr; } - terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return gpr; } ASSERT(info.spillFormat() & DataFormatJS); @@ -1400,7 +1400,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpec info.fillJSValue(*m_stream, gpr, DataFormatJS); if (!isCellSpeculation(type)) - speculationCheckWithConditionalDirection(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), isForwardSpeculation); + speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction); info.fillJSValue(*m_stream, gpr, DataFormatJSCell); return gpr; } @@ -1416,7 +1416,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpec GPRReg gpr = info.gpr(); m_gprs.lock(gpr); if (!isCellSpeculation(type)) - speculationCheckWithConditionalDirection(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), isForwardSpeculation); + speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction); info.fillJSValue(*m_stream, gpr, DataFormatJSCell); return gpr; } @@ -1427,7 +1427,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpec case DataFormatDouble: case DataFormatJSBoolean: case DataFormatBoolean: { - terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return allocate(); } @@ -1440,7 +1440,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpec } } -GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) +GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDirection direction) { #if DFG_ENABLE(DEBUG_VERBOSE) dataLogF("SpecBool@%d ", nodeIndex); @@ -1453,7 +1453,7 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) switch (info.registerFormat()) { case DataFormatNone: { if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) { - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return allocate(); } @@ -1467,7 +1467,7 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean); return gpr; } - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return gpr; } ASSERT(info.spillFormat() & DataFormatJS); @@ -1477,7 +1477,7 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) info.fillJSValue(*m_stream, gpr, DataFormatJS); if (!isBooleanSpeculation(type)) { m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); - speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg)); + speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction); m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); } info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean); @@ -1496,7 +1496,7 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) m_gprs.lock(gpr); if (!isBooleanSpeculation(type)) { m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); - speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg)); + speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction); m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr); } info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean); @@ -1509,7 +1509,7 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) case DataFormatDouble: case DataFormatJSCell: case DataFormatCell: { - terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); + terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction); return allocate(); } @@ -2219,39 +2219,9 @@ void SpeculativeJIT::compile(Node& node) // stack. compileMovHint(node); - // As far as OSR is concerned, we're on the bytecode index corresponding - // to the *next* instruction, since we've already "executed" the - // SetLocal and whatever other DFG Nodes are associated with the same - // bytecode index as the SetLocal. - ASSERT(m_codeOriginForOSR == node.codeOrigin); - Node* nextNode = &at(block()->at(m_indexInBlock + 1)); - - // But even more oddly, we need to be super careful about the following - // sequence: - // - // a: Foo() - // b: SetLocal(@a) - // c: Flush(@b) - // - // This next piece of crazy takes care of this. - if (nextNode->op() == Flush && nextNode->child1() == m_compileIndex) - nextNode = &at(block()->at(m_indexInBlock + 2)); - - // Oddly, it's possible for the bytecode index for the next node to be - // equal to ours. This will happen for op_post_inc. And, even more oddly, - // this is just fine. Ordinarily, this wouldn't be fine, since if the - // next node failed OSR then we'd be OSR-ing with this SetLocal's local - // variable already set even though from the standpoint of the old JIT, - // this SetLocal should not have executed. But for op_post_inc, it's just - // fine, because this SetLocal's local (i.e. the LHS in a x = y++ - // statement) would be dead anyway - so the fact that DFG would have - // already made the assignment, and baked it into the stack during - // OSR exit, would not be visible to the old JIT in any way. - m_codeOriginForOSR = nextNode->codeOrigin; - if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) { if (node.variableAccessData()->shouldUseDoubleFormat()) { - SpeculateDoubleOperand value(this, node.child1()); + SpeculateDoubleOperand value(this, node.child1(), ForwardSpeculation); m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); // Indicate that it's no longer necessary to retrieve the value of @@ -2263,14 +2233,14 @@ void SpeculativeJIT::compile(Node& node) SpeculatedType predictedType = node.variableAccessData()->argumentAwarePrediction(); if (isInt32Speculation(predictedType)) { - SpeculateIntegerOperand value(this, node.child1()); + SpeculateIntegerOperand value(this, node.child1(), ForwardSpeculation); m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local())); noResult(m_compileIndex); recordSetLocal(node.local(), ValueSource(Int32InJSStack)); break; } if (isCellSpeculation(predictedType)) { - SpeculateCellOperand cell(this, node.child1()); + SpeculateCellOperand cell(this, node.child1(), ForwardSpeculation); GPRReg cellGPR = cell.gpr(); m_jit.store64(cellGPR, JITCompiler::addressFor(node.local())); noResult(m_compileIndex); @@ -2278,7 +2248,7 @@ void SpeculativeJIT::compile(Node& node) break; } if (isBooleanSpeculation(predictedType)) { - SpeculateBooleanOperand boolean(this, node.child1()); + SpeculateBooleanOperand boolean(this, node.child1(), ForwardSpeculation); m_jit.store64(boolean.gpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); recordSetLocal(node.local(), ValueSource(BooleanInJSStack)); @@ -4110,7 +4080,8 @@ void SpeculativeJIT::compile(Node& node) break; } - SpeculateCellOperand base(this, node.child1(), node.op() == ForwardCheckStructure); + SpeculationDirection direction = node.op() == ForwardCheckStructure ? ForwardSpeculation : BackwardSpeculation; + SpeculateCellOperand base(this, node.child1(), direction); ASSERT(node.structureSet().size()); @@ -4121,13 +4092,13 @@ void SpeculativeJIT::compile(Node& node) exitKind = BadCache; if (node.structureSet().size() == 1) { - speculationCheckWithConditionalDirection( + speculationCheck( exitKind, JSValueRegs(base.gpr()), NoNode, m_jit.branchWeakPtr( JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), node.structureSet()[0]), - node.op() == ForwardCheckStructure); + direction); } else { GPRTemporary structure(this); @@ -4138,11 +4109,11 @@ void SpeculativeJIT::compile(Node& node) for (size_t i = 0; i < node.structureSet().size() - 1; ++i) done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node.structureSet()[i])); - speculationCheckWithConditionalDirection( + speculationCheck( exitKind, JSValueRegs(base.gpr()), NoNode, m_jit.branchWeakPtr( JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()), - node.op() == ForwardCheckStructure); + direction); done.link(&m_jit); } @@ -4160,14 +4131,16 @@ void SpeculativeJIT::compile(Node& node) // we'll just rely on the fact that when a watchpoint fires then that's // quite a hint already. + SpeculationDirection direction = node.op() == ForwardStructureTransitionWatchpoint ? ForwardSpeculation : BackwardSpeculation; + m_jit.addWeakReference(node.structure()); node.structure()->addTransitionWatchpoint( - speculationWatchpointWithConditionalDirection( + speculationWatchpoint( m_jit.graph()[node.child1()].op() == WeakJSConstant ? BadWeakConstantCache : BadCache, - node.op() == ForwardStructureTransitionWatchpoint)); + direction)); #if !ASSERT_DISABLED - SpeculateCellOperand op1(this, node.child1()); + SpeculateCellOperand op1(this, node.child1(), direction); JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node.structure())); m_jit.breakpoint(); isOK.link(&m_jit); |