OSDN Git Service

am 3144eec0: (-s ours) Replace the implementation of this class.
[android-x86/dalvik.git] / vm / alloc / VisitInlines.h
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 #ifndef _DALVIK_ALLOC_VISITINLINES
18 #define _DALVIK_ALLOC_VISITINLINES
19
20 /*
21  * Visits the instance fields of a class or data object.
22  */
23 static void visitFields(Visitor *visitor, Object *obj, void *arg)
24 {
25     assert(visitor != NULL);
26     assert(obj != NULL);
27     assert(obj->clazz != NULL);
28     if (obj->clazz->refOffsets != CLASS_WALK_SUPER) {
29         size_t refOffsets = obj->clazz->refOffsets;
30         while (refOffsets != 0) {
31             size_t rshift = CLZ(refOffsets);
32             size_t offset = CLASS_OFFSET_FROM_CLZ(rshift);
33             Object **ref = BYTE_OFFSET(obj, offset);
34             (*visitor)(ref, arg);
35             refOffsets &= ~(CLASS_HIGH_BIT >> rshift);
36         }
37     } else {
38         ClassObject *clazz;
39         for (clazz = obj->clazz; clazz != NULL; clazz = clazz->super) {
40             InstField *field = clazz->ifields;
41             int i;
42             for (i = 0; i < clazz->ifieldRefCount; ++i, ++field) {
43                 size_t offset = field->byteOffset;
44                 Object **ref = BYTE_OFFSET(obj, offset);
45                 (*visitor)(ref, arg);
46             }
47         }
48     }
49 }
50
51 /*
52  * Visits the static fields of a class object.
53  */
54 static void visitStaticFields(Visitor *visitor, ClassObject *clazz,
55                               void *arg)
56 {
57     int i;
58
59     assert(visitor != NULL);
60     assert(clazz != NULL);
61     for (i = 0; i < clazz->sfieldCount; ++i) {
62         char ch = clazz->sfields[i].field.signature[0];
63         if (ch == '[' || ch == 'L') {
64             (*visitor)(&clazz->sfields[i].value.l, arg);
65         }
66     }
67 }
68
69 /*
70  * Visit the interfaces of a class object.
71  */
72 static void visitInterfaces(Visitor *visitor, ClassObject *clazz,
73                             void *arg)
74 {
75     int i;
76
77     assert(visitor != NULL);
78     assert(clazz != NULL);
79     for (i = 0; i < clazz->interfaceCount; ++i) {
80         (*visitor)(&clazz->interfaces[i], arg);
81     }
82 }
83
84 /*
85  * Visits all the references stored in a class object instance.
86  */
87 static void visitClassObject(Visitor *visitor, Object *obj, void *arg)
88 {
89     ClassObject *classObj;
90     ClassStatus status;
91
92     assert(visitor != NULL);
93     assert(obj != NULL);
94     assert(obj->clazz != NULL);
95     assert(!strcmp(obj->clazz->descriptor, "Ljava/lang/Class;"));
96     classObj = (ClassObject *)obj;
97     (*visitor)(&obj->clazz, arg);
98     if (IS_CLASS_FLAG_SET(classObj, CLASS_ISARRAY)) {
99         (*visitor)(&classObj->elementClass, arg);
100     }
101     status = classObj->status;
102     if (status > CLASS_IDX) {
103         (*visitor)(&classObj->super, arg);
104     }
105     (*visitor)(&classObj->classLoader, arg);
106     visitFields(visitor, obj, arg);
107     visitStaticFields(visitor, classObj, arg);
108     if (status > CLASS_IDX) {
109         visitInterfaces(visitor, classObj, arg);
110     }
111 }
112
113 /*
114  * Visits the class object and, if the array is typed as an object
115  * array, all of the array elements.
116  */
117 static void visitArrayObject(Visitor *visitor, Object *obj, void *arg)
118 {
119     assert(visitor != NULL);
120     assert(obj != NULL);
121     assert(obj->clazz != NULL);
122     (*visitor)(&obj->clazz, arg);
123     if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY)) {
124         ArrayObject *array = (ArrayObject *)obj;
125         Object **contents = (Object **)array->contents;
126         size_t i;
127         for (i = 0; i < array->length; ++i) {
128             (*visitor)(&contents[i], arg);
129         }
130     }
131 }
132
133 /*
134  * Visits the class object and reference typed instance fields of a
135  * data object.
136  */
137 static void visitDataObject(Visitor *visitor, Object *obj, void *arg)
138 {
139     assert(visitor != NULL);
140     assert(obj != NULL);
141     assert(obj->clazz != NULL);
142     (*visitor)(&obj->clazz, arg);
143     visitFields(visitor, obj, arg);
144 }
145
146 /*
147  * Like visitDataObject, but visits the hidden referent field that
148  * belongings to the subclasses of java.lang.Reference.
149  */
150 static void visitReferenceObject(Visitor *visitor, Object *obj, void *arg)
151 {
152     assert(visitor != NULL);
153     assert(obj != NULL);
154     assert(obj->clazz != NULL);
155     visitDataObject(visitor, obj, arg);
156     size_t offset = gDvm.offJavaLangRefReference_referent;
157     Object **ref = BYTE_OFFSET(obj, offset);
158     (*visitor)(ref, arg);
159 }
160
161 /*
162  * Visits all of the reference stored in an object.
163  */
164 static void visitObject(Visitor *visitor, Object *obj, void *arg)
165 {
166     assert(visitor != NULL);
167     assert(obj != NULL);
168     assert(obj->clazz != NULL);
169     if (obj->clazz == gDvm.classJavaLangClass) {
170         visitClassObject(visitor, obj, arg);
171     } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
172         visitArrayObject(visitor, obj, arg);
173     } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISREFERENCE)) {
174         visitReferenceObject(visitor, obj, arg);
175     } else {
176         visitDataObject(visitor, obj, arg);
177     }
178 }
179
180 #endif /* _DALVIK_ALLOC_VISITINLINES */