X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174..refs/heads/master:/dfg/DFGThunks.cpp diff --git a/dfg/DFGThunks.cpp b/dfg/DFGThunks.cpp index 1ed46c1..560aedf 100644 --- a/dfg/DFGThunks.cpp +++ b/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 @@ -28,31 +28,39 @@ #if ENABLE(DFG_JIT) -#include "DFGFPRInfo.h" -#include "DFGGPRInfo.h" +#include "CCallHelpers.h" #include "DFGOSRExitCompiler.h" +#include "FPRInfo.h" +#include "GPRInfo.h" +#include "LinkBuffer.h" #include "MacroAssembler.h" +#include "JSCInlines.h" namespace JSC { namespace DFG { -MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData* globalData) +MacroAssemblerCodeRef osrExitGenerationThunkGenerator(VM* vm) { MacroAssembler jit; size_t scratchSize = sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters); - ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(scratchSize); + ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(scratchSize); EncodedJSValue* buffer = static_cast(scratchBuffer->dataBuffer()); - for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) - jit.storePtr(GPRInfo::toRegister(i), buffer + i); + for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { +#if USE(JSVALUE64) + jit.store64(GPRInfo::toRegister(i), buffer + i); +#else + jit.store32(GPRInfo::toRegister(i), buffer + i); +#endif + } for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0); - jit.storeDouble(FPRInfo::toRegister(i), GPRInfo::regT0); + jit.storeDouble(FPRInfo::toRegister(i), MacroAssembler::Address(GPRInfo::regT0)); } // Tell GC mark phase how much of the scratch buffer is active during call. jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::regT0); - jit.storePtr(MacroAssembler::TrustedImmPtr(scratchSize), GPRInfo::regT0); + jit.storePtr(MacroAssembler::TrustedImmPtr(scratchSize), MacroAssembler::Address(GPRInfo::regT0)); // Set up one argument. #if CPU(X86) @@ -64,22 +72,67 @@ MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData* globalData) MacroAssembler::Call functionCall = jit.call(); jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::regT0); - jit.storePtr(MacroAssembler::TrustedImmPtr(0), GPRInfo::regT0); + jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(GPRInfo::regT0)); for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0); - jit.loadDouble(GPRInfo::regT0, FPRInfo::toRegister(i)); + jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::toRegister(i)); + } + for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { +#if USE(JSVALUE64) + jit.load64(buffer + i, GPRInfo::toRegister(i)); +#else + jit.load32(buffer + i, GPRInfo::toRegister(i)); +#endif } - for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) - jit.loadPtr(buffer + i, GPRInfo::toRegister(i)); - jit.jump(MacroAssembler::AbsoluteAddress(&globalData->osrExitJumpDestination)); + jit.jump(MacroAssembler::AbsoluteAddress(&vm->osrExitJumpDestination)); - LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID); + LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID); patchBuffer.link(functionCall, compileOSRExit); - return patchBuffer.finalizeCode(); + return FINALIZE_CODE(patchBuffer, ("DFG OSR exit generation thunk")); +} + +MacroAssemblerCodeRef osrEntryThunkGenerator(VM* vm) +{ + MacroAssembler jit; + + // 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) * JSStack::CallFrameHeaderSize; + + 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(sizeof(Register)))); + jit.store32(GPRInfo::regT3, MacroAssembler::BaseIndex(GPRInfo::callFrameRegister, GPRInfo::regT4, MacroAssembler::TimesEight, -static_cast(sizeof(Register)) + static_cast(sizeof(int32_t)))); + jit.branchPtr(MacroAssembler::NotEqual, GPRInfo::regT1, MacroAssembler::TrustedImmPtr(bitwise_cast(-static_cast(JSStack::CallFrameHeaderSize)))).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(static_cast(1000)))); + jit.abortWithReason(DFGUnreasonableOSREntryJumpDestination); + ok.link(&jit); + jit.jump(GPRInfo::regT1); + + LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID); + return FINALIZE_CODE(patchBuffer, ("DFG OSR entry thunk")); } } } // namespace JSC::DFG