@@ -580,137 +580,121 @@ static void memory_scan_and_copy(HeapFragment *old_fragment, term *mem_start, co
580580
581581 while (ptr < mem_end ) {
582582 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+ }
583602
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 ;
615607 }
616- break ;
617- }
618608
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 ;
624612
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 ;
628616
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 ;
632620
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 ;
636624
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 ;
640628
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 );
647631
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.
649633
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 ;
653639 }
654- break ;
655- }
656640
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+ }
660654
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 ;
667659 }
668- break ;
669- }
670660
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 ();
675681 }
676682
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 ;
697685 }
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 ();
714698 }
715699 }
716700
@@ -835,90 +819,75 @@ HOT_FUNC static inline bool memory_heap_fragment_contains_pointer(HeapFragment *
835819
836820HOT_FUNC static term memory_shallow_copy_term (HeapFragment * old_fragment , term t , term * * new_heap , bool move )
837821{
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 :
865824 return t ;
866- }
867825
868- if (memory_is_moved_marker (boxed_value )) {
869- return memory_dereference_moved_marker (boxed_value );
870- }
826+ case TERM_PRIMARY_CP :
827+ // CP is valid only on stack
828+ // catch label is valid only on stack
829+ return t ;
871830
872- int boxed_size = term_boxed_size (t ) + 1 ;
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+ }
873837
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+ }
881841
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 ;
887843
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+ }
889851
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 ;
893857
894- return new_term ;
858+ term new_term = (( term ) dest ) | TERM_PRIMARY_BOXED ;
895859
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+ }
901863
902- if (memory_is_moved_marker (list_ptr )) {
903- return memory_dereference_moved_marker (list_ptr );
864+ return new_term ;
904865 }
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+ }
905871
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+ }
910875
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 ;
912880
913- if (move ) {
914- memory_replace_with_moved_marker (list_ptr , new_term );
915- }
881+ term new_term = ((term ) dest ) | 0x1 ;
916882
917- return new_term ;
883+ if (move ) {
884+ memory_replace_with_moved_marker (list_ptr , new_term );
885+ }
918886
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 ();
922891 }
923892}
924893
0 commit comments