Alloc.cpp revision 039167e7894ae16880f51fa0b4d44316318aae1e
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
24a5a46928b486725ed624fa0ae6c469645a209e87Carl Shapiro#if WITH_HPROF_STACK
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "hprof/Hprof.h"
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the GC universe.
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're currently using a memory-mapped arena to keep things off of the
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * main heap.  This needs to be replaced with something real.
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmGcStartup(void)
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmInitMutex(&gDvm.gcHeapLock);
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmHeapStartup();
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Post-zygote heap initialization, including starting
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the HeapWorker thread.
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmGcStartupAfterZygote(void)
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmHeapWorkerStartup()) {
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
51ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro    return dvmHeapStartupAfterZygote();
52ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro}
53ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro
54ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro/*
55ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro * Shutdown the threads internal to the garbage collector.
56ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro */
57ec805eaed940e40212e85b58b163c7649feaca56Carl Shapirovoid dvmGcThreadShutdown(void)
58ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro{
59ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro    dvmHeapWorkerShutdown();
60ec805eaed940e40212e85b58b163c7649feaca56Carl Shapiro    dvmHeapThreadShutdown();
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Shut the GC down.
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmGcShutdown(void)
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //TODO: grab and destroy the lock
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHeapShutdown();
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do any last-minute preparation before we call fork() for the first time.
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmGcPreZygoteFork(void)
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmHeapSourceStartupBeforeFork();
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
817fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * Create a "stock instance" of an exception class.
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
837fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFaddenstatic Object* createStockException(const char* descriptor, const char* msg)
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
857fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    Thread* self = dvmThreadSelf();
867fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    StringObject* msgStr = NULL;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* init;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
917fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    /* find class, initialize if necessary */
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = dvmFindSystemClass(descriptor);
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz == NULL) {
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("Unable to find %s\n", descriptor);
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
987fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    init = dvmFindDirectMethodByDescriptor(clazz, "<init>",
997fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden            "(Ljava/lang/String;)V");
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (init == NULL) {
1017fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        LOGE("Unable to find String-arg constructor for %s\n", descriptor);
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    obj = dvmAllocObject(clazz, ALLOC_DEFAULT);
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL)
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1097fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    if (msg == NULL) {
1107fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        msgStr = NULL;
1117fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    } else {
11281f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes        msgStr = dvmCreateStringFromCstr(msg);
1137fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        if (msgStr == NULL) {
1147fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden            LOGW("Could not allocate message string \"%s\"\n", msg);
1157fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden            dvmReleaseTrackedAlloc(obj, self);
1167fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden            return NULL;
1177fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        }
1187fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    }
1197fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue unused;
1217fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    dvmCallMethod(self, init, obj, &unused, msgStr);
1227fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    if (dvmCheckException(self)) {
1237fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        dvmReleaseTrackedAlloc((Object*) msgStr, self);
1247fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        dvmReleaseTrackedAlloc(obj, self);
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
1267fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    }
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1287fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    dvmReleaseTrackedAlloc((Object*) msgStr, self);     // okay if msgStr NULL
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return obj;
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1337fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * Create some "stock" exceptions.  These can be thrown when the system is
1347fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * too screwed up to allocate and initialize anything, or when we don't
1357fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * need a meaningful stack trace.
1367fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden *
1377fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * We can't do this during the initial startup because we need to execute
1387fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden * the constructors.
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1407fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFaddenbool dvmCreateStockExceptions(void)
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Pre-allocate some throwables.  These need to be explicitly added
1447fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden     * to the GC's root set (see dvmHeapMarkRootSet()).
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1467fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    gDvm.outOfMemoryObj = createStockException("Ljava/lang/OutOfMemoryError;",
1477fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        "[memory exhausted]");
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmReleaseTrackedAlloc(gDvm.outOfMemoryObj, NULL);
1497fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    gDvm.internalErrorObj = createStockException("Ljava/lang/InternalError;",
1507fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        "[pre-allocated]");
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmReleaseTrackedAlloc(gDvm.internalErrorObj, NULL);
1527fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    gDvm.noClassDefFoundErrorObj =
1534c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden        createStockException("Ljava/lang/NoClassDefFoundError;",
1544c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden            "[generic]");
1557fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    dvmReleaseTrackedAlloc(gDvm.noClassDefFoundErrorObj, NULL);
1567fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden
1577fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    if (gDvm.outOfMemoryObj == NULL || gDvm.internalErrorObj == NULL ||
1587fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden        gDvm.noClassDefFoundErrorObj == NULL)
1597fc3ce8f0223a90006ad2c431a43b0bc841ee3c2Andy McFadden    {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Unable to create stock exceptions\n");
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an instance of the specified class.
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL and throws an exception on failure.
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObject* dvmAllocObject(ClassObject* clazz, int flags)
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* newObj;
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsClassInitialized(clazz) || dvmIsClassInitializing(clazz));
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (IS_CLASS_FLAG_SET(clazz, CLASS_ISFINALIZABLE)) {
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        flags |= ALLOC_FINALIZABLE;
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* allocate on GC heap; memory is zeroed out */
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newObj = dvmMalloc(clazz->objectSize, flags);
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (newObj != NULL) {
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DVM_OBJECT_INIT(newObj, clazz);
187a5a46928b486725ed624fa0ae6c469645a209e87Carl Shapiro#if WITH_HPROF_STACK
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hprofFillInStackTrace(newObj);
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmTrackAllocation(clazz, clazz->objectSize);
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newObj;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a copy of an object, for Object.clone().
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use the size actually allocated, rather than obj->clazz->objectSize,
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because the latter doesn't work for array objects.
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObject* dvmCloneObject(Object* obj)
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* copy;
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int size;
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int flags;
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsValidObject(obj));
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* Class.java shouldn't let us get here (java.lang.Class is final
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and does not implement Clonable), but make extra sure.
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * A memcpy() clone will wreak havoc on a ClassObject's "innards".
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(obj->clazz != gDvm.classJavaLangClass);
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISFINALIZABLE))
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        flags = ALLOC_DEFAULT | ALLOC_FINALIZABLE;
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        flags = ALLOC_DEFAULT;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
221bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro    if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
222bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro        size = dvmArrayObjectSize((ArrayObject *)obj);
223bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro    } else {
224bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro        size = obj->clazz->objectSize;
225bfe4dcc3bd3d4d85a07fd3d63da537b51342b6ebCarl Shapiro    }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    copy = dvmMalloc(size, flags);
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (copy == NULL)
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
230a5a46928b486725ed624fa0ae6c469645a209e87Carl Shapiro#if WITH_HPROF_STACK
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hprofFillInStackTrace(copy);
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmTrackAllocation(obj->clazz, size);
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memcpy(copy, obj, size);
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DVM_LOCK_INIT(&copy->lock);
237364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes    dvmWriteBarrierObject(copy);
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return copy;
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Track an object that was allocated internally and isn't yet part of the
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * VM root set.
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We could do this per-thread or globally.  If it's global we don't have
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to do the thread lookup but we do have to synchronize access to the list.
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
250bd74b4b51f16e200854e41bbbe5ee6afb3af4cffAndy McFadden * "obj" must not be NULL.
251bd74b4b51f16e200854e41bbbe5ee6afb3af4cffAndy McFadden *
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: "obj" is not a fully-formed object; in particular, obj->clazz will
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * usually be NULL since we're being called from dvmMalloc().
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmAddTrackedAlloc(Object* obj, Thread* self)
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (self == NULL)
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        self = dvmThreadSelf();
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
260bd74b4b51f16e200854e41bbbe5ee6afb3af4cffAndy McFadden    assert(obj != NULL);
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(self != NULL);
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmAddToReferenceTable(&self->internalLocalRefTable, obj)) {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("threadid=%d: unable to add %p to internal ref table\n",
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            self->threadId, obj);
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpThread(self, false);
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stop tracking an object.
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We allow attempts to delete NULL "obj" so that callers don't have to wrap
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * calls with "if != NULL".
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmReleaseTrackedAlloc(Object* obj, Thread* self)
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL)
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (self == NULL)
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        self = dvmThreadSelf();
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(self != NULL);
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmRemoveFromReferenceTable(&self->internalLocalRefTable,
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            self->internalLocalRefTable.table, obj))
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("threadid=%d: failed to remove %p from internal ref table\n",
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            self->threadId, obj);
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Explicitly initiate garbage collection.
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmCollectGarbage(bool collectSoftReferences)
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockHeap();
301039167e7894ae16880f51fa0b4d44316318aae1eCarl Shapiro    dvmWaitForConcurrentGcToComplete();
3021b9b4e4b89e1c682b6684ae5e2a637e4497a67e9Barry Hayes    dvmCollectGarbageInternal(collectSoftReferences, GC_EXPLICIT);
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockHeap();
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
30541eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro
30641eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapirotypedef struct {
30741eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    const ClassObject *clazz;
30841eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    size_t count;
309f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro} CountContext;
31041eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro
31157ee270b755271166b2349321e5b8b5457731dd7Carl Shapirostatic void countInstancesOfClassCallback(void *ptr, void *arg)
31241eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro{
313f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    CountContext *ctx = arg;
31457ee270b755271166b2349321e5b8b5457731dd7Carl Shapiro    const Object *obj = ptr;
31541eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro
31641eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    assert(ctx != NULL);
31757ee270b755271166b2349321e5b8b5457731dd7Carl Shapiro    if (obj->clazz == ctx->clazz) {
31857ee270b755271166b2349321e5b8b5457731dd7Carl Shapiro        ctx->count += 1;
31941eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    }
32041eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro}
32141eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro
32241eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapirosize_t dvmCountInstancesOfClass(const ClassObject *clazz)
32341eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro{
324f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    CountContext ctx = { clazz, 0 };
32541eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
32641eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    dvmLockHeap();
32741eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    dvmHeapBitmapWalk(bitmap, countInstancesOfClassCallback, &ctx);
32841eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    dvmUnlockHeap();
32941eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro    return ctx.count;
33041eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro}
331f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro
332f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapirostatic void countAssignableInstancesOfClassCallback(void *ptr, void *arg)
333f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro{
334f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    CountContext *ctx = arg;
335f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    const Object *obj = ptr;
336f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro
337f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    assert(ctx != NULL);
338f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    if (dvmInstanceof(obj->clazz, ctx->clazz)) {
339f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro        ctx->count += 1;
340f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    }
341f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro}
342f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro
343f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapirosize_t dvmCountAssignableInstancesOfClass(const ClassObject *clazz)
344f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro{
345f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    CountContext ctx = { clazz, 0 };
346f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
347f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    dvmLockHeap();
348f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    dvmHeapBitmapWalk(bitmap, countAssignableInstancesOfClassCallback, &ctx);
349f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    dvmUnlockHeap();
350f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro    return ctx.count;
351f331a60b2a7ad79c2ecb0ba638f66bae1f37eb6cCarl Shapiro}
352