* @param typeSizeInfo
* @param maxLocals
*/
public void emitTrailer(TypeSizeInfo typeSizeInfo, int maxLocals) {
final int argSlotCount = method.getArgSlotCount();
final Label stackOverflowLabel = helper.genLabel("$$stack-overflow");
final GPR asp = helper.SP;
final GPR abp = helper.BP;
final GPR aax = helper.AAX;
final int size = helper.ADDRSIZE;
// Begin footer
// Now start the actual footer
os.setObjectRef(footerLabel);
/* Go restore the previous current frame */
emitSynchronizationCode(typeSizeInfo, entryPoints.getMonitorExitMethod());
os.writeLEA(asp, abp, EbpFrameRefOffset);
os.writePOP(abp);
restoreRegisters();
// Return
if (argSlotCount > 0) {
os.writeRET(argSlotCount * slotSize);
} else {
os.writeRET();
}
// End footer
// Begin header
// Init starts here
os.setObjectRef(initLabel);
// Test stack overflow
final int stackEndOffset = entryPoints.getVmProcessorStackEnd().getOffset();
if (os.isCode32()) {
os.writePrefix(X86Constants.FS_PREFIX);
os.writeCMP_MEM(X86Register.ESP, stackEndOffset);
} else {
os.writeCMP(X86Register.RSP, PROCESSOR64, stackEndOffset);
}
// This forward jump is not predicted by branch prediction.
// Which is good, because we do not predict a stack overflow
os.writeJCC(stackOverflowLabel, X86Constants.JLE);
// Load the statics table reference
if (method.hasLoadStaticsPragma()) {
helper.writeLoadSTATICS(helper.genLabel("$$edi"), "init", false);
}
// Test stack alignment
writeStackAlignmentTest(helper.genLabel("$$stackAlignment"));
// Create class initialization code (if needed)
helper.writeClassInitialize(method);
// Increment the invocation count
//helper.writeIncInvocationCount(aax); (NOT USED for now, aax is also invalid now)
// Fixed framelayout
saveRegisters();
os.writePUSH(abp);
os.writePUSH(cm.getCompiledCodeId());
os.writeMOV(size, abp, asp);
// Emit the code to create the locals
final int noLocalVars = maxLocals - argSlotCount;
// Create and clear all local variables
if (noLocalVars > 0) {
os.writeXOR(aax, aax);
for (int i = 0; i < noLocalVars; i++) {
os.writePUSH(aax);
}
}
// Create the synchronization enter code
emitSynchronizationCode(typeSizeInfo, entryPoints.getMonitorEnterMethod());
// And jump back to the actual code start
os.writeJMP(startCodeLabel);
// Write stack overflow code
os.setObjectRef(stackOverflowLabel);
os.writeINT(0x31);
// Write class initializers
helper.writeClassInitializers();
// End header
// No set the exception start&endPtr's
//final int noLocals = bc.getNoLocals();
//final int noLocalVars = noLocals - noArgs;
final int count = bc.getNoExceptionHandlers();
CompiledExceptionHandler[] ceh = new CompiledExceptionHandler[count];
for (int i = 0; i < count; i++) {
final VmInterpretedExceptionHandler eh = bc.getExceptionHandler(i);
final Label handlerLabel = helper.genLabel("$$ex-handler" + i);
final ObjectRef handlerRef = os.setObjectRef(handlerLabel);
/** Clear the calculation stack (only locals are left) */
if (noLocalVars < 0) {
System.out.println("@#@#@#@# noLocalVars = " + noLocalVars);
}
final int ofs = Math.max(0, noLocalVars) * slotSize;
os.writeLEA(asp, abp, -ofs);
/** Push the exception in EAX */
os.writePUSH(aax);
/** Goto the real handler */
os.writeJMP(helper.getInstrLabel(eh.getHandlerPC()));
ceh[i] = new CompiledExceptionHandler();
ceh[i].setStartPc(os.getObjectRef(helper.getInstrLabel(eh
.getStartPC())));
ceh[i].setEndPc(os
.getObjectRef(helper.getInstrLabel(eh.getEndPC())));
ceh[i].setHandler(handlerRef);
}
cm.setExceptionHandlers(ceh);
// Now create the default exception handler
Label handlerLabel = helper.genLabel("$$def-ex-handler");
cm.setDefExceptionHandler(os.setObjectRef(handlerLabel));
emitSynchronizationCode(typeSizeInfo, entryPoints.getMonitorExitMethod());
os.writeLEA(asp, abp, EbpFrameRefOffset);
os.writePOP(abp);
restoreRegisters();