Mercurial > hg > truffle
diff graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java @ 15104:ed29f7ff71eb
add DeoptimizationStub
author | twisti |
---|---|
date | Mon, 14 Apr 2014 17:21:49 -1000 |
parents | 895e9ecedfe8 |
children | 96bb07a5d667 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Apr 14 15:36:27 2014 -1000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Apr 14 17:21:49 2014 -1000 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.nodes.UncommonTrapCallNode.*; import java.util.*; @@ -43,7 +44,8 @@ import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.NoOp; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; @@ -176,12 +178,65 @@ super.emitForeignCall(linkage, result, arguments, temps, info); } - protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations) { - AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, true); + public void emitLeaveCurrentStackFrame() { + append(new AMD64HotSpotLeaveCurrentStackFrameOp()); + } + + public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { + Variable frameSizeVariable = load(frameSize); + Variable initialInfoVariable = load(initialInfo); + append(new AMD64HotSpotLeaveDeoptimizedStackFrameOp(frameSizeVariable, initialInfoVariable)); + } + + public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { + Register thread = 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)); + } + + public void emitLeaveUnpackFramesStackFrame() { + Register thread = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset())); + } + + /** + * @param savedRegisters the registers saved by this operation which may be subject to pruning + * @param savedRegisterLocations the slots to which the registers are saved + * @param supportsRemove determines if registers can be pruned + */ + protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations, boolean supportsRemove) { + AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove); append(save); return save; } + /** + * Adds a node to the graph that saves all allocatable registers to the stack. + * + * @param supportsRemove determines if registers can be pruned + * @return the register save node + */ + private AMD64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) { + StackSlot[] savedRegisterLocations = new StackSlot[savedRegisters.length]; + for (int i = 0; i < savedRegisters.length; i++) { + PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory()); + assert kind != Kind.Illegal; + StackSlot spillSlot = getResult().getFrameMap().allocateSpillSlot(kind); + savedRegisterLocations[i] = spillSlot; + } + return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove); + } + + @Override + public SaveRegistersOp emitSaveAllRegisters() { + // We are saving all registers. + // TODO Save upper half of YMM registers. + return emitSaveAllRegisters(cpuxmmRegisters, false); + } + protected void emitRestoreRegisters(AMD64SaveRegistersOp save) { append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save)); } @@ -196,19 +251,11 @@ boolean destroysRegisters = hotspotLinkage.destroysRegisters(); AMD64SaveRegistersOp save = null; - StackSlot[] savedRegisterLocations = null; if (destroysRegisters) { if (getStub() != null) { if (getStub().preservesRegisters()) { Register[] savedRegisters = getResult().getFrameMap().registerConfig.getAllocatableRegisters(); - savedRegisterLocations = new StackSlot[savedRegisters.length]; - for (int i = 0; i < savedRegisters.length; i++) { - PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory()); - assert kind != Kind.Illegal; - StackSlot spillSlot = getResult().getFrameMap().allocateSpillSlot(kind); - savedRegisterLocations[i] = spillSlot; - } - save = emitSaveRegisters(savedRegisters, savedRegisterLocations); + save = emitSaveAllRegisters(savedRegisters, true); } } } @@ -233,9 +280,9 @@ if (destroysRegisters) { if (getStub() != null) { if (getStub().preservesRegisters()) { - assert !((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo().containsKey(currentRuntimeCallInfo); - ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo().put(currentRuntimeCallInfo, save); - + AMD64HotSpotLIRGenerationResult generationResult = (AMD64HotSpotLIRGenerationResult) getResult(); + assert !generationResult.getCalleeSaveInfo().containsKey(currentRuntimeCallInfo); + generationResult.getCalleeSaveInfo().put(currentRuntimeCallInfo, save); emitRestoreRegisters(save); } else { assert zapRegisters(); @@ -246,6 +293,21 @@ return result; } + public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { + ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(UNCOMMON_TRAP); + + Register thread = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread)); + Variable result = super.emitForeignCall(linkage, null, thread.asValue(Kind.Long), trapRequest); + append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread)); + + Map<LIRFrameState, SaveRegistersOp> 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); @@ -374,6 +436,14 @@ } } + public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { + Variable frameSizeVariable = load(frameSize); + Variable framePcVariable = load(framePc); + Variable senderSpVariable = load(senderSp); + Variable initialInfoVariable = load(initialInfo); + append(new AMD64HotSpotPushInterpreterFrameOp(frameSizeVariable, framePcVariable, senderSpVariable, initialInfoVariable)); + } + @Override public Variable emitLoad(PlatformKind kind, Value address, Access access) { AMD64AddressValue loadAddress = asAddressValue(address);