@Substitute @SuppressWarnings({"unused"}) @TargetElement(onlyWith = JDK9OrLater.class) private Target_java_lang_Thread( ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { /* Non-0 instance field initialization. */ this.blockerLock = new Object(); /* Injected Target_java_lang_Thread instance field initialization. */ this.unsafeParkEvent = new AtomicReference<>(); this.sleepParkEvent = new AtomicReference<>(); /* Initialize the rest of the Thread object, ignoring `acc` and `inheritThreadLocals`. */ Util_java_lang_Thread.initialize(this, g, target, name, stackSize); }
for (PinnedObjectImpl pinnedObject = getPinHead().get(); pinnedObject != null; pinnedObject = pinnedObject.getNext()) { if (instance == pinnedObject.getObject()) { return true;
/** Constructor for subclasses. */ @Platforms(Platform.HOSTED_ONLY.class) public HeapImpl(FeatureAccess access) { this.youngGeneration = new YoungGeneration("YoungGeneration"); this.oldGeneration = new OldGeneration("OldGeneration"); this.gcImpl = new GCImpl(access); this.objectHeaderImpl = new ObjectHeaderImpl(); this.heapPolicy = new HeapPolicy(access); this.pinHead = new AtomicReference<>(); /* Pre-allocate verifiers for use during collection. */ if (getVerifyHeapBeforeGC() || getVerifyHeapAfterGC() || getVerifyStackBeforeGC() || getVerifyStackAfterGC()) { this.heapVerifier = HeapVerifierImpl.factory(); this.stackVerifier = new StackVerifier(); } else { this.heapVerifier = null; this.stackVerifier = null; } chunkProvider = new HeapChunkProvider(); this.pinnedAllocatorListHead = null; this.objectVisitorWalkerOperation = new ObjectVisitorWalkerOperation(); this.memoryMXBean = new HeapImplMemoryMXBean(); this.classList = null; SubstrateUtil.DiagnosticThunkRegister.getSingleton().register(() -> { bootImageHeapBoundariesToLog(Log.log()).newline(); zapValuesToLog(Log.log()).newline(); report(Log.log(), true).newline(); Log.log().newline(); }); }
static ParkEvent initializeOnce(AtomicReference<ParkEvent> ref, boolean resetEventBeforeWait) { ParkEvent result = ref.get(); if (result == null) { ParkEvent newEvent = ParkEvent.acquire(); /* * Assign a *new* cons-cell for this ParkEvent, whether it was acquired from the * free-list or allocated. */ newEvent.consCell = new ParkEventConsCell(newEvent); newEvent.event = false; newEvent.resetEventBeforeWait = resetEventBeforeWait; if (ref.compareAndSet(null, newEvent)) { /* We won the race. */ result = newEvent; } else { /* * We lost the race. We have one extra ParkEvent now, which we put back on the * queue, so that it is reused later on. */ ParkEvent.release(newEvent); result = ref.get(); } } return result; }
/** * Push an element onto the list. May be called by many threads simultaneously, so it uses a * compareAndSet loop. */ public static PinnedObjectImpl pushPinnedObject(PinnedObjectImpl newHead) { final Log trace = Log.noopLog().string("[PinnedObject.pushPinnedObject:").string(" newHead: ").object(newHead); final HeapImpl heap = HeapImpl.getHeapImpl(); final AtomicReference<PinnedObjectImpl> pinHead = heap.getPinHead(); PinnedObjectImpl sampleHead; do { sampleHead = pinHead.get(); newHead.setNext(sampleHead); } while (!pinHead.compareAndSet(sampleHead, newHead)); trace.string(" returns: ").object(newHead).string("]").newline(); return newHead; }
/** Return the head of the free-list, or null. */ public ParkEvent pop() { ParkEventConsCell sampleHead; ParkEventConsCell sampleNext; do { sampleHead = freeList.get(); if (sampleHead == null) { return null; } sampleNext = sampleHead.getNext(); } while (!freeList.compareAndSet(sampleHead, sampleNext)); return sampleHead.getElement(); } }
/** Private constructor: Only the singleton instance. */ private ParkEventList() { freeList = new AtomicReference<>(null); }
Target_java_lang_Thread(String withName, ThreadGroup withGroup, boolean asDaemon) { /* * Raw creation of a thread without calling init(). Used to create a Thread object for an * already running thread. */ this.unsafeParkEvent = new AtomicReference<>(); this.sleepParkEvent = new AtomicReference<>(); tid = nextThreadID(); threadStatus = ThreadStatus.RUNNABLE; name = (withName != null) ? withName : ("System-" + nextThreadNum()); group = (withGroup != null) ? withGroup : JavaThreads.singleton().rootGroup; priority = Thread.NORM_PRIORITY; blockerLock = new Object(); daemon = asDaemon; }
@Uninterruptible(reason = "Called from uninterruptible code.") public FeebleReferenceList<T> getList() { return list.get(); }
/** Clears the list, returning the previous value, which might be null. */ public FeebleReferenceList<T> clearList() { return list.getAndSet(null); }
/** Constructor for subclasses. */ protected FeebleReference(final T referent, final FeebleReferenceList<T> list) { super(referent); this.list = new AtomicReference<>(list); FeebleReferenceList.clean(this); }
/** * Claim the entire list. Only called once during each collection, but it uses getAndSet(null) * anyway so I do not have to worry about it. */ public static PinnedObjectImpl claimPinnedObjectList() { final Log trace = Log.noopLog().string("[PinnedObject.claimPinnedObjectList:").newline(); final HeapImpl heap = HeapImpl.getHeapImpl(); final AtomicReference<PinnedObjectImpl> pinHead = heap.getPinHead(); final PinnedObjectImpl result = pinHead.getAndSet(null); trace.string(" returns: ").object(result); return result; }
@Uninterruptible(reason = "Called from uninterruptible code.") private boolean compareAndSetHead(FeebleReference<? extends T> expect, FeebleReference<? extends T> update) { return head.compareAndSet(expect, update); }
@Uninterruptible(reason = "Called from uninterruptible code.") private FeebleReference<? extends T> getHead() { return head.get(); }
/** Interrupt a sleeping thread. */ protected static void interrupt(Thread thread) { final ParkEvent sleepEvent = JavaThreads.getSleepParkEvent(thread).get(); if (sleepEvent != null) { sleepEvent.unpark(); } }
@Substitute @TargetElement(onlyWith = JDK8OrEarlier.class) private void init(ThreadGroup groupArg, Runnable targetArg, String nameArg, long stackSizeArg) { /* Injected Target_java_lang_Thread instance field initialization. */ this.unsafeParkEvent = new AtomicReference<>(); this.sleepParkEvent = new AtomicReference<>(); /* Initialize the rest of the Thread object. */ Util_java_lang_Thread.initialize(this, groupArg, targetArg, nameArg, stackSizeArg); }
/** Push an element on to the free-list. */ protected void push(ParkEvent element) { ParkEventConsCell sampleHead; /* Use up the cons-cell for each attempted push to avoid the ABA problem on pops. */ ParkEventConsCell nextHead = element.consumeConsCell(); do { sampleHead = freeList.get(); nextHead.setNext(sampleHead); } while (!freeList.compareAndSet(sampleHead, nextHead)); }
/** Constructor for subclasses. */ private FeebleReferenceList() { head = new UninterruptibleUtils.AtomicReference<>(null); }