/* * Create a copy of an object, for Object.clone(). * * We use the size actually allocated, rather than obj->clazz->objectSize, * because the latter doesn't work for array objects. */ Object* dvmCloneObject(Object* obj, int flags) { assert(dvmIsValidObject(obj)); ClassObject* clazz = obj->clazz; /* Class.java shouldn't let us get here (java.lang.Class is final * and does not implement Clonable), but make extra sure. * A memcpy() clone will wreak havoc on a ClassObject's "innards". */ assert(!dvmIsTheClassClass(clazz)); size_t size; if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) { size = dvmArrayObjectSize((ArrayObject *)obj); } else { size = clazz->objectSize; } Object* copy = (Object*)dvmMalloc(size, flags); copy->tag = 0; if (copy == NULL) return NULL; DVM_OBJECT_INIT(copy, clazz); size_t offset = sizeof(Object); /* Copy instance data. We assume memcpy copies by words. */ memcpy((char*)copy + offset, (char*)obj + offset, size - offset); /* Mark the clone as finalizable if appropriate. */ if (IS_CLASS_FLAG_SET(clazz, CLASS_ISFINALIZABLE)) { dvmSetFinalizable(copy); } dvmTrackAllocation(clazz, size); /* notify DDMS */ pthread_mutex_lock(&gDvm.s_mtx); if(gDvm.newObjHook){ gDvm.newObjHook(copy); } pthread_mutex_unlock(&gDvm.s_mtx); return copy; }
/* * Create a copy of an object, for Object.clone(). * * We use the size actually allocated, rather than obj->clazz->objectSize, * because the latter doesn't work for array objects. */ Object* dvmCloneObject(Object* obj) { Object* copy; int size; int flags; assert(dvmIsValidObject(obj)); /* Class.java shouldn't let us get here (java.lang.Class is final * and does not implement Clonable), but make extra sure. * A memcpy() clone will wreak havoc on a ClassObject's "innards". */ assert(obj->clazz != gDvm.classJavaLangClass); if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISFINALIZABLE)) flags = ALLOC_DEFAULT | ALLOC_FINALIZABLE; else flags = ALLOC_DEFAULT; if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) { size = dvmArrayObjectSize((ArrayObject *)obj); } else { size = obj->clazz->objectSize; } copy = dvmMalloc(size, flags); if (copy == NULL) return NULL; #if WITH_HPROF && WITH_HPROF_STACK hprofFillInStackTrace(copy); dvmTrackAllocation(obj->clazz, size); #endif memcpy(copy, obj, size); DVM_LOCK_INIT(©->lock); dvmWriteBarrierObject(copy); return copy; }