diff options
author | Carl Shapiro <cshapiro@google.com> | 2010-07-13 17:36:41 -0700 |
---|---|---|
committer | Carl Shapiro <cshapiro@google.com> | 2010-07-13 22:25:59 -0700 |
commit | ddb0c1cfe13128de385123c52ca8c33efb1cb587 (patch) | |
tree | 4d99918e86d3fd8ef0589800e624bf0a7f5c83fb | |
parent | d2f3ff738190d5b8d8f7ea288abc921fa9c26555 (diff) | |
download | android_dalvik-ddb0c1cfe13128de385123c52ca8c33efb1cb587.tar.gz android_dalvik-ddb0c1cfe13128de385123c52ca8c33efb1cb587.tar.bz2 android_dalvik-ddb0c1cfe13128de385123c52ca8c33efb1cb587.zip |
Make the visitor routines inlined.
The chanage also removes the verbose logging from the visitor.
Change-Id: I096dbe6d5fe2846ea363a9402e8c2b46d23f1302
-rw-r--r-- | vm/alloc/Verify.c | 2 | ||||
-rw-r--r-- | vm/alloc/Visit.c | 144 | ||||
-rw-r--r-- | vm/alloc/Visit.h | 10 | ||||
-rw-r--r-- | vm/alloc/VisitInlines.h | 180 |
4 files changed, 192 insertions, 144 deletions
diff --git a/vm/alloc/Verify.c b/vm/alloc/Verify.c index 2bb88088a..2afb955c8 100644 --- a/vm/alloc/Verify.c +++ b/vm/alloc/Verify.c @@ -63,9 +63,7 @@ static void visitorCallback(void *addr, void *arg) */ void dvmVerifyObject(const Object *obj) { - LOGV("Entering dvmVerifyObject(obj=%p)", obj); dvmVisitObject(visitorCallback, (Object *)obj, NULL); - LOGV("Exiting dvmVerifyObject(obj=%p)", obj); } /* diff --git a/vm/alloc/Visit.c b/vm/alloc/Visit.c index 8d4722058..546a6a881 100644 --- a/vm/alloc/Visit.c +++ b/vm/alloc/Visit.c @@ -17,153 +17,15 @@ #include "Dalvik.h" #include "alloc/clz.h" #include "alloc/Visit.h" +#include "alloc/VisitInlines.h" /* - * Visits the instance fields of a class or data object. - */ -static void visitInstanceFields(Visitor *visitor, Object *obj, void *arg) -{ - assert(visitor != NULL); - assert(obj != NULL); - assert(obj->clazz != NULL); - LOGV("Entering visitInstanceFields(visitor=%p,obj=%p)", visitor, obj); - 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); - } - } - } - LOGV("Exiting visitInstanceFields(visitor=%p,obj=%p)", visitor, obj); -} - -/* - * 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, ClassObject *obj, void *arg) -{ - assert(visitor != NULL); - assert(obj != NULL); - LOGV("Entering visitClassObject(visitor=%p,obj=%p)", visitor, obj); - assert(!strcmp(obj->obj.clazz->descriptor, "Ljava/lang/Class;")); - (*visitor)(&obj->obj.clazz, arg); - if (IS_CLASS_FLAG_SET(obj, CLASS_ISARRAY)) { - (*visitor)(&obj->elementClass, arg); - } - if (obj->status > CLASS_IDX) { - (*visitor)(&obj->super, arg); - } - (*visitor)(&obj->classLoader, arg); - visitInstanceFields(visitor, (Object *)obj, arg); - visitStaticFields(visitor, obj, arg); - if (obj->status > CLASS_IDX) { - visitInterfaces(visitor, obj, arg); - } - LOGV("Exiting visitClassObject(visitor=%p,obj=%p)", visitor, obj); -} - -/* - * 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); - LOGV("Entering visitArrayObject(visitor=%p,obj=%p)", visitor, obj); - (*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); - } - } - LOGV("Exiting visitArrayObject(visitor=%p,obj=%p)", visitor, obj); -} - -/* - * 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); - LOGV("Entering visitDataObject(visitor=%p,obj=%p)", visitor, obj); - (*visitor)(&obj->clazz, arg); - visitInstanceFields(visitor, obj, arg); - if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISREFERENCE)) { - size_t offset = gDvm.offJavaLangRefReference_referent; - Object **ref = BYTE_OFFSET(obj, offset); - (*visitor)(ref, arg); - } - LOGV("Exiting visitDataObject(visitor=%p,obj=%p)", visitor, obj); -} - -/* - * Visits all of the reference stored in an object. + * Visits all of the reference locations in an object. */ void dvmVisitObject(Visitor *visitor, Object *obj, void *arg) { assert(visitor != NULL); assert(obj != NULL); assert(obj->clazz != NULL); - LOGV("Entering dvmVisitObject(visitor=%p,obj=%p)", visitor, obj); - if (obj->clazz == gDvm.classJavaLangClass) { - visitClassObject(visitor, (ClassObject *)obj, arg); - } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) { - visitArrayObject(visitor, obj, arg); - } else { - visitDataObject(visitor, obj, arg); - } - LOGV("Exiting dvmVisitObject(visitor=%p,obj=%p)", visitor, obj); + visitObject(visitor, obj, arg); } diff --git a/vm/alloc/Visit.h b/vm/alloc/Visit.h index 343d5675d..a954c61f0 100644 --- a/vm/alloc/Visit.h +++ b/vm/alloc/Visit.h @@ -19,8 +19,16 @@ #include "Dalvik.h" -typedef void Visitor(void *obj, void *arg); +/* + * Callback invoked with the address of a reference and a user + * supplied context argument. + */ +typedef void Visitor(void *addr, void *arg); +/* + * Visits an object and applies the callback specified by the visitor + * to each reference-containing location. + */ void dvmVisitObject(Visitor *visitor, Object *obj, void *arg); #endif /* _DALVIK_ALLOC_VISIT */ diff --git a/vm/alloc/VisitInlines.h b/vm/alloc/VisitInlines.h new file mode 100644 index 000000000..84a456a6e --- /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 */ |