@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 }
/** * 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); }
/** 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()); }
/** * 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); }
/** * 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); }