@@ -104,18 +104,30 @@ public BucketsHashStore(Entry[] entries, Entry firstInSequence, Entry lastInSequ
104
104
1073741824 + 85
105
105
};
106
106
107
+ private static final int MAX_ARRAY_SIZE = Integer .MAX_VALUE - 8 ;
108
+ private static final int MAX_ENTRIES = (int ) (MAX_ARRAY_SIZE * LOAD_FACTOR );
109
+
107
110
// endregion
108
111
// region Utilities
109
112
110
113
@ TruffleBoundary
111
- static int capacityGreaterThan (int size ) {
114
+ static int growthCapacityGreaterThan (int size ) {
115
+ int buckets = 0 ;
112
116
for (int capacity : CAPACITIES ) {
113
117
if (capacity > size ) {
114
- return capacity ;
118
+ buckets = capacity * OVERALLOCATE_FACTOR ;
119
+ break ;
115
120
}
116
121
}
117
122
118
- return CAPACITIES [CAPACITIES .length - 1 ];
123
+ if (buckets > 0 ) {
124
+ assert buckets * LOAD_FACTOR > size ;
125
+ return buckets ;
126
+ } else if (size < MAX_ENTRIES ) {
127
+ return MAX_ARRAY_SIZE ;
128
+ } else {
129
+ throw new OutOfMemoryError ("too big Hash: " + size + " entries" );
130
+ }
119
131
}
120
132
121
133
static int getBucketIndex (int hashed , int bucketsCount ) {
@@ -124,7 +136,7 @@ static int getBucketIndex(int hashed, int bucketsCount) {
124
136
125
137
@ TruffleBoundary
126
138
private void resize (RubyHash hash , int size ) {
127
- final int bucketsCount = capacityGreaterThan (size ) * OVERALLOCATE_FACTOR ;
139
+ final int bucketsCount = growthCapacityGreaterThan (size );
128
140
final Entry [] newEntries = new Entry [bucketsCount ];
129
141
130
142
final Entry firstInSequence = this .firstInSequence ;
@@ -589,7 +601,7 @@ public static class GenericHashLiteralNode extends HashLiteralNode {
589
601
590
602
public GenericHashLiteralNode (RubyNode [] keyValues ) {
591
603
super (keyValues );
592
- bucketsCount = capacityGreaterThan (keyValues .length / 2 ) * OVERALLOCATE_FACTOR ;
604
+ bucketsCount = growthCapacityGreaterThan (keyValues .length / 2 );
593
605
}
594
606
595
607
@ ExplodeLoop
0 commit comments