16
16
import com .oracle .truffle .api .dsl .Specialization ;
17
17
import com .oracle .truffle .api .nodes .Node ;
18
18
import com .oracle .truffle .api .object .Shape ;
19
+ import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
19
20
import org .truffleruby .annotations .CoreMethod ;
20
21
import org .truffleruby .annotations .CoreModule ;
21
22
import org .truffleruby .annotations .Primitive ;
29
30
import org .truffleruby .core .proc .RubyProc ;
30
31
import org .truffleruby .extra .AtomicReferenceNodes .CompareAndSetReferenceNode ;
31
32
import org .truffleruby .extra .RubyConcurrentMap .Key ;
32
- import org .truffleruby .language .RubyGuards ;
33
33
import org .truffleruby .annotations .Visibility ;
34
34
import org .truffleruby .language .objects .AllocationTracing ;
35
35
import org .truffleruby .language .yield .CallBlockNode ;
39
39
import java .util .concurrent .ConcurrentHashMap ;
40
40
import java .util .function .BiFunction ;
41
41
42
+ import static org .truffleruby .language .RubyGuards .isPrimitive ;
43
+
42
44
@ CoreModule (value = "TruffleRuby::ConcurrentMap" , isClass = true )
43
45
public class ConcurrentMapNodes {
44
46
@@ -192,19 +194,29 @@ private static Object merge(ConcurrentHashMap<Key, Object> map, Key key, Object
192
194
193
195
@ CoreMethod (names = "replace_pair" , required = 3 )
194
196
public abstract static class ReplacePairNode extends CoreMethodArrayArgumentsNode {
195
- /** See {@link CompareAndSetReferenceNode} */
196
- @ Specialization ( guards = "isPrimitive(expectedValue)" )
197
- protected boolean replacePairPrimitive (
198
- RubyConcurrentMap self , Object key , Object expectedValue , Object newValue ,
199
- @ Exclusive @ Cached ToHashByHashCode hashNode ,
200
- @ Cached ReferenceEqualNode equalNode ) {
197
+
198
+ @ Specialization
199
+ protected boolean replacePair ( RubyConcurrentMap self , Object key , Object expectedValue , Object newValue ,
200
+ @ Cached ToHashByHashCode hashNode ,
201
+ @ Cached ReferenceEqualNode equalNode ,
202
+ @ Cached InlinedConditionProfile isPrimitiveProfile ) {
201
203
final int hashCode = hashNode .execute (this , key );
204
+
205
+ if (isPrimitiveProfile .profile (this , isPrimitive (expectedValue ))) {
206
+ return replacePairPrimitive (self , key , expectedValue , newValue , hashCode , equalNode );
207
+ } else {
208
+ return replace (self .getMap (), new Key (key , hashCode ), expectedValue , newValue );
209
+ }
210
+ }
211
+
212
+ private boolean replacePairPrimitive (RubyConcurrentMap self , Object key , Object expectedValue , Object newValue ,
213
+ int hashCode , ReferenceEqualNode equalNode ) {
202
214
final Key keyWrapper = new Key (key , hashCode );
203
215
204
216
while (true ) {
205
217
final Object currentValue = get (self .getMap (), keyWrapper );
206
218
207
- if (RubyGuards . isPrimitive (currentValue ) &&
219
+ if (isPrimitive (currentValue ) &&
208
220
equalNode .execute (expectedValue , currentValue )) {
209
221
if (replace (self .getMap (), keyWrapper , currentValue , newValue )) {
210
222
return true ;
@@ -215,14 +227,6 @@ protected boolean replacePairPrimitive(
215
227
}
216
228
}
217
229
218
- @ Specialization (guards = "!isPrimitive(expectedValue)" )
219
- protected static boolean replacePair (RubyConcurrentMap self , Object key , Object expectedValue , Object newValue ,
220
- @ Exclusive @ Cached ToHashByHashCode hashNode ,
221
- @ Bind ("this" ) Node node ) {
222
- final int hashCode = hashNode .execute (node , key );
223
- return replace (self .getMap (), new Key (key , hashCode ), expectedValue , newValue );
224
- }
225
-
226
230
@ TruffleBoundary
227
231
private static boolean replace (ConcurrentHashMap <Key , Object > map , Key key , Object oldValue , Object newValue ) {
228
232
return map .replace (key , oldValue , newValue );
0 commit comments