@Inline
  private boolean acquireRecyclableBlockAddressOrder() {
    if (recyclableExhausted) {
      if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) {
        Log.writeln("[no recyclable available]");
      }
      return false;
    }
    int markState = 0;
    boolean usable = false;
    while (!usable) {
      Address next = recyclableBlock.plus(BYTES_IN_BLOCK);
      if (recyclableBlock.isZero() || ImmixSpace.isRecycleAllocChunkAligned(next)) {
        recyclableBlock = space.acquireReusableBlocks();
        if (recyclableBlock.isZero()) {
          recyclableExhausted = true;
          if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) {
            Log.writeln("[recyclable exhausted]");
          }
          line = LINES_IN_BLOCK;
          return false;
        }
      } else {
        recyclableBlock = next;
      }
      markState = Block.getBlockMarkState(recyclableBlock);
      usable = (markState > 0 && markState <= ImmixSpace.getReusuableMarkStateThreshold(copy));
      if (copy && Block.isDefragSource(recyclableBlock)) usable = false;
    }
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Block.isUnused(recyclableBlock));
    Block.setBlockAsReused(recyclableBlock);

    lineUseCount += (LINES_IN_BLOCK - markState);
    return true; // found something good
  }
예제 #2
0
  /**
   * Takes the passed address and (atomically) performs any read barrier actions before returning it
   * as an object.
   *
   * @param tmp The non-zero referent address
   * @return The referent object.
   */
  @Uninterruptible
  @Inline
  Object getInternal() {
    if (RVMType.JavaLangRefReferenceReferenceField.madeTraced()) {
      if (NEEDS_OBJECT_GETFIELD_BARRIER) {
        return Barriers.objectFieldRead(
            this,
            RVMType.JavaLangRefReferenceReferenceField.getOffset(),
            RVMType.JavaLangRefReferenceReferenceField.getId());
      } else {
        return Magic.getObjectAtOffset(
            this,
            RVMType.JavaLangRefReferenceReferenceField.getOffset(),
            RVMType.JavaLangRefReferenceReferenceField.getId());
      }
    } else {
      Address tmp = _referent;
      if (tmp.isZero()) {
        return null;
      } else {
        Object ref = Magic.addressAsObject(tmp);

        if (Barriers.NEEDS_JAVA_LANG_REFERENCE_READ_BARRIER) {
          ref = Barriers.javaLangReferenceReadBarrier(ref);
        }
        return ref;
      }
    }
  }
 /**
  * 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);
 }
예제 #4
0
 /** Called after we've successfully loaded the shared library */
 private void callOnLoad() {
   // Run any JNI_OnLoad functions defined within the library
   Address JNI_OnLoadAddress = getSymbol("JNI_OnLoad");
   if (!JNI_OnLoadAddress.isZero()) {
     int version = runJNI_OnLoad(JNI_OnLoadAddress);
     checkJNIVersion(version);
   }
 }
예제 #5
0
 /** Sweep through the large pages, releasing all superpages on the "from space" treadmill. */
 private void sweepLargePages(boolean sweepNursery) {
   while (true) {
     Address cell = sweepNursery ? treadmill.popNursery() : treadmill.pop();
     if (cell.isZero()) break;
     release(getSuperPage(cell));
   }
   if (VM.VERIFY_ASSERTIONS)
     VM.assertions._assert(sweepNursery ? treadmill.nurseryEmpty() : treadmill.fromSpaceEmpty());
 }
예제 #6
0
 /**
  * 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();
 }
예제 #7
0
  /**
   * Load a dynamic library and maintain it in this object.
   *
   * @param libraryName library name
   */
  private VM_DynamicLibrary(String libraryName) {
    // Convert file name from unicode to filesystem character set.
    // (Assume file name is ASCII, for now).
    //
    byte[] asciiName = VM_StringUtilities.stringToBytesNullTerminated(libraryName);

    // make sure we have enough stack to load the library.
    // This operation has been known to require more than 20K of stack.
    VM_Thread myThread = VM_Scheduler.getCurrentThread();
    Offset remaining = VM_Magic.getFramePointer().diff(myThread.stackLimit);
    int stackNeededInBytes = VM_StackframeLayoutConstants.STACK_SIZE_DLOPEN - remaining.toInt();
    if (stackNeededInBytes > 0) {
      if (myThread.hasNativeStackFrame()) {
        throw new java.lang.StackOverflowError("dlopen");
      } else {
        VM_Thread.resizeCurrentStack(myThread.getStackLength() + stackNeededInBytes, null);
      }
    }

    libHandler = VM_SysCall.sysCall.sysDlopen(asciiName);

    if (libHandler.isZero()) {
      VM.sysWriteln("error loading library: " + libraryName);
      throw new UnsatisfiedLinkError();
    }

    libName = libraryName;
    try {
      callOnLoad();
    } catch (UnsatisfiedLinkError e) {
      unload();
      throw e;
    }

    if (VM.verboseJNI) {
      VM.sysWriteln("[Loaded native library: " + libName + "]");
    }
  }
  /**
   * External allocation slow path (called by superclass when slow path is actually taken. This is
   * necessary (rather than a direct call from the fast path) because of the possibility of a thread
   * switch and corresponding re-association of bump pointers to kernel threads.
   *
   * @param bytes The number of bytes allocated
   * @param align The requested alignment
   * @param offset The offset from the alignment
   * @return The address of the first byte of the allocated region or zero on failure
   */
  protected final Address allocSlowOnce(int bytes, int align, int offset) {
    Address ptr = space.getSpace(hot, copy, lineUseCount);

    if (ptr.isZero()) {
      lineUseCount = 0;
      return ptr; // failed allocation --- we will need to GC
    }

    /* we have been given a clean block */
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Block.isAligned(ptr));
    lineUseCount = LINES_IN_BLOCK;

    zeroBlock(ptr);
    if (requestForLarge) {
      largeCursor = ptr;
      largeLimit = ptr.plus(BYTES_IN_BLOCK);
    } else {
      cursor = ptr;
      limit = ptr.plus(BYTES_IN_BLOCK);
    }

    return alloc(bytes, align, offset);
  }
예제 #9
0
 /**
  * Push an address onto the address stack.
  *
  * @param addr the address to be pushed onto the address queue
  */
 @Inline
 public final void push(Address addr) {
   if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!addr.isZero());
   checkHeadInsert(1);
   uncheckedHeadInsert(addr);
 }
예제 #10
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