Avail Object Representation
AvailObjectRepresentation is the representation used for all Avail objects.
Author
Todd L Smith
Mark van Gulik
Parameters
The initial descriptor for the new object.
The total number of AvailObject slots to allocate.
The total number of Long slots to allocate.
Types
Functions
Extract the current value of the indexable Long slot, pass it to the supplied inline Kotlin function, and write the result back to the slot with a compare-and-set, retrying from the beginning if it fails.
Extract the current value of the indexable object slot, pass it to the supplied Kotlin function, and write the result back to the slot with a compare-and-set, retrying from the beginning if it fails.
Turn the receiver into an indirection to the specified object.
Extract the byte at the given one-based byte subscript within the specified field. Always use little-endian encoding.
Sanity check: ensure that the specified field is writable.
Perform an atomic compare-and-set on a slot of the given array. If the value in the slot is the same Kotlin object (under ===) as the reference, replace it with the newValue and answer true. Otherwise answer false.
Utility method for decomposing this object in the debugger.
Retrieve this object's current descriptor.
Replace the descriptor with a filler. This blows up for most messages, catching further uses of this object. Note that all further uses are incorrect by definition.
Answer whether the receiver and the argument, both A_BasicObjects, are equal in value.
{@inheritDoc}
Answer whether the receiver, an object, and the argument, a byte string, are equal in value.
Answer whether the receiver, an object, and the argument, a byte tuple, are equal in value.
Answer whether the arguments, an object and a compiled code, are equal.
Answer whether the receiver equals the argument.
Answer whether the receiver equals the argument.
Determine whether the receiver is an enumeration with the given set of instances.
Answer whether the receiver, an object, and the argument, a fiber type, are equal in value.
Answer whether the receiver, an object, and the argument, a function type, are equal.
Answer whether the receiver equals the argument.
Answer whether this value equals the given list phrase type.
Answer whether the receiver equals the argument.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Answer whether the receiver equals the argument.
Extract a field from an object.
Extract a field from an object, using a one-based index into the field slots. This requires knowledge of the ObjectLayoutVariant, since the same field is at different indices in different variants.
Extract a field from an object, or answer null if it's not present.
Add or replace a field of an object.
Extract a field type from an object type.
Extract a field type from an object type, using the given field index, which is specific to an ObjectLayoutVariant.
Extract a field type from an object type, or null if it's not present.
Store the object in the specified slots of the receiver. The caller is responsible for ensuring the value has been marked Mutability.IMMUTABLE if necessary.
Store the AvailObject in the specified slot of the receiver, and answer the value that was previously in that slot. Use atomic write semantics that are compatible with volatile access. Note that this may answer nil if it's used on an unassigned variable's value slot.
Redirect Kotlin's hashCode to AbstractDescriptor.o_Hash.
Dispatch to the descriptor.
Search for the key in the 32-bit Ints encoded within the longSlots that occur within those slots identified with the specified IntegerSlotsEnum. The int slots must be in ascending sorted order, and must be distinct. If the exact int is found, answer its zero-based index within this repeated slot (i.e., ≥0). If the exact int is not found, answer (-n-1), where n is the zero-based position of the leftmost element of the repeated slot which is greater than the key (if it was equal, the "if found" case would have applied).
Answer the number of Long slots.
Search for the key in the 32-bit Ints encoded within the longSlots that occur within those slots identified with the specified IntegerSlotsEnum. Only search the given range of indices. If the given Int value is found within the given range, answer the index of the intSlot. Otherwise answer zero (0).
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
The receiver is marked with an IMMUTABLE descriptor, but its subobjects have not yet been made immutable. Scan them now, and do any additional fix-ups necessary for the kind of object.
Dispatch to the descriptor.
The receiver is marked with a SHARED descriptor, but its subobjects have not yet been made shared. Scan them now, and do any additional fix-ups necessary for the kind of object.
Dispatch to the descriptor.
Dispatch to the descriptor.
Extract an integer (at most 32 bits) from the given BitField. If the receiver is shared, then acquire its monitor.
Extract the (signed 64-bit) integer for the given field enum value, using volatile-read semantics if the receiver is shared.
Extract the object at the specified slot of the receiver. If the receiver is shared, then acquire its monitor.
Extract the (signed 64-bit) integer at the given field enum value. If the receiver is shared, then use VolatileSlotHelper.volatileRead to acquire the value.
Extract the AvailObject at the specified slot of the receiver, using volatile-read semantics if the receiver is shared.
Answer a name suitable for labeling a field containing this object.
Answer the number of AvailObject slots.
Recursively print the receiver to the builder unless it is already present in the recursionMap. Printing will begin at the specified indent level, measured in horizontal tab characters.
Dispatch to the descriptor.
Answer whether the objects occupy the same memory addresses.
Visit all of the object's object slots, passing the parent and child objects to the provided visitor.
Replace the byte at the given one-based byte subscript within the specified field. Always use little endian encoding.
Store the specified continuation in the receiver, which must be a fiber. This is the only circumstance in all of Avail in which a field of a (potentially) shared object may hold a non-shared object.
Replace this object's current currentDescriptorAbstractDescriptor].
Dispatch to the descriptor.
Store the (32-bit signed) Int at the given int-index of the receiver.
Store the signed 32-bit Int into the specified BitField, trimming upper bits beyond the BitField's size. If the receiver is shared, then use VolatileSlotHelper.compareAndSet to ensure only the intended bits are affected.
Store the (signed 64-bit) integer in the eight bytes starting at the given field enum value. If the receiver is Mutability.SHARED, then acquire its monitor.
Store the AvailObject in the specified slot of the receiver, using volatile-write semantics if the receiver is shared.
Store the (signed 64-bit) integer in the eight bytes starting at the given field enum value. If the receiver is shared, then use VolatileSlotHelper.volatileWrite to write the value.
Store the (16-bit unsigned) short at the given short-index of the receiver.
Replace the value of the BitField within this object.
Store the (signed 64-bit) integer in the eight bytes starting at the given field enum value.
Store the A_BasicObject in the specified object slot of the receiver.
Store the AvailObject in the specified slot of the receiver.
Read elements from consecutive slots of a LongArray, writing them to consecutive long slots of the receiver.
Read elements from consecutive slots of an array, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Write elements from the given List into consecutively numbered object slots. If the receiver is Mutability.SHARED, then the new value must also become shared (by the client) before it can be stored.
Read elements from consecutive integer slots of the sourceObject, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Read elements from consecutive slots of the sourceObject, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Read elements from consecutive slots of a tuple, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Replace my descriptor field with a FillerDescriptor. This blows up for most messages, catching incorrect (all, by definition) further accidental uses of this object.
Helper method for transferring this object's longSlots into an L1InstructionDecoder. The receiver's descriptor must be a CompiledCodeDescriptor.
Store the AvailObject in the specified slot of the receiver. Use volatile write semantics.
Extract a (16-bit unsigned) short at the given short-index of the receiver.
Answer whether to show value-specific content in the file name for the debugger.
Extract the value of the BitField of the receiver. Note that it's an Int even though the underlying longSlots array contains longs.
Extract the (signed 64-bit) integer for the given field enum value.
Extract the AvailObject from the specified object slot of the receiver.
Extract the (signed 64-bit) integer at the given field enum value.
Extract the AvailObject at the specified slot of the receiver.
Read consecutive long slots from the receiver, writing them into slots of a long array.
Follow indirections until a non-indirection is reached. Replace each indirection's target with the ultimate target.
Follow indirections until a non-indirection is reached. Replace each indirection's target with the ultimate target, even if it would cause the otherwise-forbidden immutable->mutable references. Only used during makeImmutable.
Follow indirections until a non-indirection is reached. Replace each indirection's target with the ultimate target, even if it would cause the otherwise-forbidden shared->unshared references. Only used during makeShared.
Reduce the number of long slots occupied by this object. In a raw memory model we would split the object representation into two objects, one at the original address, and a separate filler object occupying the long slots that were chopped off.
Slice the current AvailObject into two objects, the left one (at the same starting address as the input), and the right one (a filler object that nobody should ever create a pointer to). The new Filler can have zero post-header slots (i.e., just the header), but the left object must not, since it may turn into an indirection some day and will require at least one slot for the target pointer.
Extract the current Int value of the BitField, pass it to the supplied inline Kotlin function, and write the result back to the BitField. Note that this is not atomic, so other fields encoded in the same Long field may get clobbered if simultaneously updated by multiple threads.
Extract the current value of the Long slot, pass it to the supplied inline Kotlin function, and write the resulting Long back to the slot.
Extract the current value of the slot, pass it to the supplied inline Kotlin function, and write the result back to the slot.
Extract the current value of the slot, pass it to the supplied inline Kotlin function, make it shared, and write the result back to the slot.
Answer the number of variable integer slots in this object. This does not include the fixed integer slots.
Answer the number of variable object slots in this AvailObject. This does not include the fixed object slots.
Extract the AvailObject at the specified slot of the receiver. Use volatile semantics for the read.
Write an equivalent replacement object into an object field of this object. Since the replacement is semantically equivalent to the previous content, don't acquire a lock. Any necessary write barriers and other memory synchronizations are the responsibility of the caller.
Properties
Is the receiver an Avail extended integer?
Is the receiver an Avail IntTupleDescriptor? This is conservative, in that some object tuples may only contain ints but not be reported as being int tuples.
Is the receiver an Avail LongTupleDescriptor? This is conservative, in that some object tuples may only contain longs but not be reported as being long tuples.
Is the receiver an Avail two-byte string?
Is the receiver an Avail unsigned byte?