summaryrefslogtreecommitdiff
path: root/vm/alloc/Verify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vm/alloc/Verify.cpp')
-rw-r--r--vm/alloc/Verify.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/vm/alloc/Verify.cpp b/vm/alloc/Verify.cpp
new file mode 100644
index 0000000..6d830c7
--- /dev/null
+++ b/vm/alloc/Verify.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include "Dalvik.h"
+#include "alloc/HeapBitmap.h"
+#include "alloc/HeapSource.h"
+#include "alloc/Verify.h"
+#include "alloc/Visit.h"
+
+/*
+ * Visitor applied to each reference field when searching for things
+ * that point to an object. Sets the argument to NULL when a match is
+ * found.
+ */
+static void dumpReferencesVisitor(void *pObj, void *arg)
+{
+ Object *obj = *(Object **)pObj;
+ Object *lookingFor = *(Object **)arg;
+ if (lookingFor != NULL && lookingFor == obj) {
+ *(Object **)arg = NULL;
+ }
+}
+
+/*
+ * Visitor applied to each bitmap element to search for things that
+ * point to an object. Logs a message when a match is found.
+ */
+static void dumpReferencesCallback(Object *obj, void *arg)
+{
+ if (obj == (Object *)arg) {
+ return;
+ }
+ dvmVisitObject(dumpReferencesVisitor, obj, &arg);
+ if (arg == NULL) {
+ LOGD("Found %p in the heap @ %p", arg, obj);
+ dvmDumpObject(obj);
+ }
+}
+
+/*
+ * Visitor applied to each root to search for things that point to an
+ * object. Logs a message when a match is found.
+ */
+static void dumpReferencesRootVisitor(void *ptr, u4 threadId,
+ RootType type, void *arg)
+{
+ Object *obj = *(Object **)ptr;
+ Object *lookingFor = *(Object **)arg;
+ if (obj == lookingFor) {
+ LOGD("Found %p in a root @ %p", arg, ptr);
+ }
+}
+
+/*
+ * Searches the roots and heap for object references.
+ */
+static void dumpReferences(const Object *obj)
+{
+ HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
+ void *arg = (void *)obj;
+ dvmVisitRoots(dumpReferencesRootVisitor, arg);
+ dvmHeapBitmapWalk(bitmap, dumpReferencesCallback, arg);
+}
+
+/*
+ * Checks that the given reference points to a valid object.
+ */
+static void verifyReference(void *addr, void *arg)
+{
+ Object *obj;
+ bool isValid;
+
+ assert(addr != NULL);
+ obj = *(Object **)addr;
+ if (obj == NULL) {
+ isValid = true;
+ } else {
+ isValid = dvmIsValidObject(obj);
+ }
+ if (!isValid) {
+ Object **parent = (Object **)arg;
+ if (*parent != NULL) {
+ LOGE("Verify of object %p failed", *parent);
+ dvmDumpObject(*parent);
+ *parent = NULL;
+ }
+ LOGE("Verify of reference %p @ %p failed", obj, addr);
+ dvmDumpObject(obj);
+ }
+}
+
+/*
+ * Verifies an object reference.
+ */
+void dvmVerifyObject(const Object *obj)
+{
+ Object *arg = const_cast<Object*>(obj);
+ dvmVisitObject(verifyReference, arg, &arg);
+ if (arg == NULL) {
+ dumpReferences(obj);
+ dvmAbort();
+ }
+}
+
+/*
+ * Helper function to call dvmVerifyObject from a bitmap walker.
+ */
+static void verifyBitmapCallback(Object *obj, void *arg)
+{
+ dvmVerifyObject(obj);
+}
+
+/*
+ * Verifies the object references in a heap bitmap. Assumes the VM is
+ * suspended.
+ */
+void dvmVerifyBitmap(const HeapBitmap *bitmap)
+{
+ dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
+}
+
+/*
+ * Helper function to call verifyReference from the root verifier.
+ */
+static void verifyRootReference(void *addr, u4 threadId,
+ RootType type, void *arg)
+{
+ verifyReference(addr, arg);
+}
+
+/*
+ * Verifies references in the roots.
+ */
+void dvmVerifyRoots()
+{
+ dvmVisitRoots(verifyRootReference, NULL);
+}