Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Allocated_* macros for accessing the size of an object #2653

Merged
merged 1 commit into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 53 additions & 25 deletions ocaml/runtime/caml/mlvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -252,33 +252,61 @@ 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)
#define Bsize_wsize(sz) ((sz) * sizeof (value))
#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)))

Expand Down Expand Up @@ -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 */
Expand Down
67 changes: 47 additions & 20 deletions ocaml/runtime4/caml/mlvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -244,27 +244,54 @@ 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)
#define Bsize_wsize(sz) ((sz) * sizeof (value))
#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)))

Expand Down Expand Up @@ -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 */
Expand Down
Loading