9
9
*/
10
10
package org .truffleruby .core .array ;
11
11
12
+ import com .oracle .truffle .api .dsl .Cached ;
12
13
import com .oracle .truffle .api .dsl .NeverDefault ;
14
+ import com .oracle .truffle .api .profiles .BranchProfile ;
13
15
import org .truffleruby .core .array .library .ArrayStoreLibrary ;
14
16
import org .truffleruby .core .array .library .ArrayStoreLibrary .ArrayAllocator ;
15
17
import org .truffleruby .core .array .ArrayBuilderNodeFactory .AppendArrayNodeGen ;
@@ -48,8 +50,6 @@ public static ArrayBuilderNode create() {
48
50
return new ArrayBuilderProxyNode ();
49
51
}
50
52
51
- public abstract BuilderState start ();
52
-
53
53
public abstract BuilderState start (int length );
54
54
55
55
public abstract void appendArray (BuilderState state , int index , RubyArray array );
@@ -60,15 +60,10 @@ public static ArrayBuilderNode create() {
60
60
61
61
private static class ArrayBuilderProxyNode extends ArrayBuilderNode {
62
62
63
- @ Child StartNode startNode = new StartNode (ArrayStoreLibrary .initialAllocator (false ), 0 );
63
+ @ Child StartNode startNode = new StartNode (ArrayStoreLibrary .initialAllocator (false ));
64
64
@ Child AppendArrayNode appendArrayNode ;
65
65
@ Child AppendOneNode appendOneNode ;
66
66
67
- @ Override
68
- public BuilderState start () {
69
- return startNode .start ();
70
- }
71
-
72
67
@ Override
73
68
public BuilderState start (int length ) {
74
69
return startNode .start (length );
@@ -106,7 +101,7 @@ private AppendOneNode getAppendOneNode() {
106
101
return appendOneNode ;
107
102
}
108
103
109
- public synchronized ArrayAllocator updateStrategy (ArrayStoreLibrary .ArrayAllocator newStrategy , int newLength ) {
104
+ public synchronized ArrayAllocator updateStrategy (ArrayStoreLibrary .ArrayAllocator newStrategy ) {
110
105
final ArrayStoreLibrary .ArrayAllocator oldStrategy = startNode .allocator ;
111
106
final ArrayStoreLibrary .ArrayAllocator updatedAllocator ;
112
107
// If two threads have raced to update the strategy then
@@ -122,11 +117,8 @@ public synchronized ArrayAllocator updateStrategy(ArrayStoreLibrary.ArrayAllocat
122
117
updatedAllocator = oldStrategy ;
123
118
}
124
119
125
- final int oldLength = startNode .expectedLength ;
126
- final int newExpectedLength = Math .max (oldLength , newLength );
127
-
128
- if (updatedAllocator != oldStrategy || newExpectedLength > oldLength ) {
129
- startNode .replace (new StartNode (updatedAllocator , newExpectedLength ));
120
+ if (updatedAllocator != oldStrategy ) {
121
+ startNode .replace (new StartNode (updatedAllocator ));
130
122
}
131
123
132
124
if (newStrategy != oldStrategy ) {
@@ -145,35 +137,21 @@ public synchronized ArrayAllocator updateStrategy(ArrayStoreLibrary.ArrayAllocat
145
137
146
138
public abstract static class ArrayBuilderBaseNode extends RubyBaseNode {
147
139
148
- protected ArrayAllocator replaceNodes (ArrayStoreLibrary .ArrayAllocator strategy , int size ) {
140
+ protected ArrayAllocator replaceNodes (ArrayStoreLibrary .ArrayAllocator strategy ) {
149
141
final ArrayBuilderProxyNode parent = (ArrayBuilderProxyNode ) getParent ();
150
- return parent .updateStrategy (strategy , size );
142
+ return parent .updateStrategy (strategy );
151
143
}
152
144
}
153
145
154
146
public static class StartNode extends ArrayBuilderBaseNode {
155
147
156
148
private final ArrayStoreLibrary .ArrayAllocator allocator ;
157
- private final int expectedLength ;
158
149
159
- public StartNode (ArrayStoreLibrary .ArrayAllocator allocator , int expectedLength ) {
150
+ public StartNode (ArrayStoreLibrary .ArrayAllocator allocator ) {
160
151
this .allocator = allocator ;
161
- this .expectedLength = expectedLength ;
162
- }
163
-
164
- public BuilderState start () {
165
- if (allocator == ArrayStoreLibrary .initialAllocator (false )) {
166
- return new BuilderState (allocator .allocate (0 ), expectedLength );
167
- } else {
168
- return new BuilderState (allocator .allocate (expectedLength ), expectedLength );
169
- }
170
152
}
171
153
172
154
public BuilderState start (int length ) {
173
- if (length > expectedLength ) {
174
- CompilerDirectives .transferToInterpreterAndInvalidate ();
175
- replaceNodes (allocator , length );
176
- }
177
155
if (allocator == ArrayStoreLibrary .initialAllocator (false )) {
178
156
return new BuilderState (allocator .allocate (0 ), length );
179
157
} else {
@@ -196,15 +174,15 @@ public static AppendOneNode create() {
196
174
limit = "1" )
197
175
protected void appendCompatibleType (BuilderState state , int index , Object value ,
198
176
@ Bind ("state.store" ) Object store ,
199
- @ CachedLibrary ("store" ) ArrayStoreLibrary arrays ) {
177
+ @ CachedLibrary ("store" ) ArrayStoreLibrary arrays ,
178
+ @ Cached BranchProfile growProfile ) {
200
179
assert state .nextIndex == index ;
201
180
final int length = arrays .capacity (state .store );
202
181
if (index >= length ) {
203
- CompilerDirectives . transferToInterpreterAndInvalidate ();
182
+ growProfile . enter ();
204
183
final int capacity = ArrayUtils .capacityForOneMore (getLanguage (), length );
205
184
state .store = arrays .expand (state .store , capacity );
206
185
state .capacity = capacity ;
207
- replaceNodes (arrays .unsharedAllocator (state .store ), capacity );
208
186
}
209
187
arrays .write (state .store , index , value );
210
188
state .nextIndex ++;
@@ -229,7 +207,7 @@ protected void appendNewStrategy(BuilderState state, int index, Object value,
229
207
neededCapacity = currentCapacity ;
230
208
}
231
209
232
- newAllocator = replaceNodes (newAllocator , neededCapacity );
210
+ newAllocator = replaceNodes (newAllocator );
233
211
234
212
final Object newStore = newAllocator .allocate (neededCapacity );
235
213
stores .copyContents (state .store , 0 , newStore , 0 , index );
@@ -258,15 +236,15 @@ protected void appendCompatibleStrategy(BuilderState state, int index, RubyArray
258
236
@ Bind ("state.store" ) Object store ,
259
237
@ Bind ("other.getStore()" ) Object otherStore ,
260
238
@ CachedLibrary ("store" ) ArrayStoreLibrary arrays ,
261
- @ CachedLibrary ("otherStore" ) ArrayStoreLibrary others ) {
239
+ @ CachedLibrary ("otherStore" ) ArrayStoreLibrary others ,
240
+ @ Cached BranchProfile growProfile ) {
262
241
assert state .nextIndex == index ;
263
242
final int otherSize = other .size ;
264
243
final int neededSize = index + otherSize ;
265
244
266
245
int length = arrays .capacity (state .store );
267
246
if (neededSize > length ) {
268
- CompilerDirectives .transferToInterpreterAndInvalidate ();
269
- replaceNodes (arrays .unsharedAllocator (state .store ), neededSize );
247
+ growProfile .enter ();
270
248
final int capacity = ArrayUtils .capacity (getLanguage (), length , neededSize );
271
249
state .store = arrays .expand (state .store , capacity );
272
250
state .capacity = capacity ;
@@ -300,8 +278,7 @@ protected void appendNewStrategy(BuilderState state, int index, RubyArray other,
300
278
}
301
279
302
280
ArrayAllocator allocator = replaceNodes (
303
- newArrayLibrary .generalizeForStore (state .store , other .getStore ()),
304
- neededCapacity );
281
+ newArrayLibrary .generalizeForStore (state .store , other .getStore ()));
305
282
newStore = allocator .allocate (neededCapacity );
306
283
307
284
newArrayLibrary .copyContents (state .store , 0 , newStore , 0 , index );
0 commit comments