Visit.cpp revision 056b9663171dc6f249a36faa49389142790965ba
1adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
2adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Copyright (C) 2010 The Android Open Source Project
3adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro *
4adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Licensed under the Apache License, Version 2.0 (the "License");
5adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * you may not use this file except in compliance with the License.
6adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * You may obtain a copy of the License at
7adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro *
8adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro *      http://www.apache.org/licenses/LICENSE-2.0
9adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro *
10adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Unless required by applicable law or agreed to in writing, software
11adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * distributed under the License is distributed on an "AS IS" BASIS,
12adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * See the License for the specific language governing permissions and
14adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * limitations under the License.
15adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
16adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
17adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro#include "Dalvik.h"
18adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro#include "alloc/clz.h"
19adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro#include "alloc/Visit.h"
20adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
21adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
22adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visits the instance fields of a class or data object.
23adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
24056b9663171dc6f249a36faa49389142790965baCarl Shapirostatic void visitInstanceFields(Visitor *visitor, Object *obj, void *arg)
25adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
26adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
27adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj != NULL);
28adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj->clazz != NULL);
29adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Entering visitInstanceFields(visitor=%p,obj=%p)", visitor, obj);
30adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    if (obj->clazz->refOffsets != CLASS_WALK_SUPER) {
31adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        size_t refOffsets = obj->clazz->refOffsets;
32adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        while (refOffsets != 0) {
33adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            size_t rshift = CLZ(refOffsets);
34adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            size_t offset = CLASS_OFFSET_FROM_CLZ(rshift);
35adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            Object **ref = BYTE_OFFSET(obj, offset);
36056b9663171dc6f249a36faa49389142790965baCarl Shapiro            (*visitor)(ref, arg);
37adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            refOffsets &= ~(CLASS_HIGH_BIT >> rshift);
38adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        }
39adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    } else {
40adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        ClassObject *clazz;
41adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        for (clazz = obj->clazz; clazz != NULL; clazz = clazz->super) {
42adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            InstField *field = clazz->ifields;
43adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            int i;
44adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            for (i = 0; i < clazz->ifieldRefCount; ++i, ++field) {
45adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro                size_t offset = field->byteOffset;
46adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro                Object **ref = BYTE_OFFSET(obj, offset);
47056b9663171dc6f249a36faa49389142790965baCarl Shapiro                (*visitor)(ref, arg);
48adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro            }
49adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        }
50adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
51adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Exiting visitInstanceFields(visitor=%p,obj=%p)", visitor, obj);
52adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
53adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
54adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
55adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visits the static fields of a class object.
56adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
57056b9663171dc6f249a36faa49389142790965baCarl Shapirostatic void visitStaticFields(Visitor *visitor, ClassObject *clazz, void *arg)
58adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
59adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    int i;
60adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
61adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
62adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(clazz != NULL);
63adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    for (i = 0; i < clazz->sfieldCount; ++i) {
64adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        char ch = clazz->sfields[i].field.signature[0];
65adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        if (ch == '[' || ch == 'L') {
66056b9663171dc6f249a36faa49389142790965baCarl Shapiro            (*visitor)(&clazz->sfields[i].value.l, arg);
67adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        }
68adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
69adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
70adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
71adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
72adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visit the interfaces of a class object.
73adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
74056b9663171dc6f249a36faa49389142790965baCarl Shapirostatic void visitInterfaces(Visitor *visitor, ClassObject *clazz, void *arg)
75adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
76adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    int i;
77adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
78adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
79adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(clazz != NULL);
80adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    for (i = 0; i < clazz->interfaceCount; ++i) {
81056b9663171dc6f249a36faa49389142790965baCarl Shapiro        (*visitor)(&clazz->interfaces[i], arg);
82adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
83adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
84adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
85adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
86adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visits all the references stored in a class object instance.
87adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
88056b9663171dc6f249a36faa49389142790965baCarl Shapirostatic void visitClassObject(Visitor *visitor, ClassObject *obj, void *arg)
89adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
90adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
91adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj != NULL);
92adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Entering visitClassObject(visitor=%p,obj=%p)", visitor, obj);
93c49db8554956f8d43eb487709bc1dccfe0496ad2Barry Hayes    assert(!strcmp(obj->obj.clazz->descriptor, "Ljava/lang/Class;"));
94056b9663171dc6f249a36faa49389142790965baCarl Shapiro    (*visitor)(&obj->obj.clazz, arg);
95adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    if (IS_CLASS_FLAG_SET(obj, CLASS_ISARRAY)) {
96056b9663171dc6f249a36faa49389142790965baCarl Shapiro        (*visitor)(&obj->elementClass, arg);
97adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
98c49db8554956f8d43eb487709bc1dccfe0496ad2Barry Hayes    if (obj->status > CLASS_IDX) {
99056b9663171dc6f249a36faa49389142790965baCarl Shapiro        (*visitor)(&obj->super, arg);
100c49db8554956f8d43eb487709bc1dccfe0496ad2Barry Hayes    }
101056b9663171dc6f249a36faa49389142790965baCarl Shapiro    (*visitor)(&obj->classLoader, arg);
102056b9663171dc6f249a36faa49389142790965baCarl Shapiro    visitInstanceFields(visitor, (Object *)obj, arg);
103056b9663171dc6f249a36faa49389142790965baCarl Shapiro    visitStaticFields(visitor, obj, arg);
104c49db8554956f8d43eb487709bc1dccfe0496ad2Barry Hayes    if (obj->status > CLASS_IDX) {
105056b9663171dc6f249a36faa49389142790965baCarl Shapiro        visitInterfaces(visitor, obj, arg);
106c49db8554956f8d43eb487709bc1dccfe0496ad2Barry Hayes    }
107adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Exiting visitClassObject(visitor=%p,obj=%p)", visitor, obj);
108adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
109adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
110adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
111adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visits the class object and, if the array is typed as an object
112adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * array, all of the array elements.
113adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
114056b9663171dc6f249a36faa49389142790965baCarl Shapirostatic void visitArrayObject(Visitor *visitor, Object *obj, void *arg)
115adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
116adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
117adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj != NULL);
118adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj->clazz != NULL);
119adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Entering visitArrayObject(visitor=%p,obj=%p)", visitor, obj);
120056b9663171dc6f249a36faa49389142790965baCarl Shapiro    (*visitor)(&obj->clazz, arg);
121adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY)) {
122adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        ArrayObject *array = (ArrayObject *)obj;
123adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        Object **contents = (Object **)array->contents;
124adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        size_t i;
125adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        for (i = 0; i < array->length; ++i) {
126056b9663171dc6f249a36faa49389142790965baCarl Shapiro            (*visitor)(&contents[i], arg);
127adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        }
128adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
129adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Exiting visitArrayObject(visitor=%p,obj=%p)", visitor, obj);
130adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
131adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
132adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
133adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visits the class object and reference typed instance fields of a
134adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * data object.
135adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
136056b9663171dc6f249a36faa49389142790965baCarl Shapirostatic void visitDataObject(Visitor *visitor, Object *obj, void *arg)
137adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
138adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
139adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj != NULL);
140adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj->clazz != NULL);
141adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Entering visitDataObject(visitor=%p,obj=%p)", visitor, obj);
142056b9663171dc6f249a36faa49389142790965baCarl Shapiro    (*visitor)(&obj->clazz, arg);
143056b9663171dc6f249a36faa49389142790965baCarl Shapiro    visitInstanceFields(visitor, obj, arg);
144adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISREFERENCE)) {
145adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        size_t offset = gDvm.offJavaLangRefReference_referent;
146adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro        Object **ref = BYTE_OFFSET(obj, offset);
147056b9663171dc6f249a36faa49389142790965baCarl Shapiro        (*visitor)(ref, arg);
148adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
149adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Exiting visitDataObject(visitor=%p,obj=%p)", visitor, obj);
150adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
151adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro
152adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro/*
153adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro * Visits all of the reference stored in an object.
154adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro */
155056b9663171dc6f249a36faa49389142790965baCarl Shapirovoid dvmVisitObject(Visitor *visitor, Object *obj, void *arg)
156adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro{
157adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(visitor != NULL);
158adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    assert(obj != NULL);
159899cdb783318da43e4e9c46ced3a29f2a62d5e9cBarry Hayes    assert(obj->clazz != NULL);
160adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Entering dvmVisitObject(visitor=%p,obj=%p)", visitor, obj);
161c49db8554956f8d43eb487709bc1dccfe0496ad2Barry Hayes    if (obj->clazz == gDvm.classJavaLangClass) {
162056b9663171dc6f249a36faa49389142790965baCarl Shapiro        visitClassObject(visitor, (ClassObject *)obj, arg);
163899cdb783318da43e4e9c46ced3a29f2a62d5e9cBarry Hayes    } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
164056b9663171dc6f249a36faa49389142790965baCarl Shapiro        visitArrayObject(visitor, obj, arg);
165adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    } else {
166056b9663171dc6f249a36faa49389142790965baCarl Shapiro        visitDataObject(visitor, obj, arg);
167adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    }
168adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro    LOGV("Exiting dvmVisitObject(visitor=%p,obj=%p)", visitor, obj);
169adc346f4145e409959ec1c657bbd8fecef6d2042Carl Shapiro}
170