diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp | 152 |
1 files changed, 72 insertions, 80 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp index b5058e35a..9e468e758 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp @@ -492,7 +492,7 @@ void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node) jsValueResult(result.gpr(), m_compileIndex); } -void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) +void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) { JITCompiler::DataLabelPtr structureToCompare; JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1))); @@ -520,13 +520,9 @@ void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg PropertyAccessRecord( codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, loadWithPatch, slowPath.get(), doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR), - safeCast<int8_t>(scratchGPR), + usedRegisters(), spillMode == NeedToSpill ? PropertyAccessRecord::RegistersInUse : PropertyAccessRecord::RegistersFlushed)); addSlowPathGenerator(slowPath.release()); - - - if (scratchGPR != resultGPR && scratchGPR != InvalidGPRReg && spillMode == NeedToSpill) - unlock(scratchGPR); } void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg valueGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget) @@ -568,11 +564,15 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg slowCases, this, optimizedCall, NoResult, valueGPR, baseGPR, identifier(identifierNumber)); } + RegisterSet currentlyUsedRegisters = usedRegisters(); + currentlyUsedRegisters.clear(scratchGPR); + ASSERT(currentlyUsedRegisters.get(baseGPR)); + ASSERT(currentlyUsedRegisters.get(valueGPR)); m_jit.addPropertyAccess( PropertyAccessRecord( codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, JITCompiler::DataLabelCompact(storeWithPatch.label()), slowPath.get(), doneLabel, - safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR))); + safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), currentlyUsedRegisters)); addSlowPathGenerator(slowPath.release()); } @@ -2501,15 +2501,19 @@ void SpeculativeJIT::compile(Node& node) } case PutByVal: { - if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { + Edge child1 = m_jit.graph().varArgChild(node, 0); + Edge child2 = m_jit.graph().varArgChild(node, 1); + Edge child3 = m_jit.graph().varArgChild(node, 2); + + if (!at(child1).prediction() || !at(child2).prediction()) { terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); break; } - if (!at(node.child2()).shouldSpeculateInteger() || !isActionableMutableArraySpeculation(at(node.child1()).prediction())) { - JSValueOperand arg1(this, node.child1()); - JSValueOperand arg2(this, node.child2()); - JSValueOperand arg3(this, node.child3()); + if (!at(child2).shouldSpeculateInteger() || !isActionableMutableArraySpeculation(at(child1).prediction())) { + JSValueOperand arg1(this, child1); + JSValueOperand arg2(this, child2); + JSValueOperand arg3(this, child3); GPRReg arg1GPR = arg1.gpr(); GPRReg arg2GPR = arg2.gpr(); GPRReg arg3GPR = arg3.gpr(); @@ -2521,12 +2525,12 @@ void SpeculativeJIT::compile(Node& node) break; } - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - if (at(node.child1()).shouldSpeculateArguments()) { - JSValueOperand value(this, node.child3()); - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); + if (at(child1).shouldSpeculateArguments()) { + JSValueOperand value(this, child3); + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); GPRTemporary scratch(this); GPRTemporary scratch2(this); @@ -2539,9 +2543,9 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - if (!isArgumentsSpeculation(m_state.forNode(node.child1()).m_type)) { + if (!isArgumentsSpeculation(m_state.forNode(child1).m_type)) { speculationCheck( - BadType, JSValueSource::unboxedCell(baseReg), node.child1(), + BadType, JSValueSource::unboxedCell(baseReg), child1, m_jit.branchPtr( MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), @@ -2582,70 +2586,70 @@ void SpeculativeJIT::compile(Node& node) break; } - if (at(node.child1()).shouldSpeculateInt8Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt8Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt16Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt16Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt32Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt32Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint8Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8ClampedArray()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding); + if (at(child1).shouldSpeculateUint8ClampedArray()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding); break; } - if (at(node.child1()).shouldSpeculateUint16Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint16Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint32Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint32Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat32Array()) { - compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); + if (at(child1).shouldSpeculateFloat32Array()) { + compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat64Array()) { - compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); + if (at(child1).shouldSpeculateFloat64Array()) { + compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); if (!m_compileOkay) return; break; } - ASSERT(at(node.child1()).shouldSpeculateArray()); + ASSERT(at(child1).shouldSpeculateArray()); - JSValueOperand value(this, node.child3()); + JSValueOperand value(this, child3); GPRTemporary scratch(this); // Map base, property & value into registers, allocate a scratch register. @@ -2657,12 +2661,12 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - writeBarrier(baseReg, value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg); + writeBarrier(baseReg, value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg); // Check that base is an array, and that property is contained within m_vector (< m_vectorLength). // If we have predicted the base to be type array, we can skip the check. - if (!isArraySpeculation(m_state.forNode(node.child1()).m_type)) - speculationCheck(BadType, JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); + if (!isArraySpeculation(m_state.forNode(child1).m_type)) + speculationCheck(BadType, JSValueRegs(baseReg), child1, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); base.use(); property.use(); @@ -2701,88 +2705,92 @@ void SpeculativeJIT::compile(Node& node) } case PutByValAlias: { - if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { + Edge child1 = m_jit.graph().varArgChild(node, 0); + Edge child2 = m_jit.graph().varArgChild(node, 1); + Edge child3 = m_jit.graph().varArgChild(node, 2); + + if (!at(child1).prediction() || !at(child2).prediction()) { terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); break; } - ASSERT(isActionableMutableArraySpeculation(at(node.child1()).prediction())); - ASSERT(at(node.child2()).shouldSpeculateInteger()); + ASSERT(isActionableMutableArraySpeculation(at(child1).prediction())); + ASSERT(at(child2).shouldSpeculateInteger()); - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - if (at(node.child1()).shouldSpeculateInt8Array()) { + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); + if (at(child1).shouldSpeculateInt8Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt16Array()) { + if (at(child1).shouldSpeculateInt16Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt32Array()) { + if (at(child1).shouldSpeculateInt32Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8Array()) { + if (at(child1).shouldSpeculateUint8Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8ClampedArray()) { + if (at(child1).shouldSpeculateUint8ClampedArray()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray, ClampRounding); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint16Array()) { + if (at(child1).shouldSpeculateUint16Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint32Array()) { + if (at(child1).shouldSpeculateUint32Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat32Array()) { + if (at(child1).shouldSpeculateFloat32Array()) { compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat64Array()) { + if (at(child1).shouldSpeculateFloat64Array()) { compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck); if (!m_compileOkay) return; break; } - ASSERT(at(node.child1()).shouldSpeculateArray()); + ASSERT(at(child1).shouldSpeculateArray()); - JSValueOperand value(this, node.child3()); + JSValueOperand value(this, child3); GPRTemporary scratch(this); GPRReg baseReg = base.gpr(); GPRReg scratchReg = scratch.gpr(); - writeBarrier(base.gpr(), value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg); + writeBarrier(base.gpr(), value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg); // Get the array storage. GPRReg storageReg = scratchReg; @@ -3319,16 +3327,10 @@ void SpeculativeJIT::compile(Node& node) GPRReg baseGPR = base.gpr(); GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR; - - if (resultGPR == baseGPR) - scratchGPR = tryAllocate(); - else - scratchGPR = resultGPR; base.use(); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber()); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber()); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3339,18 +3341,12 @@ void SpeculativeJIT::compile(Node& node) GPRReg baseGPR = base.gpr(); GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR; - - if (resultGPR == baseGPR) - scratchGPR = tryAllocate(); - else - scratchGPR = resultGPR; base.use(); JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); @@ -3371,13 +3367,11 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR = selectScratchGPR(baseGPR, resultGPR); - base.use(); flushRegisters(); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3389,14 +3383,12 @@ void SpeculativeJIT::compile(Node& node) GPRResult result(this); GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR = selectScratchGPR(baseGPR, resultGPR); - base.use(); flushRegisters(); JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell, DontSpill); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell, DontSpill); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); |