Fix locking issue in oatdump.
Calling FieldHelper GetType may cause class loading, only do this for
non-null fields where we expect the type is part of the image.
Change-Id: I3c016f27fb619cc0da755bd3cecfe98326bda83b
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 05d7250..cde4dc6 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -557,12 +557,12 @@
// Loop through all the image spaces and dump their objects.
Heap* heap = Runtime::Current()->GetHeap();
const Spaces& spaces = heap->GetSpaces();
- // TODO: C++0x auto
{
WriterMutexLock mu(*GlobalSynchronization::heap_bitmap_lock_);
heap->FlushAllocStack();
}
ReaderMutexLock mu(*GlobalSynchronization::heap_bitmap_lock_);
+ // TODO: C++0x auto
for (Spaces::const_iterator cur = spaces.begin(); cur != spaces.end(); ++cur) {
(*cur)->GetLiveBitmap()->Walk(ImageDumper::Callback, this);
os_ << "\n";
@@ -609,19 +609,29 @@
static void PrintField(std::string& summary, Field* field, Object* obj)
SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
FieldHelper fh(field);
- Class* type = fh.GetType();
+ const char* descriptor = fh.GetTypeDescriptor();
StringAppendF(&summary, "\t%s: ", fh.GetName());
- if (type->IsPrimitiveLong()) {
- StringAppendF(&summary, "%lld (0x%llx)\n", field->Get64(obj), field->Get64(obj));
- } else if (type->IsPrimitiveDouble()) {
- StringAppendF(&summary, "%f (%a)\n", field->GetDouble(obj), field->GetDouble(obj));
- } else if (type->IsPrimitiveFloat()) {
- StringAppendF(&summary, "%f (%a)\n", field->GetFloat(obj), field->GetFloat(obj));
- } else if (type->IsPrimitive()) {
- StringAppendF(&summary, "%d (0x%x)\n", field->Get32(obj), field->Get32(obj));
+ if (descriptor[0] != 'L' && descriptor[0] != '[') {
+ Class* type = fh.GetType();
+ if (type->IsPrimitiveLong()) {
+ StringAppendF(&summary, "%lld (0x%llx)\n", field->Get64(obj), field->Get64(obj));
+ } else if (type->IsPrimitiveDouble()) {
+ StringAppendF(&summary, "%f (%a)\n", field->GetDouble(obj), field->GetDouble(obj));
+ } else if (type->IsPrimitiveFloat()) {
+ StringAppendF(&summary, "%f (%a)\n", field->GetFloat(obj), field->GetFloat(obj));
+ } else {
+ DCHECK(type->IsPrimitive());
+ StringAppendF(&summary, "%d (0x%x)\n", field->Get32(obj), field->Get32(obj));
+ }
} else {
+ // Get the value, don't compute the type unless it is non-null as we don't want
+ // to cause class loading.
Object* value = field->GetObj(obj);
- PrettyObjectValue(summary, type, value);
+ if (value == NULL) {
+ StringAppendF(&summary, "null %s\n", PrettyDescriptor(descriptor).c_str());
+ } else {
+ PrettyObjectValue(summary, fh.GetType(), value);
+ }
}
}