Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f57425f7355c
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7b7388c483de
Choose a head ref
  • 2 commits
  • 13 files changed
  • 1 contributor

Commits on Mar 5, 2015

  1. [Truffle] Moved frozen state from a field on RubyBasicObject to a fie…

    …ld in the dynamic object shape.
    nirvdrum committed Mar 5, 2015
    15
    Copy the full SHA
    e7fabb0 View commit details
  2. Merge branch 'master' of github.com:jruby/jruby

    Conflicts:
    	truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
    nirvdrum committed Mar 5, 2015
    Copy the full SHA
    7b7388c View commit details
16 changes: 2 additions & 14 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -340,7 +340,7 @@ public Object fallback(VirtualFrame frame, RubyArray array, RubyArray args) {

}

@CoreMethod(names = "[]=", required = 2, optional = 1, lowerFixnumParameters = 0)
@CoreMethod(names = "[]=", required = 2, optional = 1, lowerFixnumParameters = 0, raiseIfFrozenSelf = true)
public abstract static class IndexSetNode extends ArrayCoreMethodNode {

@Child private ArrayWriteDenormalizedNode writeNode;
@@ -358,8 +358,6 @@ public IndexSetNode(IndexSetNode prev) {

@Specialization
public Object set(VirtualFrame frame, RubyArray array, int index, Object value, UndefinedPlaceholder unused) {
array.checkFrozen(this);

if (writeNode == null) {
CompilerDirectives.transferToInterpreter();
writeNode = insert(ArrayWriteDenormalizedNodeFactory.create(getContext(), getSourceSection(), null, null, null));
@@ -379,8 +377,6 @@ public Object setObject(VirtualFrame frame, RubyArray array, int start, int leng
throw new RaiseException(getContext().getCoreLibrary().indexNegativeLength(length, this));
}

array.checkFrozen(this);

final int begin = array.normalizeIndex(start);

if (begin >= array.getSize()) {
@@ -406,8 +402,6 @@ public Object setIntegerFixnum(VirtualFrame frame, RubyArray array, int start, i
throw new RaiseException(getContext().getCoreLibrary().indexNegativeLength(length, this));
}

array.checkFrozen(this);

if (value.getSize() == 0) {
final int begin = array.normalizeIndex(start);
final int exclusiveEnd = begin + length;
@@ -433,8 +427,6 @@ public Object setIntegerFixnum(VirtualFrame frame, RubyArray array, int start, i

@Specialization(guards = "isIntegerFixnum")
public Object setIntegerFixnumRange(VirtualFrame frame, RubyArray array, RubyRange.IntegerFixnumRange range, RubyArray other, UndefinedPlaceholder unused) {
array.checkFrozen(this);

if (range.doesExcludeEnd()) {
CompilerDirectives.transferToInterpreter();
throw new UnsupportedOperationException();
@@ -551,7 +543,7 @@ public Object compactObjects(RubyArray array) {

}

@CoreMethod(names = "compact!")
@CoreMethod(names = "compact!", raiseIfFrozenSelf = true)
public abstract static class CompactBangNode extends ArrayCoreMethodNode {

public CompactBangNode(RubyContext context, SourceSection sourceSection) {
@@ -564,15 +556,11 @@ public CompactBangNode(CompactBangNode prev) {

@Specialization(guards = "!isObject")
public RubyNilClass compactNotObjects(RubyArray array) {
array.checkFrozen(this);

return getContext().getCoreLibrary().getNilObject();
}

@Specialization(guards = "isObject")
public Object compactObjects(RubyArray array) {
array.checkFrozen(this);

final Object[] store = (Object[]) array.getStore();
final int size = array.getSize();

Original file line number Diff line number Diff line change
@@ -60,6 +60,10 @@

int taintFrom() default -1;

boolean raiseIfFrozenSelf() default false;

int[] raiseIfFrozenParameters() default {};

UnsupportedOperationBehavior unsupportedOperationBehavior() default UnsupportedOperationBehavior.TYPE_ERROR;

}
Original file line number Diff line number Diff line change
@@ -157,6 +157,10 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
readSelfNode = new FixnumLowerNode(readSelfNode);
}

if (methodDetails.getMethodAnnotation().raiseIfFrozenSelf()) {
readSelfNode = new RaiseIfFrozenNode(readSelfNode);
}

argumentsNodes.add(readSelfNode);
}

@@ -170,6 +174,10 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
readArgumentNode = new FixnumLowerNode(readArgumentNode);
}

if (ArrayUtils.contains(methodDetails.getMethodAnnotation().raiseIfFrozenParameters(), n)) {
readArgumentNode = new FixnumLowerNode(readArgumentNode);
}

argumentsNodes.add(readArgumentNode);
}
}
Original file line number Diff line number Diff line change
@@ -316,7 +316,7 @@ public Object getBuckets(VirtualFrame frame, RubyHash hash, Object key) {

}

@CoreMethod(names = "[]=", required = 2)
@CoreMethod(names = "[]=", required = 2, raiseIfFrozenSelf = true)
public abstract static class SetIndexNode extends HashCoreMethodNode {

@Child private CallDispatchHeadNode eqlNode;
@@ -336,7 +336,6 @@ public SetIndexNode(SetIndexNode prev) {

@Specialization(guards = "isNull")
public Object setNull(RubyHash hash, Object key, Object value) {
hash.checkFrozen(this);
final Object[] store = new Object[HashOperations.SMALL_HASH_SIZE * 2];
store[0] = key;
store[1] = value;
@@ -347,8 +346,6 @@ public Object setNull(RubyHash hash, Object key, Object value) {
@ExplodeLoop
@Specialization(guards = {"!isNull", "!isBuckets"})
public Object setPackedArray(VirtualFrame frame, RubyHash hash, Object key, Object value) {
hash.checkFrozen(this);

final Object[] store = (Object[]) hash.getStore();
final int size = hash.getSize();

@@ -447,7 +444,7 @@ public Object defaultProc(RubyHash hash) {

}

@CoreMethod(names = "delete", required = 1)
@CoreMethod(names = "delete", required = 1, raiseIfFrozenSelf = true)
public abstract static class DeleteNode extends HashCoreMethodNode {

@Child private CallDispatchHeadNode eqlNode;
@@ -467,14 +464,11 @@ public DeleteNode(DeleteNode prev) {

@Specialization(guards = "isNull")
public RubyNilClass deleteNull(RubyHash hash, Object key) {
hash.checkFrozen(this);
return getContext().getCoreLibrary().getNilObject();
}

@Specialization(guards = {"!isNull", "!isBuckets"})
public Object deletePackedArray(VirtualFrame frame, RubyHash hash, Object key) {
hash.checkFrozen(this);

final Object[] store = (Object[]) hash.getStore();
final int size = hash.getSize();

66 changes: 33 additions & 33 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
@@ -26,19 +25,15 @@
import org.jruby.common.IRubyWarnings;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
import org.jruby.truffle.nodes.cast.NumericToFloatNode;
import org.jruby.truffle.nodes.cast.NumericToFloatNodeFactory;
import org.jruby.truffle.nodes.coerce.ToStrNode;
import org.jruby.truffle.nodes.coerce.ToStrNodeFactory;
import org.jruby.truffle.nodes.control.WhileNode;
import org.jruby.truffle.nodes.core.KernelNodesFactory.SameOrEqualNodeFactory;
import org.jruby.truffle.nodes.dispatch.*;
import org.jruby.truffle.nodes.globals.WrapInThreadLocalNode;
import org.jruby.truffle.nodes.literal.BooleanLiteralNode;
import org.jruby.truffle.nodes.objects.*;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.nodes.objectstorage.WriteHeadObjectFieldNode;
import org.jruby.truffle.nodes.rubinius.ObjectPrimitiveNodes;
import org.jruby.truffle.nodes.rubinius.ObjectPrimitiveNodesFactory;
@@ -48,7 +43,6 @@
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.backtrace.MRIBacktraceFormatter;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.control.ThrowException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.hash.KeyValue;
@@ -425,16 +419,22 @@ public abstract static class CloneNode extends CoreMethodNode {
private final ConditionProfile frozenProfile = ConditionProfile.createBinaryProfile();

@Child private CallDispatchHeadNode initializeCloneNode;
@Child private IsFrozenNode isFrozenNode;
@Child private FreezeNode freezeNode;

public CloneNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
// Calls private initialize_clone on the new copy.
initializeCloneNode = DispatchHeadNodeFactory.createMethodCall(context, true, MissingBehavior.CALL_METHOD_MISSING);
isFrozenNode = IsFrozenNodeFactory.create(context, sourceSection, null);
freezeNode = FreezeNodeFactory.create(context, sourceSection, null);
}

public CloneNode(CloneNode prev) {
super(prev);
initializeCloneNode = prev.initializeCloneNode;
isFrozenNode = prev.isFrozenNode;
freezeNode = prev.freezeNode;
}

@Specialization
@@ -451,8 +451,8 @@ public Object clone(VirtualFrame frame, RubyBasicObject self) {
newObject.getOperations().setInstanceVariables(newObject, self.getOperations().getInstanceVariables(self));
initializeCloneNode.call(frame, newObject, "initialize_clone", null, self);

if (frozenProfile.profile(self.isFrozen())) {
newObject.freeze();
if (frozenProfile.profile(isFrozenNode.executeIsFrozen(self))) {
freezeNode.executeFreeze(newObject);
}

return newObject;
@@ -722,53 +722,53 @@ public Object fork(Object[] args) {
}

@CoreMethod(names = "freeze")
public abstract static class FreezeNode extends CoreMethodNode {
public abstract static class KernelFreezeNode extends CoreMethodNode {

public FreezeNode(RubyContext context, SourceSection sourceSection) {
@Child private FreezeNode freezeNode;

public KernelFreezeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public FreezeNode(FreezeNode prev) {
public KernelFreezeNode(KernelFreezeNode prev) {
super(prev);
freezeNode = prev.freezeNode;
}

@Specialization
public RubyBasicObject freeze(RubyBasicObject self) {
self.freeze();
return self;
public Object freeze(Object self) {
if (freezeNode == null) {
CompilerDirectives.transferToInterpreter();
freezeNode = insert(FreezeNodeFactory.create(getContext(), getEncapsulatingSourceSection(), null));
}

return freezeNode.executeFreeze(self);
}

}

@CoreMethod(names = "frozen?")
public abstract static class FrozenNode extends CoreMethodNode {
public abstract static class KernelFrozenNode extends CoreMethodNode {

public FrozenNode(RubyContext context, SourceSection sourceSection) {
@Child private IsFrozenNode isFrozenNode;

public KernelFrozenNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public FrozenNode(FrozenNode prev) {
public KernelFrozenNode(KernelFrozenNode prev) {
super(prev);
isFrozenNode = prev.isFrozenNode;
}

@Specialization
public boolean isFrozen(int self) {
return true;
}

@Specialization
public boolean isFrozen(long self) {
return true;
}

@Specialization
public boolean isFrozen(double self) {
return true;
}
public boolean isFrozen(Object self) {
if (isFrozenNode == null) {
CompilerDirectives.transferToInterpreter();
isFrozenNode = insert(IsFrozenNodeFactory.create(getContext(), getEncapsulatingSourceSection(), null));
}

@Specialization
public boolean isFrozen(RubyBasicObject self) {
return self.isFrozen();
return isFrozenNode.executeIsFrozen(self);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 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.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.objects.IsFrozenNode;
import org.jruby.truffle.nodes.objects.IsFrozenNodeFactory;
import org.jruby.truffle.runtime.control.RaiseException;

public class RaiseIfFrozenNode extends RubyNode {

@Child private RubyNode child;
@Child private IsFrozenNode isFrozenNode;

public RaiseIfFrozenNode(RubyNode child) {
super(child.getContext(), child.getEncapsulatingSourceSection());
this.child = child;
isFrozenNode = IsFrozenNodeFactory.create(child.getContext(), child.getEncapsulatingSourceSection(), null);
}

@Override
public Object execute(VirtualFrame frame) {
Object result = child.execute(frame);

if (isFrozenNode.executeIsFrozen(result)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().frozenError(
getContext().getCoreLibrary().getLogicalClass(result).getName(), this));
}

return result;
}
}
Loading