Home | History | Annotate | Download | only in alloc
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "Dalvik.h"
     18 #include "alloc/HeapBitmap.h"
     19 #include "alloc/HeapSource.h"
     20 #include "alloc/Verify.h"
     21 #include "alloc/Visit.h"
     22 
     23 /*
     24  * Visitor applied to each reference field when searching for things
     25  * that point to an object.  Sets the argument to NULL when a match is
     26  * found.
     27  */
     28 static void dumpReferencesVisitor(void *pObj, void *arg)
     29 {
     30     Object *obj = *(Object **)pObj;
     31     Object *lookingFor = *(Object **)arg;
     32     if (lookingFor != NULL && lookingFor == obj) {
     33         *(Object **)arg = NULL;
     34     }
     35 }
     36 
     37 /*
     38  * Visitor applied to each bitmap element to search for things that
     39  * point to an object.  Logs a message when a match is found.
     40  */
     41 static void dumpReferencesCallback(Object *obj, void *arg)
     42 {
     43     if (obj == (Object *)arg) {
     44         return;
     45     }
     46     dvmVisitObject(dumpReferencesVisitor, obj, &arg);
     47     if (arg == NULL) {
     48         LOGD("Found %p in the heap @ %p", arg, obj);
     49         dvmDumpObject(obj);
     50     }
     51 }
     52 
     53 /*
     54  * Visitor applied to each root to search for things that point to an
     55  * object.  Logs a message when a match is found.
     56  */
     57 static void dumpReferencesRootVisitor(void *ptr, u4 threadId,
     58                                       RootType type, void *arg)
     59 {
     60     Object *obj = *(Object **)ptr;
     61     Object *lookingFor = *(Object **)arg;
     62     if (obj == lookingFor) {
     63         LOGD("Found %p in a root @ %p", arg, ptr);
     64     }
     65 }
     66 
     67 /*
     68  * Searches the roots and heap for object references.
     69  */
     70 static void dumpReferences(const Object *obj)
     71 {
     72     HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
     73     void *arg = (void *)obj;
     74     dvmVisitRoots(dumpReferencesRootVisitor, arg);
     75     dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg);
     76 }
     77 
     78 /*
     79  * Checks that the given reference points to a valid object.
     80  */
     81 static void verifyReference(void *addr, void *arg)
     82 {
     83     Object *obj;
     84     bool isValid;
     85 
     86     assert(addr != NULL);
     87     obj = *(Object **)addr;
     88     if (obj == NULL) {
     89         isValid = true;
     90     } else {
     91         isValid = dvmIsValidObject(obj);
     92     }
     93     if (!isValid) {
     94         Object **parent = (Object **)arg;
     95         if (*parent != NULL) {
     96             LOGE("Verify of object %p failed", *parent);
     97             dvmDumpObject(*parent);
     98             *parent = NULL;
     99         }
    100         LOGE("Verify of reference %p @ %p failed", obj, addr);
    101         dvmDumpObject(obj);
    102     }
    103 }
    104 
    105 /*
    106  * Verifies an object reference.
    107  */
    108 void dvmVerifyObject(const Object *obj)
    109 {
    110     Object *arg = const_cast<Object*>(obj);
    111     dvmVisitObject(verifyReference, arg, &arg);
    112     if (arg == NULL) {
    113         dumpReferences(obj);
    114         dvmAbort();
    115     }
    116 }
    117 
    118 /*
    119  * Helper function to call dvmVerifyObject from a bitmap walker.
    120  */
    121 static void verifyBitmapCallback(Object *obj, void *arg)
    122 {
    123     dvmVerifyObject(obj);
    124 }
    125 
    126 /*
    127  * Verifies the object references in a heap bitmap. Assumes the VM is
    128  * suspended.
    129  */
    130 void dvmVerifyBitmap(const HeapBitmap *bitmap)
    131 {
    132     dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
    133 }
    134 
    135 /*
    136  * Helper function to call verifyReference from the root verifier.
    137  */
    138 static void verifyRootReference(void *addr, u4 threadId,
    139                                 RootType type, void *arg)
    140 {
    141     verifyReference(addr, arg);
    142 }
    143 
    144 /*
    145  * Verifies references in the roots.
    146  */
    147 void dvmVerifyRoots()
    148 {
    149     dvmVisitRoots(verifyRootReference, NULL);
    150 }
    151