Ejemplo n.º 1
0
void Heap::freeUnmarked() {
    long bytes_freed = 0;
    for (int bidx = 0; bidx < NUM_BUCKETS; bidx++) {
        bytes_freed += freeChain(heads[bidx]);
        bytes_freed += freeChain(full_heads[bidx]);
    }

    LargeObj *cur = large_head;
    while (cur) {
        void *p = cur->data;
        GCObjectHeader* header = headerFromObject(p);
        if (isMarked(header)) {
            clearMark(header);
        } else {
            if (VERBOSITY() >= 2) printf("Freeing %p\n", p);
            bytes_freed += cur->mmap_size();

            *cur->prev = cur->next;
            if (cur->next) cur->next->prev = cur->prev;

            LargeObj *to_free = cur;
            cur = cur->next;
            _freeLargeObj(to_free);
            continue;
        }

        cur = cur->next;
    }

    if (VERBOSITY("gc") >= 2) if (bytes_freed) printf("Freed %ld bytes\n", bytes_freed);
}
Ejemplo n.º 2
0
static long freeChain(Block* head) {
    long bytes_freed = 0;
    while (head) {
        int num_objects = head->numObjects();
        int first_obj = head->minObjIndex();
        int atoms_per_obj = head->atomsPerObj();

        for (int obj_idx = first_obj; obj_idx < num_objects; obj_idx++) {
            int atom_idx = obj_idx * atoms_per_obj;
            int bitmap_idx = atom_idx / 64;
            int bitmap_bit = atom_idx % 64;
            uint64_t mask = 1L << bitmap_bit;

            if (head->isfree[bitmap_idx] & mask)
                continue;

            void *p = &head->atoms[atom_idx];
            GCObjectHeader* header = headerFromObject(p);

            if (isMarked(header)) {
                clearMark(header);
            } else {
                if (VERBOSITY() >= 2) printf("Freeing %p\n", p);
                //assert(p != (void*)0x127000d960); // the main module
                bytes_freed += head->size;
                head->isfree[bitmap_idx] |= mask;
            }
        }

        head = head->next;
    }
    return bytes_freed;
}
Ejemplo n.º 3
0
static void markPhase() {
#ifndef NVALGRIND
    // Have valgrind close its eyes while we do the conservative stack and data scanning,
    // since we'll be looking at potentially-uninitialized values:
    VALGRIND_DISABLE_ERROR_REPORTING;
#endif

    TraceStack stack(roots);
    collectStackRoots(&stack);

    TraceStackGCVisitor visitor(&stack);

    //if (VERBOSITY()) printf("Found %d roots\n", stack.size());
    while (void* p = stack.pop()) {
        assert(((intptr_t)p) % 8 == 0);
        GCObjectHeader* header = headerFromObject(p);
        //printf("%p\n", p);

        if (isMarked(header)) {
            //printf("Already marked, skipping\n");
            continue;
        }

        //printf("Marking + scanning %p\n", p);

        setMark(header);

        ASSERT(KIND_OFFSET <= header->kind_id && header->kind_id < KIND_OFFSET + num_kinds, "%p %d", header, header->kind_id);

        if (header->kind_id == untracked_kind.kind_id)
            continue;

        //ASSERT(kind->_cookie == AllocationKind::COOKIE, "%lx %lx", kind->_cookie, AllocationKind::COOKIE);
        //AllocationKind::GCHandler gcf = kind->gc_handler;
        AllocationKind::GCHandler gcf = handlers[header->kind_id - KIND_OFFSET];

        assert(gcf);
        //if (!gcf) {
            //std::string name = g.func_addr_registry.getFuncNameAtAddress((void*)kind, true);
            //ASSERT(gcf, "%p %s", kind, name.c_str());
        //}

        gcf(&visitor, p);

    }

#ifndef NVALGRIND
    VALGRIND_ENABLE_ERROR_REPORTING;
#endif
}
Ejemplo n.º 4
0
static void markPhase() {
    TraceStack stack(roots);
    collectStackRoots(&stack);

    TraceStackGCVisitor visitor(&stack);

    //if (VERBOSITY()) printf("Found %d roots\n", stack.size());
    while (void* p = stack.pop()) {
        assert(((intptr_t)p) % 8 == 0);
        GCObjectHeader* header = headerFromObject(p);
        //printf("%p\n", p);

        if (isMarked(header)) {
            //printf("Already marked, skipping\n");
            continue;
        }

        //printf("Marking + scanning %p\n", p);

        setMark(header);

        ASSERT(KIND_OFFSET <= header->kind_id && header->kind_id < KIND_OFFSET + num_kinds, "%p %d", header, header->kind_id);

        if (header->kind_id == untracked_kind.kind_id)
            continue;

        //ASSERT(kind->_cookie == AllocationKind::COOKIE, "%lx %lx", kind->_cookie, AllocationKind::COOKIE);
        //AllocationKind::GCHandler gcf = kind->gc_handler;
        AllocationKind::GCHandler gcf = handlers[header->kind_id - KIND_OFFSET];

        assert(gcf);
        //if (!gcf) {
            //std::string name = g.func_addr_registry.getFuncNameAtAddress((void*)kind, true);
            //ASSERT(gcf, "%p %s", kind, name.c_str());
        //}

        gcf(&visitor, p);

    }
}