summaryrefslogtreecommitdiff
path: root/vm/alloc/VisitInlines.h
diff options
context:
space:
mode:
Diffstat (limited to 'vm/alloc/VisitInlines.h')
-rw-r--r--vm/alloc/VisitInlines.h180
1 files changed, 180 insertions, 0 deletions
diff --git a/vm/alloc/VisitInlines.h b/vm/alloc/VisitInlines.h
new file mode 100644
index 0000000..84a456a
--- /dev/null
+++ b/vm/alloc/VisitInlines.h
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+#ifndef _DALVIK_ALLOC_VISITINLINES
+#define _DALVIK_ALLOC_VISITINLINES
+
+/*
+ * Visits the instance fields of a class or data object.
+ */
+static void visitFields(Visitor *visitor, Object *obj, void *arg)
+{
+ assert(visitor != NULL);
+ assert(obj != NULL);
+ assert(obj->clazz != NULL);
+ if (obj->clazz->refOffsets != CLASS_WALK_SUPER) {
+ size_t refOffsets = obj->clazz->refOffsets;
+ while (refOffsets != 0) {
+ size_t rshift = CLZ(refOffsets);
+ size_t offset = CLASS_OFFSET_FROM_CLZ(rshift);
+ Object **ref = BYTE_OFFSET(obj, offset);
+ (*visitor)(ref, arg);
+ refOffsets &= ~(CLASS_HIGH_BIT >> rshift);
+ }
+ } else {
+ ClassObject *clazz;
+ for (clazz = obj->clazz; clazz != NULL; clazz = clazz->super) {
+ InstField *field = clazz->ifields;
+ int i;
+ for (i = 0; i < clazz->ifieldRefCount; ++i, ++field) {
+ size_t offset = field->byteOffset;
+ Object **ref = BYTE_OFFSET(obj, offset);
+ (*visitor)(ref, arg);
+ }
+ }
+ }
+}
+
+/*
+ * Visits the static fields of a class object.
+ */
+static void visitStaticFields(Visitor *visitor, ClassObject *clazz,
+ void *arg)
+{
+ int i;
+
+ assert(visitor != NULL);
+ assert(clazz != NULL);
+ for (i = 0; i < clazz->sfieldCount; ++i) {
+ char ch = clazz->sfields[i].field.signature[0];
+ if (ch == '[' || ch == 'L') {
+ (*visitor)(&clazz->sfields[i].value.l, arg);
+ }
+ }
+}
+
+/*
+ * Visit the interfaces of a class object.
+ */
+static void visitInterfaces(Visitor *visitor, ClassObject *clazz,
+ void *arg)
+{
+ int i;
+
+ assert(visitor != NULL);
+ assert(clazz != NULL);
+ for (i = 0; i < clazz->interfaceCount; ++i) {
+ (*visitor)(&clazz->interfaces[i], arg);
+ }
+}
+
+/*
+ * Visits all the references stored in a class object instance.
+ */
+static void visitClassObject(Visitor *visitor, Object *obj, void *arg)
+{
+ ClassObject *classObj;
+ ClassStatus status;
+
+ assert(visitor != NULL);
+ assert(obj != NULL);
+ assert(obj->clazz != NULL);
+ assert(!strcmp(obj->clazz->descriptor, "Ljava/lang/Class;"));
+ classObj = (ClassObject *)obj;
+ (*visitor)(&obj->clazz, arg);
+ if (IS_CLASS_FLAG_SET(classObj, CLASS_ISARRAY)) {
+ (*visitor)(&classObj->elementClass, arg);
+ }
+ status = classObj->status;
+ if (status > CLASS_IDX) {
+ (*visitor)(&classObj->super, arg);
+ }
+ (*visitor)(&classObj->classLoader, arg);
+ visitFields(visitor, obj, arg);
+ visitStaticFields(visitor, classObj, arg);
+ if (status > CLASS_IDX) {
+ visitInterfaces(visitor, classObj, arg);
+ }
+}
+
+/*
+ * Visits the class object and, if the array is typed as an object
+ * array, all of the array elements.
+ */
+static void visitArrayObject(Visitor *visitor, Object *obj, void *arg)
+{
+ assert(visitor != NULL);
+ assert(obj != NULL);
+ assert(obj->clazz != NULL);
+ (*visitor)(&obj->clazz, arg);
+ if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY)) {
+ ArrayObject *array = (ArrayObject *)obj;
+ Object **contents = (Object **)array->contents;
+ size_t i;
+ for (i = 0; i < array->length; ++i) {
+ (*visitor)(&contents[i], arg);
+ }
+ }
+}
+
+/*
+ * Visits the class object and reference typed instance fields of a
+ * data object.
+ */
+static void visitDataObject(Visitor *visitor, Object *obj, void *arg)
+{
+ assert(visitor != NULL);
+ assert(obj != NULL);
+ assert(obj->clazz != NULL);
+ (*visitor)(&obj->clazz, arg);
+ visitFields(visitor, obj, arg);
+}
+
+/*
+ * Like visitDataObject, but visits the hidden referent field that
+ * belongings to the subclasses of java.lang.Reference.
+ */
+static void visitReferenceObject(Visitor *visitor, Object *obj, void *arg)
+{
+ assert(visitor != NULL);
+ assert(obj != NULL);
+ assert(obj->clazz != NULL);
+ visitDataObject(visitor, obj, arg);
+ size_t offset = gDvm.offJavaLangRefReference_referent;
+ Object **ref = BYTE_OFFSET(obj, offset);
+ (*visitor)(ref, arg);
+}
+
+/*
+ * Visits all of the reference stored in an object.
+ */
+static void visitObject(Visitor *visitor, Object *obj, void *arg)
+{
+ assert(visitor != NULL);
+ assert(obj != NULL);
+ assert(obj->clazz != NULL);
+ if (obj->clazz == gDvm.classJavaLangClass) {
+ visitClassObject(visitor, obj, arg);
+ } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
+ visitArrayObject(visitor, obj, arg);
+ } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISREFERENCE)) {
+ visitReferenceObject(visitor, obj, arg);
+ } else {
+ visitDataObject(visitor, obj, arg);
+ }
+}
+
+#endif /* _DALVIK_ALLOC_VISITINLINES */