UninitializedReadObjectFieldNode.java

  1. /*
  2.  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
  3.  * code is released under a tri EPL/GPL/LGPL license. You can use it,
  4.  * redistribute it and/or modify it under the terms of the:
  5.  *
  6.  * Eclipse Public License version 1.0
  7.  * GNU General Public License version 2
  8.  * GNU Lesser General Public License version 2.1
  9.  */
  10. package org.jruby.truffle.nodes.objectstorage;

  11. import com.oracle.truffle.api.CompilerDirectives;
  12. import com.oracle.truffle.api.nodes.NodeCost;
  13. import com.oracle.truffle.api.nodes.NodeInfo;
  14. import com.oracle.truffle.api.object.*;
  15. import org.jruby.truffle.runtime.core.RubyBasicObject;

  16. @NodeInfo(cost = NodeCost.UNINITIALIZED)
  17. public class UninitializedReadObjectFieldNode extends ReadObjectFieldNode {

  18.     private final Object name;

  19.     public UninitializedReadObjectFieldNode(Object name) {
  20.         this.name = name;
  21.     }

  22.     @Override
  23.     public Object execute(RubyBasicObject object) {
  24.         CompilerDirectives.transferToInterpreterAndInvalidate();

  25.         if (object.getDynamicObject().updateShape()) {
  26.             ReadObjectFieldNode topNode = getTopNode();
  27.             if (topNode != this) {
  28.                 // retry existing cache nodes
  29.                 return topNode.execute(object);
  30.             }
  31.         }

  32.         final Shape layout = object.getDynamicObject().getShape();
  33.         final Property property = layout.getProperty(name);

  34.         final ReadObjectFieldNode newNode;

  35.         if (property == null) {
  36.             newNode = new ReadMissingObjectFieldNode(layout, this);
  37.         } else {
  38.             final Location storageLocation = property.getLocation();

  39.             assert storageLocation != null;

  40.             if (storageLocation instanceof BooleanLocation) {
  41.                 newNode = new ReadBooleanObjectFieldNode(layout, (BooleanLocation) storageLocation, this);
  42.             } else if (storageLocation instanceof IntLocation) {
  43.                 newNode = new ReadIntegerObjectFieldNode(layout, (IntLocation) storageLocation, this);
  44.             } else if (storageLocation instanceof LongLocation) {
  45.                 newNode = new ReadLongObjectFieldNode(layout, (LongLocation) storageLocation, this);
  46.             } else if (storageLocation instanceof DoubleLocation) {
  47.                 newNode = new ReadDoubleObjectFieldNode(layout, (DoubleLocation) storageLocation, this);
  48.             } else {
  49.                 newNode = new ReadObjectObjectFieldNode(layout, storageLocation, this);
  50.             }
  51.         }

  52.         replace(newNode, "adding new read object field node to chain");
  53.         return newNode.execute(object);
  54.     }

  55.     @Override
  56.     public boolean isSet(RubyBasicObject object) {
  57.         return object.getObjectLayout().getProperty(name) != null;
  58.     }

  59.     private ReadObjectFieldNode getTopNode() {
  60.         ReadObjectFieldNode topNode = this;
  61.         while (topNode.getParent() instanceof ReadObjectFieldNode) {
  62.             topNode = (ReadObjectFieldNode) topNode.getParent();
  63.         }
  64.         return topNode;
  65.     }
  66. }