Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/byterun/compact.c b/byterun/compact.c
- index bf80301..fa83e2d 100644
- --- a/byterun/compact.c
- +++ b/byterun/compact.c
- @@ -58,7 +58,7 @@ static void invert_pointer_at (word *p)
- /* Use Ecolor (q) == 0 instead of Is_block (q) because q could be an
- inverted pointer for an infix header (with Ecolor == 2). */
- - if (Ecolor (q) == 0 && (Classify_addr (q) & In_heap)){
- + if (Ecolor (q) == 0 && Is_in_heap(q)){
- switch (Ecolor (Hd_val (q))){
- case 0:
- case 3: /* Pointer or header: insert in inverted list. */
- @@ -440,10 +440,14 @@ void caml_compact_heap (void)
- recognized as free by the recompaction. */
- caml_make_free_blocks ((value *) chunk,
- Wsize_bsize (Chunk_size (chunk)), 0, Caml_blue);
- +
- +#ifndef CAML_CONTIGUOUS_HEAP_LOG
- if (caml_page_table_add (In_heap, chunk, chunk + Chunk_size (chunk)) != 0){
- caml_free_for_heap (chunk);
- return;
- }
- +#endif
- +
- Chunk_next (chunk) = caml_heap_start;
- caml_heap_start = chunk;
- ++ caml_stat_heap_chunks;
- diff --git a/byterun/config.h b/byterun/config.h
- index 24f4e59..ef66d82 100644
- --- a/byterun/config.h
- +++ b/byterun/config.h
- @@ -17,6 +17,7 @@
- /* <include ../config/m.h> */
- /* <include ../config/s.h> */
- /* <private> */
- +#define CAML_CONTIGUOUS_HEAP_LOG 40
- #include "../config/m.h"
- #include "../config/s.h"
- /* </private> */
- @@ -143,12 +144,14 @@ typedef struct { uint32 l, h; } uint64, int64;
- /* Default size increment when growing the heap. (words)
- Must be a multiple of [Page_size / sizeof (value)].
- + This should be a power of two minus the size of a page to avoid
- + wasting virtual address space.
- (Approx 512 Kb for a 32-bit platform, 1 Mb for a 64-bit platform.) */
- -#define Heap_chunk_def (31 * Page_size)
- +#define Heap_chunk_def (255 * Page_size / sizeof (value))
- /* Default initial size of the major heap (words);
- same constraints as for Heap_chunk_def. */
- -#define Init_heap_def (31 * Page_size)
- +#define Init_heap_def (255 * Page_size / sizeof(value))
- /* Default speed setting for the major GC. The heap will grow until
- diff --git a/byterun/gc_ctrl.c b/byterun/gc_ctrl.c
- index 07cfc26..9c5ac63 100644
- --- a/byterun/gc_ctrl.c
- +++ b/byterun/gc_ctrl.c
- @@ -481,6 +481,10 @@ void caml_init_gc (uintnat minor_size, uintnat major_size,
- {
- uintnat major_heap_size = Bsize_wsize (norm_heapincr (major_size));
- +#ifdef CAML_CONTIGUOUS_HEAP_LOG
- + if (caml_block_init())
- + caml_fatal_error ("OCaml runtime error: cannot initialize memoy manager\n");
- +#endif
- if (caml_page_table_initialize(Bsize_wsize(minor_size) + major_heap_size)){
- caml_fatal_error ("OCaml runtime error: cannot initialize page table\n");
- }
- diff --git a/byterun/major_gc.c b/byterun/major_gc.c
- index 14a248f..71a48e6 100644
- --- a/byterun/major_gc.c
- +++ b/byterun/major_gc.c
- @@ -487,11 +487,13 @@ void caml_init_major_heap (asize_t heap_size)
- Chunk_next (caml_heap_start) = NULL;
- caml_stat_heap_chunks = 1;
- +#ifndef CAML_CONTIGUOUS_HEAP_LOG
- if (caml_page_table_add(In_heap, caml_heap_start,
- caml_heap_start + caml_stat_heap_size) != 0) {
- caml_fatal_error ("Fatal error: not enough memory "
- "for the initial page table.\n");
- }
- +#endif
- caml_fl_init_merge ();
- caml_make_free_blocks ((value *) caml_heap_start,
- diff --git a/byterun/memory.c b/byterun/memory.c
- index e18bde4..d199053 100644
- --- a/byterun/memory.c
- +++ b/byterun/memory.c
- @@ -216,6 +216,195 @@ int caml_page_table_remove(int kind, void * start, void * end)
- return 0;
- }
- +#ifdef CAML_CONTIGUOUS_HEAP_LOG
- +
- +#include<sys/mman.h>
- +
- +char* caml_contiguous_heap = NULL;
- +
- +struct block_descr {
- + struct block_descr *left, *right;
- + unsigned sizes;
- +};
- +static struct block_descr *root_descr = NULL;
- +
- +int caml_block_init()
- +{
- + Assert(CAML_CONTIGUOUS_HEAP_LOG-Page_log < 32);
- +
- + root_descr = (struct block_descr*)malloc(sizeof(struct block_descr));
- + if(root_descr == NULL)
- + return -1;
- + root_descr -> left = NULL;
- + root_descr -> right = NULL;
- + root_descr -> sizes = 1U<<(CAML_CONTIGUOUS_HEAP_LOG-Page_log);
- +
- + caml_contiguous_heap =
- + (char*)mmap(NULL, 1LL << CAML_CONTIGUOUS_HEAP_LOG, PROT_NONE,
- + MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
- + if(caml_contiguous_heap == NULL) {
- + free(root_descr);
- + root_descr = NULL;
- + return -1;
- + }
- +
- + return 0;
- +}
- +
- +static struct block_descr*
- + block_descrs[CAML_CONTIGUOUS_HEAP_LOG - Page_log + 1];
- +
- +char* caml_block_alloc(size_t size)
- +{
- + int log_alloc, log_block, log_cur;
- + struct block_descr **bd_pt;
- + char* block;
- +
- + Assert(caml_contiguous_heap != NULL);
- +
- + if(size > (1ULL << CAML_CONTIGUOUS_HEAP_LOG))
- + return NULL;
- +
- + Assert((size & (Page_size-1)) == 0);
- +
- + for(log_alloc = Page_log; (1ULL << log_alloc) < size; log_alloc++);
- +
- + for(log_block = log_alloc;
- + log_block <= CAML_CONTIGUOUS_HEAP_LOG &&
- + ((1U << (log_block-Page_log)) & root_descr->sizes) == 0;
- + log_block++);
- + if(log_block > CAML_CONTIGUOUS_HEAP_LOG)
- + return NULL;
- +
- + block_descrs[0] = root_descr;
- + bd_pt = block_descrs;
- + log_cur = CAML_CONTIGUOUS_HEAP_LOG;
- + block = caml_contiguous_heap;
- + while(log_cur != log_block) {
- + Assert((*bd_pt)->left != NULL);
- + Assert((*bd_pt)->right != NULL);
- + if(((*bd_pt)->left->sizes & (1U << (log_block-Page_log))) != 0)
- + *(bd_pt+1) = (*bd_pt)->left;
- + else {
- + Assert((*bd_pt)->right != NULL);
- + Assert(((*bd_pt)->right->sizes & (1U << (log_block-Page_log))) != 0);
- + *(bd_pt+1) = (*bd_pt)->right;
- + block += (1ULL << (log_cur-1));
- + }
- + bd_pt++;
- + log_cur--;
- + }
- +
- + Assert((*bd_pt)->sizes == (1U << (log_block-Page_log)));
- + Assert((*bd_pt)->left == NULL);
- + Assert((*bd_pt)->right == NULL);
- +
- + if((char*)mmap(block, size, PROT_READ | PROT_WRITE,
- + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != block)
- + return NULL;
- +
- + while(log_cur > log_alloc) {
- + (*bd_pt)->left = (struct block_descr*)malloc(sizeof(struct block_descr));
- + (*bd_pt)->right = (struct block_descr*)malloc(sizeof(struct block_descr));
- + if((*bd_pt)->left == NULL || (*bd_pt)->right == NULL) {
- + while(log_cur <= log_block) {
- + free((*bd_pt)->left);
- + (*bd_pt)->left = NULL;
- + free((*bd_pt)->right);
- + (*bd_pt)->right = NULL;
- +
- + log_cur++;
- + bd_pt--;
- + }
- + if((char*)mmap(block, size, PROT_NONE,
- + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_NORESERVE,
- + -1, 0) != block)
- + caml_fatal_error("Fatal error : could not deallocate memory\n");
- + return NULL;
- + }
- +
- + (*bd_pt)->right->left = NULL;
- + (*bd_pt)->right->right = NULL;
- + (*bd_pt)->right->sizes = 1U<<(log_cur-1-Page_log);
- +
- + *(bd_pt+1) = (*bd_pt)->left;
- + bd_pt++;
- + log_cur--;
- + }
- +
- + (*bd_pt)->left = NULL;
- + (*bd_pt)->right = NULL;
- + (*bd_pt)->sizes = 0;
- +
- + while(bd_pt > block_descrs) {
- + bd_pt--;
- + (*bd_pt)->sizes = (*bd_pt)->left->sizes | (*bd_pt)->right->sizes;
- + }
- +
- + return block;
- +}
- +
- +void caml_block_free(char *block, asize_t size)
- +{
- + asize_t offset;
- + int log_alloc, log_cur;
- + struct block_descr **bd_pt;
- +
- + Assert(caml_contiguous_heap != NULL);
- +
- + offset = block-caml_contiguous_heap;
- + Assert((size & ((1ULL<<Page_log)-1)) == 0);
- + Assert((offset & ((1ULL<<Page_log)-1)) == 0);
- + Assert(offset < (1ULL<<CAML_CONTIGUOUS_HEAP_LOG));
- +
- + for(log_alloc = Page_log; (1ULL << log_alloc) < size; log_alloc++);
- +
- + if((char*)mmap(block, size, PROT_NONE,
- + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_NORESERVE,
- + -1, 0) != block)
- + caml_fatal_error("Fatal error : could not deallocate memory\n");
- +
- + block_descrs[0] = root_descr;
- + bd_pt = block_descrs;
- + log_cur = CAML_CONTIGUOUS_HEAP_LOG;
- + while(log_cur > log_alloc) {
- + Assert((*bd_pt)->left != NULL);
- + Assert((*bd_pt)->right != NULL);
- + if((offset & (1ULL<<(log_cur-1))) != 0)
- + *(bd_pt+1) = (*bd_pt)->right;
- + else
- + *(bd_pt+1) = (*bd_pt)->left;
- + bd_pt++;
- + log_cur--;
- + }
- +
- + Assert((*bd_pt)->left == NULL);
- + Assert((*bd_pt)->right == NULL);
- + Assert((*bd_pt)->sizes == 0);
- +
- + (*bd_pt)->sizes = 1U<<(log_cur-Page_log);
- + while(bd_pt > block_descrs) {
- + bd_pt--;
- + log_cur++;
- + if((*bd_pt)->left->sizes == (1U<<(log_cur-1-Page_log)) &&
- + (*bd_pt)->right->sizes == (1U<<(log_cur-1-Page_log))) {
- + free((*bd_pt)->left);
- + (*bd_pt)->left = NULL;
- + free((*bd_pt)->right);
- + (*bd_pt)->right = NULL;
- + (*bd_pt)->sizes = 1U<<(log_cur-Page_log);
- + } else {
- + bd_pt++;
- + while(bd_pt > block_descrs) {
- + bd_pt--;
- + (*bd_pt)->sizes = (*bd_pt)->left->sizes | (*bd_pt)->right->sizes;
- + }
- + }
- + }
- +}
- +
- +#endif
- +
- /* Allocate a block of the requested size, to be passed to
- [caml_add_to_heap] later.
- [request] must be a multiple of [Page_size].
- @@ -228,10 +417,18 @@ char *caml_alloc_for_heap (asize_t request)
- char *mem;
- void *block;
- Assert (request % Page_size == 0);
- +#ifdef CAML_CONTIGUOUS_HEAP_LOG
- + /* TODO : We allocate a full new page for the chunk header.
- + That would be good to avoid this waste. */
- + block = caml_block_alloc(request+Page_size);
- + if (block == NULL) return NULL;
- + mem = block + Page_size;
- +#else
- mem = caml_aligned_malloc (request + sizeof (heap_chunk_head),
- sizeof (heap_chunk_head), &block);
- if (mem == NULL) return NULL;
- mem += sizeof (heap_chunk_head);
- +#endif
- Chunk_size (mem) = request;
- Chunk_block (mem) = block;
- return mem;
- @@ -242,7 +439,11 @@ char *caml_alloc_for_heap (asize_t request)
- */
- void caml_free_for_heap (char *mem)
- {
- +#ifdef CAML_CONTIGUOUS_HEAP_LOG
- + caml_block_free(Chunk_block (mem), Chunk_size(mem)+Page_size);
- +#else
- free (Chunk_block (mem));
- +#endif
- }
- /* Take a chunk of memory as argument, which must be the result of a
- @@ -266,9 +467,11 @@ int caml_add_to_heap (char *m)
- caml_gc_message (0x04, "Growing heap to %luk bytes\n",
- (caml_stat_heap_size + Chunk_size (m)) / 1024);
- +#ifndef CAML_CONTIGUOUS_HEAP_LOG
- /* Register block in page table */
- if (caml_page_table_add(In_heap, m, m + Chunk_size(m)) != 0)
- return -1;
- +#endif
- /* Chain this heap chunk. */
- {
- @@ -381,8 +584,10 @@ void caml_shrink_heap (char *chunk)
- while (*cp != chunk) cp = &(Chunk_next (*cp));
- *cp = Chunk_next (chunk);
- +#ifndef CAML_CONTIGUOUS_HEAP_LOG
- /* Remove the pages of [chunk] from the page table. */
- caml_page_table_remove(In_heap, chunk, chunk + Chunk_size (chunk));
- +#endif
- /* Free the [malloc] block that contains [chunk]. */
- caml_free_for_heap (chunk);
- diff --git a/byterun/memory.h b/byterun/memory.h
- index 0761070..eab0aec 100644
- --- a/byterun/memory.h
- +++ b/byterun/memory.h
- @@ -53,8 +53,12 @@ color_t caml_allocation_color (void *hp);
- /* <private> */
- #define Not_in_heap 0
- +
- +#ifndef CAML_CONTIGUOUS_HEAP_LOG
- #define In_heap 1
- #define In_young 2
- +#endif
- +
- #define In_static_data 4
- #define In_code_area 8
- @@ -81,15 +85,37 @@ CAMLextern unsigned char * caml_page_table[Pagetable1_size];
- #endif
- +#ifdef CAML_CONTIGUOUS_HEAP_LOG
- +
- +extern char* caml_contiguous_heap;
- +#define Is_in_heap(a) \
- + ((uintnat)((char*)(a) - caml_contiguous_heap) < \
- + (1ULL<<CAML_CONTIGUOUS_HEAP_LOG))
- +#define Is_in_heap_or_young(a) \
- + (Is_in_heap(a) || \
- + ((char*)(a) >= caml_young_start && (char*)(a) < caml_young_end))
- +#define Is_in_value_area(a) \
- + (Is_in_heap_or_young(a) || (Classify_addr(a) & In_static_data))
- +
- +#else
- +
- #define Is_in_value_area(a) \
- (Classify_addr(a) & (In_heap | In_young | In_static_data))
- #define Is_in_heap(a) (Classify_addr(a) & In_heap)
- #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young))
- +#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);
- +#ifdef CAML_CONTIGUOUS_HEAP_LOG
- +
- +int caml_block_init();
- +
- +#endif
- +
- #ifdef DEBUG
- #define DEBUG_clear(result, wosize) do{ \
- uintnat caml__DEBUG_i; \
- diff --git a/byterun/minor_gc.c b/byterun/minor_gc.c
- index 3e0dd4e..dcc8088 100644
- --- a/byterun/minor_gc.c
- +++ b/byterun/minor_gc.c
- @@ -83,6 +83,8 @@ void caml_set_minor_heap_size (asize_t size)
- Assert (caml_young_ptr == caml_young_end);
- new_heap = caml_aligned_malloc(size, 0, &new_heap_base);
- if (new_heap == NULL) caml_raise_out_of_memory();
- +
- +#ifndef CAML_CONTIGUOUS_HEAP_LOG
- if (caml_page_table_add(In_young, new_heap, new_heap + size) != 0)
- caml_raise_out_of_memory();
- @@ -90,6 +92,8 @@ void caml_set_minor_heap_size (asize_t size)
- caml_page_table_remove(In_young, caml_young_start, caml_young_end);
- free (caml_young_base);
- }
- +#endif
- +
- caml_young_base = new_heap_base;
- caml_young_start = new_heap;
- caml_young_end = new_heap + size;
Add Comment
Please, Sign In to add comment