-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
- 9.0.1.0
- 9.0.0.0
- 9.0.0.0.rc2
- 9.0.0.0.rc1
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,12 +11,18 @@ | |
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.Truffle; | ||
import com.oracle.truffle.api.dsl.Cached; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.FrameDescriptor; | ||
import com.oracle.truffle.api.frame.FrameSlot; | ||
import com.oracle.truffle.api.frame.MaterializedFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.nodes.globals.GetFromThreadLocalNode; | ||
import org.jruby.truffle.nodes.globals.WrapInThreadLocalNode; | ||
import org.jruby.truffle.nodes.methods.locals.ReadAbstractFrameSlotNode; | ||
import org.jruby.truffle.nodes.methods.locals.ReadAbstractFrameSlotNodeGen; | ||
import org.jruby.truffle.nodes.methods.locals.WriteAbstractFrameSlotNode; | ||
import org.jruby.truffle.nodes.methods.locals.WriteAbstractFrameSlotNodeGen; | ||
import org.jruby.truffle.runtime.RubyArguments; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
|
@@ -37,8 +43,6 @@ public InitializeCopyNode(RubyContext context, SourceSection sourceSection) { | |
|
||
@Specialization | ||
public Object initializeCopy(RubyBinding self, RubyBinding from) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
if (self == from) { | ||
return self; | ||
} | ||
|
@@ -66,21 +70,52 @@ public LocalVariableGetNode(RubyContext context, SourceSection sourceSection) { | |
super(context, sourceSection); | ||
} | ||
|
||
@Specialization | ||
public Object localVariableGet(RubyBinding binding, RubySymbol symbol) { | ||
CompilerDirectives.transferToInterpreter(); | ||
@Specialization(guards = { | ||
"!isLastLine(symbol)", | ||
"getFrameDescriptor(binding) == cachedFrameDescriptor", | ||
"symbol == cachedSymbol" | ||
|
||
}) | ||
public Object localVariableGetCached(RubyBinding binding, RubySymbol symbol, | ||
@Cached("symbol") RubySymbol cachedSymbol, | ||
@Cached("getFrameDescriptor(binding)") FrameDescriptor cachedFrameDescriptor, | ||
@Cached("createReadNode(findFrameSlot(cachedFrameDescriptor, symbol))") ReadAbstractFrameSlotNode readLocalVariableNode) { | ||
return readLocalVariableNode.executeRead(binding.getFrame()); | ||
} | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
chrisseaton
Author
Contributor
|
||
@CompilerDirectives.TruffleBoundary | ||
@Specialization(guards = "!isLastLine(symbol)") | ||
public Object localVariableGetUncached(RubyBinding binding, RubySymbol symbol) { | ||
final MaterializedFrame frame = binding.getFrame(); | ||
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString()); | ||
return frame.getValue(frameSlot); | ||
} | ||
|
||
Object value = frame.getValue(frame.getFrameDescriptor().findFrameSlot(symbol.toString())); | ||
@CompilerDirectives.TruffleBoundary | ||
@Specialization(guards = "isLastLine(symbol)") | ||
public Object localVariableGetLastLine(RubyBinding binding, RubySymbol symbol) { | ||
final MaterializedFrame frame = binding.getFrame(); | ||
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString()); | ||
final Object value = frame.getValue(frameSlot); | ||
return GetFromThreadLocalNode.get(getContext(), value); | ||
} | ||
|
||
// TODO(CS): temporary hack for $_ | ||
if (symbol.toString().equals("$_")) { | ||
value = GetFromThreadLocalNode.get(getContext(), value); | ||
} | ||
protected FrameDescriptor getFrameDescriptor(RubyBinding binding) { | ||
return binding.getFrame().getFrameDescriptor(); | ||
} | ||
|
||
return value; | ||
protected FrameSlot findFrameSlot(FrameDescriptor frameDescriptor, RubySymbol symbol) { | ||
return frameDescriptor.findFrameSlot(symbol.toString()); | ||
} | ||
|
||
protected ReadAbstractFrameSlotNode createReadNode(FrameSlot frameSlot) { | ||
return ReadAbstractFrameSlotNodeGen.create(frameSlot); | ||
} | ||
|
||
protected boolean isLastLine(RubySymbol symbol) { | ||
return symbol.toString() == "$_"; | ||
} | ||
|
||
} | ||
|
||
@CoreMethod(names = "local_variable_set", required = 2) | ||
|
@@ -90,31 +125,64 @@ public LocalVariableSetNode(RubyContext context, SourceSection sourceSection) { | |
super(context, sourceSection); | ||
} | ||
|
||
@Specialization | ||
public Object localVariableSetNode(RubyBinding binding, RubySymbol symbol, Object value) { | ||
CompilerDirectives.transferToInterpreter(); | ||
@Specialization(guards = { | ||
"!isLastLine(symbol)", | ||
"getFrameDescriptor(binding) == cachedFrameDescriptor", | ||
"symbol == cachedSymbol" | ||
This comment has been minimized.
Sorry, something went wrong.
nirvdrum
Contributor
|
||
}) | ||
public Object localVariableSetCached(RubyBinding binding, RubySymbol symbol, Object value, | ||
@Cached("symbol") RubySymbol cachedSymbol, | ||
@Cached("getFrameDescriptor(binding)") FrameDescriptor cachedFrameDescriptor, | ||
@Cached("createWriteNode(findFrameSlot(binding, symbol))") WriteAbstractFrameSlotNode writeLocalVariableNode) { | ||
return writeLocalVariableNode.executeWrite(binding.getFrame(), value); | ||
} | ||
|
||
// TODO(CS): temporary hack for $_ | ||
if (symbol.toString().equals("$_")) { | ||
value = WrapInThreadLocalNode.wrap(getContext(), value); | ||
} | ||
@CompilerDirectives.TruffleBoundary | ||
@Specialization(guards = "!isLastLine(symbol)") | ||
public Object localVariableSetUncached(RubyBinding binding, RubySymbol symbol, Object value) { | ||
final MaterializedFrame frame = binding.getFrame(); | ||
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString()); | ||
frame.setObject(frameSlot, value); | ||
return value; | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
@Specialization(guards = "isLastLine(symbol)") | ||
public Object localVariableSetLastLine(RubyBinding binding, RubySymbol symbol, Object value) { | ||
final MaterializedFrame frame = binding.getFrame(); | ||
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString()); | ||
frame.setObject(frameSlot, WrapInThreadLocalNode.wrap(getContext(), value)); | ||
return value; | ||
} | ||
|
||
protected FrameDescriptor getFrameDescriptor(RubyBinding binding) { | ||
return binding.getFrame().getFrameDescriptor(); | ||
} | ||
|
||
protected FrameSlot findFrameSlot(RubyBinding binding, RubySymbol symbol) { | ||
final String symbolString = symbol.toString(); | ||
|
||
MaterializedFrame frame = binding.getFrame(); | ||
|
||
while (frame != null) { | ||
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString()); | ||
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbolString); | ||
|
||
if (frameSlot != null) { | ||
frame.setObject(frameSlot, value); | ||
return value; | ||
return frameSlot; | ||
} | ||
|
||
frame = RubyArguments.getDeclarationFrame(frame.getArguments()); | ||
} | ||
|
||
final FrameSlot newFrameSlot = binding.getFrame().getFrameDescriptor().addFrameSlot(symbol.toString()); | ||
binding.getFrame().setObject(newFrameSlot, value); | ||
return value; | ||
return binding.getFrame().getFrameDescriptor().addFrameSlot(symbolString); | ||
} | ||
|
||
protected WriteAbstractFrameSlotNode createWriteNode(FrameSlot frameSlot) { | ||
return WriteAbstractFrameSlotNodeGen.create(frameSlot); | ||
} | ||
|
||
protected boolean isLastLine(RubySymbol symbol) { | ||
return symbol.toString() == "$_"; | ||
} | ||
} | ||
|
||
|
@@ -125,10 +193,9 @@ public LocalVariablesNode(RubyContext context, SourceSection sourceSection) { | |
super(context, sourceSection); | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
@Specialization | ||
public RubyArray localVariables(RubyBinding binding) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass()); | ||
|
||
MaterializedFrame frame = binding.getFrame(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Copyright (c) 2013, 2015 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.methods.locals; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.*; | ||
import com.oracle.truffle.api.nodes.Node; | ||
|
||
public abstract class ReadAbstractFrameSlotNode extends Node { | ||
|
||
protected final FrameSlot frameSlot; | ||
|
||
public ReadAbstractFrameSlotNode(FrameSlot slot) { | ||
assert slot != null; | ||
this.frameSlot = slot; | ||
} | ||
|
||
public abstract Object executeRead(Frame frame); | ||
|
||
@Specialization(rewriteOn = {FrameSlotTypeException.class}) | ||
public boolean doBoolean(Frame frame) throws FrameSlotTypeException { | ||
return getBoolean(frame); | ||
} | ||
|
||
@Specialization(rewriteOn = {FrameSlotTypeException.class}) | ||
public int doFixnum(Frame frame) throws FrameSlotTypeException { | ||
return getFixnum(frame); | ||
} | ||
|
||
@Specialization(rewriteOn = {FrameSlotTypeException.class}) | ||
public long doLongFixnum(Frame frame) throws FrameSlotTypeException { | ||
return getLongFixnum(frame); | ||
} | ||
|
||
@Specialization(rewriteOn = {FrameSlotTypeException.class}) | ||
public double doFloat(Frame frame) throws FrameSlotTypeException { | ||
return getFloat(frame); | ||
} | ||
|
||
@Specialization(rewriteOn = {FrameSlotTypeException.class}) | ||
public Object doObject(Frame frame) throws FrameSlotTypeException { | ||
return getObject(frame); | ||
} | ||
|
||
@Specialization | ||
public Object doValue(Frame frame) { | ||
return getValue(frame); | ||
} | ||
|
||
public final FrameSlot getFrameSlot() { | ||
return frameSlot; | ||
} | ||
|
||
@Override | ||
public ReadAbstractFrameSlotNode copy() { | ||
return (ReadAbstractFrameSlotNode) super.copy(); | ||
} | ||
|
||
protected final void setBoolean(Frame frame, boolean value) { | ||
frame.setBoolean(frameSlot, value); | ||
} | ||
|
||
protected final void setFixnum(Frame frame, int value) { | ||
frame.setInt(frameSlot, value); | ||
} | ||
|
||
protected final void setLongFixnum(Frame frame, long value) { | ||
frame.setLong(frameSlot, value); | ||
} | ||
|
||
protected final void setFloat(Frame frame, double value) { | ||
frame.setDouble(frameSlot, value); | ||
} | ||
|
||
protected final void setObject(Frame frame, Object value) { | ||
frame.setObject(frameSlot, value); | ||
} | ||
|
||
protected final boolean getBoolean(Frame frame) throws FrameSlotTypeException { | ||
return frame.getBoolean(frameSlot); | ||
} | ||
|
||
protected final int getFixnum(Frame frame) throws FrameSlotTypeException { | ||
return frame.getInt(frameSlot); | ||
} | ||
|
||
protected final long getLongFixnum(Frame frame) throws FrameSlotTypeException { | ||
return frame.getLong(frameSlot); | ||
} | ||
|
||
protected final double getFloat(Frame frame) throws FrameSlotTypeException { | ||
return frame.getDouble(frameSlot); | ||
} | ||
|
||
protected final Object getObject(Frame frame) throws FrameSlotTypeException { | ||
return frame.getObject(frameSlot); | ||
} | ||
|
||
protected final Object getValue(Frame frame) { | ||
return frame.getValue(frameSlot); | ||
} | ||
|
||
protected final boolean isBooleanKind(Frame frame) { | ||
return isKind(FrameSlotKind.Boolean); | ||
} | ||
|
||
protected final boolean isFixnumKind(Frame frame) { | ||
return isKind(FrameSlotKind.Int); | ||
} | ||
|
||
protected final boolean isLongFixnumKind(Frame frame) { | ||
return isKind(FrameSlotKind.Long); | ||
} | ||
|
||
protected final boolean isFloatKind(Frame frame) { | ||
return isKind(FrameSlotKind.Double); | ||
} | ||
|
||
protected final boolean isObjectKind(Frame frame) { | ||
if (frameSlot.getKind() != FrameSlotKind.Object) { | ||
CompilerDirectives.transferToInterpreter(); | ||
frameSlot.setKind(FrameSlotKind.Object); | ||
} | ||
return true; | ||
} | ||
|
||
private boolean isKind(FrameSlotKind kind) { | ||
return frameSlot.getKind() == kind || initialSetKind(kind); | ||
} | ||
|
||
private boolean initialSetKind(FrameSlotKind kind) { | ||
if (frameSlot.getKind() == FrameSlotKind.Illegal) { | ||
CompilerDirectives.transferToInterpreter(); | ||
frameSlot.setKind(kind); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* Copyright (c) 2013, 2015 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.methods.locals; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.*; | ||
import com.oracle.truffle.api.nodes.Node; | ||
|
||
public abstract class WriteAbstractFrameSlotNode extends Node { | ||
|
||
protected final FrameSlot frameSlot; | ||
|
||
public WriteAbstractFrameSlotNode(FrameSlot frameSlot) { | ||
assert frameSlot != null; | ||
this.frameSlot = frameSlot; | ||
} | ||
|
||
public abstract Object executeWrite(Frame frame, Object value); | ||
|
||
@Specialization(guards = "isBooleanKind(frame)") | ||
public boolean doFixnum(Frame frame, boolean value) { | ||
setBoolean(frame, value); | ||
return value; | ||
} | ||
|
||
@Specialization(guards = "isFixnumKind(frame)") | ||
public int doFixnum(Frame frame, int value) { | ||
setFixnum(frame, value); | ||
return value; | ||
} | ||
|
||
@Specialization(guards = "isLongFixnumKind(frame)") | ||
public long doLongFixnum(Frame frame, long value) { | ||
setLongFixnum(frame, value); | ||
return value; | ||
} | ||
|
||
@Specialization(guards = "isFloatKind(frame)") | ||
public double doFloat(Frame frame, double value) { | ||
setFloat(frame, value); | ||
return value; | ||
} | ||
|
||
@Specialization(guards = "isObjectKind(frame)") | ||
public Object doObject(Frame frame, Object value) { | ||
setObject(frame, value); | ||
return value; | ||
} | ||
|
||
public final FrameSlot getFrameSlot() { | ||
return frameSlot; | ||
} | ||
|
||
protected final void setBoolean(Frame frame, boolean value) { | ||
frame.setBoolean(frameSlot, value); | ||
} | ||
|
||
protected final void setFixnum(Frame frame, int value) { | ||
frame.setInt(frameSlot, value); | ||
} | ||
|
||
protected final void setLongFixnum(Frame frame, long value) { | ||
frame.setLong(frameSlot, value); | ||
} | ||
|
||
protected final void setFloat(Frame frame, double value) { | ||
frame.setDouble(frameSlot, value); | ||
} | ||
|
||
protected final void setObject(Frame frame, Object value) { | ||
frame.setObject(frameSlot, value); | ||
} | ||
|
||
protected final boolean getBoolean(Frame frame) throws FrameSlotTypeException { | ||
return frame.getBoolean(frameSlot); | ||
} | ||
|
||
protected final int getFixnum(Frame frame) throws FrameSlotTypeException { | ||
return frame.getInt(frameSlot); | ||
} | ||
|
||
protected final long getLongFixnum(Frame frame) throws FrameSlotTypeException { | ||
return frame.getLong(frameSlot); | ||
} | ||
|
||
protected final double getFloat(Frame frame) throws FrameSlotTypeException { | ||
return frame.getDouble(frameSlot); | ||
} | ||
|
||
protected final Object getObject(Frame frame) throws FrameSlotTypeException { | ||
return frame.getObject(frameSlot); | ||
} | ||
|
||
protected final Object getValue(Frame frame) { | ||
return frame.getValue(frameSlot); | ||
} | ||
|
||
protected final boolean isBooleanKind(Frame frame) { | ||
return isKind(FrameSlotKind.Boolean); | ||
} | ||
|
||
protected final boolean isFixnumKind(Frame frame) { | ||
return isKind(FrameSlotKind.Int); | ||
} | ||
|
||
protected final boolean isLongFixnumKind(Frame frame) { | ||
return isKind(FrameSlotKind.Long); | ||
} | ||
|
||
protected final boolean isFloatKind(Frame frame) { | ||
return isKind(FrameSlotKind.Double); | ||
} | ||
|
||
protected final boolean isObjectKind(Frame frame) { | ||
if (frameSlot.getKind() != FrameSlotKind.Object) { | ||
CompilerDirectives.transferToInterpreter(); | ||
frameSlot.setKind(FrameSlotKind.Object); | ||
} | ||
return true; | ||
} | ||
|
||
private boolean isKind(FrameSlotKind kind) { | ||
return frameSlot.getKind() == kind || initialSetKind(kind); | ||
} | ||
|
||
private boolean initialSetKind(FrameSlotKind kind) { | ||
if (frameSlot.getKind() == FrameSlotKind.Illegal) { | ||
CompilerDirectives.transferToInterpreter(); | ||
frameSlot.setKind(kind); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
This is another example of the new kind of caching we need to be doing. We should go back over all our nodes in time and add inline caching like this wherever we're looking something up. In this case it should allow us to constant fold through
Binding#local_variable_get/set
(it should - it doesn't yet).@nirvdrum @eregon @pitr-ch