/** @since 0.17 or earlier */ @Override public final BaseAllocator allocator() { return layout.getStrategy().createAllocator(this); }
/** @since 0.17 or earlier */ protected ShapeImpl addProperty(ShapeImpl shape, Property property) { return addProperty(shape, property, true); }
/** @since 0.17 or earlier */ protected ShapeImpl defineProperty(ShapeImpl shape, Object key, Object value, int flags, LocationFactory locationFactory) { ShapeImpl oldShape = shape; if (!oldShape.isValid()) { oldShape = ensureValid(oldShape); } Property existing = oldShape.getProperty(key); return defineProperty(oldShape, key, value, flags, locationFactory, existing); }
/** @since 0.17 or earlier */ protected ShapeImpl addProperty(ShapeImpl shape, Property property, boolean ensureValid) { assert !(shape.hasProperty(property.getKey())) : "duplicate property " + property.getKey(); AddPropertyTransition addTransition = new AddPropertyTransition(property); ShapeImpl cachedShape = shape.queryTransition(addTransition); if (cachedShape != null) { return ensureValid ? ensureValid(cachedShape) : cachedShape; } ShapeImpl oldShape = ensureSpace(shape, property.getLocation()); ShapeImpl newShape = ShapeImpl.makeShapeWithAddedProperty(oldShape, addTransition); oldShape.addDirectTransition(addTransition, newShape); return newShape; }
/** @since 0.17 or earlier */ protected ShapeImpl removeProperty(ShapeImpl shape, Property property) { assert !shape.isShared(); RemovePropertyTransition transition = new RemovePropertyTransition(property); ShapeImpl cachedShape = shape.queryTransition(transition); if (cachedShape != null) { return ensureValid(cachedShape); } ShapeImpl owningShape = getShapeFromProperty(shape, property.getKey()); if (owningShape != null) { List<Transition> transitionList = new ArrayList<>(); ShapeImpl current = shape; while (current != owningShape) { if (!(current.getTransitionFromParent() instanceof Transition.DirectReplacePropertyTransition) || !((Transition.DirectReplacePropertyTransition) current.getTransitionFromParent()).getPropertyBefore().getKey().equals(property.getKey())) { transitionList.add(current.getTransitionFromParent()); } current = current.parent; } ShapeImpl newShape = owningShape.parent; for (ListIterator<Transition> iterator = transitionList.listIterator(transitionList.size()); iterator.hasPrevious();) { Transition previous = iterator.previous(); newShape = applyTransition(newShape, previous, true); } shape.addIndirectTransition(transition, newShape); return newShape; } else { return null; } }
/** @since 0.17 or earlier */ protected void propertySetWithShapeFallback(Property property, DynamicObject store, Object value, ShapeImpl currentShape, ShapeImpl nextShape) { ShapeImpl oldShape = currentShape; ShapeImpl newNextShape = generalizeProperty(property, value, oldShape, nextShape); Property newProperty = newNextShape.getProperty(property.getKey()); newProperty.setSafe(store, value, oldShape, newNextShape); }
/** @since 0.17 or earlier */ protected void propertySetFallback(Property property, DynamicObject store, Object value, ShapeImpl currentShape) { ShapeImpl oldShape = currentShape; ShapeImpl newShape = defineProperty(oldShape, property.getKey(), value, property.getFlags(), getDefaultLocationFactory()); Property newProperty = newShape.getProperty(property.getKey()); newProperty.setSafe(store, value, oldShape, newShape); }
/** @since 0.17 or earlier */ protected ShapeImpl defineProperty(ShapeImpl oldShape, Object key, Object value, int flags, LocationFactory locationFactory, Property existing) { if (existing == null) { Property property = Property.create(key, locationFactory.createLocation(oldShape, value), flags); ShapeImpl newShape = oldShape.addProperty(property); return newShape; } else { if (existing.getFlags() == flags) { if (existing.getLocation().canSet(value)) { return oldShape; } else { return definePropertyGeneralize(oldShape, existing, value, locationFactory); } } else { return definePropertyChangeFlags(oldShape, existing, value, flags); } } }
/** @since 0.17 or earlier */ protected ShapeImpl applyTransition(ShapeImpl shape, Transition transition, boolean append) { if (transition instanceof AddPropertyTransition) { Property property = ((AddPropertyTransition) transition).getProperty(); if (append) { return shape.append(property); } else { shape.onPropertyTransition(property); return addProperty(shape, property, false); } } else if (transition instanceof ObjectTypeTransition) { return shape.changeType(((ObjectTypeTransition) transition).getObjectType()); } else if (transition instanceof ReservePrimitiveArrayTransition) { return shape.reservePrimitiveExtensionArray(); } else if (transition instanceof DirectReplacePropertyTransition) { Property oldProperty = ((DirectReplacePropertyTransition) transition).getPropertyBefore(); Property newProperty = ((DirectReplacePropertyTransition) transition).getPropertyAfter(); if (append) { oldProperty = shape.getProperty(oldProperty.getKey()); newProperty = newProperty.relocate(shape.allocator().moveLocation(newProperty.getLocation())); } return directReplaceProperty(shape, oldProperty, newProperty); } else { throw new UnsupportedOperationException(transition.getClass().getName()); } }
/** @since 0.17 or earlier */ @Override public final boolean updateShape() { return getShapeImpl().getLayout().getStrategy().updateShape(this); }
private ShapeImpl addPrimitiveExtensionArray() { assert layout.hasPrimitiveExtensionArray() && !hasPrimitiveArray(); Transition transition = new ReservePrimitiveArrayTransition(); ShapeImpl cachedShape = queryTransition(transition); if (cachedShape != null) { return cachedShape; } ShapeImpl oldShape = (ShapeImpl) layout.getStrategy().ensureSpace(this, layout.getPrimitiveArrayLocation()); ShapeImpl newShape = makeShapeWithPrimitiveExtensionArray(oldShape, transition); oldShape.addDirectTransition(transition, newShape); return newShape; }
/** @since 0.17 or earlier */ @TruffleBoundary @Override public ShapeImpl defineProperty(Object key, Object value, int flags, LocationFactory locationFactory) { return layout.getStrategy().defineProperty(this, key, value, flags, locationFactory); }
/** @since 0.17 or earlier */ @Override public final ShapeImpl reservePrimitiveExtensionArray() { if (layout.hasPrimitiveExtensionArray() && !hasPrimitiveArray()) { return layout.getStrategy().addPrimitiveExtensionArray(this); } return this; }
/** @since 0.17 or earlier */ protected ShapeImpl addProperty(ShapeImpl shape, Property property, boolean ensureValid) { assert !(shape.hasProperty(property.getKey())) : "duplicate property " + property.getKey(); AddPropertyTransition addTransition = new AddPropertyTransition(property); ShapeImpl cachedShape = shape.queryTransition(addTransition); if (cachedShape != null) { return ensureValid ? ensureValid(cachedShape) : cachedShape; } ShapeImpl oldShape = ensureSpace(shape, property.getLocation()); ShapeImpl newShape = ShapeImpl.makeShapeWithAddedProperty(oldShape, addTransition); oldShape.addDirectTransition(addTransition, newShape); return newShape; }
/** @since 0.17 or earlier */ protected ShapeImpl removeProperty(ShapeImpl shape, Property property) { assert !shape.isShared(); RemovePropertyTransition transition = new RemovePropertyTransition(property); ShapeImpl cachedShape = shape.queryTransition(transition); if (cachedShape != null) { return ensureValid(cachedShape); } ShapeImpl owningShape = getShapeFromProperty(shape, property.getKey()); if (owningShape != null) { List<Transition> transitionList = new ArrayList<>(); ShapeImpl current = shape; while (current != owningShape) { if (!(current.getTransitionFromParent() instanceof Transition.DirectReplacePropertyTransition) || !((Transition.DirectReplacePropertyTransition) current.getTransitionFromParent()).getPropertyBefore().getKey().equals(property.getKey())) { transitionList.add(current.getTransitionFromParent()); } current = current.parent; } ShapeImpl newShape = owningShape.parent; for (ListIterator<Transition> iterator = transitionList.listIterator(transitionList.size()); iterator.hasPrevious();) { Transition previous = iterator.previous(); newShape = applyTransition(newShape, previous, true); } shape.addIndirectTransition(transition, newShape); return newShape; } else { return null; } }
/** @since 0.17 or earlier */ protected void propertySetWithShapeFallback(Property property, DynamicObject store, Object value, ShapeImpl currentShape, ShapeImpl nextShape) { ShapeImpl oldShape = currentShape; ShapeImpl newNextShape = generalizeProperty(property, value, oldShape, nextShape); Property newProperty = newNextShape.getProperty(property.getKey()); newProperty.setSafe(store, value, oldShape, newNextShape); }
/** @since 0.17 or earlier */ protected void propertySetFallback(Property property, DynamicObject store, Object value, ShapeImpl currentShape) { ShapeImpl oldShape = currentShape; ShapeImpl newShape = defineProperty(oldShape, property.getKey(), value, property.getFlags(), getDefaultLocationFactory()); Property newProperty = newShape.getProperty(property.getKey()); newProperty.setSafe(store, value, oldShape, newShape); }
/** @since 0.17 or earlier */ protected ShapeImpl defineProperty(ShapeImpl oldShape, Object key, Object value, int flags, LocationFactory locationFactory, Property existing) { if (existing == null) { Property property = Property.create(key, locationFactory.createLocation(oldShape, value), flags); ShapeImpl newShape = oldShape.addProperty(property); return newShape; } else { if (existing.getFlags() == flags) { if (existing.getLocation().canSet(value)) { return oldShape; } else { return definePropertyGeneralize(oldShape, existing, value, locationFactory); } } else { return definePropertyChangeFlags(oldShape, existing, value, flags); } } }
/** @since 0.17 or earlier */ protected ShapeImpl applyTransition(ShapeImpl shape, Transition transition, boolean append) { if (transition instanceof AddPropertyTransition) { Property property = ((AddPropertyTransition) transition).getProperty(); if (append) { return shape.append(property); } else { shape.onPropertyTransition(property); return addProperty(shape, property, false); } } else if (transition instanceof ObjectTypeTransition) { return shape.changeType(((ObjectTypeTransition) transition).getObjectType()); } else if (transition instanceof ReservePrimitiveArrayTransition) { return shape.reservePrimitiveExtensionArray(); } else if (transition instanceof DirectReplacePropertyTransition) { Property oldProperty = ((DirectReplacePropertyTransition) transition).getPropertyBefore(); Property newProperty = ((DirectReplacePropertyTransition) transition).getPropertyAfter(); if (append) { oldProperty = shape.getProperty(oldProperty.getKey()); newProperty = newProperty.relocate(shape.allocator().moveLocation(newProperty.getLocation())); } return directReplaceProperty(shape, oldProperty, newProperty); } else { throw new UnsupportedOperationException(transition.getClass().getName()); } }
/** @since 0.17 or earlier */ @Override public final boolean updateShape() { return getShape().getLayout().getStrategy().updateShape(this); }