Class Shape

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

public final 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. Shape changes, like adding or removing a property, yield a new Shape derived from the old one.

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:
  • 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 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 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 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 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 Iterable<Property> getProperties()
      An Iterable over the shape's properties in insertion order.
      Since:
      0.8 or earlier
    • getPropertyList

      public 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 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 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 Iterable<Object> getKeys()
      Get all property keys in insertion order.
      Since:
      0.8 or earlier
    • getValidAssumption

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

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

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

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

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

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

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

      public Property getLastProperty()
      Gets the last property.
      Returns:
      the last property in the shape or null if empty
      Since:
      0.8 or earlier
    • getFirstProperty

      public Property getFirstProperty()
      Gets the first property.
      Returns:
      the first property in the shape or null if empty
      Since:
      25.1
    • 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 objectFlags)
      Returns a copy of the shape, with the shape flags set to newFlags.
      Parameters:
      objectFlags - 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 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 Shape getRoot()
      Get the root shape. Planned to be deprecated.
      Since:
      0.8 or earlier
    • check

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

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

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

      public 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
      Throws:
      UnsupportedOperationException - if this shape is already shared
      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
    • toString

      public String toString()
      Returns a string representation of the object.
      Overrides:
      toString in class Object
      Returns:
      a string representation of the object
      Since:
      25.1