diff options
Diffstat (limited to 'runtime/mirror/class.cc')
-rw-r--r-- | runtime/mirror/class.cc | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index a36fe1253c..c0a950d614 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -16,14 +16,17 @@ #include "class.h" +#include "android-base/macros.h" #include "android-base/stringprintf.h" +#include "array-inl.h" #include "art_field-inl.h" #include "art_method-inl.h" +#include "base/enums.h" #include "base/logging.h" // For VLOG. #include "base/utils.h" #include "class-inl.h" -#include "class_ext.h" +#include "class_ext-inl.h" #include "class_linker-inl.h" #include "class_loader.h" #include "class_root.h" @@ -1547,5 +1550,126 @@ void Class::SetAccessFlagsDCheck(uint32_t new_access_flags) { (new_access_flags & kAccVerificationAttempted) != 0); } +ObjPtr<PointerArray> Class::GetMethodIds() { + ObjPtr<ClassExt> ext(GetExtData()); + if (ext.IsNull()) { + return nullptr; + } else { + return ext->GetJMethodIDs(); + } +} +ObjPtr<PointerArray> Class::GetOrCreateMethodIds() { + DCHECK(Runtime::Current()->JniIdsAreIndices()) << "JNI Ids are pointers!"; + Thread* self = Thread::Current(); + StackHandleScope<1> hs(self); + Handle<Class> h_this(hs.NewHandle(this)); + ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self)); + if (ext.IsNull()) { + self->AssertPendingOOMException(); + return nullptr; + } + return ext->EnsureJMethodIDsArrayPresent(NumMethods()); +} + +ObjPtr<PointerArray> Class::GetStaticFieldIds() { + ObjPtr<ClassExt> ext(GetExtData()); + if (ext.IsNull()) { + return nullptr; + } else { + return ext->GetStaticJFieldIDs(); + } +} +ObjPtr<PointerArray> Class::GetOrCreateStaticFieldIds() { + DCHECK(Runtime::Current()->JniIdsAreIndices()) << "JNI Ids are pointers!"; + Thread* self = Thread::Current(); + StackHandleScope<1> hs(self); + Handle<Class> h_this(hs.NewHandle(this)); + ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self)); + if (ext.IsNull()) { + self->AssertPendingOOMException(); + return nullptr; + } + return ext->EnsureStaticJFieldIDsArrayPresent(NumStaticFields()); +} +ObjPtr<PointerArray> Class::GetInstanceFieldIds() { + ObjPtr<ClassExt> ext(GetExtData()); + if (ext.IsNull()) { + return nullptr; + } else { + return ext->GetInstanceJFieldIDs(); + } +} +ObjPtr<PointerArray> Class::GetOrCreateInstanceFieldIds() { + DCHECK(Runtime::Current()->JniIdsAreIndices()) << "JNI Ids are pointers!"; + Thread* self = Thread::Current(); + StackHandleScope<1> hs(self); + Handle<Class> h_this(hs.NewHandle(this)); + ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self)); + if (ext.IsNull()) { + self->AssertPendingOOMException(); + return nullptr; + } + return ext->EnsureInstanceJFieldIDsArrayPresent(NumInstanceFields()); +} + +size_t Class::GetStaticFieldIdOffset(ArtField* field) { + DCHECK_LT(reinterpret_cast<uintptr_t>(field), + reinterpret_cast<uintptr_t>(&*GetSFieldsPtr()->end())) + << "field not part of the current class. " << field->PrettyField() << " class is " + << PrettyClass(); + DCHECK_GE(reinterpret_cast<uintptr_t>(field), + reinterpret_cast<uintptr_t>(&*GetSFieldsPtr()->begin())) + << "field not part of the current class. " << field->PrettyField() << " class is " + << PrettyClass(); + uintptr_t start = reinterpret_cast<uintptr_t>(&GetSFieldsPtr()->At(0)); + uintptr_t fld = reinterpret_cast<uintptr_t>(field); + size_t res = (fld - start) / sizeof(ArtField); + DCHECK_EQ(&GetSFieldsPtr()->At(res), field) + << "Incorrect field computation expected: " << field->PrettyField() + << " got: " << GetSFieldsPtr()->At(res).PrettyField(); + return res; +} + +size_t Class::GetInstanceFieldIdOffset(ArtField* field) { + DCHECK_LT(reinterpret_cast<uintptr_t>(field), + reinterpret_cast<uintptr_t>(&*GetIFieldsPtr()->end())) + << "field not part of the current class. " << field->PrettyField() << " class is " + << PrettyClass(); + DCHECK_GE(reinterpret_cast<uintptr_t>(field), + reinterpret_cast<uintptr_t>(&*GetIFieldsPtr()->begin())) + << "field not part of the current class. " << field->PrettyField() << " class is " + << PrettyClass(); + uintptr_t start = reinterpret_cast<uintptr_t>(&GetIFieldsPtr()->At(0)); + uintptr_t fld = reinterpret_cast<uintptr_t>(field); + size_t res = (fld - start) / sizeof(ArtField); + DCHECK_EQ(&GetIFieldsPtr()->At(res), field) + << "Incorrect field computation expected: " << field->PrettyField() + << " got: " << GetIFieldsPtr()->At(res).PrettyField(); + return res; +} + +size_t Class::GetMethodIdOffset(ArtMethod* method, PointerSize pointer_size) { + DCHECK(GetMethodsSlice(kRuntimePointerSize).Contains(method)) + << "method not part of the current class. " << method->PrettyMethod() << "( " << reinterpret_cast<void*>(method) << ")" << " class is " + << PrettyClass() << [&]() REQUIRES_SHARED(Locks::mutator_lock_) { + std::ostringstream os; + os << " Methods are ["; + for (ArtMethod& m : GetMethodsSlice(kRuntimePointerSize)) { + os << m.PrettyMethod() << "( " << reinterpret_cast<void*>(&m) << "), "; + } + os << "]"; + return os.str(); + }(); + uintptr_t start = reinterpret_cast<uintptr_t>(&*GetMethodsSlice(pointer_size).begin()); + uintptr_t fld = reinterpret_cast<uintptr_t>(method); + size_t art_method_size = ArtMethod::Size(pointer_size); + size_t art_method_align = ArtMethod::Alignment(pointer_size); + size_t res = (fld - start) / art_method_size; + DCHECK_EQ(&GetMethodsPtr()->At(res, art_method_size, art_method_align), method) + << "Incorrect method computation expected: " << method->PrettyMethod() + << " got: " << GetMethodsPtr()->At(res, art_method_size, art_method_align).PrettyMethod(); + return res; +} + } // namespace mirror } // namespace art |