void slab_gc_mark( slab_t *slab, void *mem ) { slab_item_t *itr = slab->head; DEBUG_GC("slab: gc_mark\n"); while( itr != NULL ) { if( ((uint8_t*)mem) >= itr->mem && ((uint8_t*)mem) < (itr->mem + slab->num_items_per_pool * slab->item_size) ) { if( (((uint8_t*)mem) - (itr->mem)) % slab->item_size == 0 ) { uint8_t mask = 1 << ( ( ((uint8_t*)mem) - (itr->mem) ) / slab->item_size ); if( itr->alloc & mask ) { DEBUG_GC("slab mark: %d\n", (int) mem ); itr->gc_mark |= mask; } else { DEBUG_GC("slab: used already freed memory %d\n", (int) mem ); // use already freed memory? //itr->alloc |= mask; //itr->gc_mark |= mask; } } else { DEBUG_GC("slab: memory misalignment %d\n", (int) mem ); // TODO: misalignment? } return; } itr = itr->next; } DEBUG_GC("cannot find memory %d\n", (int) mem); //exit(1); }
void slab_gc( slab_t *slab, sos_pid_t pid ) { slab_item_t *itr = slab->head; slab_item_t *prev = NULL; // // Detect memory leak while marking the memory to malloc // while( itr != NULL ) { if( itr->alloc != itr->gc_mark ) { // leak! DEBUG_GC("leak in slab %d %d\n", itr->alloc, itr->gc_mark); led_red_toggle(); itr->alloc = itr->gc_mark; if( itr->alloc == 0 && itr != slab->head ) { prev->next = itr->next; ker_free( itr ); itr = prev; } else { // mark it used to malloc itr->gc_mark = 0; ker_gc_mark( pid, itr ); } } else { itr->gc_mark = 0; ker_gc_mark( pid, itr ); } prev = itr; itr = itr->next; } }
void interp_ti_enumerate_root_set_single_thread_on_stack(jvmtiEnv* ti_env, VM_thread *thread) { TRACE2("enumeration", "interp_enumerate_root_set_single_thread_on_stack()"); StackIterator_interp* si; si = interp_si_create_from_native(thread); int i; int depth; DEBUG_GC("\n\nGC enumeration in interpreter stack:\n"); for (depth = 0; !interp_si_is_past_end(si); depth++) { Method* method = (Method*)interp_si_get_method(si); jmethodID method_id = (jmethodID)method; int slot = 0; if (si->This) { vm_ti_enumerate_stack_root(ti_env, (void**)&si->This, si->This, JVMTI_HEAP_ROOT_STACK_LOCAL, depth, method_id, slot++); DEBUG_GC(" [THIS]: " << si->This); } if (si->exc) { vm_ti_enumerate_stack_root(ti_env, (void**)&si->exc, si->exc, JVMTI_HEAP_ROOT_STACK_LOCAL, depth, method_id, slot++); DEBUG_GC(" [EXCEPTION]: " << si->exc); } if (method->is_native()) { DEBUG_GC("[METHOD <native>]: " << method); interp_si_goto_previous(si); continue; } DEBUG_GC("[METHOD "<< si->stack.size << " " << (int)si->locals.varNum << "]: " << method); if (si->stack.size) for(i = 0; i <= si->stack.index; i++) { if (si->stack.refs[i] == FLAG_OBJECT) { DEBUG_GC(" Stack[" << i << "] "); REF* ref = &si->stack.data[i].ref; ManagedObject *obj = UNCOMPRESS_INTERP(*ref); if (obj == 0) { DEBUG_GC("NULL"); } else { DEBUG_GC(obj); vm_ti_enumerate_stack_root(ti_env, ref, (Managed_Object_Handle)obj, JVMTI_HEAP_ROOT_STACK_LOCAL, depth, method_id, slot++); } } } unsigned j; if (si->locals.varNum) for(j = 0; j < si->locals.varNum; j++) { if (si->locals.refs[j] == FLAG_OBJECT) { DEBUG_GC(" Locals[" << j << "] "); REF* ref = &si->locals.vars[j].ref; ManagedObject *obj = UNCOMPRESS_INTERP(*ref); if (obj == 0) { DEBUG_GC("NULL\n"); } else { DEBUG_GC(obj); vm_ti_enumerate_stack_root(ti_env, ref, (Managed_Object_Handle)obj, JVMTI_HEAP_ROOT_STACK_LOCAL, depth, method_id, slot++); } } } MonitorList *ml = si->locked_monitors; while(ml) { vm_ti_enumerate_stack_root(ti_env, &ml->monitor, ml->monitor, JVMTI_HEAP_ROOT_MONITOR, depth, method_id, slot++); ml = ml->next; } interp_si_goto_previous(si); } // enumerate m2n frames M2nFrame *m2n = m2n_get_last_frame(thread); while(m2n) { oh_enumerate_handles(m2n_get_local_handles(m2n)); m2n = m2n_get_previous_frame(m2n); } }
void interp_enumerate_root_set_single_thread_on_stack(VM_thread *thread) { TRACE2("enumeration", "interp_enumerate_root_set_single_thread_on_stack()"); StackIterator_interp* si; si = interp_si_create_from_native(thread); int i; DEBUG_GC("\n\nGC enumeration in interpreter stack:\n"); while(!interp_si_is_past_end(si)) { Method* method = (Method*)interp_si_get_method(si); method = method; if (si->This) { vm_enumerate_root_reference((void**)&si->This, FALSE); DEBUG_GC(" [THIS]: " << si->This); } if (si->exc) { vm_enumerate_root_reference((void**)&si->exc, FALSE); DEBUG_GC(" [EXCEPTION]: " << si->exc); } if (method->is_native()) { DEBUG_GC("[METHOD <native>]: " << method); interp_si_goto_previous(si); continue; } DEBUG_GC("[METHOD "<< si->stack.size << " " << (int)si->locals.varNum << "]: " << method); if (si->stack.size) for(i = 0; i <= si->stack.index; i++) { if (si->stack.refs[i] == FLAG_OBJECT) { DEBUG_GC(" Stack[" << i << "] "); REF* ref = &si->stack.data[i].ref; ManagedObject *obj = UNCOMPRESS_INTERP(*ref); if (obj == 0) { DEBUG_GC("NULL"); } else { DEBUG_GC(obj); vm_enumerate(ref, FALSE); // CHECK!!! can we enumerate uncompressed ref in compressed mode } } } unsigned j; if (si->locals.varNum) for(j = 0; j < si->locals.varNum; j++) { if (si->locals.refs[j] == FLAG_OBJECT) { DEBUG_GC(" Locals[" << j << "] "); REF* ref = &si->locals.vars[j].ref; ManagedObject *obj = UNCOMPRESS_INTERP(*ref); if (obj == 0) { DEBUG_GC("NULL\n"); } else { DEBUG_GC(obj); vm_enumerate(ref, FALSE); // CHECK!!! can we enumerate uncompressed ref in compressed mode } } } MonitorList *ml = si->locked_monitors; while(ml) { vm_enumerate_root_reference((void**)&ml->monitor, FALSE); ml = ml->next; } interp_si_goto_previous(si); } // enumerate m2n frames M2nFrame *m2n = m2n_get_last_frame(thread); while(m2n) { oh_enumerate_handles(m2n_get_local_handles(m2n)); m2n = m2n_get_previous_frame(m2n); } }