Object* Java_aura_rt_VM_allocateObject(Env* env, Class* c, Class* cls) { Object *o = rvmAllocateObject(env, cls); if (o && CLASS_IS_FINALIZABLE(cls)) { rvmRegisterFinalizer(env, o); } return o; }
Object* rvmAllocateMemoryForObject(Env* env, Class* clazz) { Object* m = NULL; if (CLASS_IS_FINALIZABLE(clazz) || CLASS_IS_REFERENCE(clazz) || (clazz->superclass && clazz->superclass == org_robovm_rt_bro_Struct) || (clazz->superclass && clazz->superclass == java_nio_MemoryBlock) || (clazz == java_nio_MemoryBlock)) { // These types of objects must be marked specially. We could probably // do this using GC bitmap descriptors instead. Also instances of // java.lang.Throwable must be marked specially but it has at least 1 // reference field and will thus not be allocated atomically. m = (Object*) gcAllocateKind(clazz->instanceDataSize, objectGCKind); } else if (CLASS_IS_REF_FREE(clazz)) { // Objects with 0 instance reference fields contain no pointers except for the Class // pointer and possibly a fat monitor. Those are allocated uncollectably // and will be reachable even if we alocate this atomically. m = (Object*) gcAllocateKind(clazz->instanceDataSize, atomicObjectGCKind); } else { // TODO: Use GC bitmap descriptors for small Objects. m = (Object*) gcAllocateKind(clazz->instanceDataSize, objectGCKind); } if (!m) { if (clazz == java_lang_OutOfMemoryError) { // We can't even allocate an OutOfMemoryError object. Prevent // infinite recursion by returning the shared criticalOutOfMemoryError // object. return criticalOutOfMemoryError; } rvmThrowOutOfMemoryError(env); return NULL; } return m; }
Class* rvmAllocateClass(Env* env, const char* className, Class* superclass, ClassLoader* classLoader, jint flags, jint classDataSize, jint instanceDataSize, jint instanceDataOffset, unsigned short classRefCount, unsigned short instanceRefCount, void* attributes, void* initializer) { if (superclass && CLASS_IS_INTERFACE(superclass)) { // TODO: Message should look like ? rvmThrowIncompatibleClassChangeError(env, ""); return NULL; } Class* clazz = rvmAllocateMemoryForClass(env, classDataSize); if (!clazz) return NULL; /* * NOTE: All classes we load before we have cached java.lang.Class will have NULL here so it is * important that we cache java.lang.Class as soon as possible. However, we have to cache * java.lang.Object first since it is the superclass of java.lang.Class. This means that * the java_lang_Object global variable will actually have NULL as clazz until we fix this in * rvmInitClasses(). */ clazz->object.clazz = java_lang_Class; clazz->name = className; clazz->superclass = superclass; clazz->classLoader = classLoader; clazz->flags = flags; clazz->classDataSize = classDataSize; clazz->instanceDataSize = instanceDataSize; clazz->instanceDataOffset = instanceDataOffset; clazz->classRefCount = classRefCount; clazz->instanceRefCount = instanceRefCount; clazz->_interfaces = &INTERFACES_NOT_LOADED; clazz->_fields = &FIELDS_NOT_LOADED; clazz->_methods = &METHODS_NOT_LOADED; clazz->attributes = attributes; clazz->initializer = initializer; // Inherit the CLASS_FLAG_FINALIZABLE flag from the superclass if (superclass && !CLASS_IS_FINALIZABLE(clazz) && CLASS_IS_FINALIZABLE(superclass)) { clazz->flags |= CLASS_FLAG_FINALIZABLE; } return clazz; }