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

Commits on May 14, 2016

  1. Revert "Re-port Array#hash and some related logic to fix #3884."

    This reverts commit 1b92064.
    headius committed May 14, 2016
    Copy the full SHA
    89d8af7 View commit details
  2. Smaller fix for #3884.

    The fix here is as follows:
    
    * Always provide a non-zero hash for any array, including empty.
    * Better hash combination function with less collision.
    
    An improved recursion guard will go into the next release.
    headius committed May 14, 2016
    Copy the full SHA
    f1e056b View commit details
Showing with 20 additions and 34 deletions.
  1. +20 −12 core/src/main/java/org/jruby/RubyArray.java
  2. +0 −22 core/src/main/java/org/jruby/runtime/Helpers.java
32 changes: 20 additions & 12 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -78,6 +78,7 @@
import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
import static org.jruby.runtime.Helpers.invokedynamic;
import static org.jruby.runtime.Visibility.PRIVATE;
import static org.jruby.runtime.invokedynamic.MethodNames.HASH;
import static org.jruby.runtime.invokedynamic.MethodNames.OP_CMP;
import static org.jruby.RubyEnumerator.SizeFn;

@@ -675,18 +676,25 @@ public RubyFixnum hash19(ThreadContext context) {
*
*/
@JRubyMethod(name = "hash")
public RubyFixnum hash(ThreadContext context) {
final Ruby runtime = context.runtime;
int begin = RubyArray.this.begin;
long h = (realLength << 32) & System.identityHashCode(RubyArray.class);
for (int i = begin; i < begin + realLength; i++) {
h = (h << 1) | (h < 0 ? 1 : 0);
final IRubyObject value = safeArrayRef(runtime, values, i);
RubyFixnum n = Helpers.safeHash(context, value);
h = (h * 31) + n.getLongValue();
}

return runtime.newFixnum(h);
public RubyFixnum hash(final ThreadContext context) {
return (RubyFixnum) context.runtime.execRecursiveOuter(new Ruby.RecursiveFunction() {
public IRubyObject call(IRubyObject obj, boolean recur) {
final Ruby runtime = context.runtime;
int begin = RubyArray.this.begin;
long h = realLength;
h ^= System.identityHashCode(RubyArray.class);
if (recur) {
h ^= h * 31 + RubyNumeric.num2long(invokedynamic(context, runtime.getArray(), HASH));
} else {
for (int i = begin; i < begin + realLength; i++) {
h = (h << 1) | (h < 0 ? 1 : 0);
final IRubyObject value = safeArrayRef(runtime, values, i);
h ^= h * 31 + RubyNumeric.num2long(invokedynamic(context, value, HASH));
}
}
return runtime.newFixnum(h);
}
}, RubyArray.this);
}

/** rb_ary_store
22 changes: 0 additions & 22 deletions core/src/main/java/org/jruby/runtime/Helpers.java
Original file line number Diff line number Diff line change
@@ -48,9 +48,7 @@
import org.jcodings.specific.UTF8Encoding;
import org.jcodings.unicode.UnicodeEncoding;

import static org.jruby.runtime.Helpers.invokedynamic;
import static org.jruby.runtime.invokedynamic.MethodNames.EQL;
import static org.jruby.runtime.invokedynamic.MethodNames.HASH;
import static org.jruby.runtime.invokedynamic.MethodNames.OP_EQUAL;
import static org.jruby.util.CodegenUtils.sig;
import static org.jruby.util.StringSupport.EMPTY_STRING_ARRAY;
@@ -2716,26 +2714,6 @@ public static boolean isRequiredKeywordArgumentValueNode(Node asgnNode) {
return asgnNode.childNodes().get(0) instanceof RequiredKeywordArgumentValueNode;
}

// MRI: rb_hash
public static RubyFixnum safeHash(final ThreadContext context, IRubyObject obj) {
final Ruby runtime = context.runtime;
IRubyObject hval = runtime.execRecursiveOuter(new Ruby.RecursiveFunction() {
public IRubyObject call(IRubyObject obj, boolean recur) {
if (recur) return RubyFixnum.zero(runtime);
return invokedynamic(context, obj, HASH);
}
}, obj);

while (!(hval instanceof RubyFixnum)) {
if (hval instanceof RubyBignum) {
// This is different from MRI because we don't have rb_integer_pack
return ((RubyBignum) hval).hash();
}
hval = hval.convertToInteger();
}
return (RubyFixnum) hval;
}

@Deprecated
public static String encodeParameterList(List<String[]> args) {
if (args.size() == 0) return "NONE";