@@ -852,9 +852,40 @@ struct _jl_gcframe_t {
852852
853853#define jl_pgcstack (jl_current_task->gcstack)
854854
855+ #ifndef MMTK_GC
855856#define JL_GC_ENCODE_PUSHARGS (n ) (((size_t)(n))<<2)
856857#define JL_GC_ENCODE_PUSH (n ) ((((size_t)(n))<<2)|1)
857858
859+ #define JL_GC_ENCODE_PUSHARGS_NO_TPIN (n ) JL_GC_ENCODE_PUSHARGS(n)
860+ #define JL_GC_ENCODE_PUSH_NO_TPIN (n ) JL_GC_ENCODE_PUSH(n)
861+ #else
862+
863+ // We use an extra bit (100) in the nroots value from the frame to indicate that the roots
864+ // in the frame are/are not transitively pinning.
865+ // There are currently 3 macros that encode passing nroots to the gcframe
866+ // and they use the two lowest bits to encode information about what is in the frame (as below).
867+ // To support the distinction between transtively pinning roots and non transitively pinning roots
868+ // on the stack, we take another bit from nroots to encode information about whether or not to
869+ // transitively pin the roots in the frame.
870+ //
871+ // So the ones that transitively pin look like:
872+ // #define JL_GC_ENCODE_PUSHARGS(n) (((size_t)(n))<<3)
873+ // #define JL_GC_ENCODE_PUSH(n) ((((size_t)(n))<<3)|1)
874+ // #define JL_GC_ENCODE_PUSHFRAME(n) ((((size_t)(n))<<3)|2)
875+ // and the ones that do not look like:
876+ // #define JL_GC_ENCODE_PUSHARGS_NO_TPIN(n) (((size_t)(n))<<3|4)
877+ // #define JL_GC_ENCODE_PUSH_NO_TPIN(n) ((((size_t)(n))<<3)|5)
878+ // #define JL_GC_ENCODE_PUSHFRAME_NO_TPIN(n) ((((size_t)(n))<<3)|6)
879+
880+ // these are transitively pinning
881+ #define JL_GC_ENCODE_PUSHARGS (n ) (((size_t)(n))<<3)
882+ #define JL_GC_ENCODE_PUSH (n ) ((((size_t)(n))<<3)|1)
883+
884+ // these only pin the root object itself
885+ #define JL_GC_ENCODE_PUSHARGS_NO_TPIN (n ) (((size_t)(n))<<3|4)
886+ #define JL_GC_ENCODE_PUSH_NO_TPIN (n ) ((((size_t)(n))<<3)|5)
887+ #endif
888+
858889#ifdef __clang_gcanalyzer__
859890
860891// When running with the analyzer make these real function calls, that are
@@ -905,11 +936,11 @@ extern void JL_GC_POP() JL_NOTSAFEPOINT;
905936#define JL_GC_PUSH7 (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 ) \
906937 void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH(7), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7}; \
907938 jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
939+
908940#define JL_GC_PUSH8 (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 ) \
909941 void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH(8), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8}; \
910942 jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
911943
912-
913944#define JL_GC_PUSHARGS (rts_var ,n ) \
914945 rts_var = ((jl_value_t**)alloca(((n)+2)*sizeof(jl_value_t*)))+2; \
915946 ((void**)rts_var)[-2] = (void*)JL_GC_ENCODE_PUSHARGS(n); \
@@ -921,6 +952,68 @@ extern void JL_GC_POP() JL_NOTSAFEPOINT;
921952
922953#endif
923954
955+ #ifdef MMTK_GC
956+ // these are pinning roots: only the root object needs to be pinned as opposed to
957+ // the functions above which are transitively pinning
958+ #define JL_GC_PUSH1_NO_TPIN (arg1 ) \
959+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(1), jl_pgcstack, arg1}; \
960+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
961+
962+ #define JL_GC_PUSH2_NO_TPIN (arg1 , arg2 ) \
963+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(2), jl_pgcstack, arg1, arg2}; \
964+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
965+
966+ #define JL_GC_PUSH3_NO_TPIN (arg1 , arg2 , arg3 ) \
967+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(3), jl_pgcstack, arg1, arg2, arg3}; \
968+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
969+
970+ #define JL_GC_PUSH4_NO_TPIN (arg1 , arg2 , arg3 , arg4 ) \
971+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(4), jl_pgcstack, arg1, arg2, arg3, arg4}; \
972+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
973+
974+ #define JL_GC_PUSH5_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 ) \
975+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(5), jl_pgcstack, arg1, arg2, arg3, arg4, arg5}; \
976+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
977+
978+ #define JL_GC_PUSH6_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 ) \
979+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(6), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6}; \
980+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
981+
982+ #define JL_GC_PUSH7_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 ) \
983+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(7), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7}; \
984+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
985+
986+ #define JL_GC_PUSH8_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 ) \
987+ void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH_NO_TPIN(8), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8}; \
988+ jl_pgcstack = (jl_gcframe_t*)__gc_stkf;
989+
990+ #define JL_GC_PUSHARGS_NO_TPIN (rts_var ,n ) \
991+ rts_var = ((jl_value_t**)alloca(((n)+2)*sizeof(jl_value_t*)))+2; \
992+ ((void**)rts_var)[-2] = (void*)JL_GC_ENCODE_PUSHARGS_NO_TPIN(n); \
993+ ((void**)rts_var)[-1] = jl_pgcstack; \
994+ memset((void*)rts_var, 0, (n)*sizeof(jl_value_t*)); \
995+ jl_pgcstack = (jl_gcframe_t*)&(((void**)rts_var)[-2])
996+ #else
997+ // When not using MMTk, default to the stock functions
998+ #define JL_GC_PUSH1_NO_TPIN (arg1 ) JL_GC_PUSH1(arg1)
999+
1000+ #define JL_GC_PUSH2_NO_TPIN (arg1 , arg2 ) JL_GC_PUSH2(arg1, arg2)
1001+
1002+ #define JL_GC_PUSH3_NO_TPIN (arg1 , arg2 , arg3 ) JL_GC_PUSH3(arg1, arg2, arg3)
1003+
1004+ #define JL_GC_PUSH4_NO_TPIN (arg1 , arg2 , arg3 , arg4 ) JL_GC_PUSH4(arg1, arg2, arg3, arg4)
1005+
1006+ #define JL_GC_PUSH5_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 ) JL_GC_PUSH5(arg1, arg2, arg3, arg4, arg5)
1007+
1008+ #define JL_GC_PUSH6_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 ) JL_GC_PUSH6(arg1, arg2, arg3, arg4, arg5, arg6)
1009+
1010+ #define JL_GC_PUSH7_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 ) JL_GC_PUSH7(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
1011+
1012+ #define JL_GC_PUSH8_NO_TPIN (arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 ) JL_GC_PUSH8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
1013+
1014+ #define JL_GC_PUSHARGS_NO_TPIN (rts_var ,n ) JL_GC_PUSHARGS(rts_var,n)
1015+ #endif
1016+
9241017JL_DLLEXPORT int jl_gc_enable (int on );
9251018JL_DLLEXPORT int jl_gc_is_enabled (void );
9261019
0 commit comments