diff --git a/runtime/caml/address_class.h b/runtime/caml/address_class.h index 9f61008267..08403e2dda 100644 --- a/runtime/caml/address_class.h +++ b/runtime/caml/address_class.h @@ -15,44 +15,25 @@ /* Classification of addresses for GC and runtime purposes. */ -/* The current runtime supports two different configurations that - correspond to two different value models, depending on whether - "naked pointers", that do not point to a well-formed OCaml block, - are allowed (considered valid values). +/* Multicore runtime supports only the "no naked pointers" mode where any + out-of-heap pointers are not observable by the GC. The out-of-heap pointers + are either: - In "classic mode", naked pointers are allowed, and the - implementation uses a page table. A valid value is then either: - - a tagged integer (Is_long or !Is_block from mlvalues.h) - - a pointer to the minor heap (Is_young) - - a pointer to the major heap (Is_in_heap) - - a pointer to a constant block statically-allocated by OCaml code - or the OCaml runtime (Is_in_static_data) - - a "foreign" pointer, which is none of the above; the destination - of those pointers may be a well-formed OCaml blocks, but it may - also be a naked pointer. + - wrapped in Abstract_tag or Custom_tag objects, or + - have a valid header with colour `NOT_MARKABLE`, or + - made to look like immediate values by tagging the least significant bit so + that the GC does not follow it. This strategy has the downside that + out-of-heap pointers may not point to odd addresses. - The macros and functions below give access to a global page table - to classify addresses to be able to implement Is_in_heap, - In_static_data (or their disjunction Is_in_value_area) and thus - detect values which may be naked pointers. The runtime - conservatively assumes that all foreign pointers may be naked - pointers, and uses the page table to not dereference/follow them. - - In "no naked pointers" mode (when NO_NAKED_POINTERS is defined), - naked pointers are illegal, so pointers that are values can always - be assumed to point to well-formed blocks. - - To support an implementation without a global page table, runtime - code should not rely on Is_in_heap and Is_in_static_data. This - corresponds to a simpler model where a valid value is either: + A valid value is either: - a tagged integer (Is_long) - - a pointer to the minor heap (Is_young) - - a pointer to a well-formed block outside the minor heap - (it may be in the major heap, or static, or a foreign pointer, - without a check to distinguish the various cases). + - a pointer to the minor heap + - a pointer to a well-formed block outside the minor heap. It may be in the + major heap, or static data allocated by the OCaml code or the OCaml + runtime, or a foreign pointer. - (To create a well-formed block outside the heap that the GC will - not scan, one can use the Caml_out_of_heap_header from mlvalues.h.) + To create a well-formed block outside the heap that the GC will not scan, + one can use the Caml_out_of_heap_header from mlvalues.h. */ #ifndef CAML_ADDRESS_CLASS_H @@ -62,60 +43,8 @@ #include "misc.h" #include "mlvalues.h" -/* Use the following macros to test an address for the different classes - it might belong to. */ - -#define Is_in_heap(a) (Classify_addr(a) & In_heap) - -#ifdef NO_NAKED_POINTERS - +/* These definitions are retained for backwards compatibility */ #define Is_in_heap_or_young(a) 1 #define Is_in_value_area(a) 1 -#else - -#define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young)) - -#define Is_in_value_area(a) \ - (Classify_addr(a) & (In_heap | In_young | In_static_data)) - -#define Is_in_static_data(a) (Classify_addr(a) & In_static_data) - -#endif - -/***********************************************************************/ -/* The rest of this file is private and may change without notice. */ - -#define Not_in_heap 0 -#define In_heap 1 -#define In_young 2 -#define In_static_data 4 - -#ifdef ARCH_SIXTYFOUR - -/* 64 bits: Represent page table as a sparse hash table */ -int caml_page_table_lookup(void * addr); -#define Classify_addr(a) (caml_page_table_lookup((void *)(a))) - -#else - -/* 32 bits: Represent page table as a 2-level array */ -#define Pagetable2_log 11 -#define Pagetable2_size (1 << Pagetable2_log) -#define Pagetable1_log (Page_log + Pagetable2_log) -#define Pagetable1_size (1 << (32 - Pagetable1_log)) -CAMLextern unsigned char * caml_page_table[Pagetable1_size]; - -#define Pagetable_index1(a) (((uintnat)(a)) >> Pagetable1_log) -#define Pagetable_index2(a) \ - ((((uintnat)(a)) >> Page_log) & (Pagetable2_size - 1)) -#define Classify_addr(a) \ - caml_page_table[Pagetable_index1(a)][Pagetable_index2(a)] - -#endif - -int caml_page_table_add(int kind, void * start, void * end); -int caml_page_table_remove(int kind, void * start, void * end); -int caml_page_table_initialize(mlsize_t bytesize); - #endif /* CAML_ADDRESS_CLASS_H */ diff --git a/runtime/caml/mlvalues.h b/runtime/caml/mlvalues.h index 4412c30377..640f689670 100644 --- a/runtime/caml/mlvalues.h +++ b/runtime/caml/mlvalues.h @@ -443,6 +443,14 @@ Caml_inline void caml_read_field(value x, intnat i, value* ret) { #define Long_field(x, i) Long_val(Field(x, i)) #define Bool_field(x, i) Bool_val(Field(x, i)) +/* Header for out-of-heap blocks. */ + +#define Caml_out_of_heap_header(wosize, tag) \ + (/*CAMLassert ((wosize) <= Max_wosize),*/ \ + ((header_t) (((header_t) (wosize) << 10) \ + + (3 << 8) /* matches [NOT_MARKABLE]. See [shared_heap.h]. */ \ + + (tag_t) (tag))) \ + ) #ifdef __cplusplus }