|
6 | 6 | extern "C" {
|
7 | 7 | #endif
|
8 | 8 |
|
9 |
| -jl_mutex_t pagealloc_lock; |
10 | 9 | // Protect all access to `finalizer_list`, `finalizer_list_marked` and
|
11 | 10 | // `to_finalize`.
|
12 |
| -jl_mutex_t finalizers_lock; |
| 11 | +static jl_mutex_t finalizers_lock; |
13 | 12 |
|
14 | 13 | /**
|
15 | 14 | * Note about GC synchronization:
|
@@ -273,8 +272,6 @@ static size_t max_collect_interval = 500000000UL;
|
273 | 272 | #define NS2MS(t) ((double)(t/1000)/1000)
|
274 | 273 | static int64_t live_bytes = 0;
|
275 | 274 | static int64_t promoted_bytes = 0;
|
276 |
| -static size_t current_pg_count = 0; |
277 |
| -static size_t max_pg_count = 0; |
278 | 275 |
|
279 | 276 | JL_DLLEXPORT size_t jl_gc_total_freed_bytes=0;
|
280 | 277 | #ifdef GC_FINAL_STATS
|
@@ -424,136 +421,6 @@ inline void gc_setmark_buf(void *o, int mark_mode)
|
424 | 421 | gc_setmark_big(buf, mark_mode);
|
425 | 422 | }
|
426 | 423 |
|
427 |
| -static NOINLINE void *malloc_page(void) |
428 |
| -{ |
429 |
| - void *ptr = (void*)0; |
430 |
| - int i; |
431 |
| - region_t *region; |
432 |
| - int region_i = 0; |
433 |
| - JL_LOCK_NOGC(&pagealloc_lock); |
434 |
| - while(region_i < REGION_COUNT) { |
435 |
| - region = ®ions[region_i]; |
436 |
| - if (region->pages == NULL) { |
437 |
| - const size_t pages_sz = sizeof(jl_gc_page_t) * REGION_PG_COUNT; |
438 |
| - const size_t freemap_sz = sizeof(uint32_t) * REGION_PG_COUNT / 32; |
439 |
| - const size_t meta_sz = sizeof(jl_gc_pagemeta_t) * REGION_PG_COUNT; |
440 |
| - size_t alloc_size = pages_sz + freemap_sz + meta_sz; |
441 |
| -#ifdef _OS_WINDOWS_ |
442 |
| - char *mem = (char*)VirtualAlloc(NULL, alloc_size + GC_PAGE_SZ, |
443 |
| - MEM_RESERVE, PAGE_READWRITE); |
444 |
| -#else |
445 |
| - if (GC_PAGE_SZ > jl_page_size) |
446 |
| - alloc_size += GC_PAGE_SZ; |
447 |
| - char *mem = (char*)mmap(0, alloc_size, PROT_READ | PROT_WRITE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
448 |
| - mem = mem == MAP_FAILED ? NULL : mem; |
449 |
| -#endif |
450 |
| - if (mem == NULL) { |
451 |
| - jl_printf(JL_STDERR, "could not allocate pools\n"); |
452 |
| - gc_debug_critical_error(); |
453 |
| - abort(); |
454 |
| - } |
455 |
| - if (GC_PAGE_SZ > jl_page_size) { |
456 |
| - // round data pointer up to the nearest gc_page_data-aligned |
457 |
| - // boundary if mmap didn't already do so. |
458 |
| - mem = (char*)gc_page_data(mem + GC_PAGE_SZ - 1); |
459 |
| - } |
460 |
| - region->pages = (jl_gc_page_t*)mem; |
461 |
| - region->freemap = (uint32_t*)(mem + pages_sz); |
462 |
| - region->meta = (jl_gc_pagemeta_t*)(mem + pages_sz +freemap_sz); |
463 |
| - region->lb = 0; |
464 |
| - region->ub = 0; |
465 |
| - region->pg_cnt = REGION_PG_COUNT; |
466 |
| -#ifdef _OS_WINDOWS_ |
467 |
| - VirtualAlloc(region->freemap, region->pg_cnt / 8, |
468 |
| - MEM_COMMIT, PAGE_READWRITE); |
469 |
| - VirtualAlloc(region->meta, region->pg_cnt * sizeof(jl_gc_pagemeta_t), |
470 |
| - MEM_COMMIT, PAGE_READWRITE); |
471 |
| -#endif |
472 |
| - memset(region->freemap, 0xff, region->pg_cnt / 8); |
473 |
| - } |
474 |
| - for (i = region->lb; i < region->pg_cnt / 32; i++) { |
475 |
| - if (region->freemap[i]) |
476 |
| - break; |
477 |
| - } |
478 |
| - if (i == region->pg_cnt / 32) { |
479 |
| - // region full |
480 |
| - region_i++; |
481 |
| - continue; |
482 |
| - } |
483 |
| - break; |
484 |
| - } |
485 |
| - if (region_i >= REGION_COUNT) { |
486 |
| - jl_printf(JL_STDERR, "increase REGION_COUNT or allocate less memory\n"); |
487 |
| - gc_debug_critical_error(); |
488 |
| - abort(); |
489 |
| - } |
490 |
| - if (region->lb < i) |
491 |
| - region->lb = i; |
492 |
| - if (region->ub < i) |
493 |
| - region->ub = i; |
494 |
| - |
495 |
| -#if defined(_COMPILER_MINGW_) |
496 |
| - int j = __builtin_ffs(region->freemap[i]) - 1; |
497 |
| -#elif defined(_COMPILER_MICROSOFT_) |
498 |
| - unsigned long j; |
499 |
| - _BitScanForward(&j, region->freemap[i]); |
500 |
| -#else |
501 |
| - int j = ffs(region->freemap[i]) - 1; |
502 |
| -#endif |
503 |
| - |
504 |
| - region->freemap[i] &= ~(uint32_t)(1 << j); |
505 |
| - ptr = region->pages[i*32 + j].data; |
506 |
| -#ifdef _OS_WINDOWS_ |
507 |
| - VirtualAlloc(ptr, GC_PAGE_SZ, MEM_COMMIT, PAGE_READWRITE); |
508 |
| -#endif |
509 |
| - current_pg_count++; |
510 |
| - max_pg_count = max_pg_count < current_pg_count ? current_pg_count : max_pg_count; |
511 |
| - JL_UNLOCK_NOGC(&pagealloc_lock); |
512 |
| - return ptr; |
513 |
| -} |
514 |
| - |
515 |
| -static void free_page(void *p) |
516 |
| -{ |
517 |
| - int pg_idx = -1; |
518 |
| - int i; |
519 |
| - region_t *region = regions; |
520 |
| - for (i = 0; i < REGION_COUNT && regions[i].pages != NULL; i++) { |
521 |
| - region = ®ions[i]; |
522 |
| - pg_idx = page_index(region, p); |
523 |
| - if (pg_idx >= 0 && pg_idx < region->pg_cnt) { |
524 |
| - break; |
525 |
| - } |
526 |
| - } |
527 |
| - assert(i < REGION_COUNT && region->pages != NULL); |
528 |
| - uint32_t msk = (uint32_t)(1 << (pg_idx % 32)); |
529 |
| - assert(!(region->freemap[pg_idx/32] & msk)); |
530 |
| - region->freemap[pg_idx/32] ^= msk; |
531 |
| - free(region->meta[pg_idx].ages); |
532 |
| - // tell the OS we don't need these pages right now |
533 |
| - size_t decommit_size = GC_PAGE_SZ; |
534 |
| - if (GC_PAGE_SZ < jl_page_size) { |
535 |
| - // ensure so we don't release more memory than intended |
536 |
| - size_t n_pages = (GC_PAGE_SZ + jl_page_size - 1) / GC_PAGE_SZ; |
537 |
| - decommit_size = jl_page_size; |
538 |
| - p = (void*)((uintptr_t)region->pages[pg_idx].data & ~(jl_page_size - 1)); // round down to the nearest page |
539 |
| - pg_idx = page_index(region, p); |
540 |
| - if (pg_idx + n_pages > region->pg_cnt) goto no_decommit; |
541 |
| - for (; n_pages--; pg_idx++) { |
542 |
| - msk = (uint32_t)(1 << ((pg_idx % 32))); |
543 |
| - if (!(region->freemap[pg_idx/32] & msk)) goto no_decommit; |
544 |
| - } |
545 |
| - } |
546 |
| -#ifdef _OS_WINDOWS_ |
547 |
| - VirtualFree(p, decommit_size, MEM_DECOMMIT); |
548 |
| -#else |
549 |
| - madvise(p, decommit_size, MADV_DONTNEED); |
550 |
| -#endif |
551 |
| -no_decommit: |
552 |
| - if (region->lb > pg_idx / 32) |
553 |
| - region->lb = pg_idx / 32; |
554 |
| - current_pg_count--; |
555 |
| -} |
556 |
| - |
557 | 424 | #define should_collect() (__unlikely(gc_num.allocd>0))
|
558 | 425 |
|
559 | 426 | static inline int maybe_collect(void)
|
@@ -795,7 +662,7 @@ static inline gcval_t *reset_page(pool_t *p, jl_gc_pagemeta_t *pg, gcval_t *fl)
|
795 | 662 |
|
796 | 663 | static NOINLINE void add_page(pool_t *p)
|
797 | 664 | {
|
798 |
| - char *data = (char*)malloc_page(); |
| 665 | + char *data = (char*)jl_gc_alloc_page(); |
799 | 666 | if (data == NULL)
|
800 | 667 | jl_throw(jl_memory_exception);
|
801 | 668 | jl_gc_pagemeta_t *pg = page_metadata(data + GC_PAGE_OFFSET);
|
@@ -1070,7 +937,7 @@ static gcval_t **sweep_page(pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl, int
|
1070 | 937 | #ifdef MEMDEBUG
|
1071 | 938 | memset(pg->data, 0xbb, GC_PAGE_SZ);
|
1072 | 939 | #endif
|
1073 |
| - free_page(data); |
| 940 | + jl_gc_free_page(data); |
1074 | 941 | #ifdef MEMDEBUG
|
1075 | 942 | memset(pg, 0xbb, sizeof(jl_gc_pagemeta_t));
|
1076 | 943 | #endif
|
@@ -2109,6 +1976,7 @@ JL_DLLEXPORT jl_value_t *jl_gc_alloc_3w(void)
|
2109 | 1976 |
|
2110 | 1977 | #ifdef GC_FINAL_STATS
|
2111 | 1978 | static double process_t0;
|
| 1979 | +size_t max_pg_count = 0; |
2112 | 1980 | #include <malloc.h>
|
2113 | 1981 | void jl_print_gc_stats(JL_STREAM *s)
|
2114 | 1982 | {
|
|
0 commit comments