134
134
import org .truffleruby .language .objects .IsCopyableObjectNode ;
135
135
import org .truffleruby .language .objects .IsCopyableObjectNodeGen ;
136
136
import org .truffleruby .language .objects .IsFrozenNode ;
137
+ import org .truffleruby .language .objects .LazySingletonClassNode ;
137
138
import org .truffleruby .language .objects .LogicalClassNode ;
138
139
import org .truffleruby .language .objects .MetaClassNode ;
139
140
import org .truffleruby .language .objects .ShapeCachingGuards ;
@@ -554,24 +555,24 @@ protected RubyDynamicObject copy(RubyIntOrLongRange range,
554
555
public abstract static class CloneNode extends PrimitiveArrayArgumentsNode {
555
556
556
557
@ Child IsCopyableObjectNode isCopyableObjectNode = IsCopyableObjectNodeGen .create ();
557
- @ Child SingletonClassNode singletonClassNode ;
558
- private final BranchProfile cantUnfreezeErrorProfile = BranchProfile .create ();
559
558
560
559
@ Specialization (guards = "isCopyableObjectNode.execute(object)" )
561
- protected RubyDynamicObject copyable (Object object , Object freeze ,
560
+ protected static RubyDynamicObject copyable (Object object , Object freeze ,
562
561
@ Cached MetaClassNode metaClassNode ,
563
562
@ Cached CopyNode copyNode ,
564
563
@ Cached DispatchNode initializeCloneNode ,
565
564
@ Cached InlinedConditionProfile isSingletonProfile ,
566
565
@ Cached HashingNodes .ToHashByHashCode hashNode ,
567
566
@ Cached IsFrozenNode isFrozenNode ,
568
- @ Cached FreezeNode freezeNode ) {
567
+ @ Cached FreezeNode freezeNode ,
568
+ @ Cached LazySingletonClassNode lazySingletonClassNode ,
569
+ @ Bind ("this" ) Node node ) {
569
570
final RubyDynamicObject newObject = copyNode .executeCopy (object );
570
571
571
572
// Copy the singleton class if any.
572
- final RubyClass selfMetaClass = metaClassNode .execute (this , object );
573
- if (isSingletonProfile .profile (this , selfMetaClass .isSingleton )) {
574
- final RubyClass newObjectMetaClass = executeSingletonClass (newObject );
573
+ final RubyClass selfMetaClass = metaClassNode .execute (node , object );
574
+ if (isSingletonProfile .profile (node , selfMetaClass .isSingleton )) {
575
+ final RubyClass newObjectMetaClass = lazySingletonClassNode . get ( node ). executeSingletonClass (newObject );
575
576
newObjectMetaClass .fields .initCopy (selfMetaClass );
576
577
}
577
578
@@ -581,7 +582,7 @@ protected RubyDynamicObject copyable(Object object, Object freeze,
581
582
initializeCloneNode .call (newObject , "initialize_clone" , object );
582
583
} else {
583
584
// pass :freeze keyword argument to #initialize_clone
584
- final RubyHash keywordArguments = createFreezeBooleanHash ((boolean ) freeze , hashNode );
585
+ final RubyHash keywordArguments = createFreezeBooleanHash (node , (boolean ) freeze , hashNode );
585
586
initializeCloneNode .callWithKeywords (newObject , "initialize_clone" , object , keywordArguments );
586
587
}
587
588
@@ -594,24 +595,27 @@ protected RubyDynamicObject copyable(Object object, Object freeze,
594
595
}
595
596
596
597
@ Specialization (guards = "!isCopyableObjectNode.execute(object)" )
597
- protected Object notCopyable (Object object , Object freeze ) {
598
+ protected Object notCopyable (Object object , Object freeze ,
599
+ @ Cached InlinedBranchProfile cantUnfreezeErrorProfile ) {
598
600
if (forceNotFrozen (freeze )) {
599
- raiseCantUnfreezeError (object );
601
+ raiseCantUnfreezeError (cantUnfreezeErrorProfile , object );
600
602
}
601
603
return object ;
602
604
}
603
605
604
- private RubyHash createFreezeBooleanHash (boolean freeze , HashingNodes .ToHashByHashCode hashNode ) {
605
- final RubySymbol key = coreSymbols ().FREEZE ;
606
+ private static RubyHash createFreezeBooleanHash (Node node , boolean freeze ,
607
+ HashingNodes .ToHashByHashCode hashNode ) {
608
+ final RubySymbol key = coreSymbols (node ).FREEZE ;
606
609
607
610
final Object [] newStore = PackedHashStoreLibrary .createStore ();
608
- final int hashed = hashNode .execute (this , key );
611
+ final int hashed = hashNode .execute (node , key );
609
612
PackedHashStoreLibrary .setHashedKeyValue (newStore , 0 , hashed , key , freeze );
610
613
611
- return new RubyHash (coreLibrary ().hashClass , getLanguage ().hashShape , getContext (), newStore , 1 , false );
614
+ return new RubyHash (coreLibrary (node ).hashClass , getLanguage (node ).hashShape , getContext (node ), newStore , 1 ,
615
+ false );
612
616
}
613
617
614
- private boolean forceFrozen (Object freeze ) {
618
+ private static boolean forceFrozen (Object freeze ) {
615
619
return freeze instanceof Boolean && (boolean ) freeze ;
616
620
617
621
}
@@ -620,20 +624,10 @@ private boolean forceNotFrozen(Object freeze) {
620
624
return freeze instanceof Boolean && !(boolean ) freeze ;
621
625
}
622
626
623
- private void raiseCantUnfreezeError (Object object ) {
624
- cantUnfreezeErrorProfile .enter ();
627
+ private void raiseCantUnfreezeError (InlinedBranchProfile cantUnfreezeErrorProfile , Object object ) {
628
+ cantUnfreezeErrorProfile .enter (this );
625
629
throw new RaiseException (getContext (), coreExceptions ().argumentErrorCantUnfreeze (object , this ));
626
630
}
627
-
628
- private RubyClass executeSingletonClass (RubyDynamicObject newObject ) {
629
- if (singletonClassNode == null ) {
630
- CompilerDirectives .transferToInterpreterAndInvalidate ();
631
- singletonClassNode = insert (SingletonClassNode .create ());
632
- }
633
-
634
- return singletonClassNode .executeSingletonClass (newObject );
635
- }
636
-
637
631
}
638
632
639
633
// Worth always splitting to have monomorphic #__allocate__, Shape, #initialize_dup and #initialize_copy.
@@ -886,15 +880,17 @@ protected long hashBignum(RubyBignum value) {
886
880
}
887
881
888
882
@ Specialization
889
- protected long hashString (RubyString value ,
890
- @ Cached @ Exclusive StringHelperNodes .HashStringNode stringHashNode ) {
891
- return stringHashNode .execute (value );
883
+ protected static long hashString (RubyString value ,
884
+ @ Cached @ Exclusive StringHelperNodes .HashStringNode stringHashNode ,
885
+ @ Bind ("this" ) Node node ) {
886
+ return stringHashNode .execute (node , value );
892
887
}
893
888
894
889
@ Specialization
895
- protected long hashImmutableString (ImmutableRubyString value ,
896
- @ Cached @ Exclusive StringHelperNodes .HashStringNode stringHashNode ) {
897
- return stringHashNode .execute (value );
890
+ protected static long hashImmutableString (ImmutableRubyString value ,
891
+ @ Cached @ Exclusive StringHelperNodes .HashStringNode stringHashNode ,
892
+ @ Bind ("this" ) Node node ) {
893
+ return stringHashNode .execute (node , value );
898
894
}
899
895
900
896
@ Specialization
0 commit comments