diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h | 2070 |
1 files changed, 1470 insertions, 600 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h index 3534c7b15..94f54143f 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2011-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,10 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DFGSpeculativeJIT_h -#define DFGSpeculativeJIT_h - -#include <wtf/Platform.h> +#pragma once #if ENABLE(DFG_JIT) @@ -38,9 +35,12 @@ #include "DFGOSRExitJumpPlaceholder.h" #include "DFGSilentRegisterSavePlan.h" #include "DFGValueSource.h" +#include "JITMathIC.h" #include "JITOperations.h" #include "MarkedAllocator.h" #include "PutKind.h" +#include "SpillRegistersMode.h" +#include "StructureStubInfo.h" #include "ValueRecovery.h" #include "VirtualRegister.h" @@ -56,15 +56,7 @@ class SpeculateDoubleOperand; class SpeculateCellOperand; class SpeculateBooleanOperand; -enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandDouble, GeneratedOperandJSValue}; - -inline GPRReg extractResult(GPRReg result) { return result; } -#if USE(JSVALUE64) -inline GPRReg extractResult(JSValueRegs result) { return result.gpr(); } -#else -inline JSValueRegs extractResult(JSValueRegs result) { return result; } -#endif -inline NoResultTag extractResult(NoResultTag) { return NoResult; } +enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandJSValue}; // === SpeculativeJIT === // @@ -77,11 +69,12 @@ inline NoResultTag extractResult(NoResultTag) { return NoResult; } // to propagate type information (including information that has // only speculatively been asserted) through the dataflow. class SpeculativeJIT { + WTF_MAKE_FAST_ALLOCATED; + friend struct OSRExit; private: typedef JITCompiler::TrustedImm32 TrustedImm32; typedef JITCompiler::Imm32 Imm32; - typedef JITCompiler::TrustedImmPtr TrustedImmPtr; typedef JITCompiler::ImmPtr ImmPtr; typedef JITCompiler::TrustedImm64 TrustedImm64; typedef JITCompiler::Imm64 Imm64; @@ -118,7 +111,66 @@ public: SpeculativeJIT(JITCompiler&); ~SpeculativeJIT(); + struct TrustedImmPtr { + template <typename T> + explicit TrustedImmPtr(T* value) + : m_value(value) + { + static_assert(!std::is_base_of<HeapCell, T>::value, "To use a GC pointer, the graph must be aware of it. Use SpeculativeJIT::TrustedImmPtr::weakPointer instead."); + } + + explicit TrustedImmPtr(RegisteredStructure structure) + : m_value(structure.get()) + { } + + // This is only here so that TrustedImmPtr(0) does not confuse the C++ + // overload handling rules. + explicit TrustedImmPtr(int value) + : m_value(value) + { + ASSERT(!value); + } + + explicit TrustedImmPtr(std::nullptr_t) + : m_value(0) + { } + + explicit TrustedImmPtr(FrozenValue* value) + { + RELEASE_ASSERT(value->value().isCell()); + m_value = MacroAssembler::TrustedImmPtr(value->cell()); + } + + explicit TrustedImmPtr(size_t value) + : m_value(bitwise_cast<void*>(value)) + { + } + + static TrustedImmPtr weakPointer(Graph& graph, JSCell* cell) + { + // There are weird relationships in how optimized CodeBlocks + // point to other CodeBlocks. We don't want to have them be + // part of the weak pointer set. For example, an optimized CodeBlock + // having a weak pointer to itself will cause it to get collected. + ASSERT(!jsDynamicCast<CodeBlock*>(graph.m_vm, cell)); + + graph.m_plan.weakReferences.addLazily(cell); + return TrustedImmPtr(bitwise_cast<size_t>(cell)); + } + + operator MacroAssembler::TrustedImmPtr() const { return m_value; } + + intptr_t asIntptr() + { + return m_value.asIntptr(); + } + + private: + MacroAssembler::TrustedImmPtr m_value; + }; + bool compile(); + void createOSREntries(); void linkOSREntries(LinkBuffer&); @@ -161,7 +213,11 @@ public: // and its machine registers may be reused. bool canReuse(Node* node) { - return generationInfo(node).canReuse(); + return generationInfo(node).useCount() == 1; + } + bool canReuse(Node* nodeA, Node* nodeB) + { + return nodeA == nodeB && generationInfo(nodeA).useCount() == 2; } bool canReuse(Edge nodeUse) { @@ -189,7 +245,6 @@ public: if (spillMe.isValid()) { #if USE(JSVALUE32_64) GenerationInfo& info = generationInfoFromVirtualRegister(spillMe); - RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble); if ((info.registerFormat() & DataFormatJS)) m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR()); #endif @@ -264,7 +319,7 @@ public: else if (registerFormat != DataFormatNone) m_gprs.release(info.gpr()); #elif USE(JSVALUE32_64) - if (registerFormat == DataFormatDouble || registerFormat == DataFormatJSDouble) + if (registerFormat == DataFormatDouble) m_fprs.release(info.fpr()); else if (registerFormat & DataFormatJS) { m_gprs.release(info.tagGPR()); @@ -286,22 +341,9 @@ public: } bool masqueradesAsUndefinedWatchpointIsStillValid() { - return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode->codeOrigin); + return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode->origin.semantic); } -#if ENABLE(GGC) - void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2); - void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2); - - static JITCompiler::Jump genericWriteBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2); - static JITCompiler::Jump genericWriteBarrier(CCallHelpers& jit, JSCell* owner); - static void osrWriteBarrier(CCallHelpers&, GPRReg owner, GPRReg scratch1, GPRReg scratch2); - void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2); - void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2); - - void writeBarrier(GPRReg owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2); - void writeBarrier(JSCell* owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2); -#endif void compileStoreBarrier(Node*); static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg) @@ -319,12 +361,13 @@ public: GPRReg fillSpeculateBoolean(Edge); GeneratedOperandType checkGeneratedTypeForToInt32(Node*); - void addSlowPathGenerator(PassOwnPtr<SlowPathGenerator>); - void runSlowPathGenerators(); + void addSlowPathGenerator(std::unique_ptr<SlowPathGenerator>); + void addSlowPathGenerator(std::function<void()>); + void runSlowPathGenerators(PCToCodeOriginMapBuilder&); void compile(Node*); void noticeOSRBirth(Node*); - void bail(); + void bail(AbortReason); void compileCurrentBlock(); void checkArgumentTypes(); @@ -340,7 +383,22 @@ public: SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source); void silentSpill(const SilentRegisterSavePlan&); void silentFill(const SilentRegisterSavePlan&, GPRReg canTrample); - + + template<typename CollectionType> + void silentSpill(const CollectionType& savePlans) + { + for (unsigned i = 0; i < savePlans.size(); ++i) + silentSpill(savePlans[i]); + } + + template<typename CollectionType> + void silentFill(const CollectionType& savePlans, GPRReg exclude = InvalidGPRReg) + { + GPRReg canTrample = SpeculativeJIT::pickCanTrample(exclude); + for (unsigned i = savePlans.size(); i--;) + silentFill(savePlans[i], canTrample); + } + template<typename CollectionType> void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg) { @@ -373,13 +431,15 @@ public: { silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, exclude); } -#if USE(JSVALUE32_64) template<typename CollectionType> void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, JSValueRegs exclude) { +#if USE(JSVALUE32_64) silentSpillAllRegistersImpl(doSpill, plans, exclude.tagGPR(), exclude.payloadGPR()); - } +#else + silentSpillAllRegistersImpl(doSpill, plans, exclude.gpr()); #endif + } void silentSpillAllRegisters(GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg) { @@ -389,6 +449,14 @@ public: { silentSpillAllRegisters(InvalidGPRReg, InvalidGPRReg, exclude); } + void silentSpillAllRegisters(JSValueRegs exclude) + { +#if USE(JSVALUE64) + silentSpillAllRegisters(exclude.payloadGPR()); +#else + silentSpillAllRegisters(exclude.payloadGPR(), exclude.tagGPR()); +#endif + } static GPRReg pickCanTrample(GPRReg exclude) { @@ -406,7 +474,12 @@ public: return GPRInfo::regT0; } -#if USE(JSVALUE32_64) +#if USE(JSVALUE64) + static GPRReg pickCanTrample(JSValueRegs exclude) + { + return pickCanTrample(exclude.payloadGPR()); + } +#else static GPRReg pickCanTrample(JSValueRegs exclude) { GPRReg result = GPRInfo::regT0; @@ -441,9 +514,9 @@ public: { return m_jit.boxDouble(fpr, gpr); } - FPRReg unboxDouble(GPRReg gpr, FPRReg fpr) + FPRReg unboxDouble(GPRReg gpr, GPRReg resultGPR, FPRReg fpr) { - return m_jit.unboxDouble(gpr, fpr); + return m_jit.unboxDouble(gpr, resultGPR, fpr); } GPRReg boxDouble(FPRReg fpr) { @@ -461,6 +534,10 @@ public: m_jit.unboxDouble(tagGPR, payloadGPR, fpr, scratchFPR); } #endif + void boxDouble(FPRReg fpr, JSValueRegs regs) + { + m_jit.boxDouble(fpr, regs); + } // Spill a VirtualRegister to the JSStack. void spill(VirtualRegister spillMe) @@ -530,11 +607,10 @@ public: return; } - case DataFormatDouble: - case DataFormatJSDouble: { + case DataFormatDouble: { // On JSVALUE32_64 boxing a double is a no-op. m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe)); - info.spill(*m_stream, spillMe, DataFormatJSDouble); + info.spill(*m_stream, spillMe, DataFormatDouble); return; } @@ -549,37 +625,15 @@ public: } } - bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); } + bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32Only); } bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); } - bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); } + bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32Only); } bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); } bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); } + bool isKnownNotOther(Node* node) { return !(m_state.forNode(node).m_type & SpecOther); } - // Checks/accessors for constant values. - bool isConstant(Node* node) { return m_jit.graph().isConstant(node); } - bool isJSConstant(Node* node) { return m_jit.graph().isJSConstant(node); } - bool isInt32Constant(Node* node) { return m_jit.graph().isInt32Constant(node); } - bool isDoubleConstant(Node* node) { return m_jit.graph().isDoubleConstant(node); } - bool isNumberConstant(Node* node) { return m_jit.graph().isNumberConstant(node); } - bool isBooleanConstant(Node* node) { return m_jit.graph().isBooleanConstant(node); } - bool isFunctionConstant(Node* node) { return m_jit.graph().isFunctionConstant(node); } - int32_t valueOfInt32Constant(Node* node) { return m_jit.graph().valueOfInt32Constant(node); } - double valueOfNumberConstant(Node* node) { return m_jit.graph().valueOfNumberConstant(node); } -#if USE(JSVALUE32_64) - void* addressOfDoubleConstant(Node* node) { return m_jit.addressOfDoubleConstant(node); } -#endif - JSValue valueOfJSConstant(Node* node) { return m_jit.graph().valueOfJSConstant(node); } - bool valueOfBooleanConstant(Node* node) { return m_jit.graph().valueOfBooleanConstant(node); } - JSFunction* valueOfFunctionConstant(Node* node) { return m_jit.graph().valueOfFunctionConstant(node); } - bool isNullConstant(Node* node) - { - if (!isConstant(node)) - return false; - return valueOfJSConstant(node).isNull(); - } - - StringImpl* identifierUID(unsigned index) + UniquedStringImpl* identifierUID(unsigned index) { return m_jit.graph().identifiers()[index]; } @@ -601,7 +655,6 @@ public: } } -#ifndef NDEBUG // Used to ASSERT flushRegisters() has been called prior to // calling out from JIT code to a C helper function. bool isFlushed() @@ -616,12 +669,11 @@ public: } return true; } -#endif #if USE(JSVALUE64) - MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node) + static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node) { - return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(node))); + return MacroAssembler::Imm64(JSValue::encode(node->asJSValue())); } #endif @@ -706,28 +758,30 @@ public: } // Check if the lastNode is a branch on this node. - Node* lastNode = m_block->last(); + Node* lastNode = m_block->terminal(); return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX; } void compileMovHint(Node*); void compileMovHintAndCheck(Node*); + void cachedGetById(CodeOrigin, JSValueRegs base, JSValueRegs result, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill, AccessType = AccessType::Get); + #if USE(JSVALUE64) - void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); - void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); + void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill, AccessType = AccessType::Get); + void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); #elif USE(JSVALUE32_64) - void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); - void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); + void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill, AccessType = AccessType::Get); + void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); #endif - + + void compileDeleteById(Node*); + void compileDeleteByVal(Node*); + void compileTryGetById(Node*); void compileIn(Node*); - void compileBaseValueStoreBarrier(Edge& baseEdge, Edge& valueEdge); - - void nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert = false); - void nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert = false); - bool nonSpeculativeCompareNull(Node*, Edge operand, bool invert = false); + void nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand); + void nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode); void nonSpeculativePeepholeBranch(Node*, Node* branchNode, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction); void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction); @@ -737,58 +791,18 @@ public: void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false); bool nonSpeculativeStrictEq(Node*, bool invert = false); - void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg); + void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg); void compileInstanceOf(Node*); - - ptrdiff_t calleeFrameOffset(int numArgs) - { - return virtualRegisterForLocal(m_jit.graph().m_nextMachineLocal + JSStack::CallFrameHeaderSize + numArgs).offset() * sizeof(Register); - } - - // Access to our fixed callee CallFrame. - MacroAssembler::Address calleeFrameSlot(int numArgs, int slot) - { - return MacroAssembler::Address(GPRInfo::callFrameRegister, calleeFrameOffset(numArgs) + sizeof(Register) * slot); - } - - // Access to our fixed callee CallFrame. - MacroAssembler::Address calleeArgumentSlot(int numArgs, int argument) - { - return calleeFrameSlot(numArgs, virtualRegisterForArgument(argument).offset()); - } - - MacroAssembler::Address calleeFrameTagSlot(int numArgs, int slot) - { - return calleeFrameSlot(numArgs, slot).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); - } + void compileInstanceOfCustom(Node*); - MacroAssembler::Address calleeFramePayloadSlot(int numArgs, int slot) - { - return calleeFrameSlot(numArgs, slot).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); - } - - MacroAssembler::Address calleeArgumentTagSlot(int numArgs, int argument) - { - return calleeArgumentSlot(numArgs, argument).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); - } - - MacroAssembler::Address calleeArgumentPayloadSlot(int numArgs, int argument) - { - return calleeArgumentSlot(numArgs, argument).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); - } - - MacroAssembler::Address calleeFrameCallerFrame(int numArgs) - { - return calleeFrameSlot(numArgs, 0).withOffset(CallFrame::callerFrameOffset()); - } + void compileIsCellWithType(Node*); + void compileIsTypedArrayView(Node*); void emitCall(Node*); - - int32_t framePointerOffsetToGetActivationRegisters() - { - return m_jit.codeBlock()->framePointerOffsetToGetActivationRegisters( - m_jit.graph().m_machineCaptureStart); - } + + void emitAllocateButterfly(GPRReg storageGPR, GPRReg sizeGPR, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, MacroAssembler::JumpList& slowCases); + void emitInitializeButterfly(GPRReg storageGPR, GPRReg sizeGPR, JSValueRegs emptyValueRegs, GPRReg scratchGPR); + void compileAllocateNewArrayWithSize(JSGlobalObject*, GPRReg resultGPR, GPRReg sizeGPR, IndexingType, bool shouldConvertLargeSizeToArrayStorage = true); // Called once a node has completed code generation but prior to setting // its result, to free up its children. (This must happen prior to setting @@ -860,15 +874,20 @@ public: GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); info.initCell(node, node->refCount(), reg); } - void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren) + void blessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren) { - if (mode == CallUseChildren) - useChildren(node); - - VirtualRegister virtualRegister = node->virtualRegister(); - m_gprs.retain(reg, virtualRegister, SpillOrderBoolean); - GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); - info.initBoolean(node, node->refCount(), reg); +#if USE(JSVALUE64) + jsValueResult(reg, node, DataFormatJSBoolean, mode); +#else + booleanResult(reg, node, mode); +#endif + } + void unblessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren) + { +#if USE(JSVALUE64) + blessBoolean(reg); +#endif + blessedBooleanResult(reg, node, mode); } #if USE(JSVALUE64) void jsValueResult(GPRReg reg, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren) @@ -889,6 +908,16 @@ public: jsValueResult(reg, node, DataFormatJS, mode); } #elif USE(JSVALUE32_64) + void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren) + { + if (mode == CallUseChildren) + useChildren(node); + + VirtualRegister virtualRegister = node->virtualRegister(); + m_gprs.retain(reg, virtualRegister, SpillOrderBoolean); + GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); + info.initBoolean(node, node->refCount(), reg); + } void jsValueResult(GPRReg tag, GPRReg payload, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren) { if (mode == CallUseChildren) @@ -905,6 +934,14 @@ public: jsValueResult(tag, payload, node, DataFormatJS, mode); } #endif + void jsValueResult(JSValueRegs regs, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren) + { +#if USE(JSVALUE64) + jsValueResult(regs.gpr(), node, format, mode); +#else + jsValueResult(regs.tagGPR(), regs.payloadGPR(), node, format, mode); +#endif + } void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren) { if (mode == CallUseChildren) @@ -927,7 +964,7 @@ public: } void initConstantInfo(Node* node) { - ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node)); + ASSERT(node->hasConstant()); generationInfo(node).initConstant(node, node->refCount()); } @@ -937,186 +974,292 @@ public: // machine registers, and delegate the calling convention specific // decision as to how to fill the regsiters to setupArguments* methods. + JITCompiler::Call callOperation(V_JITOperation_E operation) + { + m_jit.setupArgumentsExecState(); + return appendCall(operation); + } JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result) { m_jit.setupArgumentsExecState(); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_EC operation, GPRReg result, GPRReg cell) { m_jit.setupArgumentsWithExecState(cell); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(Jss_JITOperation_EJssUi operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_EO operation, GPRReg result, GPRReg object) { m_jit.setupArgumentsWithExecState(object); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_EOS operation, GPRReg result, GPRReg object, size_t size) { m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size) { m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size) { m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(static_cast<size_t>(size))); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_EPS operation, GPRReg result, GPRReg old, size_t size) { m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EPUi operation, GPRReg result, void* arg1, uint32_t arg2) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), TrustedImm32(arg2)); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_ES operation, GPRReg result, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_ESJss operation, GPRReg result, size_t index, GPRReg arg1) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(index), arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, Structure* structure) + JITCompiler::Call callOperation(Z_JITOperation_EOI operation, GPRReg result, GPRReg obj, GPRReg impl) + { + m_jit.setupArgumentsWithExecState(obj, impl); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, RegisteredStructure structure) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2) + JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, RegisteredStructure structure, GPRReg arg2, GPRReg arg3) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2, arg3); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2) + JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, RegisteredStructure structure, size_t arg2, GPRReg arg3) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2)); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2), arg3); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) { - m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, RegisteredStructure structure, GPRReg arg2, GPRReg butterfly) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2, butterfly); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, RegisteredStructure structure, size_t arg2, GPRReg butterfly) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2), butterfly); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size) + JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg butterfly) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, butterfly); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, GPRReg arg1, GPRReg arg2, Butterfly* butterfly) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(butterfly)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, RegisteredStructure structure, void* pointer, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size) + JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, RegisteredStructure structure, size_t index, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_E operation, GPRReg result) { m_jit.setupArgumentsExecState(); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, JSCell* cell) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell)); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), cell)); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(C_JITOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell) + JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell)); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell)); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, Structure* structure) + JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, RegisteredStructure structure) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + +#if USE(JSVALUE64) + JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, RegisteredStructure structure, GPRReg scope, SymbolTable* table, TrustedImm64 initialValue) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr::weakPointer(m_jit.graph(), table), initialValue); + return appendCallSetResult(operation, result); + } +#else + JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, RegisteredStructure structure, GPRReg scope, SymbolTable* table, TrustedImm32 tag, TrustedImm32 payload) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr::weakPointer(m_jit.graph(), table), payload, tag); + return appendCallSetResult(operation, result); + } +#endif + JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, RegisteredStructure structure, unsigned knownLength) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, RegisteredStructure structure, unsigned knownLength, unsigned minCapacity) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, RegisteredStructure structure, GPRReg length) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, RegisteredStructure structure, GPRReg length, unsigned minCapacity) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity)); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure) + JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, RegisteredStructure structure) { m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_B_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_TT operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArguments(arg1, arg2); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(S_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(S_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg2); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg2); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(Jss_JITOperation_EZ operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(V_JITOperation_EC operation, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); + } + + JITCompiler::Call callOperation(V_JITOperation_ECliJsf operation, CallLinkInfo* callLinkInfo, GPRReg arg1) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(callLinkInfo), arg1); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EC operation, JSCell* arg1) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1)); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), arg1)); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame) { m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame)); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame) { m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame)); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECZ operation, GPRReg arg1, int arg2) { m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2)); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, JSCell* arg2) { - m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2)); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), arg2)); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECC operation, JSCell* arg1, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2); - return appendCallWithExceptionCheck(operation); - } - - JITCompiler::Call callOperation(V_JITOperation_EVws operation, VariableWatchpointSet* watchpointSet) - { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet)); + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), arg1), arg2); return appendCall(operation); } @@ -1131,31 +1274,22 @@ public: m_jit.setupArgumentsExecState(); return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result); } - - template<typename FunctionType, typename ArgumentType1> - JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1) - { - return callOperation(operation, arg1); - } - template<typename FunctionType, typename ArgumentType1, typename ArgumentType2> - JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2) - { - return callOperation(operation, arg1, arg2); - } - template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3> - JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3) + JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1) { - return callOperation(operation, arg1, arg2, arg3); + m_jit.setupArgumentsWithExecState(arg1); + return appendCallSetResult(operation, result); } - template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4> - JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4) + + JITCompiler::Call callOperation(V_JITOperation_ECIZC operation, GPRReg regOp1, UniquedStringImpl* identOp2, int32_t op3, GPRReg regOp4) { - return callOperation(operation, arg1, arg2, arg3, arg4); + m_jit.setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), TrustedImm32(op3), regOp4); + return appendCall(operation); } - template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5> - JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5) + + template<typename FunctionType, typename... Args> + JITCompiler::Call callOperation(FunctionType operation, NoResultTag, Args... args) { - return callOperation(operation, arg1, arg2, arg3, arg4, arg5); + return callOperation(operation, args...); } JITCompiler::Call callOperation(D_JITOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2) @@ -1173,32 +1307,195 @@ public: m_jit.setupArguments(arg1, arg2); return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(I_JITOperation_EJss operation, GPRReg result, GPRReg arg1) + + JITCompiler::Call callOperation(J_JITOperation_EJss operation, JSValueRegs result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(T_JITOperation_EJss operation, GPRReg result, GPRReg arg1) + { + m_jit.setupArgumentsWithExecState(arg1); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJscZ operation, GPRReg result, GPRReg arg1, int32_t arg2) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2)); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, int32_t arg1) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell)); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell), arg2); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet)); + return appendCall(operation); + } + + JITCompiler::Call callOperation(C_JITOperation_ERUiUi operation, GPRReg result, GPRReg arg1, Imm32 arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.asTrustedImm32(), arg3); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(C_JITOperation_EJscI operation, GPRReg result, GPRReg arg1, UniquedStringImpl* impl) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(impl)); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(P_JITOperation_EZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(P_JITOperation_EZZ operation, GPRReg result, GPRReg arg1, TrustedImm32 arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(P_JITOperation_EDZ operation, GPRReg result, FPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(P_JITOperation_EDZ operation, GPRReg result, FPRReg arg1, TrustedImm32 arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); } #if USE(JSVALUE64) + JITCompiler::Call callOperation(Z_JITOperation_EOJ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_ECJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC) + { + m_jit.setupArgumentsWithExecState(arg.gpr(), mathIC); + return appendCallSetResult(operation, result.gpr()); + } + JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC) + { + m_jit.setupArgumentsWithExecState(arg1.gpr(), arg2.gpr(), mathIC); + return appendCallSetResult(operation, result.gpr()); + } + JITCompiler::Call callOperation(J_JITOperation_EJJI operation, GPRReg result, GPRReg arg1, GPRReg arg2, UniquedStringImpl* uid) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(uid)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(V_JITOperation_EJJJI operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, UniquedStringImpl* uid) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, TrustedImmPtr(uid)); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EJJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJJZ operation, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3.payloadGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJssJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOIJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOSymJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJOOZ operation, GPRReg arg1, JSValueRegs arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJssOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOIOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOSymOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJIUi operation, GPRReg arg1, GPRReg arg2, UniquedStringImpl* impl, unsigned value) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(impl), TrustedImm32(value)); + return appendCall(operation); + } + JITCompiler::Call callOperation(J_JITOperation_EOIUi operation, GPRReg result, GPRReg arg1, UniquedStringImpl* impl, unsigned value) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(impl), TrustedImm32(value)); + return appendCallSetResult(operation, result); + } JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result) { m_jit.setupArgumentsExecState(); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, void* pointer) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1) { @@ -1207,90 +1504,141 @@ public: m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result); return call; } - JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, StringImpl* uid) + JITCompiler::Call callOperation(Q_JITOperation_J operation, GPRReg result, GPRReg value) + { + m_jit.setupArguments(value); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(Q_JITOperation_D operation, GPRReg result, FPRReg value) + { + m_jit.setupArguments(value); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg result, void* pointer, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg result, int startConstant, int numConstants) { m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer) { m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg result, JSCell* cell) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell)); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), cell)); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid) + JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_ECZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, int32_t constant) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(constant)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, StringImpl* uid) + JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, int32_t arg1) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1)); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_EQZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(P_JITOperation_EQZ operation, GPRReg result, GPRReg arg1, TrustedImm32 arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); } + JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, GPRReg value, size_t index) @@ -1299,16 +1647,57 @@ public: return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2) + JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, RegisteredStructure structure, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1); + return appendCallSetResult(operation, result); + } + + JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1) + { + return callOperation(operation, result, globalObject, arg1.gpr()); } JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) + { + m_jit.setupArgumentsWithExecState(arg1.gpr()); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1) { @@ -1318,122 +1707,315 @@ public: JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) + { + return callOperation(operation, result, arg1.gpr()); + } + JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, JSValueRegs arg1) + { + return callOperation(operation, result.payloadGPR(), arg1.payloadGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) + { + return callOperation(operation, result, arg1.payloadGPR()); } JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EJI operation, GPRReg result, GPRReg arg1, UniquedStringImpl* uid) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(uid)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EJI operation, GPRReg result, JSValueRegs arg1, UniquedStringImpl* uid) + { + return callOperation(operation, result, arg1.gpr(), uid); } JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, JSValueRegs arg1, JSValueRegs arg2) + { + return callOperation(operation, result, arg1.gpr(), arg2.gpr()); + } + JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EPPP operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EGP operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, int32_t imm) + { + m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm)))); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm) + JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, int32_t imm, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value)))); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm))), arg2); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2) { - m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return callOperation(operation, result.payloadGPR(), arg1.payloadGPR(), arg2.payloadGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2.gpr()); - return appendCallWithExceptionCheckSetResult(operation, result); + return appendCallSetResult(operation, result); } JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer) { m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer)); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, StringImpl* uid) + JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, arg2, TrustedImmPtr(uid)); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_ECJ operation, GPRReg arg1, JSValueRegs arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR()); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } - JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1) + JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) { - m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(arg1.payloadGPR()); + return appendCallSetResult(operation, result); } -#else // USE(JSVALUE32_64) + JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, unsigned arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4); + return appendCallSetResult(operation, result); + } -// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]). -// To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary. -#if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS) -#define EABI_32BIT_DUMMY_ARG TrustedImm32(0), -#else -#define EABI_32BIT_DUMMY_ARG -#endif + JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, JSValueRegs arg1, GPRReg arg2, JSValueRegs arg3) + { + return callOperation(operation, result, arg1.payloadGPR(), arg2, arg3.payloadGPR()); + } -// JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture. -// To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary. This must only be done when there -// is no other 32-bit value argument behind this 64-bit JSValue. -#if CPU(SH4) -#define SH4_32BIT_DUMMY_ARG TrustedImm32(0), -#else -#define SH4_32BIT_DUMMY_ARG -#endif + JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, unsigned arg2) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2)); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2, unsigned arg3, GPRReg arg4, unsigned arg5) + { + m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2, TrustedImm32(arg3), arg4, TrustedImm32(arg5)); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_ECJZC operation, GPRReg regOp1, GPRReg regOp2, int32_t op3, GPRReg regOp4) + { + m_jit.setupArgumentsWithExecState(regOp1, regOp2, TrustedImm32(op3), regOp4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_ECIZJJ operation, GPRReg regOp1, UniquedStringImpl* identOp2, int32_t op3, GPRReg regOp4, GPRReg regOp5) + { + m_jit.setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), TrustedImm32(op3), regOp4, regOp5); + return appendCall(operation); + } + JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, JSValueRegs arg1) + { + m_jit.setupArgumentsWithExecState(arg1.gpr()); + return appendCallSetResult(operation, result); + } +#else // USE(JSVALUE32_64) + JITCompiler::Call callOperation(Z_JITOperation_EOJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(C_JITOperation_ECJZ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg.payloadGPR(), arg.tagGPR(), mathIC); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJZ operation, JSValueRegs result, JSValueRegs arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), mathIC); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJJI operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, UniquedStringImpl* uid) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), TrustedImmPtr(uid)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(V_JITOperation_EJJJI operation, JSValueRegs arg1, JSValueRegs arg2, JSValueRegs arg3, UniquedStringImpl* uid) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), TrustedImmPtr(uid)); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EJJJJ operation, JSValueRegs arg1, JSValueRegs arg2, JSValueRegs arg3, JSValueRegs arg4) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), arg4.payloadGPR(), arg4.tagGPR()); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJJZ operation, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJssJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOIJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOSymJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJOOZ operation, GPRReg arg1, JSValueRegs arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJssOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOIOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOSymOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_EOJIUi operation, GPRReg arg1, JSValueRegs arg2, UniquedStringImpl* impl, unsigned value) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), TrustedImmPtr(impl), TrustedImm32(value)); + return appendCall(operation); + } + JITCompiler::Call callOperation(J_JITOperation_EOIUi operation, JSValueRegs result, GPRReg arg1, UniquedStringImpl* impl, unsigned value) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(impl), TrustedImm32(value)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(D_JITOperation_G operation, FPRReg result, JSGlobalObject* globalObject) + { + m_jit.setupArguments(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject)); + return appendCallSetResult(operation, result); + } JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1) { prepareForExternalCall(); @@ -1442,126 +2024,201 @@ public: m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result); return call; } - JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg resultTag, GPRReg resultPayload) + JITCompiler::Call callOperation(J_JITOperation_E operation, JSValueRegs result) { m_jit.setupArgumentsExecState(); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer) + JITCompiler::Call callOperation(J_JITOperation_EP operation, JSValueRegs result, void* pointer) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer) + JITCompiler::Call callOperation(J_JITOperation_EPP operation, JSValueRegs result, GPRReg arg1, void* pointer) { m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EPP operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EPPP operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1) + JITCompiler::Call callOperation(J_JITOperation_EGP operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EP operation, JSValueRegs result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, StringImpl* uid) + JITCompiler::Call callOperation(J_JITOperation_EI operation, JSValueRegs result, UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EA operation, JSValueRegs result, GPRReg arg1) + { + m_jit.setupArgumentsWithExecState(arg1); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1) + JITCompiler::Call callOperation(J_JITOperation_EAZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EJC operation, JSValueRegs result, JSValueRegs arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size) + JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EPS operation, JSValueRegs result, void* pointer, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants) + JITCompiler::Call callOperation(J_JITOperation_ESS operation, JSValueRegs result, int startConstant, int numConstants) { m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer) + JITCompiler::Call callOperation(J_JITOperation_EJP operation, JSValueRegs result, JSValueRegs arg1, void* pointer) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), TrustedImmPtr(pointer)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EJP operation, JSValueRegs result, JSValueRegs arg1, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg resultTag, GPRReg resultPayload, JSCell* cell) + JITCompiler::Call callOperation(J_JITOperation_EC operation, JSValueRegs result, JSCell* cell) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), cell)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_ECZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid) + JITCompiler::Call callOperation(J_JITOperation_ECZZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, int32_t constant) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(constant)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJscC operation, JSValueRegs result, GPRReg arg1, JSCell* cell) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, JSValueRegs arg2) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell), EABI_32BIT_DUMMY_ARG arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, JSValueRegs result, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, StringImpl* uid) + JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, JSValueRegs result, StructureStubInfo* stubInfo, JSValueRegs arg1, UniquedStringImpl* uid) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1.payloadGPR(), arg1.tagGPR(), TrustedImmPtr(uid)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, StringImpl* uid) + JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, JSValueRegs result, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(uid)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, JSValueRegs result, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EDA operation, JSValueRegs result, FPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJA operation, JSValueRegs result, JSValueRegs arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EJA operation, JSValueRegs result, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2) { m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EJA operation, JSValueRegs result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) { m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload) + JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, JSValueRegs arg1) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1) + JITCompiler::Call callOperation(J_JITOperation_EZ operation, JSValueRegs result, GPRReg arg1) { m_jit.setupArgumentsWithExecState(arg1); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1) + JITCompiler::Call callOperation(J_JITOperation_EZ operation, JSValueRegs result, int32_t arg1) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, JSValueRegs result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_EZZ operation, JSValueRegs result, int32_t arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, JSValueRegs value, size_t index) @@ -1570,168 +2227,214 @@ public: return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2Tag, GPRReg arg2Payload) + JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, RegisteredStructure structure, JSValueRegs arg2) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2Payload, arg2Tag); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload) + JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1.payloadGPR(), arg1.tagGPR()); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload) + + JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) { - m_jit.setupArguments(arg1Payload, arg1Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR()); return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload) + + JITCompiler::Call callOperation(C_JITOperation_EJJ operation, GPRReg result, JSValueRegs arg1, JSValueRegs arg2) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload) + JITCompiler::Call callOperation(C_JITOperation_EJJJ operation, GPRReg result, JSValueRegs arg1, JSValueRegs arg2, JSValueRegs arg3) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload) + + JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR()); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm) + + JITCompiler::Call callOperation(S_JITOperation_EJI operation, GPRReg result, JSValueRegs arg1, UniquedStringImpl* uid) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), TrustedImmPtr(uid)); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload) + + JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, JSValueRegs arg1, JSValueRegs arg2) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result); } - JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload) + JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); + return appendCallSetResult(operation, result); + } + JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3) { - m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } + JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, MacroAssembler::TrustedImm32 imm) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), imm, TrustedImm32(JSValue::Int32Tag)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, MacroAssembler::TrustedImm32 imm, JSValueRegs arg2) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), arg2.payloadGPR(), arg2.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_EJJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, JSValueRegs arg3) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR()); - return appendCallWithExceptionCheckSetResult(operation, result.payloadGPR(), result.tagGPR()); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } - JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2) + JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2Payload) + { + m_jit.setupArgumentsWithExecState(arg1, arg2Payload, MacroAssembler::TrustedImm32(JSValue::CellTag)); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); + } + JITCompiler::Call callOperation(J_JITOperation_ECC operation, JSValueRegs result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR()); } JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3); - return appendCallWithExceptionCheck(operation); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload) + JITCompiler::Call callOperation(V_JITOperation_EJ operation, JSValueRegs arg1) { - m_jit.setupArgumentsWithExecState(arg1Tag, arg1Payload); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR()); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer) + JITCompiler::Call callOperation(V_JITOperation_EJPP operation, JSValueRegs arg1, GPRReg arg2, void* pointer) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer)); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2, TrustedImmPtr(pointer)); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, StringImpl* uid) + JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, JSValueRegs arg1, GPRReg arg2Payload, UniquedStringImpl* uid) { - m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid)); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1.payloadGPR(), arg1.tagGPR(), arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid)); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload) + JITCompiler::Call callOperation(V_JITOperation_ECJ operation, GPRReg arg1, JSValueRegs arg2) { - m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR()); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR()); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) + JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3) { - m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR()); + return appendCall(operation); } - JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) + JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3) { - m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR()); + return appendCall(operation); } JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload) { - m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag); - return appendCallWithExceptionCheck(operation); + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); + return appendCall(operation); } - - JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload) + JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); - return appendCallWithExceptionCheckSetResult(operation, result); + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); + return appendCall(operation); } -#undef EABI_32BIT_DUMMY_ARG -#undef SH4_32BIT_DUMMY_ARG - - template<typename FunctionType> - JITCompiler::Call callOperation( - FunctionType operation, JSValueRegs result) + JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, JSValueRegs arg1, GPRReg arg2, JSValueRegs arg3) { - return callOperation(operation, result.tagGPR(), result.payloadGPR()); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR()); + return appendCallSetResult(operation, result); } - template<typename FunctionType, typename ArgumentType1> - JITCompiler::Call callOperation( - FunctionType operation, JSValueRegs result, ArgumentType1 arg1) + JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) { - return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR()); + return appendCallSetResult(operation, result); } - template<typename FunctionType, typename ArgumentType1, typename ArgumentType2> - JITCompiler::Call callOperation( - FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2) + JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, JSValueRegs arg1, unsigned arg2, unsigned arg3) { - return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), TrustedImm32(arg2), TrustedImm32(arg3)); + return appendCallSetResult(operation, result); } - template< - typename FunctionType, typename ArgumentType1, typename ArgumentType2, - typename ArgumentType3> - JITCompiler::Call callOperation( - FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2, - ArgumentType3 arg3) + JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2, unsigned arg3, GPRReg arg4) { - return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3); + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), TrustedImm32(arg3), arg4); + return appendCallSetResult(operation, result); } - template< - typename FunctionType, typename ArgumentType1, typename ArgumentType2, - typename ArgumentType3, typename ArgumentType4> - JITCompiler::Call callOperation( - FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2, - ArgumentType3 arg3, ArgumentType4 arg4) + JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, JSValueRegs arg1, unsigned arg2) { - return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), TrustedImm32(arg2)); + return appendCallSetResult(operation, result); } - template< - typename FunctionType, typename ArgumentType1, typename ArgumentType2, - typename ArgumentType3, typename ArgumentType4, typename ArgumentType5> - JITCompiler::Call callOperation( - FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2, - ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5) + JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, JSValueRegs arg2, unsigned arg3, GPRReg arg4, unsigned arg5) { - return callOperation( - operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5); + m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2.payloadGPR(), arg2.tagGPR(), TrustedImm32(arg3), arg4, TrustedImm32(arg5)); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_ECJZC operation, GPRReg arg1, JSValueRegs arg2, int32_t arg3, GPRReg arg4) + { + m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), TrustedImm32(arg3), arg4); + return appendCall(operation); + } + JITCompiler::Call callOperation(V_JITOperation_ECIZCC operation, GPRReg arg1, UniquedStringImpl* identOp2, int32_t op3, GPRReg arg4, GPRReg arg5) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identOp2), TrustedImm32(op3), arg4, arg5); + return appendCall(operation); + } + JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, JSValueRegs arg1) + { + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR()); + return appendCallSetResult(operation, result); } #endif // USE(JSVALUE32_64) -#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4) +#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) void prepareForExternalCall() { // We're about to call out to a "native" helper function. The helper @@ -1750,30 +2453,19 @@ public: void prepareForExternalCall() { } #endif - // These methods add call instructions, with optional exception checks & setting results. - JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function) + // These methods add call instructions, optionally setting results, and optionally rolling back the call frame on an exception. + JITCompiler::Call appendCall(const FunctionPtr& function) { prepareForExternalCall(); - m_jit.emitStoreCodeOrigin(m_currentNode->codeOrigin); - JITCompiler::Call call = m_jit.appendCall(function); - m_jit.exceptionCheck(); - return call; + m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic); + return m_jit.appendCall(function); } JITCompiler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr& function) { - prepareForExternalCall(); - m_jit.emitStoreCodeOrigin(m_currentNode->codeOrigin); - JITCompiler::Call call = m_jit.appendCall(function); + JITCompiler::Call call = appendCall(function); m_jit.exceptionCheckWithCallFrameRollback(); return call; } - JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result) - { - JITCompiler::Call call = appendCallWithExceptionCheck(function); - if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR)) - m_jit.move(GPRInfo::returnValueGPR, result); - return call; - } JITCompiler::Call appendCallWithCallFrameRollbackOnExceptionSetResult(const FunctionPtr& function, GPRReg result) { JITCompiler::Call call = appendCallWithCallFrameRollbackOnException(function); @@ -1783,35 +2475,26 @@ public: } JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result) { - prepareForExternalCall(); - m_jit.emitStoreCodeOrigin(m_currentNode->codeOrigin); - JITCompiler::Call call = m_jit.appendCall(function); + JITCompiler::Call call = appendCall(function); if (result != InvalidGPRReg) m_jit.move(GPRInfo::returnValueGPR, result); return call; } - JITCompiler::Call appendCall(const FunctionPtr& function) + JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2) { - prepareForExternalCall(); - m_jit.emitStoreCodeOrigin(m_currentNode->codeOrigin); - return m_jit.appendCall(function); - } - JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2) - { - JITCompiler::Call call = appendCallWithExceptionCheck(function); + JITCompiler::Call call = appendCall(function); m_jit.setupResults(result1, result2); return call; } -#if CPU(X86) - JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result) + JITCompiler::Call appendCallSetResult(const FunctionPtr& function, JSValueRegs resultRegs) { - JITCompiler::Call call = appendCallWithExceptionCheck(function); - if (result != InvalidFPRReg) { - m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister); - m_jit.loadDouble(JITCompiler::stackPointerRegister, result); - } - return call; +#if USE(JSVALUE64) + return appendCallSetResult(function, resultRegs.gpr()); +#else + return appendCallSetResult(function, resultRegs.payloadGPR(), resultRegs.tagGPR()); +#endif } +#if CPU(X86) JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result) { JITCompiler::Call call = appendCall(function); @@ -1822,13 +2505,6 @@ public: return call; } #elif CPU(ARM) && !CPU(ARM_HARDFP) - JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result) - { - JITCompiler::Call call = appendCallWithExceptionCheck(function); - if (result != InvalidFPRReg) - m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2); - return call; - } JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result) { JITCompiler::Call call = appendCall(function); @@ -1836,14 +2512,7 @@ public: m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2); return call; } -#else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4) - JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result) - { - JITCompiler::Call call = appendCallWithExceptionCheck(function); - if (result != InvalidFPRReg) - m_jit.moveDouble(FPRInfo::returnValueFPR, result); - return call; - } +#else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result) { JITCompiler::Call call = appendCall(function); @@ -1947,17 +2616,6 @@ public: void dump(const char* label = 0); - bool isInteger(Node* node) - { - if (node->hasInt32Result()) - return true; - - if (isInt32Constant(node)) - return true; - - return generationInfo(node).isJSInt32(); - } - bool betterUseStrictInt52(Node* node) { return !generationInfo(node).isInt52(); @@ -1974,16 +2632,33 @@ public: void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition); void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition); void compilePeepHoleObjectEquality(Node*, Node* branchNode); + void compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode); void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode); void compileObjectEquality(Node*); + void compileObjectStrictEquality(Edge objectChild, Edge otherChild); void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild); void compileObjectOrOtherLogicalNot(Edge value); void compileLogicalNot(Node*); + void compileLogicalNotStringOrOther(Node*); + void compileStringEquality( + Node*, GPRReg leftGPR, GPRReg rightGPR, GPRReg lengthGPR, + GPRReg leftTempGPR, GPRReg rightTempGPR, GPRReg leftTemp2GPR, + GPRReg rightTemp2GPR, JITCompiler::JumpList fastTrue, + JITCompiler::JumpList fastSlow); void compileStringEquality(Node*); void compileStringIdentEquality(Node*); + void compileStringToUntypedEquality(Node*, Edge stringEdge, Edge untypedEdge); + void compileStringIdentToNotStringVarEquality(Node*, Edge stringEdge, Edge notStringVarEdge); void compileStringZeroLength(Node*); + void compileMiscStrictEq(Node*); + + void compileSymbolEquality(Node*); + void compilePeepHoleSymbolEquality(Node*, Node* branchNode); + void compileSymbolUntypedEquality(Node*, Edge symbolEdge, Edge untypedEdge); void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken); + void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken); + void emitStringOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken); void emitBranch(Node*); struct StringSwitchCase { @@ -1995,7 +2670,10 @@ public: { } - bool operator<(const StringSwitchCase& other) const; + bool operator<(const StringSwitchCase& other) const + { + return stringLessThan(*string, *other.string); + } StringImpl* string; BasicBlock* target; @@ -2013,7 +2691,9 @@ public: void emitSwitchString(Node*, SwitchData*); void emitSwitch(Node*); - void compileToStringOnCell(Node*); + void compileToStringOrCallStringConstructor(Node*); + void compileToStringOrCallStringConstructorOnNumber(Node*); + void compileNumberToStringWithRadix(Node*); void compileNewStringObject(Node*); void compileNewTypedArray(Node*); @@ -2022,13 +2702,18 @@ public: void compileInt52Compare(Node*, MacroAssembler::RelationalCondition); void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition); void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition); - - bool compileStrictEqForConstant(Node*, Edge value, JSValue constant); + void compileStringCompare(Node*, MacroAssembler::RelationalCondition); + void compileStringIdentCompare(Node*, MacroAssembler::RelationalCondition); bool compileStrictEq(Node*); void compileAllocatePropertyStorage(Node*); void compileReallocatePropertyStorage(Node*); + void compileNukeStructureAndSetButterfly(Node*); + void compileGetButterfly(Node*); + void compileCallDOMGetter(Node*); + void compileCallDOM(Node*); + void compileCheckDOM(Node*); #if USE(JSVALUE32_64) template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType> @@ -2049,112 +2734,171 @@ public: void compileGetByValOnString(Node*); void compileFromCharCode(Node*); - void compileGetByValOnArguments(Node*); - void compileGetArgumentsLength(Node*); + void compileGetByValOnDirectArguments(Node*); + void compileGetByValOnScopedArguments(Node*); + void compileGetScope(Node*); + void compileSkipScope(Node*); + void compileGetGlobalObject(Node*); + void compileGetArrayLength(Node*); + + void compileCheckTypeInfoFlags(Node*); + void compileCheckStringIdent(Node*); + + void compileParseInt(Node*); + + void compileValueRep(Node*); + void compileDoubleRep(Node*); void compileValueToInt32(Node*); void compileUInt32ToNumber(Node*); void compileDoubleAsInt32(Node*); - void compileInt32ToDouble(Node*); - void compileAdd(Node*); + + template<typename SnippetGenerator, J_JITOperation_EJJ slowPathFunction> + void emitUntypedBitOp(Node*); + void compileBitwiseOp(Node*); + + void emitUntypedRightShiftBitOp(Node*); + void compileShiftOp(Node*); + + template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction> + void compileMathIC(Node*, JITBinaryMathIC<Generator>*, bool needsScratchGPRReg, bool needsScratchFPRReg, RepatchingFunction, NonRepatchingFunction); + template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction> + void compileMathIC(Node*, JITUnaryMathIC<Generator>*, bool needsScratchGPRReg, RepatchingFunction, NonRepatchingFunction); + + void compileArithDoubleUnaryOp(Node*, double (*doubleFunction)(double), double (*operation)(ExecState*, EncodedJSValue)); + void compileValueAdd(Node*); + void compileArithAdd(Node*); void compileMakeRope(Node*); + void compileArithAbs(Node*); + void compileArithClz32(Node*); + void compileArithCos(Node*); + void compileArithTan(Node*); void compileArithSub(Node*); void compileArithNegate(Node*); void compileArithMul(Node*); void compileArithDiv(Node*); + void compileArithFRound(Node*); void compileArithMod(Node*); + void compileArithPow(Node*); + void compileArithRounding(Node*); + void compileArithRandom(Node*); + void compileArithSin(Node*); + void compileArithSqrt(Node*); + void compileArithLog(Node*); void compileConstantStoragePointer(Node*); void compileGetIndexedPropertyStorage(Node*); JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR); + JITCompiler::Jump jumpForTypedArrayIsNeuteredIfOutOfBounds(Node*, GPRReg baseGPR, JITCompiler::Jump outOfBounds); void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR); void compileGetTypedArrayByteOffset(Node*); void compileGetByValOnIntTypedArray(Node*, TypedArrayType); void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType); void compileGetByValOnFloatTypedArray(Node*, TypedArrayType); void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType); - void compileNewFunctionNoCheck(Node*); - void compileNewFunctionExpression(Node*); + template <typename ClassType> void compileNewFunctionCommon(GPRReg, RegisteredStructure, GPRReg, GPRReg, GPRReg, MacroAssembler::JumpList&, size_t, FunctionExecutable*, ptrdiff_t, ptrdiff_t, ptrdiff_t); + void compileNewFunction(Node*); + void compileSetFunctionName(Node*); + void compileForwardVarargs(Node*); + void compileCreateActivation(Node*); + void compileCreateDirectArguments(Node*); + void compileGetFromArguments(Node*); + void compilePutToArguments(Node*); + void compileGetArgument(Node*); + void compileCreateScopedArguments(Node*); + void compileCreateClonedArguments(Node*); + void compileCreateRest(Node*); + void compileSpread(Node*); + void compileNewArrayWithSpread(Node*); + void compileGetRestLength(Node*); + void compileArraySlice(Node*); + void compileNotifyWrite(Node*); bool compileRegExpExec(Node*); - - // size can be an immediate or a register, and must be in bytes. If size is a register, - // it must be a different register than resultGPR. Emits code that place a pointer to - // the end of the allocation. The returned jump is the jump to the slow path. - template<typename SizeType> - MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR) - { - CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator(); - - // It's invalid to allocate zero bytes in CopiedSpace. -#ifndef NDEBUG - m_jit.move(size, resultGPR); - MacroAssembler::Jump nonZeroSize = m_jit.branchTest32(MacroAssembler::NonZero, resultGPR); - m_jit.breakpoint(); - nonZeroSize.link(&m_jit); -#endif - - m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR); - MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR); - m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining); - m_jit.negPtr(resultGPR); - m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR); - - return slowPath; - } + void compileIsObjectOrNull(Node*); + void compileIsFunction(Node*); + void compileTypeOf(Node*); + void compileCheckStructure(Node*, GPRReg cellGPR, GPRReg tempGPR); + void compileCheckStructure(Node*); + void compilePutAccessorById(Node*); + void compilePutGetterSetterById(Node*); + void compilePutAccessorByVal(Node*); + void compileGetRegExpObjectLastIndex(Node*); + void compileSetRegExpObjectLastIndex(Node*); + void compileLazyJSConstant(Node*); + void compileMaterializeNewObject(Node*); + void compileRecordRegExpCachedResult(Node*); + void compileCallObjectConstructor(Node*); + void compileResolveScope(Node*); + void compileGetDynamicVar(Node*); + void compilePutDynamicVar(Node*); + void compileCompareEqPtr(Node*); + void compileDefineDataProperty(Node*); + void compileDefineAccessorProperty(Node*); + void compileToLowerCase(Node*); + + void moveTrueTo(GPRReg); + void moveFalseTo(GPRReg); + void blessBoolean(GPRReg); // Allocator for a cell of a specific size. template <typename StructureType> // StructureType can be GPR or ImmPtr. - void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure, + void emitAllocateJSCell( + GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, StructureType structure, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) { - m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR); - slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR)); - - // The object is half-allocated: we have what we know is a fresh object, but - // it's still on the GC's free list. - m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR); - m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead())); - - // Initialize the object's Structure. - m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSCell::structureOffset())); + m_jit.emitAllocateJSCell(resultGPR, allocator, allocatorGPR, structure, scratchGPR, slowPath); } // Allocator for an object of a specific size. template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr. - void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure, + void emitAllocateJSObject( + GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, StructureType structure, StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) { - emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath); - - // Initialize the object's property storage pointer. - m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset())); + m_jit.emitAllocateJSObject( + resultGPR, allocator, allocatorGPR, structure, storage, scratchGPR, slowPath); } - // Convenience allocator for a buit-in object. + template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr. + void emitAllocateJSObjectWithKnownSize( + GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1, + GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath, size_t size) + { + m_jit.emitAllocateJSObjectWithKnownSize<ClassType>(resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath, size); + } + + // Convenience allocator for a built-in object. template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr. void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath) { - MarkedAllocator* allocator = 0; - size_t size = ClassType::allocationSize(0); - if (ClassType::needsDestruction && ClassType::hasImmortalStructure) - allocator = &m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(size); - else if (ClassType::needsDestruction) - allocator = &m_jit.vm()->heap.allocatorForObjectWithNormalDestructor(size); - else - allocator = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(size); - m_jit.move(TrustedImmPtr(allocator), scratchGPR1); - emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath); + m_jit.emitAllocateJSObject<ClassType>(resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath); } - void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements); + template <typename ClassType, typename StructureType> // StructureType and StorageType can be GPR or ImmPtr. + void emitAllocateVariableSizedJSObject(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath) + { + m_jit.emitAllocateVariableSizedJSObject<ClassType>(resultGPR, structure, allocationSize, scratchGPR1, scratchGPR2, slowPath); + } -#if USE(JSVALUE64) - JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp); -#elif USE(JSVALUE32_64) - JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result); -#endif + template<typename ClassType> + void emitAllocateDestructibleObject(GPRReg resultGPR, RegisteredStructure structure, + GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath) + { + m_jit.emitAllocateDestructibleObject<ClassType>(resultGPR, structure.get(), scratchGPR1, scratchGPR2, slowPath); + } + + void emitAllocateRawObject(GPRReg resultGPR, RegisteredStructure, GPRReg storageGPR, unsigned numElements, unsigned vectorLength); + + void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false); + void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false); + void emitGetCallee(CodeOrigin, GPRReg calleeGPR); + void emitGetArgumentStart(CodeOrigin, GPRReg startGPR); + + // Generate an OSR exit fuzz check. Returns Jump() if OSR exit fuzz is not enabled, or if + // it's in training mode. + MacroAssembler::Jump emitOSRExitFuzzCheck(); // Add a speculation check. void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail); @@ -2171,35 +2915,67 @@ public: void emitInvalidationPoint(Node*); + void unreachable(Node*); + // Called when we statically determine that a speculation will fail. void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*); void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge); // Helpers for performing type checks on an edge stored in the given registers. bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); } - void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail); - + void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, ExitKind = BadType); + + void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType); + void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType); + void speculateInt32(Edge); - void speculateMachineInt(Edge); +#if USE(JSVALUE64) + void convertAnyInt(Edge, GPRReg resultGPR); + void speculateAnyInt(Edge); + void speculateDoubleRepAnyInt(Edge); +#endif // USE(JSVALUE64) void speculateNumber(Edge); void speculateRealNumber(Edge); + void speculateDoubleRepReal(Edge); void speculateBoolean(Edge); void speculateCell(Edge); + void speculateCellOrOther(Edge); void speculateObject(Edge); + void speculateArray(Edge, GPRReg cell); + void speculateArray(Edge); + void speculateFunction(Edge); void speculateFinalObject(Edge); + void speculateRegExpObject(Edge, GPRReg cell); + void speculateRegExpObject(Edge); + void speculateProxyObject(Edge, GPRReg cell); + void speculateProxyObject(Edge); + void speculateDerivedArray(Edge, GPRReg cell); + void speculateDerivedArray(Edge); + void speculateMapObject(Edge); + void speculateMapObject(Edge, GPRReg cell); + void speculateSetObject(Edge); + void speculateSetObject(Edge, GPRReg cell); void speculateObjectOrOther(Edge); void speculateString(Edge edge, GPRReg cell); void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage); void speculateStringIdent(Edge edge, GPRReg string); void speculateStringIdent(Edge); void speculateString(Edge); + void speculateStringOrOther(Edge, JSValueRegs, GPRReg scratch); + void speculateStringOrOther(Edge); + void speculateNotStringVar(Edge); template<typename StructureLocationType> void speculateStringObjectForStructure(Edge, StructureLocationType); void speculateStringObject(Edge, GPRReg); void speculateStringObject(Edge); void speculateStringOrStringObject(Edge); + void speculateSymbol(Edge, GPRReg cell); + void speculateSymbol(Edge); + void speculateNotCell(Edge, JSValueRegs); void speculateNotCell(Edge); void speculateOther(Edge); + void speculateMisc(Edge, JSValueRegs); + void speculateMisc(Edge); void speculate(Node*, Edge); JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType); @@ -2250,7 +3026,7 @@ public: // The current node being generated. BasicBlock* m_block; Node* m_currentNode; - bool m_canExit; + NodeType m_lastGeneratedNode; unsigned m_indexInBlock; // Virtual and physical register maps. Vector<GenerationInfo, 32> m_generationInfo; @@ -2271,8 +3047,7 @@ public: }; Vector<BranchRecord, 8> m_branches; - CodeOrigin m_codeOriginForExitTarget; - CodeOrigin m_codeOriginForExitProfile; + NodeOrigin m_origin; InPlaceAbstractState m_state; AbstractInterpreter<InPlaceAbstractState> m_interpreter; @@ -2280,10 +3055,15 @@ public: VariableEventStream* m_stream; MinifiedGraph* m_minifiedGraph; - bool m_isCheckingArgumentTypes; - - Vector<OwnPtr<SlowPathGenerator>, 8> m_slowPathGenerators; + Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators; + struct SlowPathLambda { + std::function<void()> generator; + Node* currentNode; + unsigned streamIndex; + }; + Vector<SlowPathLambda> m_slowPathLambdas; Vector<SilentRegisterSavePlan> m_plans; + std::optional<unsigned> m_outOfLineStreamIndex; }; @@ -2308,6 +3088,8 @@ public: #endif { ASSERT(m_jit); + if (!edge) + return; ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse); #if USE(JSVALUE64) if (jit->isFilled(node())) @@ -2320,8 +3102,36 @@ public: #endif } + explicit JSValueOperand(JSValueOperand&& other) + : m_jit(other.m_jit) + , m_edge(other.m_edge) + { +#if USE(JSVALUE64) + m_gprOrInvalid = other.m_gprOrInvalid; +#elif USE(JSVALUE32_64) + m_register.pair.tagGPR = InvalidGPRReg; + m_register.pair.payloadGPR = InvalidGPRReg; + m_isDouble = other.m_isDouble; + + if (m_edge) { + if (m_isDouble) + m_register.fpr = other.m_register.fpr; + else + m_register.pair = other.m_register.pair; + } +#endif + other.m_edge = Edge(); +#if USE(JSVALUE64) + other.m_gprOrInvalid = InvalidGPRReg; +#elif USE(JSVALUE32_64) + other.m_isDouble = false; +#endif + } + ~JSValueOperand() { + if (!m_edge) + return; #if USE(JSVALUE64) ASSERT(m_gprOrInvalid != InvalidGPRReg); m_jit->unlock(m_gprOrInvalid); @@ -2502,6 +3312,8 @@ public: m_gpr = m_jit->reuse(op1.gpr()); else if (m_jit->canReuse(op2.node())) m_gpr = m_jit->reuse(op2.gpr()); + else if (m_jit->canReuse(op1.node(), op2.node()) && op1.gpr() == op2.gpr()) + m_gpr = m_jit->reuse(op1.gpr()); else m_gpr = m_jit->allocate(); } @@ -2509,6 +3321,27 @@ public: GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord); #endif + GPRTemporary(GPRTemporary& other) = delete; + + GPRTemporary(GPRTemporary&& other) + { + ASSERT(other.m_jit); + ASSERT(other.m_gpr != InvalidGPRReg); + m_jit = other.m_jit; + m_gpr = other.m_gpr; + other.m_jit = nullptr; + other.m_gpr = InvalidGPRReg; + } + + GPRTemporary& operator=(GPRTemporary&& other) + { + ASSERT(!m_jit); + ASSERT(m_gpr == InvalidGPRReg); + std::swap(m_jit, other.m_jit); + std::swap(m_gpr, other.m_gpr); + return *this; + } + void adopt(GPRTemporary&); ~GPRTemporary() @@ -2527,8 +3360,30 @@ private: GPRReg m_gpr; }; +class JSValueRegsTemporary { +public: + JSValueRegsTemporary(); + JSValueRegsTemporary(SpeculativeJIT*); + template<typename T> + JSValueRegsTemporary(SpeculativeJIT*, ReuseTag, T& operand, WhichValueWord resultRegWord = PayloadWord); + JSValueRegsTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&); + ~JSValueRegsTemporary(); + + JSValueRegs regs(); + +private: +#if USE(JSVALUE64) + GPRTemporary m_gpr; +#else + GPRTemporary m_payloadGPR; + GPRTemporary m_tagGPR; +#endif +}; + class FPRTemporary { + WTF_MAKE_NONCOPYABLE(FPRTemporary); public: + FPRTemporary(FPRTemporary&&); FPRTemporary(SpeculativeJIT*); FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&); FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&); @@ -2538,11 +3393,13 @@ public: ~FPRTemporary() { - m_jit->unlock(fpr()); + if (LIKELY(m_jit)) + m_jit->unlock(fpr()); } FPRReg fpr() const { + ASSERT(m_jit); ASSERT(m_fpr != InvalidFPRReg); return m_fpr; } @@ -2564,18 +3421,18 @@ private: // // These classes lock the result of a call to a C++ helper function. -class GPRResult : public GPRTemporary { +class GPRFlushedCallResult : public GPRTemporary { public: - GPRResult(SpeculativeJIT* jit) + GPRFlushedCallResult(SpeculativeJIT* jit) : GPRTemporary(jit, GPRInfo::returnValueGPR) { } }; #if USE(JSVALUE32_64) -class GPRResult2 : public GPRTemporary { +class GPRFlushedCallResult2 : public GPRTemporary { public: - GPRResult2(SpeculativeJIT* jit) + GPRFlushedCallResult2(SpeculativeJIT* jit) : GPRTemporary(jit, GPRInfo::returnValueGPR2) { } @@ -2716,12 +3573,12 @@ private: // Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero). class SpeculateInt52Operand { public: - explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) + explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge) : m_jit(jit) , m_edge(edge) , m_gprOrInvalid(InvalidGPRReg) { - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse); + RELEASE_ASSERT(edge.useKind() == Int52RepUse); if (jit->isFilled(node())) gpr(); } @@ -2763,12 +3620,12 @@ private: // Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended). class SpeculateStrictInt52Operand { public: - explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) + explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge) : m_jit(jit) , m_edge(edge) , m_gprOrInvalid(InvalidGPRReg) { - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse); + RELEASE_ASSERT(edge.useKind() == Int52RepUse); if (jit->isFilled(node())) gpr(); } @@ -2811,35 +3668,35 @@ enum OppositeShiftTag { OppositeShift }; class SpeculateWhicheverInt52Operand { public: - explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) + explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge) : m_jit(jit) , m_edge(edge) , m_gprOrInvalid(InvalidGPRReg) , m_strict(jit->betterUseStrictInt52(edge)) { - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse); + RELEASE_ASSERT(edge.useKind() == Int52RepUse); if (jit->isFilled(node())) gpr(); } - explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other, OperandSpeculationMode mode = AutomaticOperandSpeculation) + explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other) : m_jit(jit) , m_edge(edge) , m_gprOrInvalid(InvalidGPRReg) , m_strict(other.m_strict) { - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse); + RELEASE_ASSERT(edge.useKind() == Int52RepUse); if (jit->isFilled(node())) gpr(); } - explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other, OperandSpeculationMode mode = AutomaticOperandSpeculation) + explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other) : m_jit(jit) , m_edge(edge) , m_gprOrInvalid(InvalidGPRReg) , m_strict(!other.m_strict) { - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse); + RELEASE_ASSERT(edge.useKind() == Int52RepUse); if (jit->isFilled(node())) gpr(); } @@ -2888,13 +3745,13 @@ private: class SpeculateDoubleOperand { public: - explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) + explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge) : m_jit(jit) , m_edge(edge) , m_fprOrInvalid(InvalidFPRReg) { ASSERT(m_jit); - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind())); + RELEASE_ASSERT(isDouble(edge.useKind())); if (jit->isFilled(node())) fpr(); } @@ -2934,6 +3791,8 @@ private: }; class SpeculateCellOperand { + WTF_MAKE_NONCOPYABLE(SpeculateCellOperand); + public: explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) : m_jit(jit) @@ -2948,6 +3807,16 @@ public: gpr(); } + explicit SpeculateCellOperand(SpeculateCellOperand&& other) + { + m_jit = other.m_jit; + m_edge = other.m_edge; + m_gprOrInvalid = other.m_gprOrInvalid; + + other.m_gprOrInvalid = InvalidGPRReg; + other.m_edge = Edge(); + } + ~SpeculateCellOperand() { if (!m_edge) @@ -2994,7 +3863,7 @@ public: , m_gprOrInvalid(InvalidGPRReg) { ASSERT(m_jit); - ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse); + ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse); if (jit->isFilled(node())) gpr(); } @@ -3036,28 +3905,29 @@ private: template<typename StructureLocationType> void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation) { - Structure* stringObjectStructure = - m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure(); + RegisteredStructure stringObjectStructure = + m_jit.graph().registerStructure(m_jit.globalObjectFor(m_currentNode->origin.semantic)->stringObjectStructure()); - if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(stringObjectStructure))) { + if (!m_state.forNode(edge).m_structure.isSubsetOf(RegisteredStructureSet(stringObjectStructure))) { speculationCheck( NotStringObject, JSValueRegs(), 0, - m_jit.branchPtr( - JITCompiler::NotEqual, structureLocation, TrustedImmPtr(stringObjectStructure))); + m_jit.branchWeakStructure( + JITCompiler::NotEqual, structureLocation, stringObjectStructure)); } } -#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \ +#define DFG_TYPE_CHECK_WITH_EXIT_KIND(exitKind, source, edge, typesPassedThrough, jumpToFail) do { \ JSValueSource _dtc_source = (source); \ Edge _dtc_edge = (edge); \ SpeculatedType _dtc_typesPassedThrough = typesPassedThrough; \ if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough)) \ break; \ - typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \ + typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail), exitKind); \ } while (0) +#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) \ + DFG_TYPE_CHECK_WITH_EXIT_KIND(BadType, source, edge, typesPassedThrough, jumpToFail) + } } // namespace JSC::DFG #endif -#endif - |