001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.compilers.opt.runtimesupport;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.compilers.common.CompiledMethods;
017 import org.jikesrvm.runtime.Magic;
018 import org.jikesrvm.scheduler.RVMThread;
019 import org.vmmagic.pragma.Entrypoint;
020 import org.vmmagic.pragma.Interruptible;
021 import org.vmmagic.pragma.SaveVolatile;
022 import org.vmmagic.pragma.Unpreemptible;
023 import org.vmmagic.unboxed.Address;
024 import org.vmmagic.unboxed.Offset;
025
026 /**
027 * Contains routines that must be compiled with special prologues and eplilogues that
028 * save/restore all registers (both volatile and non-volatile).
029 * TODO: Instead of SaveVolatile, make this class implement
030 * DynamicBridge...will allow us to kill support for SaveVolatile!.
031 * ISSUE: GCMapping for dynamic bridge assumes that it is being used for
032 * lazy method compilation. Need to generalize to support
033 * opt's use for other purposes.
034 *
035 * @see org.jikesrvm.compilers.opt.driver.OptimizingCompiler (hooks to recognize & specially compile this class)
036 */
037 @SaveVolatile
038 @Unpreemptible("Yield methods shouldn't be preempted")
039 public class OptSaveVolatile {
040
041 /**
042 * Handle timer interrupt taken in method prologue.
043 * This method is identical to the yieldpointFromPrologue()
044 * method used by the baseline compiler, except in the OPT compiler world,
045 * we also save the volatile registers.
046 */
047 @Entrypoint
048 public static void yieldpointFromPrologue() {
049 Address fp = Magic.getFramePointer();
050 RVMThread.yieldpoint(RVMThread.PROLOGUE, fp);
051 }
052
053 /**
054 * Handle timer interrupt taken in method epilogue.
055 * This method is identical to the yieldpointFromEpilogue()
056 * method used by the baseline compiler, except in the OPT compiler world,
057 * we also save the volatile registers.
058 */
059 @Entrypoint
060 public static void yieldpointFromEpilogue() {
061 Address fp = Magic.getFramePointer();
062 RVMThread.yieldpoint(RVMThread.EPILOGUE, fp);
063 }
064
065 /**
066 * Handle timer interrupt taken on loop backedge.
067 * This method is identical to the yieldpointFromBackedge() method used
068 * method used by the baseline compiler, except in the OPT compiler world,
069 * we also save the volatile registers.
070 */
071 @Entrypoint
072 public static void yieldpointFromBackedge() {
073 Address fp = Magic.getFramePointer();
074 RVMThread.yieldpoint(RVMThread.BACKEDGE, fp);
075 }
076
077 /**
078 * Handle timer interrupt taken in the prologue of a native method.
079 */
080 @Entrypoint
081 public static void yieldpointFromNativePrologue() {
082 // VM.sysWriteln(123);
083 // VM.sysWriteln(Magic.getFramePointer());
084 // VM.sysWriteln(Magic.getCallerFramePointer(Magic.getFramePointer()));
085 // System.gc();
086 // VM.sysWriteln("Survived GC");
087 // Address fp = Magic.getFramePointer();
088 // Thread.yieldpoint(Thread.NATIVE_PROLOGUE, fp);
089 }
090
091 /**
092 * Handle timer interrupt taken in the epilogue of a native method.
093 */
094 @Entrypoint
095 public static void yieldpointFromNativeEpilogue() {
096 // VM.sysWriteln(321);
097 // VM.sysWriteln(Magic.getFramePointer());
098 // VM.sysWriteln(Magic.getCallerFramePointer(Magic.getFramePointer()));
099 // System.gc();
100 // VM.sysWriteln("Survived GC");
101 // Address fp = Magic.getFramePointer();
102 // Thread.yieldpoint(Thread.NATIVE_EPILOGUE, fp);
103 }
104
105 /**
106 * OSR invalidation being initiated.
107 */
108 @Entrypoint
109 public static void yieldpointFromOsrOpt() {
110 Address fp = Magic.getFramePointer();
111 RVMThread.getCurrentThread().yieldToOSRRequested = true;
112 RVMThread.getCurrentThread().takeYieldpoint = 1;
113 RVMThread.yieldpoint(RVMThread.OSROPT, fp);
114 }
115
116 /**
117 * Wrapper to save/restore volatile registers when a class needs to be
118 * dynamically loaded/resolved/etc.
119 */
120 @Interruptible
121 public static void resolve() throws NoClassDefFoundError {
122 VM.disableGC();
123 // (1) Get the compiled method & compilerInfo for the (opt)
124 // compiled method that called resolve
125 Address fp = Magic.getCallerFramePointer(Magic.getFramePointer());
126 int cmid = Magic.getCompiledMethodID(fp);
127 OptCompiledMethod cm = (OptCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
128 // (2) Get the return address
129 Address ip = Magic.getReturnAddress(Magic.getFramePointer());
130 Offset offset = cm.getInstructionOffset(ip);
131 VM.enableGC();
132 // (3) Call the routine in OptLinker that does all the real work.
133 OptLinker.resolveDynamicLink(cm, offset);
134 }
135 }