/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * 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/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.jni.ppc; import static org.jikesrvm.jni.ppc.JNIStackframeLayoutConstants.JNI_GC_FLAG_OFFSET; import static org.jikesrvm.jni.ppc.JNIStackframeLayoutConstants.JNI_RVM_NONVOLATILE_OFFSET; import static org.jikesrvm.ppc.RegisterConstants.FIRST_NONVOLATILE_GPR; import static org.jikesrvm.ppc.RegisterConstants.LAST_NONVOLATILE_GPR; import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; import org.jikesrvm.jni.AbstractJNIGCMapIterator; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.AddressArray; /** * Iterator for stack frames inserted at the transition from Java to * JNI Native C. It will report JREFs associated with the executing * C frames which are in the "JREFs stack" attached to the executing * Threads JNIEnvironment. It will update register location addresses * for the non-votatile registers to point to the register save area * in the transition frame. * <p> * If GC happens, the saved non-volatile regs may get modified (ex. a ref * to a live object that gets moved), and a restore flag in the frame is * set to cause the returning Native code to restore those registers from * this save area. If GC does not occur, the Native C code has restored * these regs, and the transition return code does not do the restore. */ @Uninterruptible public final class JNIGCMapIterator extends AbstractJNIGCMapIterator { // non-volitile regs are saved at the end of the transition frame, // after the saved JTOC and SP, and preceeded by a GC flag. // // JNI Java to Native C transition frame... // // <-- | saved FP | <- this.framePtr // | | ... | // | | ... | // | | GC flag | // | | saved affinity | // | | proc reg | // | | non vol 17 | // | | ... | // | | non vol 31 | // | | saved SP | // | | saved JTOC | // --> | | <- callers FP // // The following constant is the offset from the callers FP to // the GC flag at the beginning of this area. // public JNIGCMapIterator(AddressArray registerLocations) { super(registerLocations); } @Override protected void setupIteratorForArchitecture() { Address callers_fp = this.framePtr.loadAddress(); // set the GC flag in the Java to C frame to indicate GC occurred // this forces saved non volatile regs to be restored from save area // where those containing refs have been relocated if necessary // callers_fp.minus(JNI_GC_FLAG_OFFSET).store(1); } /** * Sets register locations for non-volatiles to point to registers saved in * the JNI transition frame at a fixed negative offset from the callers FP. */ @Override protected void setRegisterLocations() { Address registerLocation = this.framePtr.loadAddress().minus(JNI_RVM_NONVOLATILE_OFFSET); for (int i = LAST_NONVOLATILE_GPR.value(); i >= FIRST_NONVOLATILE_GPR.value() - 1; --i) { registerLocations.set(i, registerLocation); registerLocation = registerLocation.minus(BYTES_IN_ADDRESS); } } @Override public Address getNextReturnAddressAddress() { return Address.zero(); } }