summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc122
1 files changed, 59 insertions, 63 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 1c3375c93a..41adae4c8a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -57,6 +57,7 @@
#include "gc/accounting/heap_bitmap-inl.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "gc/heap.h"
+#include "gc/heap-visit-objects-inl.h"
#include "gc/scoped_gc_critical_section.h"
#include "gc/space/image_space.h"
#include "gc/space/space-inl.h"
@@ -863,24 +864,6 @@ struct TrampolineCheckData {
bool error;
};
-static void CheckTrampolines(mirror::Object* obj, void* arg) NO_THREAD_SAFETY_ANALYSIS {
- if (obj->IsClass()) {
- ObjPtr<mirror::Class> klass = obj->AsClass();
- TrampolineCheckData* d = reinterpret_cast<TrampolineCheckData*>(arg);
- for (ArtMethod& m : klass->GetMethods(d->pointer_size)) {
- const void* entrypoint = m.GetEntryPointFromQuickCompiledCodePtrSize(d->pointer_size);
- if (entrypoint == d->quick_resolution_trampoline ||
- entrypoint == d->quick_imt_conflict_trampoline ||
- entrypoint == d->quick_generic_jni_trampoline ||
- entrypoint == d->quick_to_interpreter_bridge_trampoline) {
- d->m = &m;
- d->error = true;
- return;
- }
- }
- }
-}
-
bool ClassLinker::InitFromBootImage(std::string* error_msg) {
VLOG(startup) << __FUNCTION__ << " entering";
CHECK(!init_done_);
@@ -945,7 +928,24 @@ bool ClassLinker::InitFromBootImage(std::string* error_msg) {
data.quick_generic_jni_trampoline = ith_quick_generic_jni_trampoline;
data.quick_to_interpreter_bridge_trampoline = ith_quick_to_interpreter_bridge_trampoline;
ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
- spaces[i]->GetLiveBitmap()->Walk(CheckTrampolines, &data);
+ auto visitor = [&](mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (obj->IsClass()) {
+ ObjPtr<mirror::Class> klass = obj->AsClass();
+ for (ArtMethod& m : klass->GetMethods(data.pointer_size)) {
+ const void* entrypoint =
+ m.GetEntryPointFromQuickCompiledCodePtrSize(data.pointer_size);
+ if (entrypoint == data.quick_resolution_trampoline ||
+ entrypoint == data.quick_imt_conflict_trampoline ||
+ entrypoint == data.quick_generic_jni_trampoline ||
+ entrypoint == data.quick_to_interpreter_bridge_trampoline) {
+ data.m = &m;
+ data.error = true;
+ return;
+ }
+ }
+ }
+ };
+ spaces[i]->GetLiveBitmap()->Walk(visitor);
if (data.error) {
ArtMethod* m = data.m;
LOG(ERROR) << "Found a broken ArtMethod: " << ArtMethod::PrettyMethod(m);
@@ -1620,7 +1620,46 @@ class ImageSanityChecks FINAL {
static void CheckObjects(gc::Heap* heap, ClassLinker* class_linker)
REQUIRES_SHARED(Locks::mutator_lock_) {
ImageSanityChecks isc(heap, class_linker);
- heap->VisitObjects(ImageSanityChecks::SanityCheckObjectsCallback, &isc);
+ auto visitor = [&](mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK(obj != nullptr);
+ CHECK(obj->GetClass() != nullptr) << "Null class in object " << obj;
+ CHECK(obj->GetClass()->GetClass() != nullptr) << "Null class class " << obj;
+ if (obj->IsClass()) {
+ auto klass = obj->AsClass();
+ for (ArtField& field : klass->GetIFields()) {
+ CHECK_EQ(field.GetDeclaringClass(), klass);
+ }
+ for (ArtField& field : klass->GetSFields()) {
+ CHECK_EQ(field.GetDeclaringClass(), klass);
+ }
+ const auto pointer_size = isc.pointer_size_;
+ for (auto& m : klass->GetMethods(pointer_size)) {
+ isc.SanityCheckArtMethod(&m, klass);
+ }
+ auto* vtable = klass->GetVTable();
+ if (vtable != nullptr) {
+ isc.SanityCheckArtMethodPointerArray(vtable, nullptr);
+ }
+ if (klass->ShouldHaveImt()) {
+ ImTable* imt = klass->GetImt(pointer_size);
+ for (size_t i = 0; i < ImTable::kSize; ++i) {
+ isc.SanityCheckArtMethod(imt->Get(i, pointer_size), nullptr);
+ }
+ }
+ if (klass->ShouldHaveEmbeddedVTable()) {
+ for (int32_t i = 0; i < klass->GetEmbeddedVTableLength(); ++i) {
+ isc.SanityCheckArtMethod(klass->GetEmbeddedVTableEntry(i, pointer_size), nullptr);
+ }
+ }
+ mirror::IfTable* iftable = klass->GetIfTable();
+ for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
+ if (iftable->GetMethodArrayCount(i) > 0) {
+ isc.SanityCheckArtMethodPointerArray(iftable->GetMethodArray(i), nullptr);
+ }
+ }
+ }
+ };
+ heap->VisitObjects(visitor);
}
static void CheckPointerArray(gc::Heap* heap,
@@ -1632,49 +1671,6 @@ class ImageSanityChecks FINAL {
isc.SanityCheckArtMethodPointerArray(arr, size);
}
- static void SanityCheckObjectsCallback(mirror::Object* obj, void* arg)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(obj != nullptr);
- CHECK(obj->GetClass() != nullptr) << "Null class in object " << obj;
- CHECK(obj->GetClass()->GetClass() != nullptr) << "Null class class " << obj;
- if (obj->IsClass()) {
- ImageSanityChecks* isc = reinterpret_cast<ImageSanityChecks*>(arg);
-
- auto klass = obj->AsClass();
- for (ArtField& field : klass->GetIFields()) {
- CHECK_EQ(field.GetDeclaringClass(), klass);
- }
- for (ArtField& field : klass->GetSFields()) {
- CHECK_EQ(field.GetDeclaringClass(), klass);
- }
- const auto pointer_size = isc->pointer_size_;
- for (auto& m : klass->GetMethods(pointer_size)) {
- isc->SanityCheckArtMethod(&m, klass);
- }
- auto* vtable = klass->GetVTable();
- if (vtable != nullptr) {
- isc->SanityCheckArtMethodPointerArray(vtable, nullptr);
- }
- if (klass->ShouldHaveImt()) {
- ImTable* imt = klass->GetImt(pointer_size);
- for (size_t i = 0; i < ImTable::kSize; ++i) {
- isc->SanityCheckArtMethod(imt->Get(i, pointer_size), nullptr);
- }
- }
- if (klass->ShouldHaveEmbeddedVTable()) {
- for (int32_t i = 0; i < klass->GetEmbeddedVTableLength(); ++i) {
- isc->SanityCheckArtMethod(klass->GetEmbeddedVTableEntry(i, pointer_size), nullptr);
- }
- }
- mirror::IfTable* iftable = klass->GetIfTable();
- for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
- if (iftable->GetMethodArrayCount(i) > 0) {
- isc->SanityCheckArtMethodPointerArray(iftable->GetMethodArray(i), nullptr);
- }
- }
- }
- }
-
private:
ImageSanityChecks(gc::Heap* heap, ClassLinker* class_linker)
: spaces_(heap->GetBootImageSpaces()),