// return (address of) next ref in the current "frame" on the // threads JNIEnvironment stack of refs // When at the end of the current frame, update register locations to point // to the non-volatile registers saved in the JNI transition frame. // public Address getNextReferenceAddress() { // first report jni refs in the current frame in the jniRef side stack // until all in the frame are reported // if (jniNextRef > jniFramePtr) { Address ref_address = Magic.objectAsAddress(jniRefs).plus(jniNextRef); jniNextRef -= BYTES_IN_ADDRESS; return ref_address; } // no more refs to report, before returning 0, setup for processing // the next jni frame, if any // jniNextRef -> savedFramePtr for another "frame" of refs for another // sequence of Native C frames lower in the stack, or to 0 if this is the // last jni frame in the JNIRefs stack. If more frames, initialize for a // later scan of those refs. // if (jniFramePtr > 0) { jniFramePtr = jniRefs.get(jniFramePtr >> LOG_BYTES_IN_ADDRESS).toInt(); jniNextRef = jniNextRef - BYTES_IN_ADDRESS; } // set register locations for non-volatiles to point to registers saved in // the JNI transition frame at a fixed negative offset from the callers FP. // the save non-volatiles are EBX EBP and EDI. // registerLocations.set(EDI.value(), framePtr.plus(JNICompiler.EDI_SAVE_OFFSET)); registerLocations.set(EBX.value(), framePtr.plus(JNICompiler.EBX_SAVE_OFFSET)); registerLocations.set(EBP.value(), framePtr.plus(JNICompiler.EBP_SAVE_OFFSET)); return Address.zero(); // no more refs to report }
/** * Pop an address from the address stack, return zero if the stack is empty. * * @return The next address in the address stack, or zero if the stack is empty */ @Inline public final Address pop() { if (checkDequeue(1)) { return uncheckedDequeue(); } else { return Address.zero(); } }
/** * Resolve a symbol to an address in a currently loaded dynamic library. * * @return the address of the symbol of Address.zero() if it cannot be resolved */ public static synchronized Address resolveSymbol(String symbol) { for (VM_DynamicLibrary lib : dynamicLibraries.values()) { Address symbolAddress = lib.getSymbol(symbol); if (!symbolAddress.isZero()) { return symbolAddress; } } return Address.zero(); }
/** * Cast bits. Note: the returned integer is only valid until next garbage collection cycle * (thereafter the referenced object might have moved and its address changed) * * @param object object reference * @return object reference as bits */ public static <T> Address objectAsAddress(T object) { if (VM.runningVM && VM.VerifyAssertions) { VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler } if (objectAddressRemapper == null) { return Address.zero(); // tool isn't interested in remapping } return objectAddressRemapper.objectAsAddress(object); }
/** Reset the allocator. Note that this does not reset the space. */ public void reset() { cursor = Address.zero(); limit = Address.zero(); largeCursor = Address.zero(); largeLimit = Address.zero(); markTable = Address.zero(); recyclableBlock = Address.zero(); requestForLarge = false; recyclableExhausted = false; line = LINES_IN_BLOCK; lineUseCount = 0; }
public Address getNextReturnAddressAddress() { return Address.zero(); }
static void deleteGlobalRef(int index) { if (VM.VerifyAssertions) VM._assert(!isWeakRef(index)); JNIGlobalRefs.set(-index, Address.zero()); }
public static Address getDirectBufferAddress(Buffer buffer) { if (buffer.address == null) return Address.zero(); else return gnu.classpath.JikesRVMSupport.getAddressFromPointer(buffer.address); }
/** * This method is called when a call stack edge needs to be sampled. Expect the sfp argument to * point to the stack frame that contains the target of the edge to be sampled. * * <p>NOTE: This method is uninterruptible, therefore we don't need to disable thread switching * during stackframe inspection. * * @param sfp a pointer to the stack frame that corresponds to the callee of the call graph edge * that is to be sampled. * @param whereFrom Was this a yieldpoint in a PROLOGUE, BACKEDGE, or EPILOGUE? */ @Override public final void update(Address sfp, int whereFrom) { if (DEBUG) { VM.sysWrite("EdgeListener.update(", sfp, ",", whereFrom); VM.sysWriteln("): enter ", samplesTaken); } Synchronization.fetchAndAdd(this, AosEntrypoints.edgeListenerUpdateCalledField.getOffset(), 1); // don't take a sample for back edge yield points if (whereFrom == RVMThread.BACKEDGE) return; int calleeCMID = 0; int callerCMID = 0; Address returnAddress = Address.zero(); if (sfp.loadAddress().EQ(STACKFRAME_SENTINEL_FP)) { if (DEBUG) VM.sysWrite(" Walking off end of stack!\n"); return; } calleeCMID = Magic.getCompiledMethodID(sfp); if (calleeCMID == INVISIBLE_METHOD_ID) { if (DEBUG) { VM.sysWrite(" INVISIBLE_METHOD_ID (assembler code) "); VM.sysWrite(calleeCMID); VM.sysWrite("\n"); } return; } returnAddress = Magic.getReturnAddress(sfp); // return address in caller sfp = Magic.getCallerFramePointer(sfp); // caller's frame pointer if (sfp.loadAddress().EQ(STACKFRAME_SENTINEL_FP)) { if (DEBUG) VM.sysWrite(" Walking off end of stack\n"); return; } callerCMID = Magic.getCompiledMethodID(sfp); if (callerCMID == INVISIBLE_METHOD_ID) { if (DEBUG) { VM.sysWrite(" INVISIBLE_METHOD_ID (assembler code) "); VM.sysWrite(callerCMID); VM.sysWrite("\n"); } return; } // store the offset of the return address from the beginning of the // instruction CompiledMethod callerCM = CompiledMethods.getCompiledMethod(callerCMID); if (callerCM.getCompilerType() == CompiledMethod.TRAP) { if (DEBUG) { VM.sysWriteln(" HARDWARE TRAP FRAME "); } return; } Offset callSite = callerCM.getInstructionOffset(returnAddress); if (DEBUG) { VM.sysWrite(" <"); VM.sysWrite(calleeCMID); VM.sysWrite(","); VM.sysWrite(callerCMID); VM.sysWrite(","); VM.sysWrite(returnAddress); VM.sysWrite(">\n"); } // Find out what sample we are. int sampleNumber = Synchronization.fetchAndAdd( this, AosEntrypoints.edgeListenerSamplesTakenField.getOffset(), 1); int idx = 3 * sampleNumber; // If we got buffer slots that are beyond the end of the buffer, that means // that we're actually not supposed to take the sample at all (the system // is in the process of activating our organizer and processing the buffer). if (idx < buffer.length) { buffer[idx + 1] = callerCMID; buffer[idx + 2] = callSite.toInt(); Magic.sync(); buffer[idx + 0] = calleeCMID; // If we are the last sample, we need to activate the organizer. if (sampleNumber + 1 == desiredSamples) { activateOrganizer(); } } }