UninitializedReadObjectFieldNode.java
- /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
- package org.jruby.truffle.nodes.objectstorage;
- import com.oracle.truffle.api.CompilerDirectives;
- import com.oracle.truffle.api.nodes.NodeCost;
- import com.oracle.truffle.api.nodes.NodeInfo;
- import com.oracle.truffle.api.object.*;
- import org.jruby.truffle.runtime.core.RubyBasicObject;
- @NodeInfo(cost = NodeCost.UNINITIALIZED)
- public class UninitializedReadObjectFieldNode extends ReadObjectFieldNode {
- private final Object name;
- public UninitializedReadObjectFieldNode(Object name) {
- this.name = name;
- }
- @Override
- public Object execute(RubyBasicObject object) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- if (object.getDynamicObject().updateShape()) {
- ReadObjectFieldNode topNode = getTopNode();
- if (topNode != this) {
- // retry existing cache nodes
- return topNode.execute(object);
- }
- }
- final Shape layout = object.getDynamicObject().getShape();
- final Property property = layout.getProperty(name);
- final ReadObjectFieldNode newNode;
- if (property == null) {
- newNode = new ReadMissingObjectFieldNode(layout, this);
- } else {
- final Location storageLocation = property.getLocation();
- assert storageLocation != null;
- if (storageLocation instanceof BooleanLocation) {
- newNode = new ReadBooleanObjectFieldNode(layout, (BooleanLocation) storageLocation, this);
- } else if (storageLocation instanceof IntLocation) {
- newNode = new ReadIntegerObjectFieldNode(layout, (IntLocation) storageLocation, this);
- } else if (storageLocation instanceof LongLocation) {
- newNode = new ReadLongObjectFieldNode(layout, (LongLocation) storageLocation, this);
- } else if (storageLocation instanceof DoubleLocation) {
- newNode = new ReadDoubleObjectFieldNode(layout, (DoubleLocation) storageLocation, this);
- } else {
- newNode = new ReadObjectObjectFieldNode(layout, storageLocation, this);
- }
- }
- replace(newNode, "adding new read object field node to chain");
- return newNode.execute(object);
- }
- @Override
- public boolean isSet(RubyBasicObject object) {
- return object.getObjectLayout().getProperty(name) != null;
- }
- private ReadObjectFieldNode getTopNode() {
- ReadObjectFieldNode topNode = this;
- while (topNode.getParent() instanceof ReadObjectFieldNode) {
- topNode = (ReadObjectFieldNode) topNode.getParent();
- }
- return topNode;
- }
- }