@Override public Object executeDispatch( final VirtualFrame frame, final Object receiverObject, final Object methodName, DynamicObject blockObject, final Object[] argumentsObjects) { CompilerDirectives.transferToInterpreterAndInvalidate(); // Make sure to have an up-to-date Shape. if (receiverObject instanceof DynamicObject) { ((DynamicObject) receiverObject).updateShape(); } final DispatchNode dispatch = atomic( new Callable<DispatchNode>() { @Override public DispatchNode call() throws Exception { final DispatchNode first = getHeadNode().getFirstDispatchNode(); // First try to see if we did not a miss a specialization added by another thread. DispatchNode lookupDispatch = first; while (lookupDispatch != null) { if (lookupDispatch.guard(methodName, receiverObject)) { // This one worked, no need to rewrite anything. return lookupDispatch; } lookupDispatch = lookupDispatch.getNext(); } // We need a new node to handle this case. final DispatchNode newDispathNode; if (depth == getContext().getOptions().DISPATCH_CACHE) { newDispathNode = new UncachedDispatchNode( getContext(), ignoreVisibility, getDispatchAction(), missingBehavior); } else { depth++; if (RubyGuards.isForeignObject(receiverObject)) { newDispathNode = createForeign(argumentsObjects, first, methodName); } else if (RubyGuards.isRubyBasicObject(receiverObject)) { newDispathNode = doDynamicObject(frame, first, receiverObject, methodName, argumentsObjects); } else { newDispathNode = doUnboxedObject(frame, first, receiverObject, methodName); } } first.replace(newDispathNode); return newDispathNode; } }); return dispatch.executeDispatch( frame, receiverObject, methodName, blockObject, argumentsObjects); }
private void setWithShapeSlowCase( DynamicObject store, Object value, Shape currentShape, Shape nextShape) { Shape oldShape = currentShape; if (store.updateShape()) { oldShape = store.getShape(); } LayoutStrategy strategy = ((LayoutImpl) currentShape.getLayout()).getStrategy(); LayoutStrategy.ShapeAndProperty newShapeAndProperty = strategy.generalizeProperty(this, value, (ShapeImpl) oldShape, (ShapeImpl) nextShape); if (store.updateShape()) { oldShape = store.getShape(); } Shape newNextShape = newShapeAndProperty.getShape(); Property newProperty = newShapeAndProperty.getProperty(); assert newNextShape.isValid() && oldShape.isValid(); newProperty.setSafe(store, value, oldShape, newNextShape); }
private void setSlowCase(DynamicObject store, Object value) { Shape oldShape = store.getShape(); Shape newShape = oldShape.defineProperty(getKey(), value, getFlags()); if (store.updateShape()) { oldShape = store.getShape(); } assert newShape.isValid() && oldShape.isValid(); Property newProperty = newShape.getProperty(getKey()); newProperty.setSafe(store, value, oldShape, newShape); }
protected Location getLocation(DynamicObject object, Object value) { object.updateShape(); final Shape oldShape = object.getShape(); final Property property = oldShape.getProperty(name); if (property != null && property.getLocation().canSet(object, value)) { return property.getLocation(); } else { return null; } }
@TruffleBoundary @Specialization public void writeUncached(DynamicObject object, Object value) { object.updateShape(); final Shape shape = object.getShape(); final Property property = shape.getProperty(name); if (property == null) { object.define(name, value, 0); } else { property.setGeneric(object, value, shape); } }
protected static Shape createSharedShape(DynamicObject object) { object.updateShape(); final Shape oldShape = object.getShape(); return oldShape.makeSharedShape(); }
public static boolean updateShape(DynamicObject object) { CompilerDirectives.transferToInterpreter(); return object.updateShape(); }