/* * GC initialization. */ extern bool GC_init(void) { if (gc_inited) return true; // Already initialised. gc_debug("initializing"); // Check that we are in a 64-bit environment. if (sizeof(void *) != sizeof(uint64_t) || sizeof(double) != sizeof(uint64_t)) { errno = ENOEXEC; return false; } // Find the stack: gc_stackbottom = gc_get_stackbottom(); // Reserve a large chunk of the virtual address space for the GC. void *gc_memory = gc_get_memory(); if (gc_memory != GC_MEMORY) goto init_error; // Initialize all of the region information structures. for (size_t i = 0; i < GC_NUM_REGIONS; i++) { void *startptr = GC_MEMORY + i*GC_REGION_SIZE; size_t unit = gc_index_unit(i); size_t size = (i - gc_unit_offset(unit))*unit + unit; uintptr_t offset = (uintptr_t)startptr % size; if (offset != 0) startptr += size - offset; gc_region_t region = __gc_regions + i; region->size = size; region->inv_size = (UINT64_MAX / size) + 1; region->freelist = NULL; region->startptr = startptr; region->endptr = startptr + GC_REGION_SIZE; region->freeptr = startptr; region->protectptr = startptr; region->markstartptr = startptr; region->markendptr = startptr; region->markptr = NULL; region->startidx = gc_objidx(startptr); } // Reserve virtual space for the mark stack. gc_markstack = gc_get_mark_memory(GC_MARK_STACK_SIZE); if (gc_markstack == NULL) goto init_error; gc_inited = true; return true; int saved_errno; init_error: saved_errno = errno; if (gc_markstack != NULL) gc_free_memory(gc_markstack, GC_MARK_STACK_SIZE); if (gc_memory != NULL) gc_free_memory(GC_MEMORY, GC_NUM_REGIONS*GC_REGION_SIZE); errno = saved_errno; return false; }
/* * Class: java_lang_VMMemoryManager * Method: getFreeMemory * Signature: ()J */ JNIEXPORT jlong JNICALL Java_java_lang_VMMemoryManager_getFreeMemory (JNIEnv *, jclass) { return gc_free_memory(); }