Guest User

Untitled

a guest
Jul 17th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.78 KB | None | 0 0
  1. diff --git a/core/src/main/java/org/jruby/ObjectFlags.java b/core/src/main/java/org/jruby/ObjectFlags.java
  2. index 30154d1d6e..3938b1a0cf 100644
  3. --- a/core/src/main/java/org/jruby/ObjectFlags.java
  4. +++ b/core/src/main/java/org/jruby/ObjectFlags.java
  5. @@ -31,4 +31,12 @@ public interface ObjectFlags {
  6.  
  7. int COMPARE_BY_IDENTITY_F = registry.newFlag(RubyHash.class);
  8. int PROCDEFAULT_HASH_F = registry.newFlag(RubyHash.class);
  9. +
  10. + /*
  11. + * This will say whether all keys are symbols or not which makes keyword arguments a bit
  12. + * simpler to process for calls. This boolean may not strictly cover all hashes which
  13. + * contain only symbols in cases where non-symbol entries are added and then removed.
  14. + */
  15. + int ONLY_SYMBOL_KEYS_F = registry.newFlag(RubyHash.class);
  16. +
  17. }
  18. diff --git a/core/src/main/java/org/jruby/RubyHash.java b/core/src/main/java/org/jruby/RubyHash.java
  19. index 2f58c0ce70..9c2a126617 100644
  20. --- a/core/src/main/java/org/jruby/RubyHash.java
  21. +++ b/core/src/main/java/org/jruby/RubyHash.java
  22. @@ -70,6 +70,7 @@ import java.util.NoSuchElementException;
  23. import java.util.Set;
  24. import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
  25.  
  26. +import static org.jruby.ObjectFlags.ONLY_SYMBOL_KEYS_F;
  27. import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
  28. import static org.jruby.runtime.Visibility.PRIVATE;
  29. import static org.jruby.RubyEnumerator.SizeFn;
  30. @@ -304,11 +305,13 @@ public class RubyHash extends RubyObject implements Map {
  31.  
  32. private final void allocFirst() {
  33. threshold = INITIAL_THRESHOLD;
  34. + flags |= ONLY_SYMBOL_KEYS_F;
  35. table = new RubyHashEntry[MRI_HASH_RESIZE ? MRI_INITIAL_CAPACITY : JAVASOFT_INITIAL_CAPACITY];
  36. }
  37.  
  38. private final void allocFirst(int buckets) {
  39. threshold = INITIAL_THRESHOLD;
  40. + flags |= ONLY_SYMBOL_KEYS_F;
  41. table = new RubyHashEntry[buckets];
  42. }
  43.  
  44. @@ -554,6 +557,10 @@ public class RubyHash extends RubyObject implements Map {
  45.  
  46. checkIterating();
  47.  
  48. + if (!(key instanceof RubySymbol)) {
  49. + flags &= ~ONLY_SYMBOL_KEYS_F;
  50. + }
  51. +
  52. table[i] = new RubyHashEntry(hash, key, value, table[i], head);
  53. size++;
  54.  
  55. @@ -561,6 +568,13 @@ public class RubyHash extends RubyObject implements Map {
  56. return null;
  57. }
  58.  
  59. + public void putIKnowWhatIAmDoing(IRubyObject key, IRubyObject value) {
  60. + int hash = hashValue(key);
  61. + int i = bucketIndex(hash, table.length);
  62. + table[i] = new RubyHashEntry(hash, key, value, table[i], head);
  63. + size++;
  64. + }
  65. +
  66. // get implementation
  67.  
  68. protected IRubyObject internalGet(IRubyObject key) { // specialized for value
  69. @@ -692,23 +706,6 @@ public class RubyHash extends RubyObject implements Map {
  70. if (count > 0) throw concurrentModification();
  71. }
  72.  
  73. - public <T> boolean allSymbols() {
  74. - int startGeneration = generation;
  75. - // visit not more than size entries
  76. - RubyHashEntry head = this.head;
  77. - for (RubyHashEntry entry = head.nextAdded; entry != head; entry = entry.nextAdded) {
  78. - if (startGeneration != generation) {
  79. - startGeneration = generation;
  80. - entry = head.nextAdded;
  81. - if (entry == head) break;
  82. - }
  83. - if (entry != null && entry.isLive()) {
  84. - if (!(entry.key instanceof RubySymbol)) return false;
  85. - }
  86. - }
  87. - return true;
  88. - }
  89. -
  90. /* ============================
  91. * End of hash internals
  92. * ============================
  93. @@ -2161,7 +2158,8 @@ public class RubyHash extends RubyObject implements Map {
  94. final Ruby runtime = context.runtime;
  95. RubyHash dup = new RubyHash(runtime, getMetaClass(), this);
  96.  
  97. - dup.setComparedByIdentity(this.isComparedByIdentity());
  98. + dup.flags = flags;
  99. + //dup.setComparedByIdentity(this.isComparedByIdentity());
  100.  
  101. dup.ifNone = this.ifNone;
  102.  
  103. @@ -2350,6 +2348,18 @@ public class RubyHash extends RubyObject implements Map {
  104. return (flags & COMPARE_BY_IDENTITY_F) != 0;
  105. }
  106.  
  107. + /**
  108. + * Does this hash know whether it contains only symbol keys? This is different than whether
  109. + * only symbol keys exist in a hash as this flag only tracks symbol additions. If a non-symbol
  110. + * is added and then later removed the hash may only contain symbols but this flag will not
  111. + * track that unusual case.
  112. + *
  113. + * Motivation for this is for keyword argument processing optimization.
  114. + */
  115. + public boolean isOnlySymbolKeys() {
  116. + return (flags & ONLY_SYMBOL_KEYS_F) != 0;
  117. + }
  118. +
  119. /**
  120. * Sets whether this object is compared by identity or not. Shortcut for doing
  121. * setFlag(COMPARE_BY_IDENTITY_F, frozen).
  122. diff --git a/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java b/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
  123. index 62ed95afcf..d8d02cfbfe 100644
  124. --- a/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
  125. +++ b/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
  126. @@ -545,13 +545,13 @@ public class IRRuntimeHelpers {
  127. final IRubyObject maybeKwargs = toHash(args[length - 1], context);
  128.  
  129. if (maybeKwargs != null) {
  130. - if (maybeKwargs.isNil()) { // nil on to_hash is supposed to keep itself as real value so we need to make kwargs hash
  131. + if (!(maybeKwargs instanceof RubyHash)) { // nil on to_hash is supposed to keep itself as real value so we need to make kwargs hash
  132. return ArraySupport.newCopy(args, RubyHash.newSmallHash(context.runtime));
  133. }
  134.  
  135. RubyHash kwargs = (RubyHash) maybeKwargs;
  136.  
  137. - if (kwargs.allSymbols()) {
  138. + if (kwargs.isOnlySymbolKeys()) {
  139. args[length - 1] = kwargs;
  140. } else {
  141. args = homogenizeKwargs(context, args, kwargs);
Add Comment
Please, Sign In to add comment