/** * 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); } }
/** Find or create a JTOC offset for this method */ public final synchronized Offset findOrCreateJtocOffset() { if (VM.VerifyAssertions) VM._assert(!isStatic() && !isObjectInitializer()); Offset jtocOffset = getJtocOffset(); ; if (jtocOffset.EQ(Offset.zero())) { jtocOffset = Statics.allocateReferenceSlot(true); Statics.setSlotContents(jtocOffset, getCurrentEntryCodeArray()); synchronized (jtocOffsets) { jtocOffsets.put(this, Integer.valueOf(jtocOffset.toInt())); } } return jtocOffset; }