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: 0aef038c4319
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: aba18f3ff4ac
Choose a head ref
  • 8 commits
  • 8 files changed
  • 1 contributor

Commits on Nov 15, 2016

  1. Copy the full SHA
    2395792 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6ef3980 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a494271 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    177fc1e View commit details
  5. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1b26386 View commit details
  6. Copy the full SHA
    9548541 View commit details
  7. Copy the full SHA
    b5c4f55 View commit details
  8. Copy the full SHA
    aba18f3 View commit details
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2016 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.core.hash;

import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory.ReferenceEqualNodeFactory;
import org.jruby.truffle.core.kernel.KernelNodes.SameOrEqlNode;
import org.jruby.truffle.core.kernel.KernelNodesFactory.SameOrEqlNodeFactory;
import org.jruby.truffle.language.RubyBaseNode;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;

public class CompareHashKeysNode extends RubyBaseNode {

@Child private SameOrEqlNode sameOrEqlNode;
@Child private ReferenceEqualNode equalNode;

public boolean equalKeys(VirtualFrame frame, boolean compareByIdentity, Object key, int hashed, Object otherKey, int otherHashed) {
if (compareByIdentity) {
return equal(key, otherKey);
} else {
return hashed == otherHashed && sameOrEql(frame, key, otherKey);
}
}

private boolean sameOrEql(VirtualFrame frame, Object key1, Object key2) {
if (sameOrEqlNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
sameOrEqlNode = insert(SameOrEqlNodeFactory.create(null));
}
return sameOrEqlNode.executeSameOrEql(frame, key1, key2);
}

private boolean equal(Object key1, Object key2) {
if (equalNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
equalNode = insert(ReferenceEqualNodeFactory.create(null));
}
return equalNode.executeReferenceEqual(key1, key2);
}

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

import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.objects.IsFrozenNode;
import org.jruby.truffle.language.objects.IsFrozenNodeGen;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;

@NodeChildren({@NodeChild("key"), @NodeChild("compareByIdentity")})
public abstract class FreezeHashKeyIfNeededNode extends RubyNode {

@Child private IsFrozenNode isFrozenNode;
@Child private CallDispatchHeadNode dupNode;
@Child private CallDispatchHeadNode freezeNode;

public abstract Object executeFreezeIfNeeded(VirtualFrame frame, Object key, boolean compareByIdentity);

@Specialization(guards = {"isRubyString(string)", "isFrozen(string)"})
Object alreadyFrozen(DynamicObject string, boolean compareByIdentity) {
return string;
}

@Specialization(guards = {"isRubyString(string)", "!isFrozen(string)", "!compareByIdentity"})
Object dupAndFreeze(VirtualFrame frame, DynamicObject string, boolean compareByIdentity) {
return freeze(frame, dup(frame, string));
}

@Specialization(guards = {"isRubyString(string)", "!isFrozen(string)", "compareByIdentity"})
Object compareByIdentity(VirtualFrame frame, DynamicObject string, boolean compareByIdentity) {
return string;
}

@Specialization(guards = "!isRubyString(value)")
Object passThrough(Object value, boolean compareByIdentity) {
return value;
}

protected boolean isFrozen(Object value) {
if (isFrozenNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
isFrozenNode = insert(IsFrozenNodeGen.create(getContext(), null, null));
}
return isFrozenNode.executeIsFrozen(value);
}

private Object dup(VirtualFrame frame, Object value) {
if (dupNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
dupNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}
return dupNode.call(frame, value, "dup");
}

private Object freeze(VirtualFrame frame, Object value) {
if (freezeNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
freezeNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}
return freezeNode.call(frame, value, "freeze");
}

}
Original file line number Diff line number Diff line change
@@ -92,7 +92,7 @@ public static class SmallHashLiteralNode extends HashLiteralNode {

public SmallHashLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] keyValues) {
super(context, sourceSection, keyValues);
hashNode = new HashNode(context, sourceSection);
hashNode = new HashNode();
equalNode = DispatchHeadNodeFactory.createMethodCall(context);
}

@@ -156,7 +156,7 @@ public GenericHashLiteralNode(RubyContext context, SourceSection sourceSection,
public Object execute(VirtualFrame frame) {
if (setNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
setNode = insert(SetNodeGen.create(getContext(), null, null, null, null, null));
setNode = insert(SetNode.create());
}

final int bucketsCount = BucketsStrategy.capacityGreaterThan(keyValues.length / 2) * BucketsStrategy.OVERALLOCATE_FACTOR;
18 changes: 10 additions & 8 deletions truffle/src/main/java/org/jruby/truffle/core/hash/HashNode.java
Original file line number Diff line number Diff line change
@@ -12,8 +12,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;

import org.jruby.truffle.core.ObjectNodes.ObjectIDPrimitiveNode;
import org.jruby.truffle.core.ObjectNodesFactory.ObjectIDPrimitiveNodeFactory;
import org.jruby.truffle.language.RubyBaseNode;
@@ -28,17 +27,12 @@ public class HashNode extends RubyBaseNode {
private final ConditionProfile isIntegerProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile isLongProfile = ConditionProfile.createBinaryProfile();

public HashNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
hashNode = DispatchHeadNodeFactory.createMethodCall(context, true);
}

public int hash(VirtualFrame frame, Object key, boolean compareByIdentity) {
final Object hashedObject;
if (compareByIdentity) {
hashedObject = objectID(key);
} else {
hashedObject = hashNode.call(frame, key, "hash");
hashedObject = hash(frame, key);
}

if (isIntegerProfile.profile(hashedObject instanceof Integer)) {
@@ -50,6 +44,14 @@ public int hash(VirtualFrame frame, Object key, boolean compareByIdentity) {
}
}

private Object hash(VirtualFrame frame, Object object) {
if (hashNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
hashNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext(), true));
}
return hashNode.call(frame, object, "hash");
}

private Object objectID(Object object) {
if (objectIDNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Loading