summaryrefslogtreecommitdiffstats
path: root/runtime/object_utils.h
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-05-21 17:43:44 -0700
committerMathieu Chartier <mathieuc@google.com>2014-06-09 12:46:32 -0700
commitbfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe (patch)
tree3d3f667c8232a9c1bb6fe9daea0d364f9ae01d8c /runtime/object_utils.h
parent2e1ca953c7fb165da36cc26ea74d3045d7e272c8 (diff)
downloadart-bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe.zip
art-bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe.tar.gz
art-bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe.tar.bz2
Change MethodHelper to use a Handle.
Added ConstHandle to help prevent errors where you modify the value stored in the handle of the caller. Also fixed compaction bugs related to not knowing MethodHelper::GetReturnType can resolve types. This bug was present in interpreter RETURN_OBJECT. Bug: 13077697 Change-Id: I71f964d4d810ab4debda1a09bc968af8f3c874a3
Diffstat (limited to 'runtime/object_utils.h')
-rw-r--r--runtime/object_utils.h257
1 files changed, 65 insertions, 192 deletions
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index a05ebe6..28ce8f3 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -121,12 +121,9 @@ class FieldHelper {
class MethodHelper {
public:
- MethodHelper() : method_(nullptr), shorty_(nullptr), shorty_len_(0) {}
-
- explicit MethodHelper(mirror::ArtMethod* m)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : method_(nullptr), shorty_(nullptr), shorty_len_(0) {
- SetMethod(m);
+ explicit MethodHelper(Handle<mirror::ArtMethod> m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : method_(m), shorty_(nullptr), shorty_len_(0) {
+ SetMethod(m.Get());
}
void ChangeMethod(mirror::ArtMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -135,48 +132,25 @@ class MethodHelper {
shorty_ = nullptr;
}
- mirror::ArtMethod* GetMethod() const {
- return method_;
+ mirror::ArtMethod* GetMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return method_->GetInterfaceMethodIfProxy();
}
- const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
- return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
- } else {
- Runtime* runtime = Runtime::Current();
- if (method_ == runtime->GetResolutionMethod()) {
- return "<runtime internal resolution method>";
- } else if (method_ == runtime->GetImtConflictMethod()) {
- return "<runtime internal imt conflict method>";
- } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
- return "<runtime internal callee-save all registers method>";
- } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
- return "<runtime internal callee-save reference registers method>";
- } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
- return "<runtime internal callee-save reference and argument registers method>";
- } else {
- return "<unknown runtime internal method>";
- }
- }
- }
-
- mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
- return GetClassLinker()->ResolveString(dex_file, method_id.name_idx_, dex_cache);
+ mirror::String* GetNameAsString(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile* dex_file = method_->GetDexFile();
+ mirror::ArtMethod* method = method_->GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
+ StackHandleScope<1> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+ return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
+ dex_cache);
}
const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const char* result = shorty_;
if (result == nullptr) {
- const DexFile& dex_file = GetDexFile();
- result = dex_file.GetMethodShorty(dex_file.GetMethodId(method_->GetDexMethodIndex()),
- &shorty_len_);
+ result = method_->GetShorty(&shorty_len_);
shorty_ = result;
}
return result;
@@ -203,94 +177,27 @@ class MethodHelper {
return refs;
}
- const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (dex_method_idx != DexFile::kDexNoIndex) {
- return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
- } else {
- return Signature::NoSignature();
- }
- }
-
- const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
- }
-
- const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::ProtoId& proto = GetPrototype();
- return GetDexFile().GetProtoParameters(proto);
- }
-
+ // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
+ // number of bugs at call sites.
mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
- const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
+ mirror::ArtMethod* method = GetMethod();
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());
+ const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
uint16_t return_type_idx = proto_id.return_type_idx_;
return GetClassFromTypeIdx(return_type_idx, resolve);
}
- const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
- const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
- uint16_t return_type_idx = proto_id.return_type_idx_;
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
- }
-
- int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (dex_pc == DexFile::kDexNoIndex) {
- return method_->IsNative() ? -2 : -1;
- } else {
- const DexFile& dex_file = GetDexFile();
- return dex_file.GetLineNumFromPC(method_, dex_pc);
- }
- }
-
- const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
- return "<runtime method>";
- }
- return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
- }
-
- const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetSourceFile();
- }
-
- uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetDexClassDefIndex();
- }
-
- const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetDexFile().GetClassDef(GetClassDefIndex());
- }
-
- mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetClassLoader();
- }
-
- bool IsStatic() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->IsStatic();
- }
-
- bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->IsConstructor() && IsStatic();
- }
-
size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// "1 +" because the first in Args is the receiver.
// "- 1" because we don't count the return type.
- return (IsStatic() ? 0 : 1) + GetShortyLength() - 1;
+ return (method_->IsStatic() ? 0 : 1) + GetShortyLength() - 1;
}
// Get the primitive type associated with the given parameter.
Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK_LT(param, NumArgs());
- if (IsStatic()) {
+ if (GetMethod()->IsStatic()) {
param++; // 0th argument must skip return value at start of the shorty
} else if (param == 0) {
return Primitive::kPrimNot;
@@ -310,21 +217,20 @@ class MethodHelper {
}
bool HasSameNameAndSignature(MethodHelper* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
- if (GetDexCache() == other->GetDexCache()) {
+ const DexFile* dex_file = method_->GetDexFile();
+ const DexFile::MethodId& mid = dex_file->GetMethodId(GetMethod()->GetDexMethodIndex());
+ if (method_->GetDexCache() == other->method_->GetDexCache()) {
const DexFile::MethodId& other_mid =
- dex_file.GetMethodId(other->method_->GetDexMethodIndex());
+ dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
}
- const DexFile& other_dex_file = other->GetDexFile();
+ const DexFile* other_dex_file = other->method_->GetDexFile();
const DexFile::MethodId& other_mid =
- other_dex_file.GetMethodId(other->method_->GetDexMethodIndex());
- if (!DexFileStringEquals(&dex_file, mid.name_idx_,
- &other_dex_file, other_mid.name_idx_)) {
+ other_dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
+ if (!DexFileStringEquals(dex_file, mid.name_idx_, other_dex_file, other_mid.name_idx_)) {
return false; // Name mismatch.
}
- return dex_file.GetMethodSignature(mid) == other_dex_file.GetMethodSignature(other_mid);
+ return dex_file->GetMethodSignature(mid) == other_dex_file->GetMethodSignature(other_mid);
}
bool HasSameSignatureWithDifferentClassLoaders(MethodHelper* other)
@@ -332,8 +238,8 @@ class MethodHelper {
if (UNLIKELY(GetReturnType() != other->GetReturnType())) {
return false;
}
- const DexFile::TypeList* types = GetParameterTypeList();
- const DexFile::TypeList* other_types = other->GetParameterTypeList();
+ const DexFile::TypeList* types = method_->GetParameterTypeList();
+ const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
if (types == nullptr) {
return (other_types == nullptr) || (other_types->Size() == 0);
} else if (UNLIKELY(other_types == nullptr)) {
@@ -354,84 +260,63 @@ class MethodHelper {
return true;
}
- const DexFile::CodeItem* GetCodeItem()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetDexFile().GetCodeItem(method_->GetCodeItemOffset());
- }
-
- bool IsResolvedTypeIdx(uint16_t type_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDexCacheResolvedTypes()->Get(type_idx) != nullptr;
- }
-
mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
+ mirror::ArtMethod* method = GetMethod();
+ mirror::Class* type = method->GetDexCacheResolvedTypes()->Get(type_idx);
if (type == nullptr && resolve) {
- type = GetClassLinker()->ResolveType(type_idx, method_);
+ type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
}
return type;
}
- const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
- }
-
mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDexCacheResolvedTypes()->Get(type_idx);
- }
-
- const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return *GetDexCache()->GetDexFile();
- }
-
- mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetDexCache();
+ return GetMethod()->GetDexCacheResolvedTypes()->Get(type_idx);
}
mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::String* s = method_->GetDexCacheStrings()->Get(string_idx);
+ mirror::ArtMethod* method = GetMethod();
+ mirror::String* s = method->GetDexCacheStrings()->Get(string_idx);
if (UNLIKELY(s == nullptr)) {
StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
- s = GetClassLinker()->ResolveString(GetDexFile(), string_idx, dex_cache);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+ s = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(), string_idx,
+ dex_cache);
}
return s;
}
uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dexfile = GetDexFile();
- if (&dexfile == &other_dexfile) {
- return method_->GetDexMethodIndex();
+ mirror::ArtMethod* method = GetMethod();
+ const DexFile* dexfile = method->GetDexFile();
+ if (dexfile == &other_dexfile) {
+ return method->GetDexMethodIndex();
}
- const DexFile::MethodId& mid = dexfile.GetMethodId(method_->GetDexMethodIndex());
- const char* mid_declaring_class_descriptor = dexfile.StringByTypeIdx(mid.class_idx_);
+ const DexFile::MethodId& mid = dexfile->GetMethodId(method->GetDexMethodIndex());
+ const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
const DexFile::StringId* other_descriptor =
other_dexfile.FindStringId(mid_declaring_class_descriptor);
if (other_descriptor != nullptr) {
const DexFile::TypeId* other_type_id =
other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
if (other_type_id != nullptr) {
- const char* mid_name = dexfile.GetMethodName(mid);
+ const char* mid_name = dexfile->GetMethodName(mid);
const DexFile::StringId* other_name = other_dexfile.FindStringId(mid_name);
if (other_name != nullptr) {
uint16_t other_return_type_idx;
std::vector<uint16_t> other_param_type_idxs;
- bool success = other_dexfile.CreateTypeList(dexfile.GetMethodSignature(mid).ToString(),
- &other_return_type_idx,
- &other_param_type_idxs);
+ bool success = other_dexfile.CreateTypeList(
+ dexfile->GetMethodSignature(mid).ToString(), &other_return_type_idx,
+ &other_param_type_idxs);
if (success) {
const DexFile::ProtoId* other_sig =
other_dexfile.FindProtoId(other_return_type_idx, other_param_type_idxs);
if (other_sig != nullptr) {
- const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(*other_type_id,
- *other_name,
- *other_sig);
+ const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
+ *other_type_id, *other_name, *other_sig);
if (other_mid != nullptr) {
return other_dexfile.GetIndexForMethodId(*other_mid);
}
@@ -448,15 +333,17 @@ class MethodHelper {
uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
uint32_t name_and_signature_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dexfile = GetDexFile();
- const DexFile::MethodId& mid = dexfile.GetMethodId(method_->GetDexMethodIndex());
+ mirror::ArtMethod* method = GetMethod();
+ const DexFile* dexfile = method->GetDexFile();
+ const uint32_t dex_method_idx = method->GetDexMethodIndex();
+ const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
- DCHECK_STREQ(dexfile.GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
- DCHECK_EQ(dexfile.GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
- if (&dexfile == &other_dexfile) {
- return method_->GetDexMethodIndex();
+ DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
+ DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
+ if (dexfile == &other_dexfile) {
+ return dex_method_idx;
}
- const char* mid_declaring_class_descriptor = dexfile.StringByTypeIdx(mid.class_idx_);
+ const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
const DexFile::StringId* other_descriptor =
other_dexfile.FindStringId(mid_declaring_class_descriptor);
if (other_descriptor != nullptr) {
@@ -478,24 +365,10 @@ class MethodHelper {
// Set the method_ field, for proxy methods looking up the interface method via the resolved
// methods table.
void SetMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (method != nullptr) {
- mirror::Class* klass = method->GetDeclaringClass();
- if (UNLIKELY(klass->IsProxyClass())) {
- mirror::ArtMethod* interface_method =
- method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
- DCHECK(interface_method != nullptr);
- DCHECK(interface_method == GetClassLinker()->FindMethodForProxy(klass, method));
- method = interface_method;
- }
- }
- method_ = method;
- }
-
- ClassLinker* GetClassLinker() ALWAYS_INLINE {
- return Runtime::Current()->GetClassLinker();
+ method_.Assign(method);
}
- mirror::ArtMethod* method_;
+ Handle<mirror::ArtMethod> method_;
const char* shorty_;
uint32_t shorty_len_;