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