/** * Change machine code that will be used by future executions of this method (ie. optimized <-> * non-optimized) * * <p>Side effect: updates JTOC or method dispatch tables ("type information blocks") for this * class and its subclasses * * @param compiledMethod new machine code */ public final synchronized void replaceCompiledMethod(CompiledMethod compiledMethod) { if (VM.VerifyAssertions) VM._assert(getDeclaringClass().isInstantiated()); // If we're replacing with a non-null compiledMethod, ensure that is still valid! if (compiledMethod != null) { synchronized (compiledMethod) { if (compiledMethod.isInvalid()) return; } } // Grab version that is being replaced CompiledMethod oldCompiledMethod = currentCompiledMethod; currentCompiledMethod = compiledMethod; // Install the new method in JTOC/TIB. If virtual, will also replace in // all subclasses that inherited the method. getDeclaringClass().updateMethod(this); // Replace constant-ified virtual method in JTOC if necessary Offset jtocOffset = getJtocOffset(); if (jtocOffset.NE(Offset.zero())) { Statics.setSlotContents(jtocOffset, getCurrentEntryCodeArray()); } // Now that we've updated the JTOC/TIB, old version is obsolete if (oldCompiledMethod != null) { CompiledMethods.setCompiledMethodObsolete(oldCompiledMethod); } }
/** Generate machine code for this method if valid machine code doesn't already exist. */ public final synchronized void compile() { if (VM.VerifyAssertions) VM._assert(getDeclaringClass().isResolved()); if (isCompiled()) return; if (VM.TraceClassLoading && VM.runningVM) VM.sysWrite("RVMMethod: (begin) compiling " + this + "\n"); CompiledMethod cm = genCode(); // Ensure that cm wasn't invalidated while it was being compiled. synchronized (cm) { if (cm.isInvalid()) { CompiledMethods.setCompiledMethodObsolete(cm); } else { currentCompiledMethod = cm; } } if (VM.TraceClassLoading && VM.runningVM) VM.sysWrite("RVMMethod: (end) compiling " + this + "\n"); }