/** * Given a slot (ie the address of an ObjectReference), ensure that the referent will not move for * the rest of the GC. This is achieved by calling the precopyObject method. * * @param slot The slot to check */ @Inline public final void processPrecopyEdge(Address slot) { ObjectReference child = slot.loadObjectReference(); if (!child.isNull()) { child = precopyObject(child); slot.store(child); } }
/** {@inheritDoc} */ @Override public boolean isLive(ObjectReference object) { if (object.isNull()) return false; if (Space.isInSpace(SS.SS0, object)) return SS.hi ? SS.copySpace0.isLive(object) : true; if (Space.isInSpace(SS.SS1, object)) return SS.hi ? true : SS.copySpace1.isLive(object); return super.isLive(object); }
/** * Push an address onto the address stack. * * @param object the object to be pushed onto the object queue */ @Inline public final void push(ObjectReference object) { Address addr = object.toAddress(); if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!addr.isZero()); checkHeadInsert(1); uncheckedHeadInsert(addr); }
/** * This method is the core method during the trace of the object graph. The role of this method is * to: * * <p>1. Ensure the traced object is not collected. 2. If this is the first visit to the object * enqueue it to be scanned. 3. Return the forwarded reference to the object. * * <p>In this instance, we refer objects in the mark-sweep space to the immixSpace for tracing, * and defer to the superclass for all others. * * @param object The object to be traced. * @return The new reference to the same object instance. */ @Inline public ObjectReference traceObject(ObjectReference object) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Immix.immixSpace.inImmixDefragCollection()); if (object.isNull()) return object; if (Space.isInSpace(Immix.IMMIX, object)) return Immix.immixSpace.traceObject(this, object, Plan.ALLOC_DEFAULT); return super.traceObject(object); }
/** * Is the specified object live? * * @param object The object. * @return True if the object is live. */ public boolean isLive(ObjectReference object) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Immix.immixSpace.inImmixDefragCollection()); if (object.isNull()) return false; if (Space.isInSpace(Immix.IMMIX, object)) { return Immix.immixSpace.isLive(object); } return super.isLive(object); }
/** * 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 ObjectReference pop() { if (checkDequeue(1)) { return uncheckedDequeue().toObjectReference(); } else { return ObjectReference.nullReference(); } }
@Override @Inline public ObjectReference traceObject(ObjectReference object) { if (object.isNull()) return object; if (Space.isInSpace(SS.SS0, object)) return SS.copySpace0.traceObject(this, object, SS.ALLOC_SS); if (Space.isInSpace(SS.SS1, object)) return SS.copySpace1.traceObject(this, object, SS.ALLOC_SS); return super.traceObject(object); }
/** * Trace a reference during GC. This involves determining which collection policy applies and * calling the appropriate <code>trace</code> method. * * @param target The object the interior edge points within. * @param slot The location of the interior edge. * @param root True if this is a root edge. */ public final void processInteriorEdge(ObjectReference target, Address slot, boolean root) { Address interiorRef = slot.loadAddress(); Offset offset = interiorRef.diff(target.toAddress()); ObjectReference newTarget = traceObject(target, root); if (VM.VERIFY_ASSERTIONS) { if (offset.sLT(Offset.zero()) || offset.sGT(Offset.fromIntSignExtend(1 << 24))) { // There is probably no object this large Log.writeln("ERROR: Suspiciously large delta to interior pointer"); Log.write(" object base = "); Log.writeln(target); Log.write(" interior reference = "); Log.writeln(interiorRef); Log.write(" delta = "); Log.writeln(offset); VM.assertions._assert(false); } } slot.store(newTarget.toAddress().plus(offset)); }
/** * This method is the core method during the trace of the object graph. The role of this method is * to: * * <p>1. Ensure the traced object is not collected. 2. If this is the first visit to the object * enqueue it to be scanned. 3. Return the forwarded reference to the object. * * @param object The object to be traced. * @return The new reference to the same object instance. */ @Inline public ObjectReference traceObject(ObjectReference object) { if (Space.isInSpace(Plan.VM_SPACE, object)) return (Plan.SCAN_BOOT_IMAGE) ? object : Plan.vmSpace.traceObject(this, object); if (Space.isInSpace(Plan.IMMORTAL, object)) return Plan.immortalSpace.traceObject(this, object); if (Space.isInSpace(Plan.LOS, object)) return Plan.loSpace.traceObject(this, object); if (Space.isInSpace(Plan.PLOS, object)) return Plan.ploSpace.traceObject(this, object); if (Plan.USE_CODE_SPACE && Space.isInSpace(Plan.SMALL_CODE, object)) return Plan.smallCodeSpace.traceObject(this, object); if (Plan.USE_CODE_SPACE && Space.isInSpace(Plan.LARGE_CODE, object)) return Plan.largeCodeSpace.traceObject(this, object); if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false, "No special case for space in traceObject"); return ObjectReference.nullReference(); }
/** * Return true if the object resides within the nursery * * @param obj The object to be tested * @return true if the object resides within the nursery */ @Inline static boolean inNursery(ObjectReference obj) { return inNursery(obj.toAddress()); }