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