+2017-08-04 Mark Lam <mark.lam@apple.com>
+
+ Move DFG::OSRExitCompiler methods into DFG::OSRExit [step 1].
+ https://bugs.webkit.org/show_bug.cgi?id=175208
+ <rdar://problem/33732402>
+
+ Reviewed by Saam Barati.
+
+ This will minimize the code diff and make it easier to review the patch for
+ https://bugs.webkit.org/show_bug.cgi?id=175144 later. We'll do this patch in 3
+ steps:
+
+ 1. Do the code changes to move methods into OSRExit.
+ 2. Copy the 64-bit and common methods into DFGOSRExit.cpp, and delete the unused DFGOSRExitCompiler files.
+ 3. Merge the 32-bit OSRExitCompiler methods into the 64-bit version, and delete DFGOSRExitCompiler32_64.cpp.
+
+ Splitting this refactoring into these 3 steps also makes it easier to review this
+ patch and understand what is being changed.
+
+ * dfg/DFGOSRExit.h:
+ * dfg/DFGOSRExitCompiler.cpp:
+ (JSC::DFG::OSRExit::emitRestoreArguments):
+ (JSC::DFG::OSRExit::compileOSRExit):
+ (JSC::DFG::OSRExitCompiler::emitRestoreArguments): Deleted.
+ (): Deleted.
+ * dfg/DFGOSRExitCompiler.h:
+ (JSC::DFG::OSRExitCompiler::OSRExitCompiler): Deleted.
+ (): Deleted.
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExit::compileExit):
+ (JSC::DFG::OSRExitCompiler::compileExit): Deleted.
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExit::compileExit):
+ (JSC::DFG::OSRExitCompiler::compileExit): Deleted.
+ * dfg/DFGThunks.cpp:
+ (JSC::DFG::osrExitGenerationThunkGenerator):
+
2017-08-04 Devin Rousso <drousso@apple.com>
Web Inspector: add source view for WebGL shader programs
/*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "GPRInfo.h"
#include "MacroAssembler.h"
#include "MethodOfGettingAValueProfile.h"
+#include "Operands.h"
+#include "ValueRecovery.h"
-namespace JSC { namespace DFG {
+namespace JSC {
+
+class CCallHelpers;
+
+namespace DFG {
class SpeculativeJIT;
struct BasicBlock;
struct OSRExit : public OSRExitBase {
OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = UINT_MAX);
+ static void JIT_OPERATION compileOSRExit(ExecState*) WTF_INTERNAL;
+
unsigned m_patchableCodeOffset { 0 };
MacroAssemblerCodeRef m_code;
{
OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromDFG);
}
+
+private:
+ static void compileExit(CCallHelpers&, VM&, const OSRExit&, const Operands<ValueRecovery>&, SpeculationRecovery*);
+ static void emitRestoreArguments(CCallHelpers&, const Operands<ValueRecovery>&);
};
struct SpeculationFailureDebugInfo {
/*
- * Copyright (C) 2011-2013, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
namespace JSC { namespace DFG {
-void OSRExitCompiler::emitRestoreArguments(const Operands<ValueRecovery>& operands)
+void OSRExit::emitRestoreArguments(CCallHelpers& jit, const Operands<ValueRecovery>& operands)
{
HashMap<MinifiedID, int> alreadyAllocatedArguments; // Maps phantom arguments node ID to operand.
for (size_t index = 0; index < operands.size(); ++index) {
auto iter = alreadyAllocatedArguments.find(id);
if (iter != alreadyAllocatedArguments.end()) {
JSValueRegs regs = JSValueRegs::withTwoAvailableRegs(GPRInfo::regT0, GPRInfo::regT1);
- m_jit.loadValue(CCallHelpers::addressFor(iter->value), regs);
- m_jit.storeValue(regs, CCallHelpers::addressFor(operand));
+ jit.loadValue(CCallHelpers::addressFor(iter->value), regs);
+ jit.storeValue(regs, CCallHelpers::addressFor(operand));
continue;
}
InlineCallFrame* inlineCallFrame =
- m_jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame();
+ jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame();
int stackOffset;
if (inlineCallFrame)
stackOffset = 0;
if (!inlineCallFrame || inlineCallFrame->isClosureCall) {
- m_jit.loadPtr(
+ jit.loadPtr(
AssemblyHelpers::addressFor(stackOffset + CallFrameSlot::callee),
GPRInfo::regT0);
} else {
- m_jit.move(
+ jit.move(
AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeRecovery.constant().asCell()),
GPRInfo::regT0);
}
if (!inlineCallFrame || inlineCallFrame->isVarargs()) {
- m_jit.load32(
+ jit.load32(
AssemblyHelpers::payloadFor(stackOffset + CallFrameSlot::argumentCount),
GPRInfo::regT1);
} else {
- m_jit.move(
+ jit.move(
AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()),
GPRInfo::regT1);
}
- m_jit.setupArgumentsWithExecState(
+ jit.setupArgumentsWithExecState(
AssemblyHelpers::TrustedImmPtr(inlineCallFrame), GPRInfo::regT0, GPRInfo::regT1);
switch (recovery.technique()) {
case DirectArgumentsThatWereNotCreated:
- m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0);
+ jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0);
break;
case ClonedArgumentsThatWereNotCreated:
- m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0);
+ jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0);
break;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
- m_jit.call(GPRInfo::nonArgGPR0);
- m_jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand));
+ jit.call(GPRInfo::nonArgGPR0);
+ jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand));
alreadyAllocatedArguments.add(id, operand);
}
}
-extern "C" {
-
-void compileOSRExit(ExecState* exec)
+void OSRExit::compileOSRExit(ExecState* exec)
{
VM* vm = &exec->vm();
auto scope = DECLARE_THROW_SCOPE(*vm);
{
CCallHelpers jit(codeBlock);
- OSRExitCompiler exitCompiler(jit);
if (exit.m_kind == GenericUnwind) {
// We are acting as a defacto op_catch because we arrive here from genericUnwind().
jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
}
- exitCompiler.compileExit(*vm, exit, operands, recovery);
-
+ compileExit(jit, *vm, exit, operands, recovery);
+
LinkBuffer patchBuffer(jit, codeBlock);
exit.m_code = FINALIZE_CODE_IF(
shouldDumpDisassembly() || Options::verboseOSR() || Options::verboseDFGOSRExit(),
vm->osrExitJumpDestination = exit.m_code.code().executableAddress();
}
-} // extern "C"
-
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
/*
- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "DFGOSRExit.h"
#include "Operands.h"
-namespace JSC {
-
-class ExecState;
-
-namespace DFG {
-
-class OSRExitCompiler {
-public:
- OSRExitCompiler(CCallHelpers& jit)
- : m_jit(jit)
- {
- }
-
- void compileExit(VM&, const OSRExit&, const Operands<ValueRecovery>&, SpeculationRecovery*);
-
-private:
- void emitRestoreArguments(const Operands<ValueRecovery>&);
-
- CCallHelpers& m_jit;
-};
-
-extern "C" {
-void JIT_OPERATION compileOSRExit(ExecState*) WTF_INTERNAL;
-}
-
-} } // namespace JSC::DFG
-
#endif // ENABLE(DFG_JIT)
/*
- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
namespace JSC { namespace DFG {
-void OSRExitCompiler::compileExit(VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
+void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
{
// Pro-forma stuff.
if (Options::printEachOSRExit()) {
SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
- debugInfo->codeBlock = m_jit.codeBlock();
+ debugInfo->codeBlock = jit.codeBlock();
debugInfo->kind = exit.m_kind;
debugInfo->bytecodeOffset = exit.m_codeOrigin.bytecodeIndex;
- m_jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo);
+ jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo);
}
// Perform speculation recovery. This only comes into play when an operation
if (recovery) {
switch (recovery->type()) {
case SpeculativeAdd:
- m_jit.sub32(recovery->src(), recovery->dest());
+ jit.sub32(recovery->src(), recovery->dest());
break;
case SpeculativeAddImmediate:
- m_jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());
+ jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());
break;
case BooleanSpeculationCheck:
// the cell check would have already happened.
CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile;
- if (ArrayProfile* arrayProfile = m_jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {
+ if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {
GPRReg usedRegister1;
GPRReg usedRegister2;
if (exit.m_jsValueSource.isAddress()) {
scratch1 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2);
scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2, scratch1);
- m_jit.push(scratch1);
- m_jit.push(scratch2);
+ jit.push(scratch1);
+ jit.push(scratch2);
GPRReg value;
if (exit.m_jsValueSource.isAddress()) {
value = scratch1;
- m_jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value);
+ jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value);
} else
value = exit.m_jsValueSource.payloadGPR();
- m_jit.loadPtr(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);
- m_jit.storePtr(scratch1, arrayProfile->addressOfLastSeenStructureID());
- m_jit.load8(AssemblyHelpers::Address(scratch1, Structure::indexingTypeIncludingHistoryOffset()), scratch1);
- m_jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);
- m_jit.lshift32(scratch1, scratch2);
- m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
+ jit.loadPtr(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);
+ jit.storePtr(scratch1, arrayProfile->addressOfLastSeenStructureID());
+ jit.load8(AssemblyHelpers::Address(scratch1, Structure::indexingTypeIncludingHistoryOffset()), scratch1);
+ jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);
+ jit.lshift32(scratch1, scratch2);
+ jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
- m_jit.pop(scratch2);
- m_jit.pop(scratch1);
+ jit.pop(scratch2);
+ jit.pop(scratch1);
}
}
// Save a register so we can use it.
GPRReg scratchPayload = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base());
GPRReg scratchTag = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base(), scratchPayload);
- m_jit.pushToSave(scratchPayload);
- m_jit.pushToSave(scratchTag);
+ jit.pushToSave(scratchPayload);
+ jit.pushToSave(scratchTag);
JSValueRegs scratch(scratchTag, scratchPayload);
- m_jit.loadValue(exit.m_jsValueSource.asAddress(), scratch);
- profile.emitReportValue(m_jit, scratch);
+ jit.loadValue(exit.m_jsValueSource.asAddress(), scratch);
+ profile.emitReportValue(jit, scratch);
- m_jit.popToRestore(scratchTag);
- m_jit.popToRestore(scratchPayload);
+ jit.popToRestore(scratchTag);
+ jit.popToRestore(scratchPayload);
} else if (exit.m_jsValueSource.hasKnownTag()) {
GPRReg scratchTag = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.payloadGPR());
- m_jit.pushToSave(scratchTag);
- m_jit.move(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), scratchTag);
+ jit.pushToSave(scratchTag);
+ jit.move(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), scratchTag);
JSValueRegs value(scratchTag, exit.m_jsValueSource.payloadGPR());
- profile.emitReportValue(m_jit, value);
- m_jit.popToRestore(scratchTag);
+ profile.emitReportValue(jit, value);
+ jit.popToRestore(scratchTag);
} else
- profile.emitReportValue(m_jit, exit.m_jsValueSource.regs());
+ profile.emitReportValue(jit, exit.m_jsValueSource.regs());
}
}
case UnboxedInt32InGPR:
case UnboxedBooleanInGPR:
case UnboxedCellInGPR:
- m_jit.store32(
+ jit.store32(
recovery.gpr(),
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
break;
case InPair:
- m_jit.store32(
+ jit.store32(
recovery.tagGPR(),
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
- m_jit.store32(
+ jit.store32(
recovery.payloadGPR(),
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
break;
switch (recovery.technique()) {
case UnboxedDoubleInFPR:
case InFPR:
- m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
- m_jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));
+ jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
+ jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));
break;
default:
case DoubleDisplacedInJSStack:
case CellDisplacedInJSStack:
case BooleanDisplacedInJSStack:
- m_jit.load32(
+ jit.load32(
AssemblyHelpers::tagFor(recovery.virtualRegister()),
GPRInfo::regT0);
- m_jit.load32(
+ jit.load32(
AssemblyHelpers::payloadFor(recovery.virtualRegister()),
GPRInfo::regT1);
- m_jit.store32(
+ jit.store32(
GPRInfo::regT0,
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
- m_jit.store32(
+ jit.store32(
GPRInfo::regT1,
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
break;
// Need to ensure that the stack pointer accounts for the worst-case stack usage at exit. This
// could toast some stack that the DFG used. We need to do it before storing to stack offsets
// used by baseline.
- m_jit.addPtr(
+ jit.addPtr(
CCallHelpers::TrustedImm32(
- -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
+ -jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
// Restore the DFG callee saves and then save the ones the baseline JIT uses.
- m_jit.emitRestoreCalleeSaves();
- m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
+ jit.emitRestoreCalleeSaves();
+ jit.emitSaveCalleeSavesFor(jit.baselineCodeBlock());
if (exit.isExceptionHandler())
- m_jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
+ jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
// Do all data format conversions and store the results into the stack.
const ValueRecovery& recovery = operands[index];
VirtualRegister reg = operands.virtualRegisterForIndex(index);
- if (reg.isLocal() && reg.toLocal() < static_cast<int>(m_jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters()))
+ if (reg.isLocal() && reg.toLocal() < static_cast<int>(jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters()))
continue;
int operand = reg.offset();
case InPair:
case DisplacedInJSStack:
case InFPR:
- m_jit.load32(
+ jit.load32(
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag,
GPRInfo::regT0);
- m_jit.load32(
+ jit.load32(
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload,
GPRInfo::regT1);
- m_jit.store32(
+ jit.store32(
GPRInfo::regT0,
AssemblyHelpers::tagFor(operand));
- m_jit.store32(
+ jit.store32(
GPRInfo::regT1,
AssemblyHelpers::payloadFor(operand));
break;
case UnboxedDoubleInFPR:
case DoubleDisplacedInJSStack:
- m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
- m_jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);
- m_jit.purifyNaN(FPRInfo::fpRegT0);
- m_jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand));
+ jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
+ jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);
+ jit.purifyNaN(FPRInfo::fpRegT0);
+ jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand));
break;
case UnboxedInt32InGPR:
case Int32DisplacedInJSStack:
- m_jit.load32(
+ jit.load32(
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload,
GPRInfo::regT0);
- m_jit.store32(
+ jit.store32(
AssemblyHelpers::TrustedImm32(JSValue::Int32Tag),
AssemblyHelpers::tagFor(operand));
- m_jit.store32(
+ jit.store32(
GPRInfo::regT0,
AssemblyHelpers::payloadFor(operand));
break;
case UnboxedCellInGPR:
case CellDisplacedInJSStack:
- m_jit.load32(
+ jit.load32(
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload,
GPRInfo::regT0);
- m_jit.store32(
+ jit.store32(
AssemblyHelpers::TrustedImm32(JSValue::CellTag),
AssemblyHelpers::tagFor(operand));
- m_jit.store32(
+ jit.store32(
GPRInfo::regT0,
AssemblyHelpers::payloadFor(operand));
break;
case UnboxedBooleanInGPR:
case BooleanDisplacedInJSStack:
- m_jit.load32(
+ jit.load32(
&bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload,
GPRInfo::regT0);
- m_jit.store32(
+ jit.store32(
AssemblyHelpers::TrustedImm32(JSValue::BooleanTag),
AssemblyHelpers::tagFor(operand));
- m_jit.store32(
+ jit.store32(
GPRInfo::regT0,
AssemblyHelpers::payloadFor(operand));
break;
case Constant:
- m_jit.store32(
+ jit.store32(
AssemblyHelpers::TrustedImm32(recovery.constant().tag()),
AssemblyHelpers::tagFor(operand));
- m_jit.store32(
+ jit.store32(
AssemblyHelpers::TrustedImm32(recovery.constant().payload()),
AssemblyHelpers::payloadFor(operand));
break;
// Note that we also roughly assume that the arguments might still be materialized outside of its
// inline call frame scope - but for now the DFG wouldn't do that.
- emitRestoreArguments(operands);
+ emitRestoreArguments(jit, operands);
// Adjust the old JIT's execute counter. Since we are exiting OSR, we know
// that all new calls into this code will go to the new JIT, so the execute
// counter to 0; otherwise we set the counter to
// counterValueForOptimizeAfterWarmUp().
- handleExitCounts(m_jit, exit);
+ handleExitCounts(jit, exit);
// Reify inlined call frames.
- reifyInlinedCallFrames(m_jit, exit);
+ reifyInlinedCallFrames(jit, exit);
// And finish.
- adjustAndJumpToTarget(vm, m_jit, exit);
+ adjustAndJumpToTarget(vm, jit, exit);
}
} } // namespace JSC::DFG
/*
- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
namespace JSC { namespace DFG {
-void OSRExitCompiler::compileExit(VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
+void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
{
- m_jit.jitAssertTagsInPlace();
+ jit.jitAssertTagsInPlace();
// Pro-forma stuff.
if (Options::printEachOSRExit()) {
SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
- debugInfo->codeBlock = m_jit.codeBlock();
+ debugInfo->codeBlock = jit.codeBlock();
debugInfo->kind = exit.m_kind;
debugInfo->bytecodeOffset = exit.m_codeOrigin.bytecodeIndex;
- m_jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo);
+ jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo);
}
// Perform speculation recovery. This only comes into play when an operation
if (recovery) {
switch (recovery->type()) {
case SpeculativeAdd:
- m_jit.sub32(recovery->src(), recovery->dest());
- m_jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());
+ jit.sub32(recovery->src(), recovery->dest());
+ jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());
break;
case SpeculativeAddImmediate:
- m_jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());
- m_jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());
+ jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());
+ jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());
break;
case BooleanSpeculationCheck:
- m_jit.xor64(AssemblyHelpers::TrustedImm32(static_cast<int32_t>(ValueFalse)), recovery->dest());
+ jit.xor64(AssemblyHelpers::TrustedImm32(static_cast<int32_t>(ValueFalse)), recovery->dest());
break;
default:
// property access, or due to an array profile).
CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile;
- if (ArrayProfile* arrayProfile = m_jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {
+ if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {
GPRReg usedRegister;
if (exit.m_jsValueSource.isAddress())
usedRegister = exit.m_jsValueSource.base();
scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister, scratch1);
if (isARM64()) {
- m_jit.pushToSave(scratch1);
- m_jit.pushToSave(scratch2);
+ jit.pushToSave(scratch1);
+ jit.pushToSave(scratch2);
} else {
- m_jit.push(scratch1);
- m_jit.push(scratch2);
+ jit.push(scratch1);
+ jit.push(scratch2);
}
GPRReg value;
if (exit.m_jsValueSource.isAddress()) {
value = scratch1;
- m_jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value);
+ jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value);
} else
value = exit.m_jsValueSource.gpr();
- m_jit.load32(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);
- m_jit.store32(scratch1, arrayProfile->addressOfLastSeenStructureID());
- m_jit.load8(AssemblyHelpers::Address(value, JSCell::indexingTypeAndMiscOffset()), scratch1);
- m_jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);
- m_jit.lshift32(scratch1, scratch2);
- m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
+ jit.load32(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);
+ jit.store32(scratch1, arrayProfile->addressOfLastSeenStructureID());
+ jit.load8(AssemblyHelpers::Address(value, JSCell::indexingTypeAndMiscOffset()), scratch1);
+ jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);
+ jit.lshift32(scratch1, scratch2);
+ jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
if (isARM64()) {
- m_jit.popToRestore(scratch2);
- m_jit.popToRestore(scratch1);
+ jit.popToRestore(scratch2);
+ jit.popToRestore(scratch1);
} else {
- m_jit.pop(scratch2);
- m_jit.pop(scratch1);
+ jit.pop(scratch2);
+ jit.pop(scratch1);
}
}
}
if (exit.m_jsValueSource.isAddress()) {
// We can't be sure that we have a spare register. So use the tagTypeNumberRegister,
// since we know how to restore it.
- m_jit.load64(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), GPRInfo::tagTypeNumberRegister);
- profile.emitReportValue(m_jit, JSValueRegs(GPRInfo::tagTypeNumberRegister));
- m_jit.move(AssemblyHelpers::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
+ jit.load64(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), GPRInfo::tagTypeNumberRegister);
+ profile.emitReportValue(jit, JSValueRegs(GPRInfo::tagTypeNumberRegister));
+ jit.move(AssemblyHelpers::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
} else
- profile.emitReportValue(m_jit, JSValueRegs(exit.m_jsValueSource.gpr()));
+ profile.emitReportValue(jit, JSValueRegs(exit.m_jsValueSource.gpr()));
}
}
case UnboxedInt52InGPR:
case UnboxedStrictInt52InGPR:
case UnboxedCellInGPR:
- m_jit.store64(recovery.gpr(), scratch + index);
+ jit.store64(recovery.gpr(), scratch + index);
break;
default:
switch (recovery.technique()) {
case UnboxedDoubleInFPR:
case InFPR:
- m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
- m_jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));
+ jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
+ jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));
break;
default:
case DoubleDisplacedInJSStack:
case Int52DisplacedInJSStack:
case StrictInt52DisplacedInJSStack:
- m_jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0);
- m_jit.store64(GPRInfo::regT0, scratch + index);
+ jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0);
+ jit.store64(GPRInfo::regT0, scratch + index);
break;
default:
// Need to ensure that the stack pointer accounts for the worst-case stack usage at exit. This
// could toast some stack that the DFG used. We need to do it before storing to stack offsets
// used by baseline.
- m_jit.addPtr(
+ jit.addPtr(
CCallHelpers::TrustedImm32(
- -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
+ -jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
// Restore the DFG callee saves and then save the ones the baseline JIT uses.
- m_jit.emitRestoreCalleeSaves();
- m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
+ jit.emitRestoreCalleeSaves();
+ jit.emitSaveCalleeSavesFor(jit.baselineCodeBlock());
// The tag registers are needed to materialize recoveries below.
- m_jit.emitMaterializeTagCheckRegisters();
+ jit.emitMaterializeTagCheckRegisters();
if (exit.isExceptionHandler())
- m_jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
+ jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
// Do all data format conversions and store the results into the stack.
const ValueRecovery& recovery = operands[index];
VirtualRegister reg = operands.virtualRegisterForIndex(index);
- if (reg.isLocal() && reg.toLocal() < static_cast<int>(m_jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters()))
+ if (reg.isLocal() && reg.toLocal() < static_cast<int>(jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters()))
continue;
int operand = reg.offset();
case CellDisplacedInJSStack:
case BooleanDisplacedInJSStack:
case InFPR:
- m_jit.load64(scratch + index, GPRInfo::regT0);
- m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+ jit.load64(scratch + index, GPRInfo::regT0);
+ jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
break;
case UnboxedInt32InGPR:
case Int32DisplacedInJSStack:
- m_jit.load64(scratch + index, GPRInfo::regT0);
- m_jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0);
- m_jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0);
- m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+ jit.load64(scratch + index, GPRInfo::regT0);
+ jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0);
+ jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0);
+ jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
break;
case UnboxedInt52InGPR:
case Int52DisplacedInJSStack:
- m_jit.load64(scratch + index, GPRInfo::regT0);
- m_jit.rshift64(
+ jit.load64(scratch + index, GPRInfo::regT0);
+ jit.rshift64(
AssemblyHelpers::TrustedImm32(JSValue::int52ShiftAmount), GPRInfo::regT0);
- m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
- m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+ jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
+ jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
break;
case UnboxedStrictInt52InGPR:
case StrictInt52DisplacedInJSStack:
- m_jit.load64(scratch + index, GPRInfo::regT0);
- m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
- m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+ jit.load64(scratch + index, GPRInfo::regT0);
+ jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
+ jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
break;
case UnboxedDoubleInFPR:
case DoubleDisplacedInJSStack:
- m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
- m_jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);
- m_jit.purifyNaN(FPRInfo::fpRegT0);
- m_jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
- m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+ jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
+ jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);
+ jit.purifyNaN(FPRInfo::fpRegT0);
+ jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
+ jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
break;
case Constant:
- m_jit.store64(
+ jit.store64(
AssemblyHelpers::TrustedImm64(JSValue::encode(recovery.constant())),
AssemblyHelpers::addressFor(operand));
break;
// Note that we also roughly assume that the arguments might still be materialized outside of its
// inline call frame scope - but for now the DFG wouldn't do that.
- emitRestoreArguments(operands);
+ emitRestoreArguments(jit, operands);
// Adjust the old JIT's execute counter. Since we are exiting OSR, we know
// that all new calls into this code will go to the new JIT, so the execute
// counter to 0; otherwise we set the counter to
// counterValueForOptimizeAfterWarmUp().
- handleExitCounts(m_jit, exit);
+ handleExitCounts(jit, exit);
// Reify inlined call frames.
- reifyInlinedCallFrames(m_jit, exit);
+ reifyInlinedCallFrames(jit, exit);
// And finish.
- adjustAndJumpToTarget(vm, m_jit, exit);
+ adjustAndJumpToTarget(vm, jit, exit);
}
} } // namespace JSC::DFG
LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID);
- patchBuffer.link(functionCall, compileOSRExit);
+ patchBuffer.link(functionCall, OSRExit::compileOSRExit);
return FINALIZE_CODE(patchBuffer, ("DFG OSR exit generation thunk"));
}