static Interface* loadInterfaces(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !clazz->classLoader->parent ? _bcBootClassesHash : _bcClassesHash); if (!header) return NULL; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); Interface* first = NULL; for (i = 0; i < ci.interfaceCount; i++) { const char* interfaceName = readInterfaceName(&p); Class* interfaceClass = rvmFindClassUsingLoader(env, interfaceName, clazz->classLoader); if (!interfaceClass) goto error; Interface* interf = rvmAllocateInterface(env, interfaceClass); if (!interf) goto error; LL_APPEND(first, interf); // Interfaces has to be in the correct order so we need to use the slower LL_APPEND } return first; error: while (first) { Interface* next = first->next; rvmFreeMemoryUncollectable(env, first); first = next; } return NULL; }
static Field* loadFields(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !clazz->classLoader->parent ? _bcBootClassesHash : _bcClassesHash); if (!header) return NULL; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); skipInterfaceNames(&p, &ci); Field* first = NULL; for (i = 0; i < ci.fieldCount; i++) { FieldInfo fi; readFieldInfo(&p, &fi); Field* f = rvmAllocateField(env, clazz, fi.name, fi.desc, fi.access, fi.offset, fi.attributes); if (!f) goto error; LL_PREPEND(first, f); } return first; error: while (first) { Field* next = first->next; rvmFreeMemoryUncollectable(env, first); first = next; } return NULL; }
static void loadMethods(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !clazz->classLoader->parent ? _bcBootClassesHash : _bcClassesHash); if (!header) return; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); skipInterfaceNames(&p, &ci); skipFieldInfos(&p, &ci); for (i = 0; i < ci.methodCount; i++) { MethodInfo mi; readMethodInfo(&p, &mi); if (mi.targetFnPtr) { if (!rvmAddBridgeMethod(env, clazz, mi.name, mi.desc, mi.access, mi.size, mi.impl, mi.synchronizedImpl, mi.targetFnPtr, mi.attributes)) return; } else if (mi.callbackImpl) { if (!rvmAddCallbackMethod(env, clazz, mi.name, mi.desc, mi.access, mi.size, mi.impl, mi.synchronizedImpl, mi.callbackImpl, mi.attributes)) return; } else { if (!rvmAddMethod(env, clazz, mi.name, mi.desc, mi.access, mi.size, mi.impl, mi.synchronizedImpl, mi.attributes)) return; } } }
static Class* createClass(Env* env, ClassInfoHeader* header, ClassLoader* classLoader) { ClassInfo ci; void* p = header; readClassInfo(&p, &ci); Class* superclass = NULL; if (ci.superclassName) { superclass = rvmFindClassUsingLoader(env, ci.superclassName, classLoader); if (!superclass) return NULL; } rvmObtainClassLock(env); Class* clazz = rvmAllocateClass(env, header->className, superclass, classLoader, ci.access, header->typeInfo, header->vitable, header->itables, header->classDataSize, header->instanceDataSize, header->instanceDataOffset, header->classRefCount, header->instanceRefCount, ci.attributes, header->initializer); if (clazz) { if (!rvmRegisterClass(env, clazz)) { rvmReleaseClassLock(env); return NULL; } header->clazz = clazz; rvmHookClassLoaded(env, clazz, (void*)header); } rvmReleaseClassLock(env); return clazz; }
static void loadFields(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !clazz->classLoader->parent ? _bcBootClassesHash : _bcClassesHash); if (!header) return; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); skipInterfaceNames(&p, &ci); for (i = 0; i < ci.fieldCount; i++) { FieldInfo fi; readFieldInfo(&p, &fi); if (!rvmAddField(env, clazz, fi.name, fi.desc, fi.access, fi.offset, fi.attributes)) return; } }
static void loadInterfaces(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !clazz->classLoader->parent ? _bcBootClassesHash : _bcClassesHash); if (!header) return; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); for (i = 0; i < ci.interfaceCount; i++) { const char* interfaceName = readInterfaceName(&p); Class* interface = rvmFindClassUsingLoader(env, interfaceName, clazz->classLoader); if (!interface) return; rvmAddInterface(env, clazz, interface); if (rvmExceptionCheck(env)) return; } }
static void iterateClassInfos(Env* env, jboolean (*callback)(Env*, ClassInfoHeader*, MethodInfo*, void*), void* hash, void* data) { ClassInfoHeader** base = getClassInfosBase(hash); jint count = getClassInfosCount(hash); jint i = 0; for (i = 0; i < count; i++) { ClassInfo ci; void* p = base[i]; readClassInfo(&p, &ci); skipInterfaceNames(&p, &ci); skipFieldInfos(&p, &ci); jint j; for (j = 0; j < ci.methodCount; j++) { MethodInfo mi; readMethodInfo(&p, &mi); if (!callback(env, base[i], &mi, data)) { break; } } } }
static Method* loadMethods(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !rvmGetParentClassLoader(env, clazz->classLoader) ? _bcBootClassesHash : _bcClassesHash); if (!header) return NULL; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); skipInterfaceNames(&p, &ci); skipFieldInfos(&p, &ci); Method* first = NULL; for (i = 0; i < ci.methodCount; i++) { MethodInfo mi; readMethodInfo(&p, &mi); if (!isStrippedMethod(&mi)) { Method* m = NULL; if (mi.targetFnPtr) { m = (Method*) rvmAllocateBridgeMethod(env, clazz, mi.name, mi.desc, mi.vtableIndex, mi.access, mi.size, mi.impl, mi.synchronizedImpl, mi.targetFnPtr, mi.attributes); } else if (mi.callbackImpl) { m = (Method*) rvmAllocateCallbackMethod(env, clazz, mi.name, mi.desc, mi.vtableIndex, mi.access, mi.size, mi.impl, mi.synchronizedImpl, mi.linetable, mi.callbackImpl, mi.attributes); } else { m = rvmAllocateMethod(env, clazz, mi.name, mi.desc, mi.vtableIndex, mi.access, mi.size, mi.impl, mi.synchronizedImpl, mi.linetable, mi.attributes); } if (!m) goto error; LL_PREPEND(first, m); } } return first; error: while (first) { Method* next = first->next; rvmFreeMemoryUncollectable(env, first); first = next; } return NULL; }
static Class* createClass(Env* env, ClassInfoHeader* header, ClassLoader* classLoader) { ClassInfo ci; void* p = header; readClassInfo(&p, &ci); Class* superclass = NULL; if (ci.superclassName) { superclass = rvmFindClassUsingLoader(env, ci.superclassName, classLoader); if (!superclass) return NULL; } Class* clazz = rvmAllocateClass(env, header->className, superclass, classLoader, ci.access, header->classDataSize, header->instanceDataSize, header->instanceDataOffset, header->classRefCount, header->instanceRefCount, ci.attributes, header->initializer); if (clazz) { if (!rvmRegisterClass(env, clazz)) return NULL; header->clazz = clazz; } return clazz; }