summaryrefslogtreecommitdiffstats
path: root/oatdump
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-07-30 16:20:06 -0700
committerMathieu Chartier <mathieuc@google.com>2015-08-05 18:15:22 -0700
commit54d220eb9cc51215d75b9e0fe921b94bebbb3fd6 (patch)
treefe08749dea3ca6cad97bce48416beb37203efdf5 /oatdump
parent275bc5e5f318ba6ea1bad6c89c2924d1248b7523 (diff)
downloadart-54d220eb9cc51215d75b9e0fe921b94bebbb3fd6.tar.gz
art-54d220eb9cc51215d75b9e0fe921b94bebbb3fd6.tar.bz2
art-54d220eb9cc51215d75b9e0fe921b94bebbb3fd6.zip
Move ArtFields and ArtMethods to be a length prefixed array
Fixes race conditions between changing method and fields arrays being seen in the wrong order by the GC. Bug: 22832610 Change-Id: Ia21d6698f73ba207a6392c3d6b9be2658933073f
Diffstat (limited to 'oatdump')
-rw-r--r--oatdump/oatdump.cc42
1 files changed, 25 insertions, 17 deletions
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index b8b6a5f7c0..b61cfc9445 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1615,16 +1615,12 @@ class ImageDumper {
// TODO: Dump fields.
// Dump methods after.
const auto& methods_section = image_header_.GetMethodsSection();
- const auto pointer_size =
+ const size_t pointer_size =
InstructionSetPointerSize(oat_dumper_->GetOatInstructionSet());
- const auto method_size = ArtMethod::ObjectSize(pointer_size);
- for (size_t pos = 0; pos < methods_section.Size(); pos += method_size) {
- auto* method = reinterpret_cast<ArtMethod*>(
- image_space->Begin() + pos + methods_section.Offset());
- indent_os << method << " " << " ArtMethod: " << PrettyMethod(method) << "\n";
- DumpMethod(method, this, indent_os);
- indent_os << "\n";
- }
+ DumpArtMethodVisitor visitor(this);
+ methods_section.VisitPackedArtMethods(&visitor,
+ image_space->Begin(),
+ ArtMethod::ObjectSize(pointer_size));
}
}
// Dump the large objects separately.
@@ -1663,6 +1659,21 @@ class ImageDumper {
}
private:
+ class DumpArtMethodVisitor : public ArtMethodVisitor {
+ public:
+ explicit DumpArtMethodVisitor(ImageDumper* image_dumper) : image_dumper_(image_dumper) {}
+
+ virtual void Visit(ArtMethod* method) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
+ std::ostream& indent_os = image_dumper_->vios_.Stream();
+ indent_os << method << " " << " ArtMethod: " << PrettyMethod(method) << "\n";
+ image_dumper_->DumpMethod(method, image_dumper_, indent_os);
+ indent_os << "\n";
+ }
+
+ private:
+ ImageDumper* const image_dumper_;
+ };
+
static void PrettyObjectValue(std::ostream& os, mirror::Class* type, mirror::Object* value)
SHARED_REQUIRES(Locks::mutator_lock_) {
CHECK(type != nullptr);
@@ -1739,9 +1750,8 @@ class ImageDumper {
if (super != nullptr) {
DumpFields(os, obj, super);
}
- ArtField* fields = klass->GetIFields();
- for (size_t i = 0, count = klass->NumInstanceFields(); i < count; i++) {
- PrintField(os, &fields[i], obj);
+ for (ArtField& field : klass->GetIFields()) {
+ PrintField(os, &field, obj);
}
}
@@ -1837,13 +1847,11 @@ class ImageDumper {
}
} else if (obj->IsClass()) {
mirror::Class* klass = obj->AsClass();
- ArtField* sfields = klass->GetSFields();
- const size_t num_fields = klass->NumStaticFields();
- if (num_fields != 0) {
+ if (klass->NumStaticFields() != 0) {
os << "STATICS:\n";
ScopedIndentation indent2(&state->vios_);
- for (size_t i = 0; i < num_fields; i++) {
- PrintField(os, &sfields[i], sfields[i].GetDeclaringClass());
+ for (ArtField& field : klass->GetSFields()) {
+ PrintField(os, &field, field.GetDeclaringClass());
}
}
} else {