84
84
@ ExportLibrary (HashingStorageLibrary .class )
85
85
public final class DynamicObjectStorage extends HashingStorage {
86
86
public static final int SIZE_THRESHOLD = 100 ;
87
+ public static final int EXPLODE_LOOP_SIZE_LIMIT = 16 ;
87
88
88
89
final DynamicObject store ;
89
90
private final MroSequenceStorage mro ;
@@ -136,7 +137,7 @@ private static List<Object> filter(List<Object> l) {
136
137
@ ExportMessage
137
138
static class Length {
138
139
139
- @ Specialization (guards = {"cachedShape == self.store.getShape()" , "keys.length < 16 " }, limit = "3 " )
140
+ @ Specialization (guards = {"cachedShape == self.store.getShape()" , "keys.length < EXPLODE_LOOP_SIZE_LIMIT " }, limit = "2 " )
140
141
@ ExplodeLoop
141
142
static int cachedLen (DynamicObjectStorage self ,
142
143
@ SuppressWarnings ("unused" ) @ Cached ("self.store.getShape()" ) Shape cachedShape ,
@@ -150,18 +151,25 @@ static int cachedLen(DynamicObjectStorage self,
150
151
return len ;
151
152
}
152
153
153
- @ Specialization (replaces = "cachedLen" )
154
- static int length (DynamicObjectStorage self ,
155
- @ Exclusive @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
154
+ @ Specialization (replaces = "cachedLen" , guards = {"cachedShape == self.store.getShape()" }, limit = "3" )
155
+ static int cachedKeys (DynamicObjectStorage self ,
156
+ @ SuppressWarnings ("unused" ) @ Cached ("self.store.getShape()" ) Shape cachedShape ,
157
+ @ Cached (value = "keyArray(self)" , dimensions = 1 ) Object [] keys ,
158
+ @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
156
159
int len = 0 ;
157
- Object [] keys = keyArray (self );
158
160
for (int i = 0 ; i < keys .length ; i ++) {
159
161
Object key = keys [i ];
160
162
len = incrementLen (self , readNode , len , key );
161
163
}
162
164
return len ;
163
165
}
164
166
167
+ @ Specialization (replaces = "cachedKeys" )
168
+ static int length (DynamicObjectStorage self ,
169
+ @ Exclusive @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
170
+ return cachedKeys (self , self .store .getShape (), keyArray (self ), readNode );
171
+ }
172
+
165
173
private static boolean hasStringKey (DynamicObjectStorage self , String key , ReadAttributeFromDynamicObjectNode readNode ) {
166
174
return readNode .execute (self .store , key ) != PNone .NO_VALUE ;
167
175
}
@@ -197,7 +205,7 @@ static Object pstring(DynamicObjectStorage self, PString key, ThreadState state,
197
205
return string (self , castStr .execute (key ), state , readKey , noValueProfile );
198
206
}
199
207
200
- @ Specialization (guards = {"cachedShape == self.store.getShape()" , "keyList.length < 16 " , "!isBuiltinString(key, profile)" }, limit = "1" )
208
+ @ Specialization (guards = {"cachedShape == self.store.getShape()" , "keyList.length < EXPLODE_LOOP_SIZE_LIMIT " , "!isBuiltinString(key, profile)" }, limit = "1" )
201
209
@ ExplodeLoop (kind = LoopExplosionKind .FULL_UNROLL_UNTIL_RETURN )
202
210
static Object notString (DynamicObjectStorage self , Object key , ThreadState state ,
203
211
@ Shared ("readKey" ) @ Cached ReadAttributeFromDynamicObjectNode readKey ,
@@ -366,12 +374,12 @@ public HashingStorage delItemWithState(Object key, ThreadState state,
366
374
367
375
@ ExportMessage
368
376
static class ForEachUntyped {
369
- @ Specialization (guards = {"cachedShape == self.store.getShape()" , "keys.length < 16 " }, limit = "1 " )
377
+ @ Specialization (guards = {"cachedShape == self.store.getShape()" , "keys.length < EXPLODE_LOOP_SIZE_LIMIT " }, limit = "2 " )
370
378
@ ExplodeLoop
371
379
static Object cachedLen (DynamicObjectStorage self , ForEachNode <Object > node , Object firstValue ,
372
380
@ Exclusive @ SuppressWarnings ("unused" ) @ Cached ("self.store.getShape()" ) Shape cachedShape ,
373
381
@ Cached (value = "keyArray(self)" , dimensions = 1 ) Object [] keys ,
374
- @ Shared ( "readNodeInject" ) @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
382
+ @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
375
383
Object result = firstValue ;
376
384
for (int i = 0 ; i < keys .length ; i ++) {
377
385
Object key = keys [i ];
@@ -380,10 +388,11 @@ static Object cachedLen(DynamicObjectStorage self, ForEachNode<Object> node, Obj
380
388
return result ;
381
389
}
382
390
383
- @ Specialization (replaces = "cachedLen" )
384
- static Object addAll (DynamicObjectStorage self , ForEachNode <Object > node , Object firstValue ,
385
- @ Shared ("readNodeInject" ) @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
386
- Object [] keys = keyArray (self );
391
+ @ Specialization (replaces = "cachedLen" , guards = {"cachedShape == self.store.getShape()" }, limit = "3" )
392
+ static Object cachedKeys (DynamicObjectStorage self , ForEachNode <Object > node , Object firstValue ,
393
+ @ Exclusive @ SuppressWarnings ("unused" ) @ Cached ("self.store.getShape()" ) Shape cachedShape ,
394
+ @ Cached (value = "keyArray(self)" , dimensions = 1 ) Object [] keys ,
395
+ @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
387
396
Object result = firstValue ;
388
397
for (int i = 0 ; i < keys .length ; i ++) {
389
398
Object key = keys [i ];
@@ -392,6 +401,12 @@ static Object addAll(DynamicObjectStorage self, ForEachNode<Object> node, Object
392
401
return result ;
393
402
}
394
403
404
+ @ Specialization (replaces = "cachedKeys" )
405
+ static Object addAll (DynamicObjectStorage self , ForEachNode <Object > node , Object firstValue ,
406
+ @ Cached ReadAttributeFromDynamicObjectNode readNode ) {
407
+ return cachedKeys (self , node , firstValue , self .store .getShape (), keyArray (self ), readNode );
408
+ }
409
+
395
410
private static Object runNode (DynamicObjectStorage self , Object key , Object acc , ReadAttributeFromDynamicObjectNode readNode , ForEachNode <Object > node ) {
396
411
if (key instanceof String ) {
397
412
Object value = readNode .execute (self .store , key );
0 commit comments