/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Common Public License (CPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/cpl1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.compilers.opt; import org.jikesrvm.VM; import org.jikesrvm.compilers.common.VM_CompiledMethods; import org.jikesrvm.runtime.VM_Magic; import org.jikesrvm.scheduler.VM_Processor; import org.jikesrvm.scheduler.VM_Thread; import org.jikesrvm.scheduler.greenthreads.VM_GreenThread; import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.SaveVolatile; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.LocalAddress; import org.vmmagic.unboxed.Offset; /** * Contains routines that must be compiled with special prologues and eplilogues that * save/restore all registers (both volatile and non-volatile). * TODO: Instead of SaveVolatile, make this class implement * DynamicBridge...will allow us to kill support for SaveVolatile!. * ISSUE: GCMapping for dynamic bridge assumes that it is being used for * lazy method compilation. Need to generalize to support * opt's use for other purposes. * * @see OPT_Compiler (hooks to recognize & specially compile this class) */ @SaveVolatile @Uninterruptible public class VM_OptSaveVolatile { /** * Handle timer interrupt taken in method prologue. * This method is identical to the yieldpointFromPrologue() * method used by the baseline compiler, except in the OPT compiler world, * we also save the volatile registers. */ @Entrypoint public static void OPT_yieldpointFromPrologue() { LocalAddress fp = VM_Magic.getFramePointer(); VM_GreenThread.yieldpoint(VM_Thread.PROLOGUE, fp); } /** * Handle timer interrupt taken in method epilogue. * This method is identical to the yieldpointFromEpilogue() * method used by the baseline compiler, except in the OPT compiler world, * we also save the volatile registers. */ @Entrypoint public static void OPT_yieldpointFromEpilogue() { LocalAddress fp = VM_Magic.getFramePointer(); VM_GreenThread.yieldpoint(VM_Thread.EPILOGUE, fp); } /** * Handle timer interrupt taken on loop backedge. * This method is identical to the yieldpointFromBackedge() method used * method used by the baseline compiler, except in the OPT compiler world, * we also save the volatile registers. */ @Entrypoint public static void OPT_yieldpointFromBackedge() { LocalAddress fp = VM_Magic.getFramePointer(); VM_GreenThread.yieldpoint(VM_Thread.BACKEDGE, fp); } /** * Handle timer interrupt taken in the prologue of a native method. */ @Entrypoint public static void OPT_yieldpointFromNativePrologue() { // VM.sysWriteln(123); // VM.sysWriteln(VM_Magic.getFramePointer()); // VM.sysWriteln(VM_Magic.getCallerFramePointer(VM_Magic.getFramePointer())); // System.gc(); // VM.sysWriteln("Survived GC"); // Address fp = VM_Magic.getFramePointer(); // VM_Thread.yieldpoint(VM_Thread.NATIVE_PROLOGUE, fp); } /** * Handle timer interrupt taken in the epilogue of a native method. */ @Entrypoint public static void OPT_yieldpointFromNativeEpilogue() { // VM.sysWriteln(321); // VM.sysWriteln(VM_Magic.getFramePointer()); // VM.sysWriteln(VM_Magic.getCallerFramePointer(VM_Magic.getFramePointer())); // System.gc(); // VM.sysWriteln("Survived GC"); // Address fp = VM_Magic.getFramePointer(); // VM_Thread.yieldpoint(VM_Thread.NATIVE_EPILOGUE, fp); } /** * OSR invalidation being initiated. */ @Entrypoint public static void OPT_yieldpointFromOsrOpt() { LocalAddress fp = VM_Magic.getFramePointer(); VM_Processor.getCurrentProcessor().yieldToOSRRequested = true; VM_GreenThread.yieldpoint(VM_Thread.OSROPT, fp); } /** * Wrapper to save/restore volatile registers when a class needs to be * dynamically loaded/resolved/etc. */ @Interruptible public static void OPT_resolve() throws NoClassDefFoundError { VM.disableGC(); // (1) Get the compiled method & compilerInfo for the (opt) // compiled method that called OPT_resolve LocalAddress fp = VM_Magic.getCallerFramePointer(VM_Magic.getFramePointer()); int cmid = VM_Magic.getCompiledMethodID(fp); VM_OptCompiledMethod cm = (VM_OptCompiledMethod) VM_CompiledMethods.getCompiledMethod(cmid); // (2) Get the return address LocalAddress ip = VM_Magic.getReturnAddress(VM_Magic.getFramePointer()); Offset offset = cm.getInstructionOffset(ip); VM.enableGC(); // (3) Call the routine in VM_OptLinker that does all the real work. VM_OptLinker.resolveDynamicLink(cm, offset); } }