@@ -580,137 +580,121 @@ static void memory_scan_and_copy(HeapFragment *old_fragment, term *mem_start, co
580
580
581
581
while (ptr < mem_end ) {
582
582
term t = * ptr ;
583
+ switch (t & TERM_PRIMARY_MASK ) {
584
+ case TERM_PRIMARY_IMMED :
585
+ TRACE ("Found immediate (%" TERM_X_FMT ")\n" , t );
586
+ ptr ++ ;
587
+ break ;
588
+ case TERM_PRIMARY_CP : {
589
+ TRACE ("Found boxed header (%" TERM_X_FMT ")\n" , t );
590
+
591
+ size_t arity = term_get_size_from_boxed_header (t );
592
+ switch (t & TERM_BOXED_TAG_MASK ) {
593
+ case TERM_BOXED_TUPLE : {
594
+ TRACE ("- Boxed is tuple (%" TERM_X_FMT "), arity: %i\n" , t , (int ) arity );
595
+
596
+ for (size_t i = 1 ; i <= arity ; i ++ ) {
597
+ TRACE ("-- Elem: %" TERM_X_FMT "\n" , ptr [i ]);
598
+ ptr [i ] = memory_shallow_copy_term (old_fragment , ptr [i ], & new_heap , move );
599
+ }
600
+ break ;
601
+ }
583
602
584
- if (term_is_atom (t )) {
585
- TRACE ("Found atom (%" TERM_X_FMT ")\n" , t );
586
- ptr ++ ;
587
-
588
- } else if (term_is_integer (t )) {
589
- TRACE ("Found integer (%" TERM_X_FMT ")\n" , t );
590
- ptr ++ ;
591
-
592
- } else if (term_is_nil (t )) {
593
- TRACE ("Found NIL (%" TERM_X_FMT ")\n" , t );
594
- ptr ++ ;
595
-
596
- } else if (term_is_local_pid (t )) {
597
- TRACE ("Found PID (%" TERM_X_FMT ")\n" , t );
598
- ptr ++ ;
599
-
600
- } else if (term_is_local_port (t )) {
601
- TRACE ("Found port (%" TERM_X_FMT ")\n" , t );
602
- ptr ++ ;
603
-
604
- } else if ((t & 0x3 ) == 0x0 ) {
605
- TRACE ("Found boxed header (%" TERM_X_FMT ")\n" , t );
606
-
607
- size_t arity = term_get_size_from_boxed_header (t );
608
- switch (t & TERM_BOXED_TAG_MASK ) {
609
- case TERM_BOXED_TUPLE : {
610
- TRACE ("- Boxed is tuple (%" TERM_X_FMT "), arity: %i\n" , t , (int ) arity );
611
-
612
- for (size_t i = 1 ; i <= arity ; i ++ ) {
613
- TRACE ("-- Elem: %" TERM_X_FMT "\n" , ptr [i ]);
614
- ptr [i ] = memory_shallow_copy_term (old_fragment , ptr [i ], & new_heap , move );
603
+ case TERM_BOXED_BIN_MATCH_STATE : {
604
+ TRACE ("- Found bin match state.\n" );
605
+ ptr [1 ] = memory_shallow_copy_term (old_fragment , ptr [1 ], & new_heap , move );
606
+ break ;
615
607
}
616
- break ;
617
- }
618
608
619
- case TERM_BOXED_BIN_MATCH_STATE : {
620
- TRACE ("- Found bin match state.\n" );
621
- ptr [1 ] = memory_shallow_copy_term (old_fragment , ptr [1 ], & new_heap , move );
622
- break ;
623
- }
609
+ case TERM_BOXED_POSITIVE_INTEGER :
610
+ TRACE ("- Found boxed pos int.\n" );
611
+ break ;
624
612
625
- case TERM_BOXED_POSITIVE_INTEGER :
626
- TRACE ("- Found boxed pos int .\n" );
627
- break ;
613
+ case TERM_BOXED_REF :
614
+ TRACE ("- Found ref .\n" );
615
+ break ;
628
616
629
- case TERM_BOXED_REF :
630
- TRACE ("- Found ref .\n" );
631
- break ;
617
+ case TERM_BOXED_EXTERNAL_PID :
618
+ TRACE ("- Found external pid .\n" );
619
+ break ;
632
620
633
- case TERM_BOXED_EXTERNAL_PID :
634
- TRACE ("- Found external pid .\n" );
635
- break ;
621
+ case TERM_BOXED_EXTERNAL_PORT :
622
+ TRACE ("- Found external port .\n" );
623
+ break ;
636
624
637
- case TERM_BOXED_EXTERNAL_PORT :
638
- TRACE ("- Found external port .\n" );
639
- break ;
625
+ case TERM_BOXED_EXTERNAL_REF :
626
+ TRACE ("- Found external ref .\n" );
627
+ break ;
640
628
641
- case TERM_BOXED_EXTERNAL_REF :
642
- TRACE ("- Found external ref.\n" );
643
- break ;
644
-
645
- case TERM_BOXED_FUN : {
646
- TRACE ("- Found fun, size: %i.\n" , (int ) arity );
629
+ case TERM_BOXED_FUN : {
630
+ TRACE ("- Found fun, size: %i.\n" , (int ) arity );
647
631
648
- // first term is the boxed header, followed by module and fun index.
632
+ // first term is the boxed header, followed by module and fun index.
649
633
650
- for (size_t i = 3 ; i <= arity ; i ++ ) {
651
- TRACE ("-- Frozen: %" TERM_X_FMT "\n" , ptr [i ]);
652
- ptr [i ] = memory_shallow_copy_term (old_fragment , ptr [i ], & new_heap , move );
634
+ for (size_t i = 3 ; i <= arity ; i ++ ) {
635
+ TRACE ("-- Frozen: %" TERM_X_FMT "\n" , ptr [i ]);
636
+ ptr [i ] = memory_shallow_copy_term (old_fragment , ptr [i ], & new_heap , move );
637
+ }
638
+ break ;
653
639
}
654
- break ;
655
- }
656
640
657
- case TERM_BOXED_FLOAT :
658
- TRACE ("- Found float.\n" );
659
- break ;
641
+ case TERM_BOXED_FLOAT :
642
+ TRACE ("- Found float.\n" );
643
+ break ;
644
+
645
+ case TERM_BOXED_REFC_BINARY : {
646
+ TRACE ("- Found refc binary.\n" );
647
+ term ref = ((term ) ptr ) | TERM_PRIMARY_BOXED ;
648
+ if (!term_refc_binary_is_const (ref )) {
649
+ * mso_list = term_list_init_prepend (ptr + REFC_BINARY_CONS_OFFSET , ref , * mso_list );
650
+ refc_binary_increment_refcount ((struct RefcBinary * ) term_refc_binary_ptr (ref ));
651
+ }
652
+ break ;
653
+ }
660
654
661
- case TERM_BOXED_REFC_BINARY : {
662
- TRACE ("- Found refc binary.\n" );
663
- term ref = ((term ) ptr ) | TERM_PRIMARY_BOXED ;
664
- if (!term_refc_binary_is_const (ref )) {
665
- * mso_list = term_list_init_prepend (ptr + REFC_BINARY_CONS_OFFSET , ref , * mso_list );
666
- refc_binary_increment_refcount ((struct RefcBinary * ) term_refc_binary_ptr (ref ));
655
+ case TERM_BOXED_SUB_BINARY : {
656
+ TRACE ("- Found sub binary.\n" );
657
+ ptr [3 ] = memory_shallow_copy_term (old_fragment , ptr [3 ], & new_heap , move );
658
+ break ;
667
659
}
668
- break ;
669
- }
670
660
671
- case TERM_BOXED_SUB_BINARY : {
672
- TRACE ("- Found sub binary.\n" );
673
- ptr [3 ] = memory_shallow_copy_term (old_fragment , ptr [3 ], & new_heap , move );
674
- break ;
661
+ case TERM_BOXED_HEAP_BINARY :
662
+ TRACE ("- Found binary.\n" );
663
+ break ;
664
+
665
+ case TERM_BOXED_MAP : {
666
+ TRACE ("- Found map.\n" );
667
+ size_t map_size = arity - 1 ;
668
+ size_t keys_offset = term_get_map_keys_offset ();
669
+ size_t value_offset = term_get_map_value_offset ();
670
+ TRACE ("-- Map keys: %" TERM_X_FMT "\n" , ptr [keys_offset ]);
671
+ ptr [keys_offset ] = memory_shallow_copy_term (old_fragment , ptr [keys_offset ], & new_heap , move );
672
+ for (size_t i = value_offset ; i < value_offset + map_size ; ++ i ) {
673
+ TRACE ("-- Map Value: %" TERM_X_FMT "\n" , ptr [i ]);
674
+ ptr [i ] = memory_shallow_copy_term (old_fragment , ptr [i ], & new_heap , move );
675
+ }
676
+ } break ;
677
+
678
+ default :
679
+ fprintf (stderr , "- Found unknown boxed type: %" TERM_X_FMT "\n" , (t >> 2 ) & 0xF );
680
+ AVM_ABORT ();
675
681
}
676
682
677
- case TERM_BOXED_HEAP_BINARY :
678
- TRACE ("- Found binary.\n" );
679
- break ;
680
-
681
- case TERM_BOXED_MAP : {
682
- TRACE ("- Found map.\n" );
683
- size_t map_size = arity - 1 ;
684
- size_t keys_offset = term_get_map_keys_offset ();
685
- size_t value_offset = term_get_map_value_offset ();
686
- TRACE ("-- Map keys: %" TERM_X_FMT "\n" , ptr [keys_offset ]);
687
- ptr [keys_offset ] = memory_shallow_copy_term (old_fragment , ptr [keys_offset ], & new_heap , move );
688
- for (size_t i = value_offset ; i < value_offset + map_size ; ++ i ) {
689
- TRACE ("-- Map Value: %" TERM_X_FMT "\n" , ptr [i ]);
690
- ptr [i ] = memory_shallow_copy_term (old_fragment , ptr [i ], & new_heap , move );
691
- }
692
- } break ;
693
-
694
- default :
695
- fprintf (stderr , "- Found unknown boxed type: %" TERM_X_FMT "\n" , (t >> 2 ) & 0xF );
696
- AVM_ABORT ();
683
+ ptr += arity + 1 ;
684
+ break ;
697
685
}
698
-
699
- ptr += arity + 1 ;
700
-
701
- } else if (term_is_nonempty_list (t )) {
702
- TRACE ("Found nonempty list (%p)\n" , (void * ) t );
703
- * ptr = memory_shallow_copy_term (old_fragment , t , & new_heap , move );
704
- ptr ++ ;
705
-
706
- } else if (term_is_boxed (t )) {
707
- TRACE ("Found boxed (%p)\n" , (void * ) t );
708
- * ptr = memory_shallow_copy_term (old_fragment , t , & new_heap , move );
709
- ptr ++ ;
710
-
711
- } else {
712
- fprintf (stderr , "bug: found unknown term type: 0x%" TERM_X_FMT "\n" , t );
713
- AVM_ABORT ();
686
+ case TERM_PRIMARY_LIST :
687
+ TRACE ("Found nonempty list (%p)\n" , (void * ) t );
688
+ * ptr = memory_shallow_copy_term (old_fragment , t , & new_heap , move );
689
+ ptr ++ ;
690
+ break ;
691
+ case TERM_PRIMARY_BOXED :
692
+ TRACE ("Found boxed (%p)\n" , (void * ) t );
693
+ * ptr = memory_shallow_copy_term (old_fragment , t , & new_heap , move );
694
+ ptr ++ ;
695
+ break ;
696
+ default :
697
+ UNREACHABLE ();
714
698
}
715
699
}
716
700
@@ -835,90 +819,75 @@ HOT_FUNC static inline bool memory_heap_fragment_contains_pointer(HeapFragment *
835
819
836
820
HOT_FUNC static term memory_shallow_copy_term (HeapFragment * old_fragment , term t , term * * new_heap , bool move )
837
821
{
838
- if (term_is_atom (t )) {
839
- return t ;
840
-
841
- } else if (term_is_integer (t )) {
842
- return t ;
843
-
844
- } else if (term_is_nil (t )) {
845
- return t ;
846
-
847
- } else if (term_is_local_pid (t )) {
848
- return t ;
849
-
850
- } else if (term_is_local_port (t )) {
851
- return t ;
852
-
853
- } else if (term_is_cp (t )) {
854
- // CP is valid only on stack
855
- return t ;
856
-
857
- } else if (term_is_catch_label (t )) {
858
- // catch label is valid only on stack
859
- return t ;
860
-
861
- } else if (term_is_boxed (t )) {
862
- term * boxed_value = term_to_term_ptr (t );
863
- // Do not GC terms from messages until the message is destroyed
864
- if (old_fragment != NULL && !memory_heap_fragment_contains_pointer (old_fragment , boxed_value )) {
822
+ switch (t & TERM_PRIMARY_MASK ) {
823
+ case TERM_PRIMARY_IMMED :
865
824
return t ;
866
- }
867
825
868
- if (memory_is_moved_marker (boxed_value )) {
869
- return memory_dereference_moved_marker (boxed_value );
870
- }
871
-
872
- int boxed_size = term_boxed_size (t ) + 1 ;
826
+ case TERM_PRIMARY_CP :
827
+ // CP is valid only on stack
828
+ // catch label is valid only on stack
829
+ return t ;
830
+
831
+ case TERM_PRIMARY_BOXED : {
832
+ term * boxed_value = term_to_term_ptr (t );
833
+ // Do not GC terms from messages until the message is destroyed
834
+ if (old_fragment != NULL && !memory_heap_fragment_contains_pointer (old_fragment , boxed_value )) {
835
+ return t ;
836
+ }
873
837
874
- // It must be an empty tuple, so we are not going to use moved markers.
875
- // Empty tuples memory is too small to store moved markers.
876
- // However it is also required to avoid boxed terms duplication.
877
- // So instead all empty tuples will reference the same boxed term.
878
- if (boxed_size == 1 ) {
879
- return ((term ) & empty_tuple ) | TERM_PRIMARY_BOXED ;
880
- }
838
+ if (memory_is_moved_marker (boxed_value )) {
839
+ return memory_dereference_moved_marker (boxed_value );
840
+ }
881
841
882
- term * dest = * new_heap ;
883
- for (int i = 0 ; i < boxed_size ; i ++ ) {
884
- dest [i ] = boxed_value [i ];
885
- }
886
- * new_heap += boxed_size ;
842
+ int boxed_size = term_boxed_size (t ) + 1 ;
887
843
888
- term new_term = ((term ) dest ) | TERM_PRIMARY_BOXED ;
844
+ // It must be an empty tuple, so we are not going to use moved markers.
845
+ // Empty tuples memory is too small to store moved markers.
846
+ // However it is also required to avoid boxed terms duplication.
847
+ // So instead all empty tuples will reference the same boxed term.
848
+ if (boxed_size == 1 ) {
849
+ return ((term ) & empty_tuple ) | TERM_PRIMARY_BOXED ;
850
+ }
889
851
890
- if (move ) {
891
- memory_replace_with_moved_marker (boxed_value , new_term );
892
- }
852
+ term * dest = * new_heap ;
853
+ for (int i = 0 ; i < boxed_size ; i ++ ) {
854
+ dest [i ] = boxed_value [i ];
855
+ }
856
+ * new_heap += boxed_size ;
893
857
894
- return new_term ;
858
+ term new_term = (( term ) dest ) | TERM_PRIMARY_BOXED ;
895
859
896
- } else if (term_is_nonempty_list (t )) {
897
- term * list_ptr = term_get_list_ptr (t );
898
- if (old_fragment != NULL && !memory_heap_fragment_contains_pointer (old_fragment , list_ptr )) {
899
- return t ;
900
- }
860
+ if (move ) {
861
+ memory_replace_with_moved_marker (boxed_value , new_term );
862
+ }
901
863
902
- if (memory_is_moved_marker (list_ptr )) {
903
- return memory_dereference_moved_marker (list_ptr );
864
+ return new_term ;
904
865
}
866
+ case TERM_PRIMARY_LIST : {
867
+ term * list_ptr = term_get_list_ptr (t );
868
+ if (old_fragment != NULL && !memory_heap_fragment_contains_pointer (old_fragment , list_ptr )) {
869
+ return t ;
870
+ }
905
871
906
- term * dest = * new_heap ;
907
- dest [0 ] = list_ptr [0 ];
908
- dest [1 ] = list_ptr [1 ];
909
- * new_heap += 2 ;
872
+ if (memory_is_moved_marker (list_ptr )) {
873
+ return memory_dereference_moved_marker (list_ptr );
874
+ }
910
875
911
- term new_term = ((term ) dest ) | 0x1 ;
876
+ term * dest = * new_heap ;
877
+ dest [0 ] = list_ptr [0 ];
878
+ dest [1 ] = list_ptr [1 ];
879
+ * new_heap += 2 ;
912
880
913
- if (move ) {
914
- memory_replace_with_moved_marker (list_ptr , new_term );
915
- }
881
+ term new_term = ((term ) dest ) | 0x1 ;
916
882
917
- return new_term ;
883
+ if (move ) {
884
+ memory_replace_with_moved_marker (list_ptr , new_term );
885
+ }
918
886
919
- } else {
920
- fprintf (stderr , "Unexpected term. Term is: %" TERM_X_FMT "\n" , t );
921
- AVM_ABORT ();
887
+ return new_term ;
888
+ }
889
+ default :
890
+ UNREACHABLE ();
922
891
}
923
892
}
924
893
0 commit comments