Class Shape

java.lang.Object
com.oracle.truffle.api.object.Shape

public abstract class Shape extends Object
A Shape is an immutable descriptor of the current object "shape" of a DynamicObject, i.e., object layout, metadata (type, flags), and a mapping of properties to storage locations. This allows cached DynamicObjectLibrary to do a simple shape check to determine the contents of an object and do fast, constant-time property accesses.

Shapes are shared between objects that assume the same shape if they follow the same shape transitions, like adding the same properties in the same order, starting from a common root shape. Shape transitions are automatically, weakly cached.

Dynamic objects start off with an initial shape that has no instance properties (but may have constant properties that are stored in the shape). Initial shapes are created via newBuilder().

Since:
0.8 or earlier
See Also:
  • Constructor Details

    • Shape

      protected Shape()
      Constructor for subclasses.
      Since:
      0.8 or earlier
  • Method Details

    • newBuilder

      public static Shape.Builder newBuilder()
      Creates a new initial shape builder. The builder instance is not thread-safe and must not be used from multiple threads at the same time.
      Since:
      20.2.0
    • newBuilder

      public static Shape.DerivedBuilder newBuilder(Shape baseShape)
      Creates a new derived shape builder that allows changing a root shape's flags and dynamic type and adding constant properties. The builder instance is not thread-safe and must not be used from multiple threads at the same time.
      Parameters:
      baseShape - the shape to be modified
      Since:
      20.2.0
      See Also:
    • getProperty

      public abstract Property getProperty(Object key)
      Get a property entry by key.
      Parameters:
      key - the identifier to look up
      Returns:
      a Property object, or null if not found
      Since:
      0.8 or earlier
    • addProperty

      protected abstract Shape addProperty(Property property)
      Add a new property in the map, yielding a new or cached Shape object.
      Parameters:
      property - the property to add
      Returns:
      the new Shape
      Since:
      0.8 or earlier
    • defineProperty

      @Deprecated(since="22.2") public abstract Shape defineProperty(Object key, Object value, int propertyFlags)
      Add or change property in the map, yielding a new or cached Shape object.
      Returns:
      the shape after defining the property
      Since:
      0.8 or earlier
    • defineProperty

      protected abstract Shape defineProperty(Object key, Object value, int propertyFlags, int putFlags)
      Add or change property in the map, yielding a new or cached Shape object.
      Returns:
      the shape after defining the property
      Since:
      24.1
    • getProperties

      public abstract Iterable<Property> getProperties()
      An Iterable over the shape's properties in insertion order.
      Since:
      0.8 or earlier
    • getPropertyList

      public abstract List<Property> getPropertyList()
      Get a list of all properties that this Shape stores. Properties with a HiddenKey are not included.
      Returns:
      list of properties
      Since:
      0.8 or earlier
    • getPropertyListInternal

      public abstract List<Property> getPropertyListInternal(boolean ascending)
      Returns all (also hidden) property objects in this shape.
      Parameters:
      ascending - desired order (true for insertion order, false for reverse insertion order)
      Since:
      0.8 or earlier
    • getKeyList

      public abstract List<Object> getKeyList()
      Get a list of all property keys in insertion order. Properties with a HiddenKey are not included.
      Since:
      0.8 or earlier
    • getKeys

      public abstract Iterable<Object> getKeys()
      Get all property keys in insertion order.
      Since:
      0.8 or earlier
    • getValidAssumption

      public abstract Assumption getValidAssumption()
      Get an assumption that the shape is valid.
      Since:
      0.8 or earlier
    • isValid

      public abstract boolean isValid()
      Check whether this shape is valid.
      Since:
      0.8 or earlier
    • getLeafAssumption

      public abstract Assumption getLeafAssumption()
      Get an assumption that the shape is a leaf.
      Since:
      0.8 or earlier
    • isLeaf

      public abstract boolean isLeaf()
      Check whether this shape is a leaf in the transition graph, i.e. transitionless.
      Since:
      0.8 or earlier
    • hasProperty

      public abstract boolean hasProperty(Object key)
      Check whether the shape has a property with the given key.
      Since:
      0.8 or earlier
    • removeProperty

      protected abstract Shape removeProperty(Property property)
      Remove the given property from the shape.
      Since:
      0.8 or earlier
    • replaceProperty

      protected abstract Shape replaceProperty(Property oldProperty, Property newProperty)
      Replace a property in the shape.
      Since:
      0.8 or earlier
    • getLastProperty

      public abstract Property getLastProperty()
      Get the last property.
      Since:
      0.8 or earlier
    • getFlags

      public int getFlags()
      Returns the language-specific shape flags previously set using DynamicObjectLibrary.setShapeFlags(DynamicObject, int) or Shape.Builder.shapeFlags(int). If no shape flags were explicitly set, the default of 0 is returned. These flags may be used to tag objects that possess characteristics that need to be queried efficiently on fast and slow paths. For example, they can be used to mark objects as frozen.
      Since:
      20.2.0
      See Also:
    • setFlags

      protected Shape setFlags(int newFlags)
      Returns a copy of the shape, with the shape flags set to newFlags.
      Parameters:
      newFlags - the new shape flags; an int value in the range from 0 to 65535 (inclusive)
      Throws:
      IllegalArgumentException - if the flags value is not in the supported range
      Since:
      20.2.0
      See Also:
    • getPropertyCount

      public abstract int getPropertyCount()
      Returns the number of properties in this shape.
      Since:
      0.8 or earlier
    • getDynamicType

      public Object getDynamicType()
      Get the shape's dynamic object type identifier.
      Since:
      20.2.0
    • setDynamicType

      protected Shape setDynamicType(Object dynamicType)
      Returns a copy of the shape, with the dynamic object type identifier set to dynamicType.
      Parameters:
      dynamicType - the new dynamic object type identifier
      Throws:
      NullPointerException - if the argument is null.
      Since:
      20.2.0
      See Also:
    • getRoot

      public abstract Shape getRoot()
      Get the root shape. Planned to be deprecated.
      Since:
      0.8 or earlier
    • check

      public abstract boolean check(DynamicObject subject)
      Checks whether the given object's shape is identical to this shape.
      Since:
      0.8 or earlier
    • getLayout

      protected abstract Layout getLayout()
      Get the shape's layout.
      Since:
      0.8 or earlier
      See Also:
    • getLayoutClass

      public Class<? extends DynamicObject> getLayoutClass()
      Get the shape's layout class.
      Since:
      21.1
      See Also:
    • getSharedData

      public abstract Object getSharedData()
      Get the shape's shared data.
      Since:
      0.8 or earlier
      See Also:
    • tryMerge

      public abstract Shape tryMerge(Shape other)
      Try to merge two related shapes to a more general shape that has the same properties and can store at least the values of both shapes.
      Returns:
      this, other, or a new shape that is compatible with both shapes
      Since:
      0.8 or earlier
    • isShared

      public boolean isShared()
      Returns true if this shape is marked as shared.
      Since:
      0.18
      See Also:
    • makeSharedShape

      public Shape makeSharedShape()
      Make a shared variant of this shape, to allow safe usage of this object between threads. Shared shapes will not reuse storage locations for other fields. In combination with careful synchronization on writes, this can prevent reading out-of-thin-air values.

      Note: Where possible, avoid using this method and use DynamicObjectLibrary.markShared(DynamicObject) instead.

      Returns:
      a cached and shared variant of this shape
      Since:
      0.18
      See Also:
    • hasInstanceProperties

      protected boolean hasInstanceProperties()
      Returns true if this shape has instance properties (i.e., stored in the object).
      Since:
      20.2.0
    • getPropertyAssumption

      public Assumption getPropertyAssumption(Object key)
      Gets a stable property assumption for the given property key. May be invalid. If a valid assumption is returned, it may be used to assume this particular property is still absent or present at the current storage location in objects of this shape. The assumption is invalidated if a shape change is triggered because of a property with the given key was added, removed, or changed, or a resetShape.

      Only applicable if property assumptions are enabled for this shape, otherwise always returns an invalid assumption.

      Parameters:
      key - the property key of interest
      Returns:
      an assumption that the property is stable or an invalid assumption
      Since:
      20.2.0
      See Also:
    • allPropertiesMatch

      public boolean allPropertiesMatch(Predicate<Property> predicate)
      Tests if all properties in the shape match the provided predicate. May not evaluate the predicate on all properties if a predicate did not match. If the shape does not contain any properties, returns true and does not evaluate the predicate.
      Returns:
      true if the all properties match the predicate, else false
      Since:
      20.2.0
    • makePropertyGetter

      public PropertyGetter makePropertyGetter(Object key)
      Makes a property getter for this shape and the given property key, if it exists. Otherwise, returns null. Note that the returned PropertyGetter only accepts objects of this particular Shape.
      Parameters:
      key - the identifier to look up
      Returns:
      a PropertyGetter, or null if the property was not found in this shape
      Since:
      22.2