@Override @AvailMethod void o_SetStartingChunkAndReoptimizationCountdown( final AvailObject object, final L2Chunk chunk, final long countdown) { final AtomicLong atomicCounter = getInvocationStatistic(object).countdownToReoptimize; if (isShared()) { synchronized (object) { object.setSlot(STARTING_CHUNK, chunk.chunkPojo); } // Must be outside the synchronized section to ensure the write of // the new chunk is committed before the counter reset is visible. atomicCounter.set(countdown); } else { object.setSlot(STARTING_CHUNK, chunk.chunkPojo); atomicCounter.set(countdown); } }
/** * Create a new compiled code object with the given properties. * * @param nybbles The nybblecodes. * @param locals The number of local variables. * @param stack The maximum stack depth. * @param functionType The type that the code's functions will have. * @param primitive Which primitive to invoke, or zero. * @param literals A tuple of literals. * @param localTypes A tuple of types of local variables. * @param outerTypes A tuple of types of outer (captured) variables. * @param module The module in which the code, or nil. * @param lineNumber The module line number on which this code starts. * @return The new compiled code object. */ public static AvailObject create( final A_Tuple nybbles, final int locals, final int stack, final A_Type functionType, final @Nullable Primitive primitive, final A_Tuple literals, final A_Tuple localTypes, final A_Tuple outerTypes, final A_Module module, final int lineNumber) { if (primitive != null) { // Sanity check for primitive blocks. Use this to hunt incorrectly // specified primitive signatures. final boolean canHaveCode = primitive.canHaveNybblecodes(); assert canHaveCode == (nybbles.tupleSize() > 0); final A_Type restrictionSignature = primitive.blockTypeRestriction(); assert restrictionSignature.isSubtypeOf(functionType); } else { assert nybbles.tupleSize() > 0; } assert localTypes.tupleSize() == locals; final A_Type argCounts = functionType.argsTupleType().sizeRange(); final int numArgs = argCounts.lowerBound().extractInt(); assert argCounts.upperBound().extractInt() == numArgs; final int literalsSize = literals.tupleSize(); final int outersSize = outerTypes.tupleSize(); assert 0 <= numArgs && numArgs <= 0xFFFF; assert 0 <= locals && locals <= 0xFFFF; final int slotCount = numArgs + locals + stack; assert 0 <= slotCount && slotCount <= 0xFFFF; assert 0 <= outersSize && outersSize <= 0xFFFF; assert module.equalsNil() || module.isInstanceOf(MODULE.o()); assert lineNumber >= 0; final AvailObject code = mutable.create(literalsSize + outersSize + locals); final InvocationStatistic statistic = new InvocationStatistic(); statistic.countdownToReoptimize.set(L2Chunk.countdownForNewCode()); final AvailObject statisticPojo = RawPojoDescriptor.identityWrap(statistic); code.setSlot(NUM_LOCALS, locals); code.setSlot(NUM_ARGS, numArgs); code.setSlot(FRAME_SLOTS, slotCount); code.setSlot(NUM_OUTERS, outersSize); code.setSlot(PRIMITIVE, primitive == null ? 0 : primitive.primitiveNumber); code.setSlot(NYBBLES, nybbles.makeShared()); code.setSlot(FUNCTION_TYPE, functionType.makeShared()); code.setSlot(PROPERTY_ATOM, NilDescriptor.nil()); code.setSlot(STARTING_CHUNK, L2Chunk.unoptimizedChunk().chunkPojo); code.setSlot(INVOCATION_STATISTIC, statisticPojo); // Fill in the literals. int dest; for (dest = 1; dest <= literalsSize; dest++) { code.setSlot(LITERAL_AT_, dest, literals.tupleAt(dest).makeShared()); } for (int i = 1; i <= outersSize; i++) { code.setSlot(LITERAL_AT_, dest++, outerTypes.tupleAt(i).makeShared()); } for (int i = 1; i <= locals; i++) { code.setSlot(LITERAL_AT_, dest++, localTypes.tupleAt(i).makeShared()); } assert dest == literalsSize + outersSize + locals + 1; final A_Atom propertyAtom = AtomWithPropertiesDescriptor.create(TupleDescriptor.empty(), module); propertyAtom.setAtomProperty(lineNumberKeyAtom(), IntegerDescriptor.fromInt(lineNumber)); code.setSlot(PROPERTY_ATOM, propertyAtom.makeShared()); final int hash = propertyAtom.hash() ^ -0x3087B215; code.setSlot(HASH, hash); code.makeShared(); // Add the newborn raw function to the weak set being used for code // coverage tracking. activeRawFunctions.add(code); return code; }