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); for (auto h : *getRootHandles()) { visitor.visitPotential(h->value); } // if (VERBOSITY()) printf("Found %d roots\n", stack.size()); while (void* p = stack.pop()) { assert(((intptr_t)p) % 8 == 0); GCAllocation* al = GCAllocation::fromUserData(p); if (isMarked(al)) { continue; } // printf("Marking + scanning %p\n", p); setMark(al); GCKind kind_id = al->kind_id; if (kind_id == GCKind::UNTRACKED) { continue; } else if (kind_id == GCKind::CONSERVATIVE) { uint32_t bytes = al->kind_data; visitor.visitPotentialRange((void**)p, (void**)((char*)p + bytes)); } else if (kind_id == GCKind::PYTHON) { Box* b = reinterpret_cast<Box*>(p); BoxedClass* cls = b->cls; if (cls) { // The cls can be NULL since we use 'new' to construct them. // An arbitrary amount of stuff can happen between the 'new' and // the call to the constructor (ie the args get evaluated), which // can trigger a collection. ASSERT(cls->gc_visit, "%s", getTypeName(b)->c_str()); cls->gc_visit(&visitor, b); } } else { RELEASE_ASSERT(0, "Unhandled kind: %d", (int)kind_id); } } #ifndef NVALGRIND VALGRIND_ENABLE_ERROR_REPORTING; #endif }
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 }
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); } }