Esempio n. 1
0
 /** Prints the address of the object. */
 @Override
 public String toString() {
   if (value.isNull()) {
     return "null";
   }
   return value.toString();
 }
Esempio n. 2
0
 @Uninterruptible
 public static void dumpRef(ObjectReference ref) {
   VM.sysWrite("REF=");
   if (ref.isNull()) {
     VM.sysWrite("NULL\n");
     return;
   }
   VM.sysWrite(ref);
   if (!mappedVMRef(ref)) {
     VM.sysWrite(" (REF OUTSIDE OF HEAP OR NOT MAPPED)\n");
     return;
   }
   ObjectModel.dumpHeader(ref);
   ObjectReference tib = ObjectReference.fromObject(ObjectModel.getTIB(ref));
   if (!MemoryManager.mightBeTIB(tib)) {
     VM.sysWrite(" (INVALID TIB: CLASS NOT ACCESSIBLE)\n");
     return;
   }
   RVMType type = Magic.getObjectType(ref.toObject());
   ObjectReference itype = ObjectReference.fromObject(type);
   VM.sysWrite(" TYPE=");
   VM.sysWrite(itype);
   if (!validType(itype)) {
     VM.sysWrite(" (INVALID TYPE: CLASS NOT ACCESSIBLE)\n");
     return;
   }
   VM.sysWrite(" CLASS=");
   VM.sysWrite(type.getDescriptor());
   VM.sysWrite("\n");
 }
Esempio n. 3
0
  /**
   * Store a value into a reference field of an object.
   *
   * @param object The object to store the field of.
   * @param index The field index.
   * @param value The value to store.
   */
  public void storeReferenceField(ObjectReference object, int index, ObjectReference value) {
    int limit = ObjectModel.getRefs(object);
    if (Trace.isEnabled(Item.STORE) || ObjectModel.isWatched(object)) {
      Trace.printf(
          Item.STORE,
          "[%s].object[%d/%d] = %s",
          ObjectModel.getString(object),
          index,
          limit,
          value.toString());
    }
    check(!object.isNull(), "Object can not be null");
    check(index >= 0, "Index must be non-negative");
    check(index < limit, "Index " + index + " out of bounds " + limit);

    Address referenceSlot = ObjectModel.getRefSlot(object, index);
    if (ActivePlan.constraints.needsWriteBarrier()) {
      context.writeBarrier(object, referenceSlot, value, null, null, Plan.AASTORE_WRITE_BARRIER);
      if (gcEveryWB) {
        gc();
      }
    } else {
      referenceSlot.store(value);
    }
  }
Esempio n. 4
0
 /**
  * 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);
   }
 }
Esempio n. 5
0
 private static synchronized Throwable fillInStackTrace(Throwable instance) {
   ObjectReference.fromObject(instance)
       .toAddress()
       .add(BACKTRACE_OFFSET)
       .store(
           ObjectReference.fromObject(
               VmThread.getStackTrace(VmProcessor.current().getCurrentThread())));
   return instance;
 }
Esempio n. 6
0
  /**
   * Store a value into the data field of an object.
   *
   * @param object The object to store the field of.
   * @param index The field index.
   * @param value The value to store.
   */
  public void storeDataField(ObjectReference object, int index, int value) {
    int limit = ObjectModel.getDataCount(object);
    check(!object.isNull(), "Object can not be null");
    check(index >= 0, "Index must be non-negative");
    check(index < limit, "Index " + index + " out of bounds " + limit);

    Address ref = ObjectModel.getDataSlot(object, index);
    ref.store(value);
    Trace.trace(Item.STORE, "%s.[%d] = %d", object.toString(), index, value);
  }
 /** All Scalars */
 public static void scalar(Object object, TransitiveClosure trace) {
   Address base = Magic.objectAsAddress(object);
   int[] offsets = ObjectModel.getObjectType(object).asClass().getReferenceOffsets();
   for (int i = 0; i < offsets.length; i++) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(offsets[i]));
   }
 }
 /** {@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);
 }
 /** Reference Arrays */
 public static void referenceArray(Object object, TransitiveClosure trace) {
   Address base = Magic.objectAsAddress(object);
   int length = ObjectModel.getArrayLength(object);
   for (int i = 0; i < length; i++) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(i << LOG_BYTES_IN_ADDRESS));
   }
 }
Esempio n. 11
0
 /**
  * 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();
   }
 }
Esempio n. 13
0
 /**
  * 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);
 }
Esempio n. 14
0
 private static int getStackTraceDepth(Throwable instance) {
   return ((Object[])
           ObjectReference.fromObject(instance)
               .toAddress()
               .add(BACKTRACE_OFFSET)
               .loadObjectReference()
               .toObject())
       .length;
 }
 @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);
 }
Esempio n. 16
0
 /**
  * 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));
 }
Esempio n. 17
0
  /**
   * Load and return the value of a reference field of an object.
   *
   * @param object The object to load the field of.
   * @param index The field index.
   */
  public ObjectReference loadReferenceField(ObjectReference object, int index) {
    int limit = ObjectModel.getRefs(object);
    check(!object.isNull(), "Object can not be null");
    check(index >= 0, "Index must be non-negative");
    check(index < limit, "Index " + index + " out of bounds " + limit);

    Address referenceSlot = ObjectModel.getRefSlot(object, index);
    ObjectReference result;
    if (ActivePlan.constraints.needsReadBarrier()) {
      result = context.readBarrier(object, referenceSlot, null, null, Plan.AASTORE_WRITE_BARRIER);
    } else {
      result = referenceSlot.loadObjectReference();
    }
    Trace.trace(
        Item.LOAD,
        "[%s].object[%d] returned [%s]",
        ObjectModel.getString(object),
        index,
        result.toString());
    return result;
  }
  static int newGlobalRef(Object referent) {
    if (VM.VerifyAssertions)
      VM._assert(MemoryManager.validRef(ObjectReference.fromObject(referent)));

    if (free >= JNIGlobalRefs.length()) {
      AddressArray newGlobalRefs = AddressArray.create(JNIGlobalRefs.length() * 2);
      copyAndReplaceGlobalRefs(newGlobalRefs);
    }

    JNIGlobalRefs.set(free, Magic.objectAsAddress(referent));
    return -free++;
  }
Esempio n. 19
0
  /**
   * Load and return the value of a data field of an object.
   *
   * @param object The object to load the field of.
   * @param index The field index.
   */
  public int loadDataField(ObjectReference object, int index) {
    int limit = ObjectModel.getDataCount(object);
    check(!object.isNull(), "Object can not be null");
    check(index >= 0, "Index must be non-negative");
    check(index < limit, "Index " + index + " out of bounds " + limit);

    Address dataSlot = ObjectModel.getDataSlot(object, index);
    int result = dataSlot.loadInt();
    Trace.trace(
        Item.LOAD, "[%s].int[%d] returned [%d]", ObjectModel.getString(object), index, result);
    return result;
  }
Esempio n. 20
0
 /**
  * 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();
 }
Esempio n. 21
0
 private static StackTraceElement getStackTraceElement(Throwable instance, int index) {
   final VmStackFrame frame =
       (VmStackFrame)
           ((Object[])
                   ObjectReference.fromObject(instance)
                       .toAddress()
                       .add(BACKTRACE_OFFSET)
                       .loadObjectReference()
                       .toObject())
               [index];
   final String location = frame.getLocationInfo();
   final int lineNumber = "?".equals(location) ? -1 : Integer.parseInt(location);
   final VmMethod method = frame.getMethod();
   final VmType<?> vmClass = (method == null) ? null : method.getDeclaringClass();
   final String fname = (vmClass == null) ? null : vmClass.getSourceFile();
   final String cname = (vmClass == null) ? "<unknown class>" : vmClass.getName();
   final String mname = (method == null) ? "<unknown method>" : method.getName();
   return new StackTraceElement(
       cname, mname, fname, method == null || method.isNative() ? -2 : lineNumber);
 }
 /** Fallback */
 public static void fallback(Object object, TransitiveClosure trace) {
   ObjectReference objectRef = ObjectReference.fromObject(object);
   RVMType type = ObjectModel.getObjectType(objectRef.toObject());
   if (type.isClassType()) {
     RVMClass klass = type.asClass();
     int[] offsets = klass.getReferenceOffsets();
     for (int i = 0; i < offsets.length; i++) {
       trace.processEdge(objectRef, objectRef.toAddress().plus(offsets[i]));
     }
   } else if (type.isArrayType() && type.asArray().getElementType().isReferenceType()) {
     for (int i = 0; i < ObjectModel.getArrayLength(objectRef.toObject()); i++) {
       trace.processEdge(objectRef, objectRef.toAddress().plus(i << LOG_BYTES_IN_ADDRESS));
     }
   }
 }
 /** All patterns bottom out here */
 @Inline
 public static void pattern(int pattern, Object object, TransitiveClosure trace) {
   Address base = Magic.objectAsAddress(object).plus(FIELD_ZERO_OFFSET);
   if ((pattern & 1) != 0) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(0));
   }
   if ((pattern & 2) != 0) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(1 << LOG_BYTES_IN_ADDRESS));
   }
   if ((pattern & 4) != 0) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(2 << LOG_BYTES_IN_ADDRESS));
   }
   if ((pattern & 8) != 0) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(3 << LOG_BYTES_IN_ADDRESS));
   }
   if ((pattern & 16) != 0) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(4 << LOG_BYTES_IN_ADDRESS));
   }
   if ((pattern & 32) != 0) {
     trace.processEdge(ObjectReference.fromObject(object), base.plus(5 << LOG_BYTES_IN_ADDRESS));
   }
 }
Esempio n. 24
0
 /** Use the hash code of the underlying ObjectReference */
 @Override
 public int hashCode() {
   return value.hashCode();
 }
Esempio n. 25
0
 /**
  * Checks if a reference, its TIB pointer and type pointer are all in the heap.
  *
  * @param ref the reference to check
  * @return {@code true} if and only if the reference refers to a valid object
  */
 @Uninterruptible
 public static boolean validObject(Object ref) {
   return validRef(ObjectReference.fromObject(ref));
 }
Esempio n. 26
0
 /** Construct an initially null object value */
 public ObjectValue() {
   this(ObjectReference.nullReference());
 }
Esempio n. 27
0
 /** Get this value as a boolean. */
 @Override
 public boolean getBoolValue() {
   return !value.isNull();
 }
Esempio n. 28
0
  @Uninterruptible
  public static boolean validRef(ObjectReference ref) {

    if (ref.isNull()) return true;
    if (!Space.isMappedObject(ref)) {
      VM.sysWrite("validRef: REF outside heap, ref = ");
      VM.sysWrite(ref);
      VM.sysWrite("\n");
      Space.printVMMap();
      return false;
    }
    if (MOVES_OBJECTS) {
      /*
      TODO: Work out how to check if forwarded
      if (Plan.isForwardedOrBeingForwarded(ref)) {
        // TODO: actually follow forwarding pointer
        // (need to bound recursion when things are broken!!)
        return true;
      }
      */
    }

    TIB tib = ObjectModel.getTIB(ref);
    Address tibAddr = Magic.objectAsAddress(tib);
    if (!Space.isMappedObject(ObjectReference.fromObject(tib))) {
      VM.sysWrite("validRef: TIB outside heap, ref = ");
      VM.sysWrite(ref);
      VM.sysWrite(" tib = ");
      VM.sysWrite(tibAddr);
      VM.sysWrite("\n");
      ObjectModel.dumpHeader(ref);
      return false;
    }
    if (tibAddr.isZero()) {
      VM.sysWrite("validRef: TIB is Zero! ");
      VM.sysWrite(ref);
      VM.sysWrite("\n");
      ObjectModel.dumpHeader(ref);
      return false;
    }
    if (tib.length() == 0) {
      VM.sysWrite("validRef: TIB length zero, ref = ");
      VM.sysWrite(ref);
      VM.sysWrite(" tib = ");
      VM.sysWrite(tibAddr);
      VM.sysWrite("\n");
      ObjectModel.dumpHeader(ref);
      return false;
    }

    ObjectReference type = ObjectReference.fromObject(tib.getType());
    if (!validType(type)) {
      VM.sysWrite("validRef: invalid TYPE, ref = ");
      VM.sysWrite(ref);
      VM.sysWrite(" tib = ");
      VM.sysWrite(Magic.objectAsAddress(tib));
      VM.sysWrite(" type = ");
      VM.sysWrite(type);
      VM.sysWrite("\n");
      ObjectModel.dumpHeader(ref);
      return false;
    }
    return true;
  } // validRef
Esempio n. 29
0
 /** Get the hash code for the given object. */
 public int hash(ObjectReference object) {
   check(!object.isNull(), "Object can not be null");
   int result = ObjectModel.getHashCode(object);
   Trace.trace(Item.HASH, "hash(%s) returned [%d]", ObjectModel.getString(object), result);
   return result;
 }
Esempio n. 30
0
 /**
  * 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());
 }