Navigation Menu

Skip to content

Commit

Permalink
[Truffle] Adopt OM API.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Woess committed Dec 2, 2014
1 parent 5460e11 commit 42d8c43
Show file tree
Hide file tree
Showing 43 changed files with 706 additions and 1,074 deletions.
19 changes: 19 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/core/ClassNodes.java
Expand Up @@ -53,6 +53,8 @@ public abstract static class NewNode extends CoreMethodNode {

@Child protected AllocateNode allocateNode;
@Child protected DispatchHeadNode initialize;
@CompilerDirectives.CompilationFinal private boolean isCached = true;
@CompilerDirectives.CompilationFinal private RubyClass cachedClass;

public NewNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
Expand Down Expand Up @@ -82,6 +84,23 @@ private RubyBasicObject doNewInstance(VirtualFrame frame, RubyClass rubyClass, O
return instance;
}

private RubyClass cachedClass(RubyClass rubyClass) {
if (isCached) {
if (cachedClass == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
cachedClass = rubyClass;
}

if (rubyClass == cachedClass) {
return cachedClass;
} else {
CompilerDirectives.transferToInterpreterAndInvalidate();
isCached = false;
cachedClass = null;
}
}
return rubyClass;
}
}

@CoreMethod(names = "class_variables")
Expand Down
Expand Up @@ -421,7 +421,7 @@ public Object clone(VirtualFrame frame, RubyBasicObject self) {
newObject.getSingletonClass(this).initCopy(self.getMetaClass());
}

newObject.setInstanceVariables(self.getFields());
newObject.setInstanceVariables(self.getInstanceVariables());
initializeCloneNode.call(frame, newObject, "initialize_clone", null, self);

return newObject;
Expand Down Expand Up @@ -450,8 +450,7 @@ public Object dup(VirtualFrame frame, RubyBasicObject self) {
// This method is pretty crappy for compilation - it should improve with the OM

final RubyBasicObject newObject = self.getLogicalClass().newInstance(this);

newObject.setInstanceVariables(self.getFields());
newObject.setInstanceVariables(self.getInstanceVariables());
initializeDupNode.call(frame, newObject, "initialize_dup", null, self);

return newObject;
Expand Down
Expand Up @@ -9,44 +9,20 @@
*/
package org.jruby.truffle.nodes.objects;

import com.oracle.truffle.api.*;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.object.Property;
import com.oracle.truffle.api.object.Shape;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.utilities.BranchProfile;
import org.jruby.truffle.nodes.*;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.nodes.objectstorage.RespecializeHook;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.objectstorage.*;

public class ReadInstanceVariableNode extends RubyNode implements ReadNode {

private final RespecializeHook hook = new RespecializeHook() {

@Override
public void hookRead(ObjectStorage object, String name) {
final RubyBasicObject rubyObject = (RubyBasicObject) object;

if (!rubyObject.hasPrivateLayout()) {
rubyObject.updateLayoutToMatchClass();
}
}

@Override
public void hookWrite(ObjectStorage object, String name, Object value) {
final RubyBasicObject rubyObject = (RubyBasicObject) object;

if (!rubyObject.hasPrivateLayout()) {
rubyObject.updateLayoutToMatchClass();
}

rubyObject.setInstanceVariable(name, value);
}

};

@Child protected RubyNode receiver;
@Child protected ReadHeadObjectFieldNode readNode;
private final boolean isGlobal;
Expand All @@ -57,7 +33,7 @@ public void hookWrite(ObjectStorage object, String name, Object value) {
public ReadInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, boolean isGlobal) {
super(context, sourceSection);
this.receiver = receiver;
readNode = new ReadHeadObjectFieldNode(name, hook);
readNode = new ReadHeadObjectFieldNode(name);
this.isGlobal = isGlobal;
}

Expand Down Expand Up @@ -142,10 +118,10 @@ public Object isDefined(VirtualFrame frame) {
if (receiverObject instanceof RubyBasicObject) {
final RubyBasicObject receiverRubyObject = (RubyBasicObject) receiverObject;

final ObjectLayout layout = receiverRubyObject.getObjectLayout();
final StorageLocation storageLocation = layout.findStorageLocation(readNode.getName());
final Shape layout = receiverRubyObject.getDynamicObject().getShape();
final Property storageLocation = layout.getProperty(readNode.getName());

if (storageLocation.isSet(receiverRubyObject)) {
if (storageLocation != null) {
return context.makeString("instance-variable");
} else {
return getContext().getCoreLibrary().getNilObject();
Expand Down
Expand Up @@ -9,7 +9,7 @@
*/
package org.jruby.truffle.nodes.objects;

import com.oracle.truffle.api.*;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
Expand All @@ -18,35 +18,9 @@
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyMatchData;
import org.jruby.truffle.runtime.objectstorage.*;

public class WriteInstanceVariableNode extends RubyNode implements WriteNode {

private final RespecializeHook hook = new RespecializeHook() {

@Override
public void hookRead(ObjectStorage object, String name) {
final RubyBasicObject rubyObject = (RubyBasicObject) object;

if (!rubyObject.hasPrivateLayout()) {
rubyObject.updateLayoutToMatchClass();
}
}

@Override
public void hookWrite(ObjectStorage object, String name, Object value) {
final RubyBasicObject rubyObject = (RubyBasicObject) object;

if (!rubyObject.hasPrivateLayout()) {
rubyObject.updateLayoutToMatchClass();
}

rubyObject.setInstanceVariable(name, value);
}

};

@Child protected RubyNode receiver;
@Child protected RubyNode rhs;
@Child protected WriteHeadObjectFieldNode writeNode;
Expand All @@ -56,7 +30,7 @@ public WriteInstanceVariableNode(RubyContext context, SourceSection sourceSectio
super(context, sourceSection);
this.receiver = receiver;
this.rhs = rhs;
writeNode = new WriteHeadObjectFieldNode(name, hook);
writeNode = new WriteHeadObjectFieldNode(name);
this.isGlobal = isGlobal;
}

Expand Down
@@ -0,0 +1,33 @@
/*
* 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.object.Shape;
import org.jruby.truffle.runtime.core.RubyBasicObject;

public class MigrateNode extends WriteObjectFieldChainNode {

private final Shape expectedShape;

public MigrateNode(Shape expectedShape, WriteObjectFieldNode next) {
super(next);
this.expectedShape = expectedShape;
}

@Override
public void execute(RubyBasicObject object, Object value) {
if (object.getObjectLayout() == expectedShape) {
object.getDynamicObject().updateShape();
}

next.execute(object, value);
}

}
@@ -0,0 +1,68 @@
/*
* 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.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.BooleanLocation;
import com.oracle.truffle.api.object.Shape;
import org.jruby.truffle.runtime.core.RubyBasicObject;

@NodeInfo(cost = NodeCost.POLYMORPHIC)
public class ReadBooleanObjectFieldNode extends ReadObjectFieldChainNode {

private final Shape objectLayout;
private final BooleanLocation storageLocation;

public ReadBooleanObjectFieldNode(Shape objectLayout, BooleanLocation storageLocation, ReadObjectFieldNode next) {
super(next);
this.objectLayout = objectLayout;
this.storageLocation = storageLocation;
}

@Override
public boolean executeBoolean(RubyBasicObject object) throws UnexpectedResultException {
try {
objectLayout.getValidAssumption().check();
} catch (InvalidAssumptionException e) {
replace(next);
return next.executeBoolean(object);
}

final boolean condition = object.getObjectLayout() == objectLayout;

if (condition) {
return storageLocation.getBoolean(object.getDynamicObject(), objectLayout);
} else {
return next.executeBoolean(object);
}
}

@Override
public Object execute(RubyBasicObject object) {
try {
objectLayout.getValidAssumption().check();
} catch (InvalidAssumptionException e) {
replace(next);
return next.execute(object);
}

final boolean condition = object.getObjectLayout() == objectLayout;

if (condition) {
return storageLocation.get(object.getDynamicObject(), objectLayout);
} else {
return next.execute(object);
}
}

}
Expand Up @@ -9,42 +9,57 @@
*/
package org.jruby.truffle.nodes.objectstorage;

import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.jruby.truffle.runtime.objectstorage.DoubleStorageLocation;
import org.jruby.truffle.runtime.objectstorage.ObjectLayout;
import org.jruby.truffle.runtime.objectstorage.ObjectStorage;
import com.oracle.truffle.api.object.DoubleLocation;
import com.oracle.truffle.api.object.Shape;
import org.jruby.truffle.runtime.core.RubyBasicObject;

@NodeInfo(cost = NodeCost.POLYMORPHIC)
public class ReadDoubleObjectFieldNode extends ReadObjectFieldChainNode {

private final ObjectLayout objectLayout;
private final DoubleStorageLocation storageLocation;
private final Shape objectLayout;
private final DoubleLocation storageLocation;

public ReadDoubleObjectFieldNode(ObjectLayout objectLayout, DoubleStorageLocation storageLocation, ReadObjectFieldNode next) {
public ReadDoubleObjectFieldNode(Shape objectLayout, DoubleLocation storageLocation, ReadObjectFieldNode next) {
super(next);
this.objectLayout = objectLayout;
this.storageLocation = storageLocation;
}

@Override
public double executeDouble(ObjectStorage object) throws UnexpectedResultException {
public double executeDouble(RubyBasicObject object) throws UnexpectedResultException {
try {
objectLayout.getValidAssumption().check();
} catch (InvalidAssumptionException e) {
replace(next);
return next.executeDouble(object);
}

final boolean condition = object.getObjectLayout() == objectLayout;

if (condition) {
return storageLocation.readDouble(object, condition);
return storageLocation.getDouble(object.getDynamicObject(), objectLayout);
} else {
return next.executeDouble(object);
}
}

@Override
public Object execute(ObjectStorage object) {
public Object execute(RubyBasicObject object) {
try {
objectLayout.getValidAssumption().check();
} catch (InvalidAssumptionException e) {
replace(next);
return next.execute(object);
}

final boolean condition = object.getObjectLayout() == objectLayout;

if (condition) {
return storageLocation.read(object, condition);
return storageLocation.get(object.getDynamicObject(), objectLayout);
} else {
return next.execute(object);
}
Expand Down
Expand Up @@ -11,39 +11,39 @@

import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.jruby.truffle.runtime.objectstorage.ObjectStorage;
import org.jruby.truffle.runtime.core.RubyBasicObject;

public class ReadHeadObjectFieldNode extends Node {

private final String name;
@Child protected ReadObjectFieldNode first;

public ReadHeadObjectFieldNode(String name, RespecializeHook hook) {
public ReadHeadObjectFieldNode(String name) {
this.name = name;
first = new UninitializedReadObjectFieldNode(name, hook);
first = new UninitializedReadObjectFieldNode(name);
}

public int executeInteger(ObjectStorage object) throws UnexpectedResultException {
public int executeInteger(RubyBasicObject object) throws UnexpectedResultException {
return first.executeInteger(object);
}

public long executeLong(ObjectStorage object) throws UnexpectedResultException {
public long executeLong(RubyBasicObject object) throws UnexpectedResultException {
return first.executeLong(object);
}

public double executeDouble(ObjectStorage object) throws UnexpectedResultException {
public double executeDouble(RubyBasicObject object) throws UnexpectedResultException {
return first.executeDouble(object);
}

public Object execute(ObjectStorage object) {
public Object execute(RubyBasicObject object) {
return first.execute(object);
}

public String getName() {
return name;
}

public boolean isSet(ObjectStorage object) {
public boolean isSet(RubyBasicObject object) {
return first.isSet(object);
}

Expand Down

0 comments on commit 42d8c43

Please sign in to comment.