# HG changeset patch # User twisti # Date 1398908504 36000 # Node ID bb97b75d1d65f32bc00e1d8c6249c8e146fcd4e4 # Parent 6e036e2a2091cb78411edd93c646e9b54b1220e8 AMD64: implemented DeoptimizationStub.deoptimizationHandler diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Wed Apr 30 15:41:44 2014 -1000 @@ -79,6 +79,14 @@ } } + public final void movptr(Register dst, AMD64Address src) { + movq(dst, src); + } + + public final void movptr(AMD64Address dst, Register src) { + movq(dst, src); + } + public final void movptr(AMD64Address dst, int src) { movslq(dst, src); } @@ -277,7 +285,7 @@ /** * Emit code to save a given set of callee save registers in the {@linkplain CalleeSaveLayout * CSA} within the frame. - * + * * @param csl the description of the CSA * @param frameToCSA offset from the frame pointer to the CSA */ diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Wed Apr 30 15:41:44 2014 -1000 @@ -27,7 +27,6 @@ import java.util.*; import java.util.Map.Entry; -import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.*; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Wed Apr 30 15:41:44 2014 -1000 @@ -28,7 +28,6 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.match.MatchPattern.MatchResultCode; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java Wed Apr 30 15:41:44 2014 -1000 @@ -35,7 +35,7 @@ public AMD64DeoptimizationStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { super(providers, target, linkage); - registerConfig = new AMD64HotSpotRegisterConfig(target.arch, HotSpotGraalRuntime.runtime().getConfig(), new Register[]{rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r13, r14}); + registerConfig = new AMD64HotSpotRegisterConfig(target.arch, HotSpotGraalRuntime.runtime().getConfig(), new Register[]{rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r13, r14}); } @Override diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.amd64; -import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Apr 30 15:41:44 2014 -1000 @@ -312,7 +312,7 @@ MarkId.recordMark(crb, MarkId.EXCEPTION_HANDLER_ENTRY); AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null); MarkId.recordMark(crb, MarkId.DEOPT_HANDLER_ENTRY); - AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null); + AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(DEOPTIMIZATION_HANDLER), null, false, null); } else { // No need to emit the stubs for entries back into the method since // it has no calls that can cause such "return" entries diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.amd64; -import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -31,6 +31,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -41,7 +42,7 @@ @Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME") final class AMD64HotSpotEnterUnpackFramesStackFrameOp extends AMD64LIRInstruction { - private final Register thread; + private final Register threadRegister; private final int threadLastJavaSpOffset; private final int threadLastJavaPcOffset; private final int threadLastJavaFpOffset; @@ -49,32 +50,51 @@ @Alive(REG) AllocatableValue senderSp; @Alive(REG) AllocatableValue senderFp; - AMD64HotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset, AllocatableValue framePc, AllocatableValue senderSp, - AllocatableValue senderFp) { - this.thread = thread; + private final SaveRegistersOp saveRegisterOp; + + AMD64HotSpotEnterUnpackFramesStackFrameOp(Register threadRegister, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset, AllocatableValue framePc, + AllocatableValue senderSp, AllocatableValue senderFp, SaveRegistersOp saveRegisterOp) { + this.threadRegister = threadRegister; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; this.threadLastJavaFpOffset = threadLastJavaFpOffset; this.framePc = framePc; this.senderSp = senderSp; this.senderFp = senderFp; + this.saveRegisterOp = saveRegisterOp; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - final int totalFrameSize = crb.frameMap.totalFrameSize(); + FrameMap frameMap = crb.frameMap; + RegisterConfig registerConfig = frameMap.registerConfig; + RegisterSaveLayout registerSaveLayout = saveRegisterOp.getMap(frameMap); + Register stackPointerRegister = registerConfig.getFrameRegister(); + final int totalFrameSize = frameMap.totalFrameSize(); + + // Push return address. masm.push(asRegister(framePc)); + + // Push base pointer. masm.push(asRegister(senderFp)); - masm.movq(rbp, rsp); + masm.movq(rbp, stackPointerRegister); /* * Allocate a full sized frame. Since return address and base pointer are already in place * (see above) we allocate two words less. */ - masm.decrementq(rsp, totalFrameSize - 2 * crb.target.wordSize); + masm.decrementq(stackPointerRegister, totalFrameSize - 2 * crb.target.wordSize); + + // Save return registers after moving the frame. + final int stackSlotSize = frameMap.stackSlotSize(); + Register integerResultRegister = registerConfig.getReturnRegister(Kind.Long); + masm.movptr(new AMD64Address(stackPointerRegister, registerSaveLayout.registerToSlot(integerResultRegister) * stackSlotSize), integerResultRegister); + + Register floatResultRegister = registerConfig.getReturnRegister(Kind.Double); + masm.movdbl(new AMD64Address(stackPointerRegister, registerSaveLayout.registerToSlot(floatResultRegister) * stackSlotSize), floatResultRegister); // Set up last Java values. - masm.movq(new AMD64Address(thread, threadLastJavaSpOffset), rsp); + masm.movq(new AMD64Address(threadRegister, threadLastJavaSpOffset), stackPointerRegister); /* * Save the PC since it cannot easily be retrieved using the last Java SP after we aligned @@ -82,12 +102,12 @@ * blob. */ masm.leaq(rax, new AMD64Address(rip, 0)); - masm.movq(new AMD64Address(thread, threadLastJavaPcOffset), rax); + masm.movq(new AMD64Address(threadRegister, threadLastJavaPcOffset), rax); // Use BP because the frames look interpreted now. - masm.movq(new AMD64Address(thread, threadLastJavaFpOffset), rbp); + masm.movq(new AMD64Address(threadRegister, threadLastJavaFpOffset), rbp); // Align the stack for the following unpackFrames call. - masm.andq(rsp, -(crb.target.stackAlignment)); + masm.andq(stackPointerRegister, -(crb.target.stackAlignment)); } } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Wed Apr 30 15:41:44 2014 -1000 @@ -26,10 +26,10 @@ import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.api.meta.Value.*; -import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.*; import static com.oracle.graal.hotspot.replacements.CRC32Substitutions.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.*; @@ -63,7 +63,8 @@ register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, null, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, exceptionCc, null, NOT_REEXECUTABLE, ANY_LOCATION)); - link(new AMD64DeoptimizationStub(providers, target, registerStubCall(UNCOMMON_TRAP_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS))); + link(new AMD64DeoptimizationStub(providers, target, registerStubCall(DEOPTIMIZATION_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS))); + link(new AMD64UncommonTrapStub(providers, target, registerStubCall(UNCOMMON_TRAP_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS))); // When the java.ext.dirs property is modified then the crypto classes might not be found. // If that's the case we ignore the ClassNotFoundException and continue since we cannot diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Apr 30 15:41:44 2014 -1000 @@ -41,6 +41,7 @@ import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; @@ -189,8 +190,8 @@ super.emitForeignCall(linkage, result, arguments, temps, info); } - public void emitLeaveCurrentStackFrame() { - append(new AMD64HotSpotLeaveCurrentStackFrameOp()); + public void emitLeaveCurrentStackFrame(SaveRegistersOp saveRegisterOp) { + append(new AMD64HotSpotLeaveCurrentStackFrameOp(saveRegisterOp)); } public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { @@ -199,18 +200,18 @@ append(new AMD64HotSpotLeaveDeoptimizedStackFrameOp(frameSizeVariable, initialInfoVariable)); } - public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { - Register thread = getProviders().getRegisters().getThreadRegister(); + public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp, SaveRegistersOp saveRegisterOp) { + Register threadRegister = getProviders().getRegisters().getThreadRegister(); Variable framePcVariable = load(framePc); Variable senderSpVariable = load(senderSp); Variable senderFpVariable = load(senderFp); - append(new AMD64HotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset(), framePcVariable, - senderSpVariable, senderFpVariable)); + append(new AMD64HotSpotEnterUnpackFramesStackFrameOp(threadRegister, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset(), framePcVariable, + senderSpVariable, senderFpVariable, saveRegisterOp)); } - public void emitLeaveUnpackFramesStackFrame() { - Register thread = getProviders().getRegisters().getThreadRegister(); - append(new AMD64HotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset())); + public void emitLeaveUnpackFramesStackFrame(SaveRegistersOp saveRegisterOp) { + Register threadRegister = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotLeaveUnpackFramesStackFrameOp(threadRegister, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset(), saveRegisterOp)); } /** @@ -321,6 +322,21 @@ return result; } + public Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) { + ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(DeoptimizationFetchUnrollInfoCallNode.FETCH_UNROLL_INFO); + + Register thread = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread)); + Variable result = super.emitForeignCall(linkage, null, thread.asValue(Kind.Long)); + append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread)); + + Map calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo(); + assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); + calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp); + + return result; + } + protected AMD64ZapRegistersOp emitZapRegisters(Register[] zappedRegisters, Constant[] zapValues) { AMD64ZapRegistersOp zap = new AMD64ZapRegistersOp(zappedRegisters, zapValues); append(zap); diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -24,19 +24,50 @@ import static com.oracle.graal.amd64.AMD64.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.asm.*; /** - * Pops the current frame off the stack including the return address. + * Pops the current frame off the stack including the return address and restores the return + * registers stored on the stack. */ @Opcode("LEAVE_CURRENT_STACK_FRAME") final class AMD64HotSpotLeaveCurrentStackFrameOp extends AMD64HotSpotEpilogueOp { + private final SaveRegistersOp saveRegisterOp; + + public AMD64HotSpotLeaveCurrentStackFrameOp(SaveRegistersOp saveRegisterOp) { + this.saveRegisterOp = saveRegisterOp; + } + @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + FrameMap frameMap = crb.frameMap; + RegisterConfig registerConfig = frameMap.registerConfig; + RegisterSaveLayout registerSaveLayout = saveRegisterOp.getMap(frameMap); + Register stackPointer = registerConfig.getFrameRegister(); + + // Restore integer result register. + final int stackSlotSize = frameMap.stackSlotSize(); + Register integerResultRegister = registerConfig.getReturnRegister(Kind.Long); + masm.movptr(integerResultRegister, new AMD64Address(stackPointer, registerSaveLayout.registerToSlot(integerResultRegister) * stackSlotSize)); + masm.movptr(rdx, new AMD64Address(stackPointer, registerSaveLayout.registerToSlot(rdx) * stackSlotSize)); + + // Restore float result register. + Register floatResultRegister = registerConfig.getReturnRegister(Kind.Double); + masm.movdbl(floatResultRegister, new AMD64Address(stackPointer, registerSaveLayout.registerToSlot(floatResultRegister) * stackSlotSize)); + + /* + * All of the register save area will be popped of the stack. Only the return address + * remains. + */ leaveFrameAndRestoreRbp(crb, masm); - masm.addq(rsp, crb.target.arch.getReturnAddressSize()); + + // Remove return address. + masm.addq(stackPointer, crb.target.arch.getReturnAddressSize()); } } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,13 +26,14 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; /** - * Pops the current frame off the stack including the return address. + * Pops a deoptimized stack frame off the stack including the return address. */ @Opcode("LEAVE_DEOPTIMIZED_STACK_FRAME") final class AMD64HotSpotLeaveDeoptimizedStackFrameOp extends AMD64HotSpotEpilogueOp { @@ -47,9 +48,13 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - masm.addq(rsp, asRegister(frameSize)); - // Restore the frame pointer before stack bang because if a stack overflow is thrown it - // needs to be pushed (and preserved). + Register stackPointer = crb.frameMap.registerConfig.getFrameRegister(); + masm.addq(stackPointer, asRegister(frameSize)); + + /* + * Restore the frame pointer before stack bang because if a stack overflow is thrown it + * needs to be pushed (and preserved). + */ masm.movq(rbp, asRegister(framePointer)); } } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -22,12 +22,12 @@ */ package com.oracle.graal.hotspot.amd64; -import static com.oracle.graal.amd64.AMD64.*; - import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -38,26 +38,42 @@ @Opcode("LEAVE_UNPACK_FRAMES_STACK_FRAME") final class AMD64HotSpotLeaveUnpackFramesStackFrameOp extends AMD64LIRInstruction { - private final Register thread; + private final Register threadRegister; private final int threadLastJavaSpOffset; private final int threadLastJavaPcOffset; private final int threadLastJavaFpOffset; - AMD64HotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset) { - this.thread = thread; + private final SaveRegistersOp saveRegisterOp; + + AMD64HotSpotLeaveUnpackFramesStackFrameOp(Register threadRegister, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset, SaveRegistersOp saveRegisterOp) { + this.threadRegister = threadRegister; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; this.threadLastJavaFpOffset = threadLastJavaFpOffset; + this.saveRegisterOp = saveRegisterOp; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + FrameMap frameMap = crb.frameMap; + RegisterConfig registerConfig = frameMap.registerConfig; + RegisterSaveLayout registerSaveLayout = saveRegisterOp.getMap(frameMap); + Register stackPointerRegister = registerConfig.getFrameRegister(); + // Restore stack pointer. - masm.movq(rsp, new AMD64Address(thread, threadLastJavaSpOffset)); + masm.movq(stackPointerRegister, new AMD64Address(threadRegister, threadLastJavaSpOffset)); // Clear last Java frame values. - masm.movslq(new AMD64Address(thread, threadLastJavaSpOffset), 0); - masm.movslq(new AMD64Address(thread, threadLastJavaPcOffset), 0); - masm.movslq(new AMD64Address(thread, threadLastJavaFpOffset), 0); + masm.movslq(new AMD64Address(threadRegister, threadLastJavaSpOffset), 0); + masm.movslq(new AMD64Address(threadRegister, threadLastJavaPcOffset), 0); + masm.movslq(new AMD64Address(threadRegister, threadLastJavaFpOffset), 0); + + // Restore return values. + final int stackSlotSize = frameMap.stackSlotSize(); + Register integerResultRegister = registerConfig.getReturnRegister(Kind.Long); + masm.movptr(integerResultRegister, new AMD64Address(stackPointerRegister, registerSaveLayout.registerToSlot(integerResultRegister) * stackSlotSize)); + + Register floatResultRegister = registerConfig.getReturnRegister(Kind.Double); + masm.movdbl(floatResultRegister, new AMD64Address(stackPointerRegister, registerSaveLayout.registerToSlot(floatResultRegister) * stackSlotSize)); } } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64UncommonTrapStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64UncommonTrapStub.java Wed Apr 30 15:41:44 2014 -1000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.amd64.AMD64.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.stubs.*; + +final class AMD64UncommonTrapStub extends UncommonTrapStub { + + private RegisterConfig registerConfig; + + public AMD64UncommonTrapStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); + Register[] allocatable = new Register[]{rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r13, r14}; + registerConfig = new AMD64HotSpotRegisterConfig(target.arch, HotSpotGraalRuntime.runtime().getConfig(), allocatable); + } + + @Override + public RegisterConfig getRegisterConfig() { + return registerConfig; + } +} diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Wed Apr 30 15:41:44 2014 -1000 @@ -281,31 +281,8 @@ return result; } - public void emitLeaveCurrentStackFrame() { - throw GraalInternalError.unimplemented(); - } - - public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { - throw GraalInternalError.unimplemented(); - } - - public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { - throw GraalInternalError.unimplemented(); - } - - public void emitLeaveUnpackFramesStackFrame() { - throw GraalInternalError.unimplemented(); - } - public SaveRegistersOp emitSaveAllRegisters() { throw GraalInternalError.unimplemented(); } - public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { - throw GraalInternalError.unimplemented(); - } - - public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { - throw GraalInternalError.unimplemented(); - } } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java Wed Apr 30 15:41:44 2014 -1000 @@ -72,31 +72,8 @@ throw GraalInternalError.unimplemented(); } - public void emitLeaveCurrentStackFrame() { - throw GraalInternalError.unimplemented(); - } - - public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { - throw GraalInternalError.unimplemented(); - } - - public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { - throw GraalInternalError.unimplemented(); - } - - public void emitLeaveUnpackFramesStackFrame() { - throw GraalInternalError.unimplemented(); - } - public SaveRegistersOp emitSaveAllRegisters() { throw GraalInternalError.unimplemented(); } - public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { - throw GraalInternalError.unimplemented(); - } - - public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { - throw GraalInternalError.unimplemented(); - } } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.sparc; -import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.lir.*; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Apr 30 15:41:44 2014 -1000 @@ -232,7 +232,7 @@ MarkId.recordMark(crb, MarkId.EXCEPTION_HANDLER_ENTRY); SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null); MarkId.recordMark(crb, MarkId.DEOPT_HANDLER_ENTRY); - SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null); + SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(DEOPTIMIZATION_HANDLER), null, false, null); } else { // No need to emit the stubs for entries back into the method since // it has no calls that can cause such "return" entries diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Wed Apr 30 15:41:44 2014 -1000 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.sparc; -import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Wed Apr 30 15:41:44 2014 -1000 @@ -24,10 +24,10 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.api.meta.Value.*; -import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Apr 30 15:41:44 2014 -1000 @@ -300,7 +300,7 @@ return emitSaveRegisters(savedRegisters, savedRegisterLocations, false); } - public void emitLeaveCurrentStackFrame() { + public void emitLeaveCurrentStackFrame(SaveRegistersOp saveRegisterOp) { append(new SPARCHotSpotLeaveCurrentStackFrameOp()); } @@ -308,7 +308,7 @@ append(new SPARCHotSpotLeaveDeoptimizedStackFrameOp()); } - public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { + public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp, SaveRegistersOp saveRegisterOp) { Register thread = getProviders().getRegisters().getThreadRegister(); Variable framePcVariable = load(framePc); Variable senderSpVariable = load(senderSp); @@ -316,7 +316,7 @@ append(new SPARCHotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), framePcVariable, senderSpVariable, scratchVariable)); } - public void emitLeaveUnpackFramesStackFrame() { + public void emitLeaveUnpackFramesStackFrame(SaveRegistersOp saveRegisterOp) { Register thread = getProviders().getRegisters().getThreadRegister(); append(new SPARCHotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset())); } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Wed Apr 30 15:41:44 2014 -1000 @@ -45,11 +45,6 @@ public abstract class HotSpotBackend extends Backend { /** - * Descriptor for {@link DeoptimizationStub}. - */ - public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class); - - /** * Descriptor for {@link ExceptionHandlerStub}. This stub is called by the * {@linkplain HotSpotVMConfig#codeInstallerMarkIdExceptionHandlerEntry exception handler} in a * compiled method. @@ -57,11 +52,6 @@ public static final ForeignCallDescriptor EXCEPTION_HANDLER = new ForeignCallDescriptor("exceptionHandler", void.class, Object.class, Word.class); /** - * Descriptor for SharedRuntime::deopt_blob()->unpack(). - */ - public static final ForeignCallDescriptor DEOPT_HANDLER = new ForeignCallDescriptor("deoptHandler", void.class); - - /** * Descriptor for SharedRuntime::get_ic_miss_stub(). */ public static final ForeignCallDescriptor IC_MISS_HANDLER = new ForeignCallDescriptor("icMissHandler", void.class); diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Wed Apr 30 15:41:44 2014 -1000 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotHostBackend.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CompilationResult.Call; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Wed Apr 30 15:41:44 2014 -1000 @@ -31,6 +31,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.spi.*; /** @@ -39,6 +40,16 @@ public abstract class HotSpotHostBackend extends HotSpotBackend implements HostBackend { /** + * Descriptor for {@link DeoptimizationStub#deoptimizationHandler}. + */ + public static final ForeignCallDescriptor DEOPTIMIZATION_HANDLER = new ForeignCallDescriptor("deoptimizationHandler", void.class); + + /** + * Descriptor for {@link UncommonTrapStub#uncommonTrapHandler}. + */ + public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class); + + /** * This will be 0 if stack banging is disabled. */ protected final int pagesToBang; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Wed Apr 30 15:41:44 2014 -1000 @@ -24,8 +24,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.gen.*; @@ -43,21 +45,87 @@ */ void emitTailcall(Value[] args, Value address); - void emitLeaveCurrentStackFrame(); - - void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo); + void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason); - void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp); - - void emitLeaveUnpackFramesStackFrame(); - + /** + * Emits code for a {@link SaveAllRegistersNode}. + * + * @return a {@link SaveRegistersOp} operation + */ SaveRegistersOp emitSaveAllRegisters(); - void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason); + /** + * Emits code for a {@link LeaveCurrentStackFrameNode}. + * + * @param saveRegisterOp saved registers + */ + default void emitLeaveCurrentStackFrame(SaveRegistersOp saveRegisterOp) { + throw GraalInternalError.unimplemented(); + } + + /** + * Emits code for a {@link LeaveDeoptimizedStackFrameNode}. + * + * @param frameSize + * @param initialInfo + */ + default void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { + throw GraalInternalError.unimplemented(); + } + + /** + * Emits code for a {@link EnterUnpackFramesStackFrameNode}. + * + * @param framePc + * @param senderSp + * @param senderFp + * @param saveRegisterOp + */ + default void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp, SaveRegistersOp saveRegisterOp) { + throw GraalInternalError.unimplemented(); + } - void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo); + /** + * Emits code for a {@link LeaveUnpackFramesStackFrameNode}. + * + * @param saveRegisterOp + */ + default void emitLeaveUnpackFramesStackFrame(SaveRegistersOp saveRegisterOp) { + throw GraalInternalError.unimplemented(); + } + + /** + * Emits code for a {@link PushInterpreterFrameNode}. + * + * @param frameSize + * @param framePc + * @param senderSp + * @param initialInfo + */ + default void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { + throw GraalInternalError.unimplemented(); + } - Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp); + /** + * Emits code for a {@link UncommonTrapCallNode}. + * + * @param trapRequest + * @param saveRegisterOp + * @return a {@code Deoptimization::UnrollBlock} pointer + */ + default Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { + throw GraalInternalError.unimplemented(); + } + + /** + * Emits code for a {@link DeoptimizationFetchUnrollInfoCallNode}. + * + * @param saveRegisterOp + * @return a {@code Deoptimization::UnrollBlock} pointer + */ + default Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) { + throw GraalInternalError.unimplemented(); + } /** * Gets a stack slot for a lock at a given lock nesting depth. diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Apr 30 15:41:44 2014 -1000 @@ -1353,8 +1353,6 @@ return unsafe.getAddress(codeCacheHeap + codeHeapMemoryOffset + virtualSpaceHighBoundaryOffset); } - @Stable public long handleDeoptStub; - @HotSpotVMField(name = "StubRoutines::_aescrypt_encryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptEncryptBlockStub; @HotSpotVMField(name = "StubRoutines::_aescrypt_decryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptDecryptBlockStub; @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_encryptAESCrypt", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingEncryptAESCryptStub; diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Wed Apr 30 15:41:44 2014 -1000 @@ -103,7 +103,6 @@ public void initialize(HotSpotProviders providers, HotSpotVMConfig c) { TargetDescription target = providers.getCodeCache().getTarget(); - registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub(), NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Wed Apr 30 15:41:44 2014 -1000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.nodes; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.word.*; + +/** + * A call to the runtime code {@code Deoptimization::fetch_unroll_info}. + */ +@NodeInfo(allowedUsageTypes = {InputType.Memory}) +public class DeoptimizationFetchUnrollInfoCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi { + + @Input private SaveAllRegistersNode registerSaver; + private final ForeignCallsProvider foreignCalls; + public static final ForeignCallDescriptor FETCH_UNROLL_INFO = new ForeignCallDescriptor("fetchUnrollInfo", Word.class, Word.class); + + public DeoptimizationFetchUnrollInfoCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver) { + super(StampFactory.forKind(Kind.fromJavaClass(FETCH_UNROLL_INFO.getResultType()))); + this.registerSaver = (SaveAllRegistersNode) registerSaver; + this.foreignCalls = foreignCalls; + } + + @Override + public LocationIdentity[] getLocationIdentities() { + return foreignCalls.getKilledLocations(FETCH_UNROLL_INFO); + } + + public SaveRegistersOp getSaveRegistersOp() { + return registerSaver.getSaveRegistersOp(); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitDeoptimizationFetchUnrollInfoCall(getSaveRegistersOp()); + gen.setResult(this, result); + } + + @NodeIntrinsic + public static native Word fetchUnrollInfo(long registerSaver); + + public MemoryCheckpoint asMemoryCheckpoint() { + return null; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } +} diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java Wed Apr 30 15:41:44 2014 -1000 @@ -26,6 +26,7 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; @@ -39,12 +40,18 @@ @Input private ValueNode framePc; @Input private ValueNode senderSp; @Input private ValueNode senderFp; + @Input private SaveAllRegistersNode registerSaver; - public EnterUnpackFramesStackFrameNode(ValueNode framePc, ValueNode senderSp, ValueNode senderFp) { + public EnterUnpackFramesStackFrameNode(ValueNode framePc, ValueNode senderSp, ValueNode senderFp, ValueNode registerSaver) { super(StampFactory.forVoid()); this.framePc = framePc; this.senderSp = senderSp; this.senderFp = senderFp; + this.registerSaver = (SaveAllRegistersNode) registerSaver; + } + + private SaveRegistersOp getSaveRegistersOp() { + return registerSaver.getSaveRegistersOp(); } @Override @@ -52,9 +59,9 @@ Value operandValue = gen.operand(framePc); Value senderSpValue = gen.operand(senderSp); Value senderFpValue = gen.operand(senderFp); - ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitEnterUnpackFramesStackFrame(operandValue, senderSpValue, senderFpValue); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitEnterUnpackFramesStackFrame(operandValue, senderSpValue, senderFpValue, getSaveRegistersOp()); } @NodeIntrinsic - public static native void enterUnpackFramesStackFrame(Word framePc, Word senderSp, Word senderFp); + public static native void enterUnpackFramesStackFrame(Word framePc, Word senderSp, Word senderFp, long registerSaver); } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java Wed Apr 30 15:41:44 2014 -1000 @@ -24,6 +24,7 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -33,15 +34,22 @@ */ public class LeaveCurrentStackFrameNode extends FixedWithNextNode implements LIRLowerable { - public LeaveCurrentStackFrameNode() { + @Input private SaveAllRegistersNode registerSaver; + + public LeaveCurrentStackFrameNode(ValueNode registerSaver) { super(StampFactory.forVoid()); + this.registerSaver = (SaveAllRegistersNode) registerSaver; + } + + private SaveRegistersOp getSaveRegistersOp() { + return registerSaver.getSaveRegistersOp(); } @Override public void generate(NodeLIRBuilderTool gen) { - ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveCurrentStackFrame(); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveCurrentStackFrame(getSaveRegistersOp()); } @NodeIntrinsic - public static native void leaveCurrentStackFrame(); + public static native void leaveCurrentStackFrame(long registerSaver); } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java Wed Apr 30 15:41:44 2014 -1000 @@ -25,6 +25,7 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,15 +35,22 @@ */ public class LeaveUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable { - public LeaveUnpackFramesStackFrameNode() { + @Input private SaveAllRegistersNode registerSaver; + + public LeaveUnpackFramesStackFrameNode(ValueNode registerSaver) { super(StampFactory.forVoid()); + this.registerSaver = (SaveAllRegistersNode) registerSaver; + } + + private SaveRegistersOp getSaveRegistersOp() { + return registerSaver.getSaveRegistersOp(); } @Override public void generate(NodeLIRBuilderTool gen) { - ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveUnpackFramesStackFrame(); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveUnpackFramesStackFrame(getSaveRegistersOp()); } @NodeIntrinsic - public static native void leaveUnpackFramesStackFrame(); + public static native void leaveUnpackFramesStackFrame(long registerSaver); } diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Wed Apr 30 15:09:15 2014 -1000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Wed Apr 30 15:41:44 2014 -1000 @@ -45,30 +45,35 @@ * * The steps taken by this frame are as follows: * - * - push a dummy "register_save" and save the return values (O0, O1, F0/F1, G1) and all potentially - * live registers (at a pollpoint many registers can be live). + *
  • push a dummy "register_save" and save the return values (O0, O1, F0/F1, G1) and all + * potentially live registers (at a pollpoint many registers can be live). * - * - call the C routine: Deoptimization::fetch_unroll_info (this function returns information about - * the number and size of interpreter frames which are equivalent to the frame which is being + *
  • call the C routine: Deoptimization::fetch_unroll_info (this function returns information + * about the number and size of interpreter frames which are equivalent to the frame which is being * deoptimized) * - * - deallocate the unpack frame, restoring only results values. Other volatile registers will now + *
  • deallocate the unpack frame, restoring only results values. Other volatile registers will now * be captured in the vframeArray as needed. * - * - deallocate the deoptimization frame + *
  • deallocate the deoptimization frame * - * - in a loop using the information returned in the previous step push new interpreter frames (take - * care to propagate the return values through each new frame pushed) + *
  • in a loop using the information returned in the previous step push new interpreter frames + * (take care to propagate the return values through each new frame pushed) * - * - create a dummy "unpack_frame" and save the return values (O0, O1, F0) + *
  • create a dummy "unpack_frame" and save the return values (O0, O1, F0) * - * - call the C routine: Deoptimization::unpack_frames (this function lays out values on the + *
  • call the C routine: Deoptimization::unpack_frames (this function lays out values on the * interpreter frame which was just created) * - * - deallocate the dummy unpack_frame + *
  • deallocate the dummy unpack_frame + * + *
  • ensure that all the return values are correctly set and then do a return to the interpreter + * entry point * - * - ensure that all the return values are correctly set and then do a return to the interpreter - * entry point + *

    + * ATTENTION: We cannot do any complicated operations e.g. logging via printf in this snippet + * because we change the current stack layout and so the code is very sensitive to register + * allocation. */ public class DeoptimizationStub extends SnippetStub { @@ -97,31 +102,15 @@ } /** - * Uncommon trap. - * - * We save the argument return registers. We call the first C routine, fetch_unroll_info(). This - * routine captures the return values and returns a structure which describes the current frame - * size and the sizes of all replacement frames. The current frame is compiled code and may - * contain many inlined functions, each with their own JVM state. We pop the current frame, then - * push all the new frames. Then we call the C routine unpack_frames() to populate these frames. - * Finally unpack_frames() returns us the new target address. Notice that callee-save registers - * are BLOWN here; they have already been captured in the vframeArray at the time the return PC - * was patched. - * - *

    - * ATTENTION: We cannot do any complicated operations e.g. logging via printf in this snippet - * because we change the current stack layout and so the code is very sensitive to register - * allocation. + * Deoptimization handler for normal deoptimization + * {@link HotSpotVMConfig#deoptimizationUnpackDeopt}. */ @Snippet - private static void uncommonTrapHandler(@ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister) { + private static void deoptimizationHandler(@ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister) { final Word thread = registerAsWord(threadRegister); - long registerSaver = SaveAllRegistersNode.saveAllRegisters(); + final long registerSaver = SaveAllRegistersNode.saveAllRegisters(); - final int actionAndReason = readPendingDeoptimization(thread); - writePendingDeoptimization(thread, -1); - - final Word unrollBlock = UncommonTrapCallNode.uncommonTrap(registerSaver, actionAndReason); + final Word unrollBlock = DeoptimizationFetchUnrollInfoCallNode.fetchUnrollInfo(registerSaver); // Pop all the frames we must move/replace. // @@ -131,7 +120,7 @@ // 3: caller of deoptimizing frame (could be compiled/interpreted). // Pop self-frame. - LeaveCurrentStackFrameNode.leaveCurrentStackFrame(); + LeaveCurrentStackFrameNode.leaveCurrentStackFrame(registerSaver); // Load the initial info we should save (e.g. frame pointer). final Word initialInfo = unrollBlock.readWord(deoptimizationUnrollBlockInitialInfoOffset()); @@ -193,13 +182,13 @@ * unknown alignment we need to align it here before calling C++ code. */ final Word senderFp = initialInfo; - EnterUnpackFramesStackFrameNode.enterUnpackFramesStackFrame(framePc, senderSp, senderFp); + EnterUnpackFramesStackFrameNode.enterUnpackFramesStackFrame(framePc, senderSp, senderFp, registerSaver); - // Pass uncommon trap mode to unpack frames. - final int mode = deoptimizationUnpackUncommonTrap(); + // Pass unpack deopt mode to unpack frames. + final int mode = deoptimizationUnpackDeopt(); unpackFrames(UNPACK_FRAMES, thread, mode); - LeaveUnpackFramesStackFrameNode.leaveUnpackFramesStackFrame(); + LeaveUnpackFramesStackFrameNode.leaveUnpackFramesStackFrame(registerSaver); } /** diff -r 6e036e2a2091 -r bb97b75d1d65 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Wed Apr 30 15:41:44 2014 -1000 @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.stubs; + +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.hotspot.stubs.StubUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.*; +import com.oracle.graal.word.*; + +/** + * Uncommon trap stub. + * + * This is the entry point for code which is returning to a de-optimized frame. + * + * The steps taken by this frame are as follows: + * + *

  • push a dummy "register_save" and save the return values (O0, O1, F0/F1, G1) and all + * potentially live registers (at a pollpoint many registers can be live). + * + *
  • call the C routine: Deoptimization::fetch_unroll_info (this function returns information + * about the number and size of interpreter frames which are equivalent to the frame which is being + * deoptimized) + * + *
  • deallocate the unpack frame, restoring only results values. Other volatile registers will now + * be captured in the vframeArray as needed. + * + *
  • deallocate the deoptimization frame + * + *
  • in a loop using the information returned in the previous step push new interpreter frames + * (take care to propagate the return values through each new frame pushed) + * + *
  • create a dummy "unpack_frame" and save the return values (O0, O1, F0) + * + *
  • call the C routine: Deoptimization::unpack_frames (this function lays out values on the + * interpreter frame which was just created) + * + *
  • deallocate the dummy unpack_frame + * + *
  • ensure that all the return values are correctly set and then do a return to the interpreter + * entry point + * + *

    + * ATTENTION: We cannot do any complicated operations e.g. logging via printf in this snippet + * because we change the current stack layout and so the code is very sensitive to register + * allocation. + */ +public class UncommonTrapStub extends SnippetStub { + + private final TargetDescription target; + + public UncommonTrapStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); + this.target = target; + } + + @Override + public boolean preservesRegisters() { + return false; + } + + @Override + protected Object getConstantParameterValue(int index, String name) { + switch (index) { + case 0: + return providers.getRegisters().getThreadRegister(); + case 1: + return providers.getRegisters().getStackPointerRegister(); + default: + throw GraalInternalError.shouldNotReachHere("unknown parameter " + name + " at index " + index); + } + } + + /** + * Uncommon trap handler. + * + * We save the argument return registers. We call the first C routine, fetch_unroll_info(). This + * routine captures the return values and returns a structure which describes the current frame + * size and the sizes of all replacement frames. The current frame is compiled code and may + * contain many inlined functions, each with their own JVM state. We pop the current frame, then + * push all the new frames. Then we call the C routine unpack_frames() to populate these frames. + * Finally unpack_frames() returns us the new target address. Notice that callee-save registers + * are BLOWN here; they have already been captured in the vframeArray at the time the return PC + * was patched. + */ + @Snippet + private static void uncommonTrapHandler(@ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister) { + final Word thread = registerAsWord(threadRegister); + final long registerSaver = SaveAllRegistersNode.saveAllRegisters(); + + final int actionAndReason = readPendingDeoptimization(thread); + writePendingDeoptimization(thread, -1); + + final Word unrollBlock = UncommonTrapCallNode.uncommonTrap(registerSaver, actionAndReason); + + // Pop all the frames we must move/replace. + // + // Frame picture (youngest to oldest) + // 1: self-frame + // 2: deoptimizing frame + // 3: caller of deoptimizing frame (could be compiled/interpreted). + + // Pop self-frame. + LeaveCurrentStackFrameNode.leaveCurrentStackFrame(registerSaver); + + // Load the initial info we should save (e.g. frame pointer). + final Word initialInfo = unrollBlock.readWord(deoptimizationUnrollBlockInitialInfoOffset()); + + // Pop deoptimized frame. + final int sizeOfDeoptimizedFrame = unrollBlock.readInt(deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset()); + LeaveDeoptimizedStackFrameNode.leaveDeoptimizedStackFrame(sizeOfDeoptimizedFrame, initialInfo); + + /* + * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for + * total size of the interpreter frames plus shadow page size. Bang one page at a time + * because large sizes can bang beyond yellow and red zones. + * + * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. + */ + final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset()); + final int bangPages = NumUtil.roundUp(totalFrameSizes, pageSize()) / pageSize() + stackShadowPages(); + Word stackPointer = readRegister(stackPointerRegister); + + for (int i = 1; i < bangPages; i++) { + stackPointer.writeInt((-i * pageSize()) + stackBias(), 0); + } + + // Load number of interpreter frames. + final int numberOfFrames = unrollBlock.readInt(deoptimizationUnrollBlockNumberOfFramesOffset()); + + // Load address of array of frame sizes. + final Word frameSizes = unrollBlock.readWord(deoptimizationUnrollBlockFrameSizesOffset()); + + // Load address of array of frame PCs. + final Word framePcs = unrollBlock.readWord(deoptimizationUnrollBlockFramePcsOffset()); + + /* + * Get the current stack pointer (sender's original SP) before adjustment so that we can + * save it in the skeletal interpreter frame. + */ + Word senderSp = readRegister(stackPointerRegister); + + // Adjust old interpreter frame to make space for new frame's extra Java locals. + final int callerAdjustment = unrollBlock.readInt(deoptimizationUnrollBlockCallerAdjustmentOffset()); + writeRegister(stackPointerRegister, readRegister(stackPointerRegister).subtract(callerAdjustment)); + + for (int i = 0; i < numberOfFrames; i++) { + final Word frameSize = frameSizes.readWord(i * wordSize()); + final Word framePc = framePcs.readWord(i * wordSize()); + + // Push an interpreter frame onto the stack. + PushInterpreterFrameNode.pushInterpreterFrame(frameSize, framePc, senderSp, initialInfo); + + // Get the current stack pointer (sender SP) and pass it to next frame. + senderSp = readRegister(stackPointerRegister); + } + + // Get final return address. + final Word framePc = framePcs.readWord(numberOfFrames * wordSize()); + + /* + * Enter a frame to call out to unpack frames. Since we changed the stack pointer to an + * unknown alignment we need to align it here before calling C++ code. + */ + final Word senderFp = initialInfo; + EnterUnpackFramesStackFrameNode.enterUnpackFramesStackFrame(framePc, senderSp, senderFp, registerSaver); + + // Pass uncommon trap mode to unpack frames. + final int mode = deoptimizationUnpackUncommonTrap(); + unpackFrames(UNPACK_FRAMES, thread, mode); + + LeaveUnpackFramesStackFrameNode.leaveUnpackFramesStackFrame(registerSaver); + } + + /** + * Reads the value of the passed register as a Word. + */ + private static Word readRegister(Register register) { + return registerAsWord(register, false, false); + } + + /** + * Writes the value of the passed register. + * + * @param value value the register should be set to + */ + private static void writeRegister(Register register, Word value) { + writeRegisterAsWord(register, value); + } + + @Fold + private static int stackShadowPages() { + return config().useStackBanging ? config().stackShadowPages : 0; + } + + /** + * Returns the stack bias for the host architecture. + * + * @deprecated This method should go away as soon as JDK-8032410 hits the Graal repository. + * + * @return stack bias + */ + @Deprecated + @Fold + private static int stackBias() { + return config().stackBias; + } + + @Fold + private static int deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset() { + return config().deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset; + } + + @Fold + private static int deoptimizationUnrollBlockCallerAdjustmentOffset() { + return config().deoptimizationUnrollBlockCallerAdjustmentOffset; + } + + @Fold + private static int deoptimizationUnrollBlockNumberOfFramesOffset() { + return config().deoptimizationUnrollBlockNumberOfFramesOffset; + } + + @Fold + private static int deoptimizationUnrollBlockTotalFrameSizesOffset() { + return config().deoptimizationUnrollBlockTotalFrameSizesOffset; + } + + @Fold + private static int deoptimizationUnrollBlockFrameSizesOffset() { + return config().deoptimizationUnrollBlockFrameSizesOffset; + } + + @Fold + private static int deoptimizationUnrollBlockFramePcsOffset() { + return config().deoptimizationUnrollBlockFramePcsOffset; + } + + @Fold + private static int deoptimizationUnrollBlockInitialInfoOffset() { + return config().deoptimizationUnrollBlockInitialInfoOffset; + } + + @Fold + private static int deoptimizationUnpackDeopt() { + return config().deoptimizationUnpackDeopt; + } + + @Fold + private static int deoptimizationUnpackUncommonTrap() { + return config().deoptimizationUnpackUncommonTrap; + } + + public static final ForeignCallDescriptor UNPACK_FRAMES = descriptorFor(UncommonTrapStub.class, "unpackFrames"); + + @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true) + public static native int unpackFrames(@ConstantNodeParameter ForeignCallDescriptor unpackFrames, Word thread, int mode); +} diff -r 6e036e2a2091 -r bb97b75d1d65 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Apr 30 15:09:15 2014 -1000 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Apr 30 15:41:44 2014 -1000 @@ -156,8 +156,6 @@ //------------------------------------------------------------------------------------------------ - set_address("handleDeoptStub", SharedRuntime::deopt_blob()->unpack()); - set_address("registerFinalizerAddress", SharedRuntime::register_finalizer); set_address("exceptionHandlerForReturnAddressAddress", SharedRuntime::exception_handler_for_return_address); set_address("osrMigrationEndAddress", SharedRuntime::OSR_migration_end); diff -r 6e036e2a2091 -r bb97b75d1d65 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Wed Apr 30 15:09:15 2014 -1000 +++ b/src/share/vm/runtime/deoptimization.cpp Wed Apr 30 15:41:44 2014 -1000 @@ -359,7 +359,8 @@ #ifdef ASSERT assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub() || - strcmp("Stub", cb->name()) == 0, + strcmp("Stub", cb->name()) == 0 || + strcmp("Stub", cb->name()) == 0, err_msg("unexpected code blob: %s", cb->name())); #endif #else