void resetStack() { resumeStack(); }
void dump() { int m = 0; int k = 0; while (k < sp - 1) { final long record = dataLong[k++]; final int slots = getNumSlots(record); System.err.println("\tm=" + (m++) + " entry=" + getEntry(record) + " sp=" + k + " slots=" + slots + " prevSlots=" + getPrevNumSlots(record)); for (int i = 0; i < slots; i++, k++) System.err.println("\t\tsp=" + k + " long=" + dataLong[k] + " obj=" + dataObject[k]); } }
private static int getPrevNumSlots(long record) { return (int) getUnsignedBits(record, 30, 16); } ///////////////////////////////////////////////////////////////
/** * Called before a method is called. * * @param entry the entry point in the method for resume * @param numSlots the number of required stack slots for storing the state */ public final void pushMethodAndReserveSpace(int entry, int numSlots) { final int methodIdx = methodTOS; if (method.length - methodIdx < 2) growMethodStack(); curMethodSP = method[methodIdx - 1]; final int dataTOS = curMethodSP + numSlots; method[methodIdx] = entry; method[methodIdx + 1] = dataTOS; //System.out.println("entry="+entry+" size="+size+" sp="+curMethodSP+" tos="+dataTOS+" nr="+methodIdx); if (dataTOS > dataObject.length) growDataStack(dataTOS); }
/** * called at the beginning of a method * * @return the entry point of this method */ public final int nextMethodEntry() { int idx = 0; int slots = 0; if (sp > 0) { slots = getNumSlots(dataLong[sp - FRAME_RECORD_SIZE]); idx = sp + slots; } sp = idx + FRAME_RECORD_SIZE; long record = dataLong[idx]; int entry = getEntry(record); dataLong[idx] = setPrevNumSlots(record, slots); if (fiber.isRecordingLevel(2)) fiber.record(2, "Stack", "nextMethodEntry", "%s %s %s", Thread.currentThread().getStackTrace()[2], entry, sp /*Arrays.toString(fiber.getStackTrace())*/); return entry; }
this.target = target; this.fjTask = new FiberForkJoinTask<V>(this); this.stack = new Stack(this, stackSize > 0 ? stackSize : DEFAULT_STACK_SIZE); this.state = State.NEW;
private static Fiber verifyCurrent() { Fiber current = currentFiber(); if (current == null) { final Stack stack = Stack.getStack(); if (stack != null) { current = stack.getFiber(); if (!current.getStackTrace) throw new AssertionError(); return current; } throw new IllegalStateException("Not called on a fiber (current strand: " + Strand.currentStrand() + ")"); } return current; }
/** * called when nextMethodEntry returns 0 */ public final boolean isFirstInStackOrPushed() { boolean p = pushed; pushed = false; if (sp == FRAME_RECORD_SIZE | p) return true; // not first, but nextMethodEntry returned 0: revert changes sp -= FRAME_RECORD_SIZE + getPrevNumSlots(dataLong[sp - FRAME_RECORD_SIZE]); return false; }
this.task = scheduler != null ? scheduler.newFiberTask(this) : new FiberForkJoinTask(this); this.initialStackSize = stackSize; this.stack = new Stack(this, stackSize > 0 ? stackSize : DEFAULT_STACK_SIZE); this.priority = (byte)NORM_PRIORITY;
public final void popMethod(int slots) { pushed = false; final int oldSP = sp; final int idx = oldSP - FRAME_RECORD_SIZE; final long record = dataLong[idx]; // final int slots = getNumSlots(record); final int newSP = idx - getPrevNumSlots(record); // clear frame record (probably unnecessary) dataLong[idx] = 0L; // for (int i = 0; i < FRAME_RECORD_SIZE; i++) // dataLong[idx + i] = 0L; // help GC for (int i = oldSP; i < oldSP + slots && i < dataObject.length; i++) dataObject[i] = null; sp = newSP; if (fiber.isRecordingLevel(2)) fiber.record(2, "Stack", "popMethod ", "%s %d", Thread.currentThread().getStackTrace()[2], sp /*Arrays.toString(fiber.getStackTrace())*/); }
Stack(Fiber fiber, int stackSize) { if (stackSize <= 0) throw new IllegalArgumentException("stackSize"); this.fiber = fiber; this.dataLong = new long[stackSize + (FRAME_RECORD_SIZE * INITIAL_METHOD_STACK_DEPTH)]; this.dataObject = new Object[stackSize + (FRAME_RECORD_SIZE * INITIAL_METHOD_STACK_DEPTH)]; resumeStack(); }
private static boolean getBit(long word, int offset) { return (getUnsignedBits(word, offset, 1) != 0); }
assert ex != SuspendExecution.PARK && ex != SuspendExecution.YIELD; stack.resumeStack();
private static int getNumSlots(long record) { return (int) getUnsignedBits(record, 14, 16); }
f.inheritableFiberLocals = null; try { f.stack.resumeStack(); kryo.writeClass(output, f.getClass()); new FieldSerializer(kryo, f.getClass()).write(kryo, output, f); f.inheritableFiberLocals = realInheritableFiberLocals != null ? ThreadAccess.toMap(realInheritableFiberLocals).keySet().toArray() : null; f.stack.resumeStack();
private static int getEntry(long record) { return (int) getUnsignedBits(record, 0, 14); }
assert ex == SuspendExecution.instance; stack.resumeStack(); state = State.WAITING; fjTask.doPark(false); // now we can complete parking
assert ex == SuspendExecution.PARK || ex == SuspendExecution.YIELD; stack.resumeStack(); runningThread = null; orderedSetState(timeoutTask != null ? State.TIMED_WAITING : State.WAITING);