Alloc.cpp revision 50e5fd5984c9b0a6f0927ed5ddf13bde40e338c7
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Garbage-collecting memory allocator. 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/Heap.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/HeapInternal.h" 2241eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro#include "alloc/HeapSource.h" 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the GC universe. 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're currently using a memory-mapped arena to keep things off of the 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * main heap. This needs to be replaced with something real. 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 301e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmGcStartup() 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInitMutex(&gDvm.gcHeapLock); 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmHeapStartup(); 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Post-zygote heap initialization, including starting 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the HeapWorker thread. 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 411e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmGcStartupAfterZygote() 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 43ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro return dvmHeapStartupAfterZygote(); 44ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro} 45ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro 46ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro/* 47ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro * Shutdown the threads internal to the garbage collector. 48ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro */ 491e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmGcThreadShutdown() 50ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro{ 51ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro dvmHeapThreadShutdown(); 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Shut the GC down. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 571e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmGcShutdown() 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //TODO: grab and destroy the lock 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHeapShutdown(); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do any last-minute preparation before we call fork() for the first time. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 661e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmGcPreZygoteFork() 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmHeapSourceStartupBeforeFork(); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 711e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmGcStartupClasses() 72ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro{ 73ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro { 74ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro const char *klassName = "Ljava/lang/ref/ReferenceQueueThread;"; 75ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro ClassObject *klass = dvmFindSystemClass(klassName); 76ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro if (klass == NULL) { 77ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro return false; 78ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro } 79ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro const char *methodName = "startReferenceQueue"; 80ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro Method *method = dvmFindDirectMethodByDescriptor(klass, methodName, "()V"); 81ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro if (method == NULL) { 82ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro return false; 83ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro } 84ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro Thread *self = dvmThreadSelf(); 85ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro assert(self != NULL); 86ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro JValue unusedResult; 87ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro dvmCallMethod(self, method, NULL, &unusedResult); 88ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro } 89ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro { 90ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro const char *klassName = "Ljava/lang/FinalizerThread;"; 91ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro ClassObject *klass = dvmFindSystemClass(klassName); 92ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro if (klass == NULL) { 93ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro return false; 94ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro } 95ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro const char *methodName = "startFinalizer"; 96ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro Method *method = dvmFindDirectMethodByDescriptor(klass, methodName, "()V"); 97ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro if (method == NULL) { 98ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro return false; 99ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro } 100ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro Thread *self = dvmThreadSelf(); 101ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro assert(self != NULL); 102ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro JValue unusedResult; 103ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro dvmCallMethod(self, method, NULL, &unusedResult); 104ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro } 105ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro 106ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro return true; 107ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro} 108ce87bfed41bbe4248b2770fb1a90f34b2518f6faCarl Shapiro 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1107fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * Create a "stock instance" of an exception class. 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1127fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFaddenstatic Object* createStockException(const char* descriptor, const char* msg) 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1147fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden Thread* self = dvmThreadSelf(); 1157fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden StringObject* msgStr = NULL; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* init; 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1207fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden /* find class, initialize if necessary */ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = dvmFindSystemClass(descriptor); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to find %s\n", descriptor); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1277fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden init = dvmFindDirectMethodByDescriptor(clazz, "<init>", 1287fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden "(Ljava/lang/String;)V"); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (init == NULL) { 1307fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden LOGE("Unable to find String-arg constructor for %s\n", descriptor); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = dvmAllocObject(clazz, ALLOC_DEFAULT); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == NULL) 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1387fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden if (msg == NULL) { 1397fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden msgStr = NULL; 1407fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden } else { 14181f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes msgStr = dvmCreateStringFromCstr(msg); 1427fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden if (msgStr == NULL) { 1437fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden LOGW("Could not allocate message string \"%s\"\n", msg); 1447fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden dvmReleaseTrackedAlloc(obj, self); 1457fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden return NULL; 1467fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden } 1477fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden } 1487fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue unused; 1507fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden dvmCallMethod(self, init, obj, &unused, msgStr); 1517fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden if (dvmCheckException(self)) { 1527fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden dvmReleaseTrackedAlloc((Object*) msgStr, self); 1537fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden dvmReleaseTrackedAlloc(obj, self); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1557fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden } 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1577fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden dvmReleaseTrackedAlloc((Object*) msgStr, self); // okay if msgStr NULL 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return obj; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1627fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * Create some "stock" exceptions. These can be thrown when the system is 1637fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * too screwed up to allocate and initialize anything, or when we don't 1647fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * need a meaningful stack trace. 1657fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * 1667fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * We can't do this during the initial startup because we need to execute 1677fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * the constructors. 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1691e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmCreateStockExceptions() 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pre-allocate some throwables. These need to be explicitly added 1737fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * to the GC's root set (see dvmHeapMarkRootSet()). 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1757fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden gDvm.outOfMemoryObj = createStockException("Ljava/lang/OutOfMemoryError;", 1767fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden "[memory exhausted]"); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(gDvm.outOfMemoryObj, NULL); 1787fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden gDvm.internalErrorObj = createStockException("Ljava/lang/InternalError;", 1797fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden "[pre-allocated]"); 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(gDvm.internalErrorObj, NULL); 1817fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden gDvm.noClassDefFoundErrorObj = 1824c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden createStockException("Ljava/lang/NoClassDefFoundError;", 1834c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden "[generic]"); 1847fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden dvmReleaseTrackedAlloc(gDvm.noClassDefFoundErrorObj, NULL); 1857fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden 1867fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden if (gDvm.outOfMemoryObj == NULL || gDvm.internalErrorObj == NULL || 1877fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden gDvm.noClassDefFoundErrorObj == NULL) 1887fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden { 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Unable to create stock exceptions\n"); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an instance of the specified class. 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL and throws an exception on failure. 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObject* dvmAllocObject(ClassObject* clazz, int flags) 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* newObj; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2063475f9cdb47a6d6f8ad2ce49bbc3af46bca92f09Carl Shapiro assert(clazz != NULL); 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsClassInitialized(clazz) || dvmIsClassInitializing(clazz)); 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* allocate on GC heap; memory is zeroed out */ 210fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro newObj = (Object*)dvmMalloc(clazz->objectSize, flags); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newObj != NULL) { 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DVM_OBJECT_INIT(newObj, clazz); 2136af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden dvmTrackAllocation(clazz, clazz->objectSize); /* notify DDMS */ 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newObj; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a copy of an object, for Object.clone(). 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use the size actually allocated, rather than obj->clazz->objectSize, 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because the latter doesn't work for array objects. 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2250f27ad70ce7a8e739cdf5870346af837e2b9b6c0Andy McFaddenObject* dvmCloneObject(Object* obj, int flags) 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsValidObject(obj)); 228122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro ClassObject* clazz = obj->clazz; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Class.java shouldn't let us get here (java.lang.Class is final 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and does not implement Clonable), but make extra sure. 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A memcpy() clone will wreak havoc on a ClassObject's "innards". 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 234c6d2470eec726ae0ad95e4fd2d9d7da7cb2cdcbaDan Bornstein assert(!dvmIsTheClassClass(clazz)); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro size_t size; 2376af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) { 238bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro size = dvmArrayObjectSize((ArrayObject *)obj); 239bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro } else { 2406af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden size = clazz->objectSize; 241bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro Object* copy = (Object*)dvmMalloc(size, flags); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (copy == NULL) 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro DVM_OBJECT_INIT(copy, clazz); 248122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro size_t offset = sizeof(Object); 249122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro /* Copy instance data. We assume memcpy copies by words. */ 250122dac5b92c649b5d3182b163d7fce35e8c69d76Carl Shapiro memcpy((char*)copy + offset, (char*)obj + offset, size - offset); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25239721ef72fab792b97ec88aa068bb22d1426db23Carl Shapiro /* Mark the clone as finalizable if appropriate. */ 2536af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden if (IS_CLASS_FLAG_SET(clazz, CLASS_ISFINALIZABLE)) { 2546af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden dvmSetFinalizable(copy); 2556af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden } 2566af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden 2576af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden dvmTrackAllocation(clazz, size); /* notify DDMS */ 2586af2ddd107842c3737c04c37343cac9be17f4209Andy McFadden 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return copy; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Track an object that was allocated internally and isn't yet part of the 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * VM root set. 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We could do this per-thread or globally. If it's global we don't have 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to do the thread lookup but we do have to synchronize access to the list. 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 270bd74b4b51f16e200854e41bbbe5ee6afb3af4cffAndy McFadden * "obj" must not be NULL. 271bd74b4b51f16e200854e41bbbe5ee6afb3af4cffAndy McFadden * 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: "obj" is not a fully-formed object; in particular, obj->clazz will 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * usually be NULL since we're being called from dvmMalloc(). 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmAddTrackedAlloc(Object* obj, Thread* self) 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (self == NULL) 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self = dvmThreadSelf(); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280bd74b4b51f16e200854e41bbbe5ee6afb3af4cffAndy McFadden assert(obj != NULL); 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(self != NULL); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmAddToReferenceTable(&self->internalLocalRefTable, obj)) { 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("threadid=%d: unable to add %p to internal ref table\n", 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->threadId, obj); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDumpThread(self, false); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stop tracking an object. 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We allow attempts to delete NULL "obj" so that callers don't have to wrap 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * calls with "if != NULL". 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmReleaseTrackedAlloc(Object* obj, Thread* self) 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == NULL) 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (self == NULL) 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self = dvmThreadSelf(); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(self != NULL); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmRemoveFromReferenceTable(&self->internalLocalRefTable, 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->internalLocalRefTable.table, obj)) 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("threadid=%d: failed to remove %p from internal ref table\n", 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->threadId, obj); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Explicitly initiate garbage collection. 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3181e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmCollectGarbage() 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 320821fd06d4dc53f23e82074fcc8d8ffdc32ea3a51Carl Shapiro if (gDvm.disableExplicitGc) { 321821fd06d4dc53f23e82074fcc8d8ffdc32ea3a51Carl Shapiro return; 322821fd06d4dc53f23e82074fcc8d8ffdc32ea3a51Carl Shapiro } 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockHeap(); 324039167e7894ae16880f51fa0b4d44316318aae1eCarl Shapiro dvmWaitForConcurrentGcToComplete(); 325cc6f5118d19bae06cb80841386a0c95f24616a65Carl Shapiro dvmCollectGarbageInternal(GC_EXPLICIT); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 32841eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro 32950e5fd5984c9b0a6f0927ed5ddf13bde40e338c7Carl Shapirostruct CountContext { 33041eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro const ClassObject *clazz; 33141eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro size_t count; 33250e5fd5984c9b0a6f0927ed5ddf13bde40e338c7Carl Shapiro}; 33341eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro 33457ee270b755271166b2349321e5b8b5457731dd7Carl Shapirostatic void countInstancesOfClassCallback(void *ptr, void *arg) 33541eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro{ 336fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro CountContext *ctx = (CountContext *)arg; 337fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro const Object *obj = (const Object *)ptr; 33841eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro 33941eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro assert(ctx != NULL); 34057ee270b755271166b2349321e5b8b5457731dd7Carl Shapiro if (obj->clazz == ctx->clazz) { 34157ee270b755271166b2349321e5b8b5457731dd7Carl Shapiro ctx->count += 1; 34241eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro } 34341eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro} 34441eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro 34541eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapirosize_t dvmCountInstancesOfClass(const ClassObject *clazz) 34641eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro{ 347f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro CountContext ctx = { clazz, 0 }; 34841eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro dvmLockHeap(); 349a4313feb23dd454905a3297bdc9ba745e6066a16Carl Shapiro HeapBitmap *bitmap = dvmHeapSourceGetLiveBits(); 35041eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro dvmHeapBitmapWalk(bitmap, countInstancesOfClassCallback, &ctx); 35141eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro dvmUnlockHeap(); 35241eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro return ctx.count; 35341eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro} 354f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro 355f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapirostatic void countAssignableInstancesOfClassCallback(void *ptr, void *arg) 356f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro{ 357fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro CountContext *ctx = (CountContext *)arg; 358fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro const Object *obj = (const Object *)ptr; 359f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro 360f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro assert(ctx != NULL); 3612efc12622b0a98cde09447f2bfeb47667c5dd192Carl Shapiro if (obj->clazz != NULL && dvmInstanceof(obj->clazz, ctx->clazz)) { 362f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro ctx->count += 1; 363f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro } 364f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro} 365f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro 366f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapirosize_t dvmCountAssignableInstancesOfClass(const ClassObject *clazz) 367f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro{ 368f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro CountContext ctx = { clazz, 0 }; 369f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro dvmLockHeap(); 370a4313feb23dd454905a3297bdc9ba745e6066a16Carl Shapiro HeapBitmap *bitmap = dvmHeapSourceGetLiveBits(); 371f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro dvmHeapBitmapWalk(bitmap, countAssignableInstancesOfClassCallback, &ctx); 372f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro dvmUnlockHeap(); 373f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro return ctx.count; 374f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro} 3752494c5038e668add68c74dea83aca05187a89e7cCarl Shapiro 3762494c5038e668add68c74dea83aca05187a89e7cCarl Shapirobool dvmIsHeapAddress(void *address) 3772494c5038e668add68c74dea83aca05187a89e7cCarl Shapiro{ 3782494c5038e668add68c74dea83aca05187a89e7cCarl Shapiro return dvmHeapSourceContainsAddress(address); 3792494c5038e668add68c74dea83aca05187a89e7cCarl Shapiro} 380