summaryrefslogtreecommitdiffstats
path: root/vm/ReferenceTable.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
commitf72d5de56a522ac3be03873bdde26f23a5eeeb3c (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /vm/ReferenceTable.c
parent31e30105703263782efd450d356cd67ea01af3b7 (diff)
downloadandroid_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.tar.gz
android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.tar.bz2
android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.zip
auto import from //depot/cupcake/@135843
Diffstat (limited to 'vm/ReferenceTable.c')
-rw-r--r--vm/ReferenceTable.c283
1 files changed, 0 insertions, 283 deletions
diff --git a/vm/ReferenceTable.c b/vm/ReferenceTable.c
deleted file mode 100644
index c748222a7..000000000
--- a/vm/ReferenceTable.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Reference table management.
- */
-#include "Dalvik.h"
-
-/*
- * Initialize a ReferenceTable structure.
- */
-bool dvmInitReferenceTable(ReferenceTable* pRef, int initialCount,
- int maxCount)
-{
- assert(initialCount > 0);
- assert(initialCount <= maxCount);
-
- pRef->table = (Object**) malloc(initialCount * sizeof(Object*));
- if (pRef->table == NULL)
- return false;
-#ifndef NDEBUG
- memset(pRef->table, 0xdd, initialCount * sizeof(Object*));
-#endif
- pRef->nextEntry = pRef->table;
- pRef->allocEntries = initialCount;
- pRef->maxEntries = maxCount;
-
- return true;
-}
-
-/*
- * Clears out the contents of a ReferenceTable, freeing allocated storage.
- */
-void dvmClearReferenceTable(ReferenceTable* pRef)
-{
- free(pRef->table);
- pRef->table = pRef->nextEntry = NULL;
- pRef->allocEntries = pRef->maxEntries = -1;
-}
-
-/*
- * Add "obj" to "pRef".
- */
-bool dvmAddToReferenceTable(ReferenceTable* pRef, Object* obj)
-{
- assert(dvmIsValidObject(obj));
- assert(obj != NULL);
- assert(pRef->table != NULL);
-
- if (pRef->nextEntry == pRef->table + pRef->maxEntries) {
- LOGW("ReferenceTable overflow (max=%d)\n", pRef->maxEntries);
- return false;
- } else if (pRef->nextEntry == pRef->table + pRef->allocEntries) {
- Object** newTable;
- int newSize;
-
- newSize = pRef->allocEntries * 2;
- if (newSize > pRef->maxEntries)
- newSize = pRef->maxEntries;
- assert(newSize > pRef->allocEntries);
-
- newTable = (Object**) realloc(pRef->table, newSize * sizeof(Object*));
- if (newTable == NULL) {
- LOGE("Unable to expand ref table (from %d to %d %d-byte entries)\n",
- pRef->allocEntries, newSize, sizeof(Object*));
- return false;
- }
- LOGVV("Growing %p from %d to %d\n", pRef, pRef->allocEntries, newSize);
-
- /* update entries; adjust "nextEntry" in case memory moved */
- pRef->nextEntry = newTable + (pRef->nextEntry - pRef->table);
- pRef->table = newTable;
- pRef->allocEntries = newSize;
- }
-
- *pRef->nextEntry++ = obj;
- return true;
-}
-
-/*
- * Returns NULL if not found.
- */
-Object** dvmFindInReferenceTable(const ReferenceTable* pRef, Object** top,
- Object* obj)
-{
- Object** ptr;
-
- ptr = pRef->nextEntry;
- while (--ptr >= top) {
- if (*ptr == obj)
- return ptr;
- }
- return NULL;
-}
-
-/*
- * Remove "obj" from "pRef". We start at the end of the list (where the
- * most-recently-added element is), and stop searching for a match after
- * examining the element at "top".
- *
- * Most of the time "obj" is at or near the end of the list. If not, we
- * compact it down.
- */
-bool dvmRemoveFromReferenceTable(ReferenceTable* pRef, Object** top,
- Object* obj)
-{
- Object** ptr;
-
- assert(pRef->table != NULL);
-
- /*
- * Scan from the most-recently-added entry up to the top entry for
- * this frame.
- */
- ptr = dvmFindInReferenceTable(pRef, top, obj);
- if (ptr == NULL)
- return false;
-
- /*
- * Delete the entry.
- */
- pRef->nextEntry--;
- int moveCount = pRef->nextEntry - ptr;
- if (moveCount != 0) {
- /* remove from middle, slide the rest down */
- memmove(ptr, ptr+1, moveCount * sizeof(Object*));
- //LOGV("LREF delete %p, shift %d down\n", obj, moveCount);
- } else {
- /* last entry, falls off the end */
- //LOGV("LREF delete %p from end\n", obj);
- }
-
- return true;
-}
-
-/*
- * This is a qsort() callback. We sort Object* by class, allocation size,
- * and then by the Object* itself.
- */
-static int compareObject(const void* vobj1, const void* vobj2)
-{
- Object* obj1 = *((Object**) vobj1);
- Object* obj2 = *((Object**) vobj2);
-
- if (obj1 == NULL || obj2 == NULL)
- return (u1*)obj1 - (u1*)obj2;
-
- if (obj1->clazz != obj2->clazz) {
- return (u1*)obj1->clazz - (u1*)obj2->clazz;
- } else {
- int size1 = dvmObjectSizeInHeap(obj1);
- int size2 = dvmObjectSizeInHeap(obj2);
- if (size1 != size2) {
- return size1 - size2;
- } else {
- return (u1*)obj1 - (u1*)obj2;
- }
- }
-}
-
-/*
- * Log an object with some additional info.
- *
- * Pass in the number of additional elements that are identical to or
- * equivalent to the original.
- */
-static void logObject(Object* obj, int size, int identical, int equiv)
-{
- if (obj == NULL) {
- LOGW(" NULL reference (count=%d)\n", equiv);
- return;
- }
-
- if (identical + equiv != 0) {
- LOGW("%5d of %s %dB (%d unique)\n", identical + equiv +1,
- obj->clazz->descriptor, size, equiv +1);
- } else {
- LOGW("%5d of %s %dB\n", identical + equiv +1,
- obj->clazz->descriptor, size);
- }
-}
-
-/*
- * Dump the contents of a ReferenceTable to the log.
- *
- * The caller should lock any external sync before calling.
- *
- * (This was originally written to be tolerant of null entries in the table.
- * I don't think that can happen anymore.)
- */
-void dvmDumpReferenceTable(const ReferenceTable* pRef, const char* descr)
-{
- const int kLast = 10;
- int count = dvmReferenceTableEntries(pRef);
- Object** refs;
- int i;
-
- if (count == 0) {
- LOGW("Reference table has no entries\n");
- return;
- }
- assert(count > 0);
-
- /*
- * Dump the most recent N entries.
- */
- LOGW("Last %d entries in %s reference table:\n", kLast, descr);
- refs = pRef->table; // use unsorted list
- int size;
- int start = count - kLast;
- if (start < 0)
- start = 0;
-
- for (i = start; i < count; i++) {
- size = (refs[i] == NULL) ? 0 : dvmObjectSizeInHeap(refs[i]);
- Object* ref = refs[i];
- if (ref->clazz == gDvm.classJavaLangClass) {
- ClassObject* clazz = (ClassObject*) ref;
- LOGW("%5d: %p cls=%s '%s' (%d bytes)\n", i, ref,
- (refs[i] == NULL) ? "-" : ref->clazz->descriptor,
- clazz->descriptor, size);
- } else {
- LOGW("%5d: %p cls=%s (%d bytes)\n", i, ref,
- (refs[i] == NULL) ? "-" : ref->clazz->descriptor, size);
- }
- }
-
- /*
- * Make a copy of the table, and sort it.
- */
- Object** tableCopy = (Object**)malloc(sizeof(Object*) * count);
- memcpy(tableCopy, pRef->table, sizeof(Object*) * count);
- qsort(tableCopy, count, sizeof(Object*), compareObject);
- refs = tableCopy; // use sorted list
-
- /*
- * Dump uniquified table summary. While we're at it, generate a
- * cumulative total amount of pinned memory based on the unique entries.
- */
- LOGW("%s reference table summary (%d entries):\n", descr, count);
- int equiv, identical, total;
- total = equiv = identical = 0;
- for (i = 1; i < count; i++) {
- size = (refs[i-1] == NULL) ? 0 : dvmObjectSizeInHeap(refs[i-1]);
-
- if (refs[i] == refs[i-1]) {
- /* same reference, added more than once */
- identical++;
- } else if (refs[i]->clazz == refs[i-1]->clazz &&
- (int) dvmObjectSizeInHeap(refs[i]) == size)
- {
- /* same class / size, different object */
- total += size;
- equiv++;
- } else {
- /* different class */
- total += size;
- logObject(refs[i-1], size, identical, equiv);
- equiv = identical = 0;
- }
- }
-
- /* handle the last entry (everything above outputs refs[i-1]) */
- size = (refs[count-1] == NULL) ? 0 : dvmObjectSizeInHeap(refs[count-1]);
- total += size;
- logObject(refs[count-1], size, identical, equiv);
-
- LOGW("Memory held directly by native code is %d bytes\n", total);
- free(tableCopy);
-}
-