gcfuncs.c
来自「基于LWVCL开发的库」· C语言 代码 · 共 754 行 · 第 1/2 页
C
754 行
* currently the case: for instance, resolved field type are not * marked as resolved in the constant pool, even though they do * have an index there! XXX * * The second hypothesis is that if the class is loaded by the * system and thus anchored, then everything that we can reach from * here is anchored as well. If that property holds, we should be * able to just return if class->loader == null here. XXX */ /* walk fields */ if (CLASS_FIELDS(class) != 0) { /* walk all fields to keep their types alive */ fld = CLASS_FIELDS(class); for (n = 0; n < CLASS_NFIELDS(class); n++) { /* don't mark field types that are primitive classes */ if (FIELD_RESOLVED(fld) && !CLASS_IS_PRIMITIVE(fld->type)) { if (!CLASS_GCJ(fld->type)) { KGC_markObject(collector, gc_info, fld->type); } } /* else it's an Utf8Const that is not subject to gc */ fld++; } /* walk static fields that contain references */ fld = CLASS_SFIELDS(class); for (n = 0; n < CLASS_NSFIELDS(class); n++) { /* Note that we must resolve field types eagerly * in processClass for gcj code cause it may never * call anything like getField to get the field * type resolved. This can happen for such types as [C */ if (FIELD_RESOLVED(fld) && FIELD_ISREF(fld)) { void **faddr = (void**)FIELD_ADDRESS(fld);#if defined (HAVE_GCJ_SUPPORT)/* 1. GCJ work-around, see * http://sourceware.cygnus.com/ml/java-discuss/1999-q4/msg00379.html */ if (FIELD_TYPE(fld) == getStringClass()) { KGC_markAddress(collector, gc_info, *faddr); } else { KGC_markObject(collector, gc_info, *faddr); }#else KGC_markObject(collector, gc_info, *faddr);#endif } fld++; } } /* The interface table for array classes points to static memory, * so we must not mark it. */ if (!CLASS_IS_ARRAY(class)) { /* mark interfaces referenced by this class */ for (n = 0; n < class->total_interface_len; n++) { KGC_markObject(collector, gc_info, class->interfaces[n]); } } else { /* array classes should keep their element type alive */ Hjava_lang_Class *etype = Kaffe_get_array_element_type(class); if (etype && !CLASS_IS_PRIMITIVE(etype)) { KGC_markObject(collector, gc_info, etype); } } /* Now we walk the interface table pointer. */ if (class->itable2dtable != NULL) { KGC_markObject(collector, gc_info, class->itable2dtable); /* We want the number of interfaces registered in the table. As * this number is not recorded in the table we recompute it * quickly using if2itable. (See classMethod.c/buildInterfaceDispatchTable). */ for (idx = 1, n = 0; n < class->total_interface_len; n++) { void *iface = class->itable2dtable[idx]; KGC_markObject(collector, gc_info, iface); idx += class->interfaces[n]->msize+1; } } /* CLASS_METHODS only points to the method array for non-array and * non-primitive classes */ if (!CLASS_IS_PRIMITIVE(class) && !CLASS_IS_ARRAY(class) && Kaffe_get_class_methods(class) != 0) { walkMethods(collector, gc_info, Kaffe_get_class_methods(class), CLASS_NMETHODS(class)); } KGC_markObject(collector, gc_info, class->loader); KGC_markObject(collector, gc_info, class->signers); KGC_markObject(collector, gc_info, class->protectionDomain); KGC_markObject(collector, gc_info, class->constructor);}/***************************************************************************** * various walk functions functions *//* * Walk an array object objects. */staticvoidwalkRefArray(Collector* collector, void *gc_info, void* base, uint32 size UNUSED){ Hjava_lang_Object* arr; int i; iLock *lk; Hjava_lang_Object** ptr; arr = (Hjava_lang_Object*)base; if (arr->vtable == 0) { /* see walkObject */ return; } lk = GET_HEAVYLOCK(arr->lock); if (lk != NULL && KGC_getObjectIndex(collector, lk) == KGC_ALLOC_LOCK) KGC_markObject(collector, gc_info, lk);DBG(GCPRECISE, dprintf("walkRefArray `%s' (num=%d)\n", CLASS_CNAME(arr->vtable->class), ARRAY_SIZE(arr)); ); ptr = OBJARRAY_DATA(arr); /* mark class only if not a system class (which would be anchored * anyway.) */ if (arr->vtable->class->loader != 0) { KGC_markObject(collector, gc_info, arr->vtable->class); } for (i = ARRAY_SIZE(arr); i > 0; i--) { Hjava_lang_Object* el = *ptr++; /* * NB: This would break if some objects (i.e. class objects) * are not gc-allocated. */ KGC_markObject(collector, gc_info, el); }}/* * Walk an object. */staticvoidwalkObject(Collector* collector, void *gc_info, void* base, uint32 size){ Hjava_lang_Object *obj = (Hjava_lang_Object*)base; Hjava_lang_Class *clazz; int *layout; int8* mem; unsigned int i; int l, nbits; iLock *lk; /* * Note that there is a window after the object is allocated but * before dtable is set. In this case, we don't have to walk anything. */ if (obj->vtable == 0) return; /* retrieve the layout of this object from its class */ clazz = obj->vtable->class; /* class without a loader, i.e., system classes are anchored so don't * bother marking them. */ if (clazz->loader != 0) { KGC_markObject(collector, gc_info, clazz); } lk = GET_HEAVYLOCK(obj->lock); if (lk != NULL && KGC_getObjectIndex(collector, lk) == KGC_ALLOC_LOCK) KGC_markObject(collector, gc_info, lk); layout = clazz->gc_layout; nbits = CLASS_FSIZE(clazz)/ALIGNMENTOF_VOIDP;DBG(GCPRECISE, dprintf("walkObject `%s' ", CLASS_CNAME(clazz)); BITMAP_DUMP(layout, nbits) dprintf(" (nbits=%d) %p-%p\n", nbits, base, ((char *)base) + size); ); assert(CLASS_FSIZE(clazz) > 0); assert(size > 0); mem = (int8 *)base; /* optimize this! */ while (nbits > 0) { /* get next integer from bitmap */ l = *layout++; i = 0; while (i < BITMAP_BPI) { /* skip the rest if no refs left */ if (l == 0) { mem += (BITMAP_BPI - i) * ALIGNMENTOF_VOIDP; break; } if (l < 0) { /* we know this pointer points to gc'ed memory * there is no need to check - go ahead and * mark it. Note that p may or may not point * to a "real" Java object. */ void *p = *(void **)mem; KGC_markObject(collector, gc_info, p); } i++; l <<= 1; mem += ALIGNMENTOF_VOIDP; } nbits -= BITMAP_BPI; }}/* * Walk a loader object. */staticvoidwalkLoader(Collector* collector, void *gc_info, void* base, uint32 size){ walkObject(collector, gc_info, base, size); walkClassEntries(collector, gc_info, (Hjava_lang_ClassLoader*)base);}static void/* ARGSUSED */finalizeObject(Collector* collector UNUSED, void* ob){ Hjava_lang_Object* obj = (Hjava_lang_Object*)ob; if (!obj->vtable) { /* Suppose we catch ThreadDeath inside newObject() */ return; } assert(obj->finalizer_call != NULL); ((KaffeVM_Finalizer)obj->finalizer_call)(obj);}/* * Print a description of an object at a given address. * Single-threaded. */const char*describeObject(const void* mem){ static char buf[256]; /* BIG XXX */ const Hjava_lang_Class* clazz; const Hjava_lang_String* str; const Hjava_lang_Object* obj; char* c; jchar* jc; int l; int idx = KGC_getObjectIndex(main_collector, mem); switch (idx) { case KGC_ALLOC_JAVASTRING: str = (const Hjava_lang_String*)mem; strcpy(buf, "java.lang.String `"); c = buf + strlen(buf); jc = unhand(str)->value ? STRING_DATA(str) : NULL; l = STRING_SIZE(str); while (jc && l-- > 0 && c < buf + sizeof(buf) - 2) { *c++ = (char)*jc++; } *c++ = '\''; *c = 0; break; case KGC_ALLOC_CLASSOBJECT: clazz = (const Hjava_lang_Class*)mem; sprintf(buf, "java.lang.Class `%s'", clazz->name ? CLASS_CNAME(clazz) : "name unknown"); break; case KGC_ALLOC_JAVALOADER: case KGC_ALLOC_NORMALOBJECT: case KGC_ALLOC_FINALIZEOBJECT: case KGC_ALLOC_REFARRAY: case KGC_ALLOC_PRIMARRAY: obj = (const Hjava_lang_Object*)mem; if (obj->vtable != 0) { clazz = obj->vtable->class; sprintf(buf, "%s", CLASS_CNAME(clazz)); } else { sprintf(buf, "newly born %s", KGC_getObjectDescription(main_collector, mem)); } break; /* add more? */ default: return KGC_getObjectDescription(main_collector, mem); } return (buf);}Collector*initCollector(void){ Collector *gc = createGC(); DBG(INIT, dprintf("initCollector()\n"); ); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JAVASTRING, stringWalk, stringDestroy, NULL, "j.l.String"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_NOWALK, NULL, KGC_OBJECT_NORMAL, NULL, "other-nowalk"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_NORMALOBJECT, walkObject, KGC_OBJECT_NORMAL, NULL, "obj-no-final"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_PRIMARRAY, NULL, finalizeObject, NULL, "prim-arrays"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_REFARRAY, walkRefArray, finalizeObject, NULL, "ref-arrays"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_CLASSOBJECT, walkClass, finalizeObject, destroyClass, "j.l.Class"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_FINALIZEOBJECT, walkObject, finalizeObject, NULL, "obj-final"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JAVALOADER, walkLoader, finalizeObject, destroyClassLoader, "j.l.ClassLoader"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_THREADCTX, NULL, KGC_OBJECT_NORMAL, NULL, "thread-ctxts"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_INTERFACE, NULL, KGC_OBJECT_NORMAL, NULL, "interfaces"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_INTERFACE_TABLE, NULL, KGC_OBJECT_NORMAL, NULL, "interface table"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_TRAMPOLINE, NULL, KGC_OBJECT_NORMAL, NULL, "trampoline"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JITCODE, NULL, KGC_OBJECT_NORMAL, NULL, "jit-code"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_BYTECODE, NULL, KGC_OBJECT_NORMAL, NULL, "java-bytecode"); KGC_registerGcTypeByIndex(gc, KGC_ALLOC_LOCK, NULL, KGC_OBJECT_NORMAL, KaffeLock_destroyLock, "locks"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_STATIC_THREADDATA, "thread-data"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_EXCEPTIONTABLE, "exc-table"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_STATICDATA, "static-data"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CONSTANT, "constants"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_FIXED, "other-fixed"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_DISPATCHTABLE, "dtable"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_METHOD, "methods"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_FIELD, "fields"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_UTF8CONST, "utf8consts"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_REF, "gc-refs"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JITTEMP, "jit-temp-data"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JAR, "jar"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CODEANALYSE, "code-analyse"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CLASSPOOL, "class-pool"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_LINENRTABLE, "linenr-table"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_LOCALVARTABLE, "lvar-table"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_DECLAREDEXC, "declared-exc"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CLASSMISC, "class-misc"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_VERIFIER, "verifier"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_NATIVELIB, "native-lib"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_SEQ, "jit-seq"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_CONST, "jit-const"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_ARGS, "jit-args"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_FAKE_CALL, "jit-fake-call"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_SLOTS, "jit-slots"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_CODEBLOCK, "jit-codeblock"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_LABELS, "jit-labels"); KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_VMWEAKREF, "vm-weak-ref"); DBG(INIT, dprintf("initCollector() done\n"); ); return (gc);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?