Esempio n. 1
0
File: gc.c Progetto: GJDuck/SMCHR
/*
 * 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();
}