From 2c94209682b190631be11f7af0003a46287df20c Mon Sep 17 00:00:00 2001 From: Nick Roberts Date: Tue, 4 Jun 2024 13:51:28 -0400 Subject: [PATCH] Add new Allocated_* macros for accessing the size of an object --- ocaml/runtime/caml/mlvalues.h | 78 +++++++++++++++++++++++----------- ocaml/runtime4/caml/mlvalues.h | 67 ++++++++++++++++++++--------- 2 files changed, 100 insertions(+), 45 deletions(-) diff --git a/ocaml/runtime/caml/mlvalues.h b/ocaml/runtime/caml/mlvalues.h index 4f265d583eb..6cdcc0a2493 100644 --- a/ocaml/runtime/caml/mlvalues.h +++ b/ocaml/runtime/caml/mlvalues.h @@ -130,7 +130,7 @@ mixed blocks. In the upstream compiler, R is set with the #define Tag_hd(hd) ((tag_t) ((hd) & HEADER_TAG_MASK)) #define Hd_with_tag(hd, tag) (((hd) &~ HEADER_TAG_MASK) | (tag)) -#define Wosize_hd(hd) ((mlsize_t) (((hd) & HEADER_WOSIZE_MASK) \ +#define Allocated_wosize_hd(hd) ((mlsize_t) (((hd) & HEADER_WOSIZE_MASK) \ >> HEADER_WOSIZE_SHIFT)) /* A "clean" header, without reserved or color bits. */ @@ -192,7 +192,7 @@ Caml_inline mlsize_t Scannable_wosize_hd_native(header_t hd) { return Is_mixed_block_reserved(res) ? Mixed_block_scannable_wosize_reserved_native(res) - : Wosize_hd(hd); + : Allocated_wosize_hd(hd); } /* Bytecode versions of mixed block macros. @@ -203,8 +203,8 @@ Caml_inline mlsize_t Scannable_wosize_hd_native(header_t hd) { in the header bits. */ -#define Scannable_wosize_hd_byte(hd) (Wosize_hd (hd)) -#define Scannable_wosize_val_byte(val) (Wosize_hd (Hd_val (val))) +#define Scannable_wosize_hd_byte(hd) (Allocated_wosize_hd (hd)) +#define Scannable_wosize_val_byte(val) (Allocated_wosize_hd (Hd_val (val))) Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, mlsize_t size) { (void)res; @@ -252,16 +252,6 @@ Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, #define Num_tags (1ull << HEADER_TAG_BITS) #define Max_wosize ((1ull << HEADER_WOSIZE_BITS) - 1ull) -// Note that Wosize_val and the other macros that read headers will not -// be optimized by common subexpression elimination, because of the -// atomic header loads. It is best to bind the results of such macros -// to variables if they will be tested repeatedly, e.g. as the end condition -// in a for-loop. - -#define Wosize_val(val) (Wosize_hd (Hd_val (val))) -#define Wosize_op(op) (Wosize_val (op)) -#define Wosize_bp(bp) (Wosize_val (bp)) -#define Wosize_hp(hp) (Wosize_hd (Hd_hp (hp))) #define Whsize_wosize(sz) ((sz) + 1) #define Wosize_whsize(sz) ((sz) - 1) #define Wosize_bhsize(sz) ((sz) / sizeof (value) - 1) @@ -269,16 +259,54 @@ Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, #define Wsize_bsize(sz) ((sz) / sizeof (value)) #define Bhsize_wosize(sz) (Bsize_wsize (Whsize_wosize (sz))) #define Bhsize_bosize(sz) ((sz) + sizeof (header_t)) -#define Bosize_val(val) (Bsize_wsize (Wosize_val (val))) -#define Bosize_op(op) (Bosize_val (Val_op (op))) -#define Bosize_bp(bp) (Bosize_val (Val_bp (bp))) -#define Bosize_hd(hd) (Bsize_wsize (Wosize_hd (hd))) -#define Whsize_hp(hp) (Whsize_wosize (Wosize_hp (hp))) -#define Whsize_val(val) (Whsize_hp (Hp_val (val))) -#define Whsize_bp(bp) (Whsize_val (Val_bp (bp))) -#define Whsize_hd(hd) (Whsize_wosize (Wosize_hd (hd))) -#define Bhsize_hp(hp) (Bsize_wsize (Whsize_hp (hp))) -#define Bhsize_hd(hd) (Bsize_wsize (Whsize_hd (hd))) + +/* Note that Allocated_wosize_val and the other macros that read headers will not + be optimized by common subexpression elimination, because of the + atomic header loads. It is best to bind the results of such macros + to variables if they will be tested repeatedly, e.g. as the end condition + in a for-loop. +*/ + +/* flambda-backend: We rename the size macros to [Allocated_...] so that we're + forced to think about whether C code needs to updated for mixed blocks, which + have separate notions of scannable size and total size of an object, even for + scannable tags. We call an object's size (including possibly non-scannable + fields) its "allocated" size to document the fact that you shouldn't scan + fields on the basis of this size alone. + */ + +#define Allocated_wosize_val(val) (Allocated_wosize_hd (Hd_val (val))) +#define Allocated_wosize_op(op) (Allocated_wosize_val (op)) +#define Allocated_wosize_bp(bp) (Allocated_wosize_val (bp)) +#define Allocated_wosize_hp(hp) (Allocated_wosize_hd (Hd_hp (hp))) +#define Allocated_bosize_val(val) (Bsize_wsize (Allocated_wosize_val (val))) +#define Allocated_bosize_op(op) (Allocated_bosize_val (Val_op (op))) +#define Allocated_bosize_bp(bp) (Allocated_bosize_val (Val_bp (bp))) +#define Allocated_bosize_hd(hd) (Bsize_wsize (Allocated_wosize_hd (hd))) +#define Allocated_whsize_hp(hp) (Whsize_wosize (Allocated_wosize_hp (hp))) +#define Allocated_whsize_val(val) (Allocated_whsize_hp (Hp_val (val))) +#define Allocated_whsize_bp(bp) (Allocated_whsize_val (Val_bp (bp))) +#define Allocated_whsize_hd(hd) (Whsize_wosize (Allocated_wosize_hd (hd))) +#define Allocated_bhsize_hp(hp) (Bsize_wsize (Allocated_whsize_hp (hp))) +#define Allocated_bhsize_hd(hd) (Bsize_wsize (Allocated_whsize_hd (hd))) + +#ifndef Hide_upstream_size_macros +#define Wosize_hd(hd) Allocated_wosize_hd(hd) +#define Wosize_val(val) Allocated_wosize_val(val) +#define Wosize_op(op) Allocated_wosize_op(op) +#define Wosize_bp(bp) Allocated_wosize_bp(bp) +#define Wosize_hp(hp) Allocated_wosize_hp(hp) +#define Bosize_val(val) Allocated_bosize_val(val) +#define Bosize_op(op) Allocated_bosize_op(op) +#define Bosize_bp(bp) Allocated_bosize_bp(bp) +#define Bosize_hd(hd) Allocated_bosize_hd(hd) +#define Whsize_hp(hp) Allocated_whsize_hp(hp) +#define Whsize_val(val) Allocated_whsize_val(val) +#define Whsize_bp(bp) Allocated_whsize_bp(bp) +#define Whsize_hd(hd) Allocated_whsize_hd(hd) +#define Bhsize_hp(hp) Allocated_bhsize_hp(hp) +#define Bhsize_hd(hd) Allocated_bhsize_hd(hd) +#endif // Hide_upstream_size_macros #define Reserved_val(val) (Reserved_hd (Hd_val (val))) @@ -333,7 +361,7 @@ Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, with tag Closure_tag (see compact.c). */ #define Infix_tag 249 -#define Infix_offset_hd(hd) (Bosize_hd(hd)) +#define Infix_offset_hd(hd) (Allocated_bosize_hd(hd)) #define Infix_offset_val(v) Infix_offset_hd(Hd_val(v)) /* Another special case: objects */ diff --git a/ocaml/runtime4/caml/mlvalues.h b/ocaml/runtime4/caml/mlvalues.h index a66fb60fc8b..8556655f423 100644 --- a/ocaml/runtime4/caml/mlvalues.h +++ b/ocaml/runtime4/caml/mlvalues.h @@ -132,11 +132,11 @@ originally built for Spacetime profiling, hence the odd name. #define PROFINFO_MASK (Gen_profinfo_mask(PROFINFO_WIDTH)) #define NO_PROFINFO 0 #define Hd_no_profinfo(hd) ((hd) & ~(PROFINFO_MASK << PROFINFO_SHIFT)) -#define Wosize_hd(hd) ((mlsize_t) ((Hd_no_profinfo(hd)) >> 10)) +#define Allocated_wosize_hd(hd) ((mlsize_t) ((Hd_no_profinfo(hd)) >> 10)) #define Profinfo_hd(hd) (Gen_profinfo_hd(PROFINFO_WIDTH, hd)) #else #define NO_PROFINFO 0 -#define Wosize_hd(hd) ((mlsize_t) ((hd) >> 10)) +#define Allocated_wosize_hd(hd) ((mlsize_t) ((hd) >> 10)) #define Profinfo_hd(hd) NO_PROFINFO #endif /* WITH_PROFINFO */ @@ -184,7 +184,7 @@ Caml_inline mlsize_t Scannable_wosize_hd_native(header_t hd) { return Is_mixed_block_reserved(res) ? Mixed_block_scannable_wosize_reserved_native(res) - : Wosize_hd(hd); + : Allocated_wosize_hd(hd); } /* Bytecode versions of mixed block macros. @@ -195,8 +195,8 @@ Caml_inline mlsize_t Scannable_wosize_hd_native(header_t hd) { in the header bits. */ -#define Scannable_wosize_hd_byte(hd) (Wosize_hd (hd)) -#define Scannable_wosize_val_byte(val) (Wosize_hd (Hd_val (val))) +#define Scannable_wosize_hd_byte(hd) (Allocated_wosize_hd (hd)) +#define Scannable_wosize_val_byte(val) (Allocated_wosize_hd (Hd_val (val))) Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, mlsize_t size) { (void)res; @@ -244,10 +244,6 @@ Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, #define Max_wosize ((1 << 22) - 1) #endif /* ARCH_SIXTYFOUR */ -#define Wosize_val(val) (Wosize_hd (Hd_val (val))) -#define Wosize_op(op) (Wosize_val (op)) -#define Wosize_bp(bp) (Wosize_val (bp)) -#define Wosize_hp(hp) (Wosize_hd (Hd_hp (hp))) #define Whsize_wosize(sz) ((sz) + 1) #define Wosize_whsize(sz) ((sz) - 1) #define Wosize_bhsize(sz) ((sz) / sizeof (value) - 1) @@ -255,16 +251,47 @@ Caml_inline mlsize_t Scannable_wosize_reserved_byte(reserved_t res, #define Wsize_bsize(sz) ((sz) / sizeof (value)) #define Bhsize_wosize(sz) (Bsize_wsize (Whsize_wosize (sz))) #define Bhsize_bosize(sz) ((sz) + sizeof (header_t)) -#define Bosize_val(val) (Bsize_wsize (Wosize_val (val))) -#define Bosize_op(op) (Bosize_val (Val_op (op))) -#define Bosize_bp(bp) (Bosize_val (Val_bp (bp))) -#define Bosize_hd(hd) (Bsize_wsize (Wosize_hd (hd))) -#define Whsize_hp(hp) (Whsize_wosize (Wosize_hp (hp))) -#define Whsize_val(val) (Whsize_hp (Hp_val (val))) -#define Whsize_bp(bp) (Whsize_val (Val_bp (bp))) -#define Whsize_hd(hd) (Whsize_wosize (Wosize_hd (hd))) -#define Bhsize_hp(hp) (Bsize_wsize (Whsize_hp (hp))) -#define Bhsize_hd(hd) (Bsize_wsize (Whsize_hd (hd))) + +/* flambda-backend: We rename the size macros to [Allocated_...] so that we're + forced to think about whether C code needs to updated for mixed blocks, which + have separate notions of scannable size and total size of an object, even for + scannable tags. We call an object's size (including possibly non-scannable + fields) its "allocated" size to document the fact that you shouldn't scan + fields on the basis of this size alone. +*/ + +#define Allocated_wosize_val(val) (Allocated_wosize_hd (Hd_val (val))) +#define Allocated_wosize_op(op) (Allocated_wosize_val (op)) +#define Allocated_wosize_bp(bp) (Allocated_wosize_val (bp)) +#define Allocated_wosize_hp(hp) (Allocated_wosize_hd (Hd_hp (hp))) +#define Allocated_bosize_val(val) (Bsize_wsize (Allocated_wosize_val (val))) +#define Allocated_bosize_op(op) (Allocated_bosize_val (Val_op (op))) +#define Allocated_bosize_bp(bp) (Allocated_bosize_val (Val_bp (bp))) +#define Allocated_bosize_hd(hd) (Bsize_wsize (Allocated_wosize_hd (hd))) +#define Allocated_whsize_hp(hp) (Whsize_wosize (Allocated_wosize_hp (hp))) +#define Allocated_whsize_val(val) (Allocated_whsize_hp (Hp_val (val))) +#define Allocated_whsize_bp(bp) (Allocated_whsize_val (Val_bp (bp))) +#define Allocated_whsize_hd(hd) (Whsize_wosize (Allocated_wosize_hd (hd))) +#define Allocated_bhsize_hp(hp) (Bsize_wsize (Allocated_whsize_hp (hp))) +#define Allocated_bhsize_hd(hd) (Bsize_wsize (Allocated_whsize_hd (hd))) + +#ifndef Hide_upstream_size_macros +#define Wosize_hd(hd) Allocated_wosize_hd(hd) +#define Wosize_val(val) Allocated_wosize_val(val) +#define Wosize_op(op) Allocated_wosize_op(op) +#define Wosize_bp(bp) Allocated_wosize_bp(bp) +#define Wosize_hp(hp) Allocated_wosize_hp(hp) +#define Bosize_val(val) Allocated_bosize_val(val) +#define Bosize_op(op) Allocated_bosize_op(op) +#define Bosize_bp(bp) Allocated_bosize_bp(bp) +#define Bosize_hd(hd) Allocated_bosize_hd(hd) +#define Whsize_hp(hp) Allocated_whsize_hp(hp) +#define Whsize_val(val) Allocated_whsize_val(val) +#define Whsize_bp(bp) Allocated_whsize_bp(bp) +#define Whsize_hd(hd) Allocated_whsize_hd(hd) +#define Bhsize_hp(hp) Allocated_bhsize_hp(hp) +#define Bhsize_hd(hd) Allocated_bhsize_hd(hd) +#endif // Hide_upstream_size_macros #define Scannable_wosize_hp(hp) (Scannable_wosize_hd (Hd_hp (hp))) @@ -322,7 +349,7 @@ typedef opcode_t * code_t; with tag Closure_tag (see compact.c). */ #define Infix_tag 249 -#define Infix_offset_hd(hd) (Bosize_hd(hd)) +#define Infix_offset_hd(hd) (Allocated_bosize_hd(hd)) #define Infix_offset_val(v) Infix_offset_hd(Hd_val(v)) /* Another special case: objects */