diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGThunks.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGThunks.cpp | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGThunks.cpp b/Source/JavaScriptCore/dfg/DFGThunks.cpp index c0935b95a..38bdd11d1 100644 --- a/Source/JavaScriptCore/dfg/DFGThunks.cpp +++ b/Source/JavaScriptCore/dfg/DFGThunks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,15 +30,22 @@ #include "CCallHelpers.h" #include "DFGOSRExitCompiler.h" +#include "DFGJITCode.h" #include "FPRInfo.h" #include "GPRInfo.h" +#include "LinkBuffer.h" #include "MacroAssembler.h" +#include "JSCInlines.h" +#include "DFGOSRExitCompilerCommon.h" namespace JSC { namespace DFG { MacroAssemblerCodeRef osrExitGenerationThunkGenerator(VM* vm) { MacroAssembler jit; + + // This needs to happen before we use the scratch buffer because this function also uses the scratch buffer. + adjustFrameAndStackInOSRExitCompilerThunk<DFG::JITCode>(jit, vm, JITCode::DFGJIT); size_t scratchSize = sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters); ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(scratchSize); @@ -86,13 +93,57 @@ MacroAssemblerCodeRef osrExitGenerationThunkGenerator(VM* vm) jit.jump(MacroAssembler::AbsoluteAddress(&vm->osrExitJumpDestination)); - LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID); + LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID); patchBuffer.link(functionCall, compileOSRExit); return FINALIZE_CODE(patchBuffer, ("DFG OSR exit generation thunk")); } +MacroAssemblerCodeRef osrEntryThunkGenerator(VM* vm) +{ + AssemblyHelpers jit(vm, nullptr); + + // We get passed the address of a scratch buffer. The first 8-byte slot of the buffer + // is the frame size. The second 8-byte slot is the pointer to where we are supposed to + // jump. The remaining bytes are the new call frame header followed by the locals. + + ptrdiff_t offsetOfFrameSize = 0; // This is the DFG frame count. + ptrdiff_t offsetOfTargetPC = offsetOfFrameSize + sizeof(EncodedJSValue); + ptrdiff_t offsetOfPayload = offsetOfTargetPC + sizeof(EncodedJSValue); + ptrdiff_t offsetOfLocals = offsetOfPayload + sizeof(Register) * CallFrame::headerSizeInRegisters; + + jit.move(GPRInfo::returnValueGPR2, GPRInfo::regT0); + jit.loadPtr(MacroAssembler::Address(GPRInfo::regT0, offsetOfFrameSize), GPRInfo::regT1); // Load the frame size. + jit.move(GPRInfo::regT1, GPRInfo::regT2); + jit.lshiftPtr(MacroAssembler::Imm32(3), GPRInfo::regT2); + jit.move(GPRInfo::callFrameRegister, MacroAssembler::stackPointerRegister); + jit.subPtr(GPRInfo::regT2, MacroAssembler::stackPointerRegister); + + MacroAssembler::Label loop = jit.label(); + jit.subPtr(MacroAssembler::TrustedImm32(1), GPRInfo::regT1); + jit.move(GPRInfo::regT1, GPRInfo::regT4); + jit.negPtr(GPRInfo::regT4); + jit.load32(MacroAssembler::BaseIndex(GPRInfo::regT0, GPRInfo::regT1, MacroAssembler::TimesEight, offsetOfLocals), GPRInfo::regT2); + jit.load32(MacroAssembler::BaseIndex(GPRInfo::regT0, GPRInfo::regT1, MacroAssembler::TimesEight, offsetOfLocals + sizeof(int32_t)), GPRInfo::regT3); + jit.store32(GPRInfo::regT2, MacroAssembler::BaseIndex(GPRInfo::callFrameRegister, GPRInfo::regT4, MacroAssembler::TimesEight, -static_cast<intptr_t>(sizeof(Register)))); + jit.store32(GPRInfo::regT3, MacroAssembler::BaseIndex(GPRInfo::callFrameRegister, GPRInfo::regT4, MacroAssembler::TimesEight, -static_cast<intptr_t>(sizeof(Register)) + static_cast<intptr_t>(sizeof(int32_t)))); + jit.branchPtr(MacroAssembler::NotEqual, GPRInfo::regT1, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(-static_cast<intptr_t>(CallFrame::headerSizeInRegisters)))).linkTo(loop, &jit); + + jit.loadPtr(MacroAssembler::Address(GPRInfo::regT0, offsetOfTargetPC), GPRInfo::regT1); + MacroAssembler::Jump ok = jit.branchPtr(MacroAssembler::Above, GPRInfo::regT1, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(static_cast<intptr_t>(1000)))); + jit.abortWithReason(DFGUnreasonableOSREntryJumpDestination); + + ok.link(&jit); + jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(); + jit.emitMaterializeTagCheckRegisters(); + + jit.jump(GPRInfo::regT1); + + LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID); + return FINALIZE_CODE(patchBuffer, ("DFG OSR entry thunk")); +} + } } // namespace JSC::DFG #endif // ENABLE(DFG_JIT) |