Merge "Compute PPID at ninja time"
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 2d0dd3c..9efd636 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -31,10 +31,6 @@
namespace art {
-inline mirror::DexCache* CompilerDriver::GetDexCache(const DexCompilationUnit* mUnit) {
- return mUnit->GetClassLinker()->FindDexCache(Thread::Current(), *mUnit->GetDexFile(), false);
-}
-
inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAccess& soa,
const DexCompilationUnit* mUnit) {
return soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()).Decode();
@@ -87,10 +83,6 @@
return resolved_field;
}
-inline mirror::DexCache* CompilerDriver::FindDexCache(const DexFile* dex_file) {
- return Runtime::Current()->GetClassLinker()->FindDexCache(Thread::Current(), *dex_file, false);
-}
-
inline ArtField* CompilerDriver::ResolveField(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
@@ -100,31 +92,16 @@
is_static);
}
-inline void CompilerDriver::GetResolvedFieldDexFileLocation(
- ArtField* resolved_field, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) {
- mirror::Class* declaring_class = resolved_field->GetDeclaringClass();
- *declaring_dex_file = declaring_class->GetDexCache()->GetDexFile();
- *declaring_class_idx = declaring_class->GetDexTypeIndex();
- *declaring_field_idx = resolved_field->GetDexFieldIndex();
-}
-
-inline bool CompilerDriver::IsFieldVolatile(ArtField* field) {
- return field->IsVolatile();
-}
-
-inline MemberOffset CompilerDriver::GetFieldOffset(ArtField* field) {
- return field->GetOffset();
-}
-
inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
ArtField* resolved_field, uint16_t field_idx) {
DCHECK(!resolved_field->IsStatic());
- mirror::Class* fields_class = resolved_field->GetDeclaringClass();
+ ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
bool fast_get = referrer_class != nullptr &&
- referrer_class->CanAccessResolvedField(fields_class, resolved_field,
- dex_cache, field_idx);
+ referrer_class->CanAccessResolvedField(fields_class.Decode(),
+ resolved_field,
+ dex_cache,
+ field_idx);
bool fast_put = fast_get && (!resolved_field->IsFinal() || fields_class == referrer_class);
return std::make_pair(fast_get, fast_put);
}
@@ -167,13 +144,13 @@
uint32_t* storage_index) {
DCHECK(resolved_member->IsStatic());
if (LIKELY(referrer_class != nullptr)) {
- mirror::Class* members_class = resolved_member->GetDeclaringClass();
+ ObjPtr<mirror::Class> members_class = resolved_member->GetDeclaringClass();
if (members_class == referrer_class) {
*storage_index = members_class->GetDexTypeIndex();
return std::make_pair(true, true);
}
if (CanAccessResolvedMember<ArtMember>(
- referrer_class, members_class, resolved_member, dex_cache, member_idx)) {
+ referrer_class, members_class.Decode(), resolved_member, dex_cache, member_idx)) {
// We have the resolved member, we must make it into a index for the referrer
// in its static storage (which may fail if it doesn't have a slot for it)
// TODO: for images we can elide the static storage base null check
@@ -217,43 +194,6 @@
return result.first;
}
-inline bool CompilerDriver::IsStaticFieldInReferrerClass(mirror::Class* referrer_class,
- ArtField* resolved_field) {
- DCHECK(resolved_field->IsStatic());
- mirror::Class* fields_class = resolved_field->GetDeclaringClass();
- return referrer_class == fields_class;
-}
-
-inline bool CompilerDriver::CanAssumeClassIsInitialized(mirror::Class* klass) {
- // Being loaded is a pre-requisite for being initialized but let's do the cheap check first.
- //
- // NOTE: When AOT compiling an app, we eagerly initialize app classes (and potentially their
- // super classes in the boot image) but only those that have a trivial initialization, i.e.
- // without <clinit>() or static values in the dex file for that class or any of its super
- // classes. So while we could see the klass as initialized during AOT compilation and have
- // it only loaded at runtime, the needed initialization would have to be trivial and
- // unobservable from Java, so we may as well treat it as initialized.
- if (!klass->IsInitialized()) {
- return false;
- }
- return CanAssumeClassIsLoaded(klass);
-}
-
-inline bool CompilerDriver::CanReferrerAssumeClassIsInitialized(mirror::Class* referrer_class,
- mirror::Class* klass) {
- return (referrer_class != nullptr
- && !referrer_class->IsInterface()
- && referrer_class->IsSubClass(klass))
- || CanAssumeClassIsInitialized(klass);
-}
-
-inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
- ArtField* resolved_field) {
- DCHECK(resolved_field->IsStatic());
- mirror::Class* fields_class = resolved_field->GetDeclaringClass();
- return CanReferrerAssumeClassIsInitialized(referrer_class, fields_class);
-}
-
inline ArtMethod* CompilerDriver::ResolveMethod(
ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
@@ -273,35 +213,6 @@
return resolved_method;
}
-inline void CompilerDriver::GetResolvedMethodDexFileLocation(
- ArtMethod* resolved_method, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_method_idx) {
- mirror::Class* declaring_class = resolved_method->GetDeclaringClass();
- *declaring_dex_file = declaring_class->GetDexCache()->GetDexFile();
- *declaring_class_idx = declaring_class->GetDexTypeIndex();
- *declaring_method_idx = resolved_method->GetDexMethodIndex();
-}
-
-inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex(
- ArtMethod* resolved_method, InvokeType type) {
- if (type == kVirtual || type == kSuper) {
- return resolved_method->GetMethodIndex();
- } else if (type == kInterface) {
- return resolved_method->GetDexMethodIndex();
- } else {
- return DexFile::kDexNoIndex16;
- }
-}
-
-inline bool CompilerDriver::IsMethodsClassInitialized(mirror::Class* referrer_class,
- ArtMethod* resolved_method) {
- if (!resolved_method->IsStatic()) {
- return true;
- }
- mirror::Class* methods_class = resolved_method->GetDeclaringClass();
- return CanReferrerAssumeClassIsInitialized(referrer_class, methods_class);
-}
-
} // namespace art
#endif // ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 2ec3f16..2ad30ee 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -95,8 +95,6 @@
public:
AOTCompilationStats()
: stats_lock_("AOT compilation statistics lock"),
- types_in_dex_cache_(0), types_not_in_dex_cache_(0),
- strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
resolved_types_(0), unresolved_types_(0),
resolved_instance_fields_(0), unresolved_instance_fields_(0),
resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
@@ -112,8 +110,6 @@
}
void Dump() {
- DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
- DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
DumpStat(resolved_types_, unresolved_types_, "types resolved");
DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
@@ -164,26 +160,6 @@
#define STATS_LOCK()
#endif
- void TypeInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- types_in_dex_cache_++;
- }
-
- void TypeNotInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- types_not_in_dex_cache_++;
- }
-
- void StringInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- strings_in_dex_cache_++;
- }
-
- void StringNotInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- strings_not_in_dex_cache_++;
- }
-
void TypeDoesntNeedAccessCheck() REQUIRES(!stats_lock_) {
STATS_LOCK();
resolved_types_++;
@@ -225,67 +201,6 @@
type_based_devirtualization_++;
}
- // Indicate that a method of the given type was resolved at compile time.
- void ResolvedMethod(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- resolved_methods_[type]++;
- }
-
- // Indicate that a method of the given type was unresolved at compile time as it was in an
- // unknown dex file.
- void UnresolvedMethod(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- unresolved_methods_[type]++;
- }
-
- // Indicate that a type of virtual method dispatch has been converted into a direct method
- // dispatch.
- void VirtualMadeDirect(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK(type == kVirtual || type == kInterface || type == kSuper);
- STATS_LOCK();
- virtual_made_direct_[type]++;
- }
-
- // Indicate that a method of the given type was able to call directly into boot.
- void DirectCallsToBoot(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- direct_calls_to_boot_[type]++;
- }
-
- // Indicate that a method of the given type was able to be resolved directly from boot.
- void DirectMethodsToBoot(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- direct_methods_to_boot_[type]++;
- }
-
- void ProcessedInvoke(InvokeType type, int flags) REQUIRES(!stats_lock_) {
- STATS_LOCK();
- if (flags == 0) {
- unresolved_methods_[type]++;
- } else {
- DCHECK_NE((flags & kFlagMethodResolved), 0);
- resolved_methods_[type]++;
- if ((flags & kFlagVirtualMadeDirect) != 0) {
- virtual_made_direct_[type]++;
- if ((flags & kFlagPreciseTypeDevirtualization) != 0) {
- type_based_devirtualization_++;
- }
- } else {
- DCHECK_EQ((flags & kFlagPreciseTypeDevirtualization), 0);
- }
- if ((flags & kFlagDirectCallToBoot) != 0) {
- direct_calls_to_boot_[type]++;
- }
- if ((flags & kFlagDirectMethodToBoot) != 0) {
- direct_methods_to_boot_[type]++;
- }
- }
- }
-
// A check-cast could be eliminated due to verifier type analysis.
void SafeCast() REQUIRES(!stats_lock_) {
STATS_LOCK();
@@ -301,12 +216,6 @@
private:
Mutex stats_lock_;
- size_t types_in_dex_cache_;
- size_t types_not_in_dex_cache_;
-
- size_t strings_in_dex_cache_;
- size_t strings_not_in_dex_cache_;
-
size_t resolved_types_;
size_t unresolved_types_;
@@ -849,9 +758,10 @@
// TODO: Collect the relevant string indices in parallel, then allocate them sequentially in a
// stable order.
-static void ResolveConstStrings(CompilerDriver* driver,
+static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache,
const DexFile& dex_file,
- const DexFile::CodeItem* code_item) {
+ const DexFile::CodeItem* code_item)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
if (code_item == nullptr) {
// Abstract or native method.
return;
@@ -859,18 +769,19 @@
const uint16_t* code_ptr = code_item->insns_;
const uint16_t* code_end = code_item->insns_ + code_item->insns_size_in_code_units_;
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
while (code_ptr < code_end) {
const Instruction* inst = Instruction::At(code_ptr);
switch (inst->Opcode()) {
case Instruction::CONST_STRING: {
uint32_t string_index = inst->VRegB_21c();
- driver->CanAssumeStringIsPresentInDexCache(dex_file, string_index);
+ class_linker->ResolveString(dex_file, string_index, dex_cache);
break;
}
case Instruction::CONST_STRING_JUMBO: {
uint32_t string_index = inst->VRegB_31c();
- driver->CanAssumeStringIsPresentInDexCache(dex_file, string_index);
+ class_linker->ResolveString(dex_file, string_index, dex_cache);
break;
}
@@ -885,7 +796,13 @@
static void ResolveConstStrings(CompilerDriver* driver,
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings) {
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
+ MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
+
for (const DexFile* dex_file : dex_files) {
+ dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file, false));
TimingLogger::ScopedTiming t("Resolve const-string Strings", timings);
size_t class_def_count = dex_file->NumClassDefs();
@@ -926,7 +843,7 @@
continue;
}
previous_direct_method_idx = method_idx;
- ResolveConstStrings(driver, *dex_file, it.GetMethodCodeItem());
+ ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());
it.Next();
}
// Virtual methods.
@@ -940,7 +857,7 @@
continue;
}
previous_virtual_method_idx = method_idx;
- ResolveConstStrings(driver, *dex_file, it.GetMethodCodeItem());
+ ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());
it.Next();
}
DCHECK(!it.HasNext());
@@ -1411,54 +1328,6 @@
dex_to_dex_references_.back().GetMethodIndexes().SetBit(method_ref.dex_method_index);
}
-bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(Handle<mirror::DexCache> dex_cache,
- uint32_t type_idx) {
- bool result = false;
- if ((IsBootImage() &&
- IsImageClass(dex_cache->GetDexFile()->StringDataByIdx(
- dex_cache->GetDexFile()->GetTypeId(type_idx).descriptor_idx_))) ||
- Runtime::Current()->UseJitCompilation()) {
- mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
- result = (resolved_class != nullptr);
- }
-
- if (result) {
- stats_->TypeInDexCache();
- } else {
- stats_->TypeNotInDexCache();
- }
- return result;
-}
-
-bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
- uint32_t string_idx) {
- // See also Compiler::ResolveDexFile
-
- bool result = false;
- if (IsBootImage() || Runtime::Current()->UseJitCompilation()) {
- ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(
- soa.Self(), dex_file, false)));
- if (IsBootImage()) {
- // We resolve all const-string strings when building for the image.
- class_linker->ResolveString(dex_file, string_idx, dex_cache);
- result = true;
- } else {
- // Just check whether the dex cache already has the string.
- DCHECK(Runtime::Current()->UseJitCompilation());
- result = (dex_cache->GetResolvedString(string_idx) != nullptr);
- }
- }
- if (result) {
- stats_->StringInDexCache();
- } else {
- stats_->StringNotInDexCache();
- }
- return result;
-}
-
bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx,
Handle<mirror::DexCache> dex_cache,
uint32_t type_idx) {
@@ -1522,108 +1391,6 @@
return result;
}
-bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
- bool* is_type_initialized, bool* use_direct_type_ptr,
- uintptr_t* direct_type_ptr, bool* out_is_finalizable) {
- ScopedObjectAccess soa(Thread::Current());
- Runtime* runtime = Runtime::Current();
- mirror::DexCache* dex_cache = runtime->GetClassLinker()->FindDexCache(
- soa.Self(), dex_file, false);
- mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
- if (resolved_class == nullptr) {
- return false;
- }
- if (GetCompilerOptions().GetCompilePic()) {
- // Do not allow a direct class pointer to be used when compiling for position-independent
- return false;
- }
- *out_is_finalizable = resolved_class->IsFinalizable();
- gc::Heap* heap = runtime->GetHeap();
- const bool compiling_boot = heap->IsCompilingBoot();
- const bool support_boot_image_fixup = GetSupportBootImageFixup();
- if (compiling_boot) {
- // boot -> boot class pointers.
- // True if the class is in the image at boot compiling time.
- const bool is_image_class = IsBootImage() && IsImageClass(
- dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_));
- // True if pc relative load works.
- if (is_image_class && support_boot_image_fixup) {
- *is_type_initialized = resolved_class->IsInitialized();
- *use_direct_type_ptr = false;
- *direct_type_ptr = 0;
- return true;
- } else {
- return false;
- }
- } else if (runtime->UseJitCompilation() && !heap->IsMovableObject(resolved_class)) {
- *is_type_initialized = resolved_class->IsInitialized();
- // If the class may move around, then don't embed it as a direct pointer.
- *use_direct_type_ptr = true;
- *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
- return true;
- } else {
- // True if the class is in the image at app compiling time.
- const bool class_in_image = heap->FindSpaceFromObject(resolved_class, false)->IsImageSpace();
- if (class_in_image && support_boot_image_fixup) {
- // boot -> app class pointers.
- *is_type_initialized = resolved_class->IsInitialized();
- // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
- *use_direct_type_ptr = !GetCompilerOptions().GetIncludePatchInformation();
- *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
- return true;
- } else {
- // app -> app class pointers.
- // Give up because app does not have an image and class
- // isn't created at compile time. TODO: implement this
- // if/when each app gets an image.
- return false;
- }
- }
-}
-
-bool CompilerDriver::CanEmbedReferenceTypeInCode(ClassReference* ref,
- bool* use_direct_ptr,
- uintptr_t* direct_type_ptr) {
- CHECK(ref != nullptr);
- CHECK(use_direct_ptr != nullptr);
- CHECK(direct_type_ptr != nullptr);
-
- ScopedObjectAccess soa(Thread::Current());
- mirror::Class* reference_class = mirror::Reference::GetJavaLangRefReference();
- bool is_initialized = false;
- bool unused_finalizable;
- // Make sure we have a finished Reference class object before attempting to use it.
- if (!CanEmbedTypeInCode(*reference_class->GetDexCache()->GetDexFile(),
- reference_class->GetDexTypeIndex(), &is_initialized,
- use_direct_ptr, direct_type_ptr, &unused_finalizable) ||
- !is_initialized) {
- return false;
- }
- ref->first = &reference_class->GetDexFile();
- ref->second = reference_class->GetDexClassDefIndex();
- return true;
-}
-
-uint32_t CompilerDriver::GetReferenceSlowFlagOffset() const {
- ScopedObjectAccess soa(Thread::Current());
- mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
- DCHECK(klass->IsInitialized());
- return klass->GetSlowPathFlagOffset().Uint32Value();
-}
-
-uint32_t CompilerDriver::GetReferenceDisableFlagOffset() const {
- ScopedObjectAccess soa(Thread::Current());
- mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
- DCHECK(klass->IsInitialized());
- return klass->GetDisableIntrinsicFlagOffset().Uint32Value();
-}
-
-DexCacheArraysLayout CompilerDriver::GetDexCacheArraysLayout(const DexFile* dex_file) {
- return ContainsElement(GetDexFilesForOatFile(), dex_file)
- ? DexCacheArraysLayout(GetInstructionSetPointerSize(instruction_set_), dex_file)
- : DexCacheArraysLayout();
-}
-
void CompilerDriver::ProcessedInstanceField(bool resolved) {
if (!resolved) {
stats_->UnresolvedInstanceField();
@@ -1642,10 +1409,6 @@
}
}
-void CompilerDriver::ProcessedInvoke(InvokeType invoke_type, int flags) {
- stats_->ProcessedInvoke(invoke_type, flags);
-}
-
ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
const DexCompilationUnit* mUnit, bool is_put,
const ScopedObjectAccess& soa) {
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 52a04cc..fc63df1 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -189,15 +189,6 @@
uint16_t class_def_index)
REQUIRES(!requires_constructor_barrier_lock_);
- // Callbacks from compiler to see what runtime checks must be generated.
-
- bool CanAssumeTypeIsPresentInDexCache(Handle<mirror::DexCache> dex_cache,
- uint32_t type_idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- bool CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, uint32_t string_idx)
- REQUIRES(!Locks::mutator_lock_);
-
// Are runtime access checks necessary in the compiled code?
bool CanAccessTypeWithoutChecks(uint32_t referrer_idx,
Handle<mirror::DexCache> dex_cache,
@@ -212,24 +203,6 @@
bool* out_is_finalizable)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
- bool* is_type_initialized, bool* use_direct_type_ptr,
- uintptr_t* direct_type_ptr, bool* out_is_finalizable);
-
- // Query methods for the java.lang.ref.Reference class.
- bool CanEmbedReferenceTypeInCode(ClassReference* ref,
- bool* use_direct_type_ptr, uintptr_t* direct_type_ptr);
- uint32_t GetReferenceSlowFlagOffset() const;
- uint32_t GetReferenceDisableFlagOffset() const;
-
- // Get the DexCache for the
- mirror::DexCache* GetDexCache(const DexCompilationUnit* mUnit)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa,
- const DexCompilationUnit* mUnit)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Resolve compiling method's class. Returns null on failure.
mirror::Class* ResolveCompilingMethodsClass(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
@@ -257,19 +230,6 @@
uint32_t field_idx, bool is_static)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get declaration location of a resolved field.
- void GetResolvedFieldDexFileLocation(
- ArtField* resolved_field, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_field_idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- bool IsFieldVolatile(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
- MemberOffset GetFieldOffset(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Find a dex cache for a dex file.
- inline mirror::DexCache* FindDexCache(const DexFile* dex_file)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset.
std::pair<bool, bool> IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
@@ -295,15 +255,6 @@
uint32_t* storage_index)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Is static field's in referrer's class?
- bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, ArtField* resolved_field)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Is static field's class initialized?
- bool IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
- ArtField* resolved_field)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Resolve a method. Returns null on failure, including incompatible class change.
ArtMethod* ResolveMethod(
ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
@@ -311,37 +262,8 @@
uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get declaration location of a resolved field.
- void GetResolvedMethodDexFileLocation(
- ArtMethod* resolved_method, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_method_idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Get the index in the vtable of the method.
- uint16_t GetResolvedMethodVTableIndex(
- ArtMethod* resolved_method, InvokeType type)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Is method's class initialized for an invoke?
- // For static invokes to determine whether we need to consider potential call to <clinit>().
- // For non-static invokes, assuming a non-null reference, the class is always initialized.
- bool IsMethodsClassInitialized(mirror::Class* referrer_class, ArtMethod* resolved_method)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Get the layout of dex cache arrays for a dex file. Returns invalid layout if the
- // dex cache arrays don't have a fixed layout.
- DexCacheArraysLayout GetDexCacheArraysLayout(const DexFile* dex_file);
-
void ProcessedInstanceField(bool resolved);
void ProcessedStaticField(bool resolved, bool local);
- void ProcessedInvoke(InvokeType invoke_type, int flags);
-
- void ComputeFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
- const ScopedObjectAccess& soa, bool is_static,
- ArtField** resolved_field,
- mirror::Class** referrer_class,
- mirror::DexCache** dex_cache)
- REQUIRES_SHARED(Locks::mutator_lock_);
// Can we fast path instance field access? Computes field's offset and volatility.
bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
@@ -393,6 +315,7 @@
void SetDedupeEnabled(bool dedupe_enabled) {
compiled_method_storage_.SetDedupeEnabled(dedupe_enabled);
}
+
bool DedupeEnabled() const {
return compiled_method_storage_.DedupeEnabled();
}
@@ -456,6 +379,13 @@
return current_dex_to_dex_methods_;
}
+ // Compute constant code and method pointers when possible.
+ void GetCodeAndMethodForDirectCall(const mirror::Class* referrer_class,
+ ArtMethod* method,
+ /* out */ uintptr_t* direct_code,
+ /* out */ uintptr_t* direct_method)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
// Return whether the declaring class of `resolved_member` is
// available to `referrer_class` for read or write access using two
@@ -484,38 +414,9 @@
uint32_t field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Can we assume that the klass is initialized?
- bool CanAssumeClassIsInitialized(mirror::Class* klass)
- REQUIRES_SHARED(Locks::mutator_lock_);
- bool CanReferrerAssumeClassIsInitialized(mirror::Class* referrer_class, mirror::Class* klass)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // These flags are internal to CompilerDriver for collecting INVOKE resolution statistics.
- // The only external contract is that unresolved method has flags 0 and resolved non-0.
- enum {
- kBitMethodResolved = 0,
- kBitVirtualMadeDirect,
- kBitPreciseTypeDevirtualization,
- kBitDirectCallToBoot,
- kBitDirectMethodToBoot
- };
- static constexpr int kFlagMethodResolved = 1 << kBitMethodResolved;
- static constexpr int kFlagVirtualMadeDirect = 1 << kBitVirtualMadeDirect;
- static constexpr int kFlagPreciseTypeDevirtualization = 1 << kBitPreciseTypeDevirtualization;
- static constexpr int kFlagDirectCallToBoot = 1 << kBitDirectCallToBoot;
- static constexpr int kFlagDirectMethodToBoot = 1 << kBitDirectMethodToBoot;
- static constexpr int kFlagsMethodResolvedVirtualMadeDirect =
- kFlagMethodResolved | kFlagVirtualMadeDirect;
- static constexpr int kFlagsMethodResolvedPreciseTypeDevirtualization =
- kFlagsMethodResolvedVirtualMadeDirect | kFlagPreciseTypeDevirtualization;
-
- public: // TODO make private or eliminate.
- // Compute constant code and method pointers when possible.
- void GetCodeAndMethodForDirectCall(const mirror::Class* referrer_class,
- ArtMethod* method,
- /* out */ uintptr_t* direct_code,
- /* out */ uintptr_t* direct_method)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa,
+ const DexCompilationUnit* mUnit)
+ REQUIRES_SHARED(Locks::mutator_lock_);
private:
void PreCompile(jobject class_loader,
@@ -573,8 +474,6 @@
REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
void UpdateImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_);
- static void FindClinitImageClassesCallback(mirror::Object* object, void* arg)
- REQUIRES_SHARED(Locks::mutator_lock_);
void Compile(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 41bda60..210943c 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -908,7 +908,7 @@
ArtField** resolved_fields = dex_cache->GetResolvedFields();
for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
ArtField* field = mirror::DexCache::GetElementPtrSize(resolved_fields, i, target_ptr_size_);
- if (field != nullptr && !KeepClass(field->GetDeclaringClass())) {
+ if (field != nullptr && !KeepClass(field->GetDeclaringClass().Decode())) {
dex_cache->SetResolvedField(i, nullptr, target_ptr_size_);
}
}
@@ -1742,7 +1742,7 @@
case kNativeObjectRelocationTypeArtField: {
memcpy(dest, pair.first, sizeof(ArtField));
reinterpret_cast<ArtField*>(dest)->SetDeclaringClass(
- GetImageAddress(reinterpret_cast<ArtField*>(pair.first)->GetDeclaringClass()));
+ GetImageAddress(reinterpret_cast<ArtField*>(pair.first)->GetDeclaringClass().Decode()));
break;
}
case kNativeObjectRelocationTypeRuntimeMethod:
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 5a47df1..15cebfe 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -84,7 +84,7 @@
void VisitNewArray(HNewArray* instr) OVERRIDE;
void VisitParameterValue(HParameterValue* instr) OVERRIDE;
void UpdateFieldAccessTypeInfo(HInstruction* instr, const FieldInfo& info);
- void SetClassAsTypeInfo(HInstruction* instr, mirror::Class* klass, bool is_exact)
+ void SetClassAsTypeInfo(HInstruction* instr, ObjPtr<mirror::Class> klass, bool is_exact)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitInstanceFieldGet(HInstanceFieldGet* instr) OVERRIDE;
void VisitStaticFieldGet(HStaticFieldGet* instr) OVERRIDE;
@@ -427,7 +427,7 @@
}
void ReferenceTypePropagation::RTPVisitor::SetClassAsTypeInfo(HInstruction* instr,
- mirror::Class* klass,
+ ObjPtr<mirror::Class> klass,
bool is_exact) {
if (instr->IsInvokeStaticOrDirect() && instr->AsInvokeStaticOrDirect()->IsStringInit()) {
// Calls to String.<init> are replaced with a StringFactory.
@@ -454,7 +454,7 @@
}
instr->SetReferenceTypeInfo(
ReferenceTypeInfo::Create(handle_cache_->GetStringClassHandle(), /* is_exact */ true));
- } else if (IsAdmissible(klass)) {
+ } else if (IsAdmissible(klass.Decode())) {
ReferenceTypeInfo::TypeHandle handle = handle_cache_->NewHandle(klass);
is_exact = is_exact || handle->CannotBeAssignedFromOtherTypes();
instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(handle, is_exact));
@@ -512,7 +512,7 @@
}
ScopedObjectAccess soa(Thread::Current());
- mirror::Class* klass = nullptr;
+ ObjPtr<mirror::Class> klass;
// The field index is unknown only during tests.
if (info.GetFieldIndex() != kUnknownFieldIndex) {
diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h
index 1fa6624..61428b2 100644
--- a/compiler/optimizing/reference_type_propagation.h
+++ b/compiler/optimizing/reference_type_propagation.h
@@ -21,6 +21,7 @@
#include "driver/dex_compilation_unit.h"
#include "handle_scope-inl.h"
#include "nodes.h"
+#include "obj_ptr.h"
#include "optimization.h"
#include "optimizing_compiler_stats.h"
@@ -62,6 +63,11 @@
return handles_->NewHandle(object);
}
+ template <typename T>
+ MutableHandle<T> NewHandle(ObjPtr<T> object) REQUIRES_SHARED(Locks::mutator_lock_) {
+ return handles_->NewHandle(object);
+ }
+
ReferenceTypeInfo::TypeHandle GetObjectClassHandle();
ReferenceTypeInfo::TypeHandle GetClassClassHandle();
ReferenceTypeInfo::TypeHandle GetStringClassHandle();
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index be5224b..4d0dc56 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1687,7 +1687,9 @@
ImageDumper* const image_dumper_;
};
- static void PrettyObjectValue(std::ostream& os, mirror::Class* type, mirror::Object* value)
+ static void PrettyObjectValue(std::ostream& os,
+ ObjPtr<mirror::Class> type,
+ ObjPtr<mirror::Object> value)
REQUIRES_SHARED(Locks::mutator_lock_) {
CHECK(type != nullptr);
if (value == nullptr) {
@@ -1700,11 +1702,11 @@
mirror::Class* klass = value->AsClass();
os << StringPrintf("%p Class: %s\n", klass, PrettyDescriptor(klass).c_str());
} else {
- os << StringPrintf("%p %s\n", value, PrettyDescriptor(type).c_str());
+ os << StringPrintf("%p %s\n", value.Decode(), PrettyDescriptor(type).c_str());
}
}
- static void PrintField(std::ostream& os, ArtField* field, mirror::Object* obj)
+ static void PrintField(std::ostream& os, ArtField* field, ObjPtr<mirror::Object> obj)
REQUIRES_SHARED(Locks::mutator_lock_) {
os << StringPrintf("%s: ", field->GetName());
switch (field->GetTypeAsPrimitiveType()) {
@@ -1736,16 +1738,17 @@
case Primitive::kPrimNot: {
// Get the value, don't compute the type unless it is non-null as we don't want
// to cause class loading.
- mirror::Object* value = field->GetObj(obj);
+ ObjPtr<mirror::Object> value = field->GetObj(obj);
if (value == nullptr) {
os << StringPrintf("null %s\n", PrettyDescriptor(field->GetTypeDescriptor()).c_str());
} else {
// Grab the field type without causing resolution.
- mirror::Class* field_type = field->GetType<false>();
+ ObjPtr<mirror::Class> field_type = field->GetType<false>();
if (field_type != nullptr) {
PrettyObjectValue(os, field_type, value);
} else {
- os << StringPrintf("%p %s\n", value,
+ os << StringPrintf("%p %s\n",
+ value.Decode(),
PrettyDescriptor(field->GetTypeDescriptor()).c_str());
}
}
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index d58f38c..b259f64 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -504,7 +504,8 @@
void Visit(ArtField* field) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
ArtField* const dest = patch_oat_->RelocatedCopyOf(field);
- dest->SetDeclaringClass(patch_oat_->RelocatedAddressOfPointer(field->GetDeclaringClass()));
+ dest->SetDeclaringClass(
+ patch_oat_->RelocatedAddressOfPointer(field->GetDeclaringClass().Decode()));
}
private:
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index 5e39f42..432ba36 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -1688,7 +1688,7 @@
EXPECT_EQ(res, reinterpret_cast<size_t>(val)) << "Value " << val;
- EXPECT_EQ(val, f->GetObj(trg));
+ EXPECT_OBJ_PTR_EQ(val, f->GetObj(trg));
}
#endif
diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h
index ca96169..a52c714 100644
--- a/runtime/art_field-inl.h
+++ b/runtime/art_field-inl.h
@@ -34,15 +34,15 @@
namespace art {
template<ReadBarrierOption kReadBarrierOption>
-inline mirror::Class* ArtField::GetDeclaringClass() {
+inline ObjPtr<mirror::Class> ArtField::GetDeclaringClass() {
GcRootSource gc_root_source(this);
- mirror::Class* result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
+ ObjPtr<mirror::Class> result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
DCHECK(result != nullptr);
DCHECK(result->IsLoaded() || result->IsErroneous()) << result->GetStatus();
return result;
}
-inline void ArtField::SetDeclaringClass(mirror::Class* new_declaring_class) {
+inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
}
@@ -61,7 +61,7 @@
return MemberOffset(offset_);
}
-inline uint32_t ArtField::Get32(mirror::Object* object) {
+inline uint32_t ArtField::Get32(ObjPtr<mirror::Object> object) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -71,7 +71,7 @@
}
template<bool kTransactionActive>
-inline void ArtField::Set32(mirror::Object* object, uint32_t new_value) {
+inline void ArtField::Set32(ObjPtr<mirror::Object> object, uint32_t new_value) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -81,7 +81,7 @@
}
}
-inline uint64_t ArtField::Get64(mirror::Object* object) {
+inline uint64_t ArtField::Get64(ObjPtr<mirror::Object> object) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -91,7 +91,7 @@
}
template<bool kTransactionActive>
-inline void ArtField::Set64(mirror::Object* object, uint64_t new_value) {
+inline void ArtField::Set64(ObjPtr<mirror::Object> object, uint64_t new_value) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -101,23 +101,24 @@
}
}
-inline mirror::Object* ArtField::GetObj(mirror::Object* object) {
+template<class MirrorType>
+inline ObjPtr<MirrorType> ArtField::GetObj(ObjPtr<mirror::Object> object) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
- return object->GetFieldObjectVolatile<mirror::Object>(GetOffset());
+ return object->GetFieldObjectVolatile<MirrorType>(GetOffset());
}
- return object->GetFieldObject<mirror::Object>(GetOffset());
+ return object->GetFieldObject<MirrorType>(GetOffset());
}
template<bool kTransactionActive>
-inline void ArtField::SetObj(mirror::Object* object, mirror::Object* new_value) {
+inline void ArtField::SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
- object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
+ object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value.Decode());
} else {
- object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
+ object->SetFieldObject<kTransactionActive>(GetOffset(), new_value.Decode());
}
}
@@ -140,46 +141,46 @@
(object)->SetField ## type<kTransactionActive>(GetOffset(), value); \
}
-inline uint8_t ArtField::GetBoolean(mirror::Object* object) {
+inline uint8_t ArtField::GetBoolean(ObjPtr<mirror::Object> object) {
FIELD_GET(object, Boolean);
}
template<bool kTransactionActive>
-inline void ArtField::SetBoolean(mirror::Object* object, uint8_t z) {
+inline void ArtField::SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) {
FIELD_SET(object, Boolean, z);
}
-inline int8_t ArtField::GetByte(mirror::Object* object) {
+inline int8_t ArtField::GetByte(ObjPtr<mirror::Object> object) {
FIELD_GET(object, Byte);
}
template<bool kTransactionActive>
-inline void ArtField::SetByte(mirror::Object* object, int8_t b) {
+inline void ArtField::SetByte(ObjPtr<mirror::Object> object, int8_t b) {
FIELD_SET(object, Byte, b);
}
-inline uint16_t ArtField::GetChar(mirror::Object* object) {
+inline uint16_t ArtField::GetChar(ObjPtr<mirror::Object> object) {
FIELD_GET(object, Char);
}
template<bool kTransactionActive>
-inline void ArtField::SetChar(mirror::Object* object, uint16_t c) {
+inline void ArtField::SetChar(ObjPtr<mirror::Object> object, uint16_t c) {
FIELD_SET(object, Char, c);
}
-inline int16_t ArtField::GetShort(mirror::Object* object) {
+inline int16_t ArtField::GetShort(ObjPtr<mirror::Object> object) {
FIELD_GET(object, Short);
}
template<bool kTransactionActive>
-inline void ArtField::SetShort(mirror::Object* object, int16_t s) {
+inline void ArtField::SetShort(ObjPtr<mirror::Object> object, int16_t s) {
FIELD_SET(object, Short, s);
}
#undef FIELD_GET
#undef FIELD_SET
-inline int32_t ArtField::GetInt(mirror::Object* object) {
+inline int32_t ArtField::GetInt(ObjPtr<mirror::Object> object) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
@@ -188,7 +189,7 @@
}
template<bool kTransactionActive>
-inline void ArtField::SetInt(mirror::Object* object, int32_t i) {
+inline void ArtField::SetInt(ObjPtr<mirror::Object> object, int32_t i) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
@@ -196,7 +197,7 @@
Set32<kTransactionActive>(object, i);
}
-inline int64_t ArtField::GetLong(mirror::Object* object) {
+inline int64_t ArtField::GetLong(ObjPtr<mirror::Object> object) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
@@ -205,7 +206,7 @@
}
template<bool kTransactionActive>
-inline void ArtField::SetLong(mirror::Object* object, int64_t j) {
+inline void ArtField::SetLong(ObjPtr<mirror::Object> object, int64_t j) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
@@ -213,7 +214,7 @@
Set64<kTransactionActive>(object, j);
}
-inline float ArtField::GetFloat(mirror::Object* object) {
+inline float ArtField::GetFloat(ObjPtr<mirror::Object> object) {
DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetI(Get32(object));
@@ -221,14 +222,14 @@
}
template<bool kTransactionActive>
-inline void ArtField::SetFloat(mirror::Object* object, float f) {
+inline void ArtField::SetFloat(ObjPtr<mirror::Object> object, float f) {
DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetF(f);
Set32<kTransactionActive>(object, bits.GetI());
}
-inline double ArtField::GetDouble(mirror::Object* object) {
+inline double ArtField::GetDouble(ObjPtr<mirror::Object> object) {
DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetJ(Get64(object));
@@ -236,20 +237,20 @@
}
template<bool kTransactionActive>
-inline void ArtField::SetDouble(mirror::Object* object, double d) {
+inline void ArtField::SetDouble(ObjPtr<mirror::Object> object, double d) {
DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetD(d);
Set64<kTransactionActive>(object, bits.GetJ());
}
-inline mirror::Object* ArtField::GetObject(mirror::Object* object) {
+inline ObjPtr<mirror::Object> ArtField::GetObject(ObjPtr<mirror::Object> object) {
DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
return GetObj(object);
}
template<bool kTransactionActive>
-inline void ArtField::SetObject(mirror::Object* object, mirror::Object* l) {
+inline void ArtField::SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l) {
DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
SetObj<kTransactionActive>(object, l);
}
@@ -288,16 +289,16 @@
}
template <bool kResolve>
-inline mirror::Class* ArtField::GetType() {
+inline ObjPtr<mirror::Class> ArtField::GetType() {
const uint32_t field_index = GetDexFieldIndex();
- auto* declaring_class = GetDeclaringClass();
+ ObjPtr<mirror::Class> declaring_class = GetDeclaringClass();
if (UNLIKELY(declaring_class->IsProxyClass())) {
return ProxyFindSystemClass(GetTypeDescriptor());
}
auto* dex_cache = declaring_class->GetDexCache();
const DexFile* const dex_file = dex_cache->GetDexFile();
const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
- mirror::Class* type = dex_cache->GetResolvedType(field_id.type_idx_);
+ ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(field_id.type_idx_);
if (kResolve && UNLIKELY(type == nullptr)) {
type = ResolveGetType(field_id.type_idx_);
CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
@@ -309,7 +310,7 @@
return Primitive::ComponentSize(GetTypeAsPrimitiveType());
}
-inline mirror::DexCache* ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
+inline ObjPtr<mirror::DexCache> ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
return GetDeclaringClass()->GetDexCache();
}
@@ -317,13 +318,13 @@
return GetDexCache()->GetDexFile();
}
-inline mirror::String* ArtField::GetStringName(Thread* self, bool resolve) {
+inline ObjPtr<mirror::String> ArtField::GetStringName(Thread* self, bool resolve) {
auto dex_field_index = GetDexFieldIndex();
CHECK_NE(dex_field_index, DexFile::kDexNoIndex);
- auto* dex_cache = GetDexCache();
+ ObjPtr<mirror::DexCache> dex_cache = GetDexCache();
const auto* dex_file = dex_cache->GetDexFile();
const auto& field_id = dex_file->GetFieldId(dex_field_index);
- auto* name = dex_cache->GetResolvedString(field_id.name_idx_);
+ ObjPtr<mirror::String> name = dex_cache->GetResolvedString(field_id.name_idx_);
if (resolve && name == nullptr) {
name = ResolveGetStringName(self, *dex_file, field_id.name_idx_, dex_cache);
}
@@ -337,8 +338,8 @@
template <typename Visitor>
inline void ArtField::UpdateObjects(const Visitor& visitor) {
- mirror::Class* old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
- mirror::Class* new_class = visitor(old_class);
+ ObjPtr<mirror::Class> old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
+ ObjPtr<mirror::Class> new_class = visitor(old_class.Decode());
if (old_class != new_class) {
SetDeclaringClass(new_class);
}
@@ -369,7 +370,7 @@
}
template <bool kExactOffset>
-inline ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass,
+inline ArtField* ArtField::FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass,
uint32_t field_offset) {
DCHECK(klass != nullptr);
ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset);
@@ -382,7 +383,8 @@
}
template <bool kExactOffset>
-inline ArtField* ArtField::FindStaticFieldWithOffset(mirror::Class* klass, uint32_t field_offset) {
+inline ArtField* ArtField::FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass,
+ uint32_t field_offset) {
DCHECK(klass != nullptr);
return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset);
}
diff --git a/runtime/art_field.cc b/runtime/art_field.cc
index 3b4db0b..78c62d6 100644
--- a/runtime/art_field.cc
+++ b/runtime/art_field.cc
@@ -30,10 +30,6 @@
namespace art {
-ArtField::ArtField() : access_flags_(0), field_dex_idx_(0), offset_(0) {
- declaring_class_ = GcRoot<mirror::Class>(nullptr);
-}
-
void ArtField::SetOffset(MemberOffset num_bytes) {
DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
if (kIsDebugBuild && Runtime::Current()->IsAotCompiler() &&
@@ -47,20 +43,23 @@
offset_ = num_bytes.Uint32Value();
}
-mirror::Class* ArtField::ProxyFindSystemClass(const char* descriptor) {
+ObjPtr<mirror::Class> ArtField::ProxyFindSystemClass(const char* descriptor) {
DCHECK(GetDeclaringClass()->IsProxyClass());
return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), descriptor);
}
-mirror::Class* ArtField::ResolveGetType(uint32_t type_idx) {
+ObjPtr<mirror::Class> ArtField::ResolveGetType(uint32_t type_idx) {
return Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this);
}
-mirror::String* ArtField::ResolveGetStringName(Thread* self, const DexFile& dex_file,
- uint32_t string_idx, mirror::DexCache* dex_cache) {
+ObjPtr<mirror::String> ArtField::ResolveGetStringName(Thread* self,
+ const DexFile& dex_file,
+ uint32_t string_idx,
+ ObjPtr<mirror::DexCache> dex_cache) {
StackHandleScope<1> hs(self);
- return Runtime::Current()->GetClassLinker()->ResolveString(
- dex_file, string_idx, hs.NewHandle(dex_cache));
+ return Runtime::Current()->GetClassLinker()->ResolveString(dex_file,
+ string_idx,
+ hs.NewHandle(dex_cache));
}
} // namespace art
diff --git a/runtime/art_field.h b/runtime/art_field.h
index 16e6c75..8ba383c 100644
--- a/runtime/art_field.h
+++ b/runtime/art_field.h
@@ -21,6 +21,7 @@
#include "gc_root.h"
#include "modifiers.h"
+#include "obj_ptr.h"
#include "offsets.h"
#include "primitive.h"
#include "read_barrier_option.h"
@@ -39,12 +40,10 @@
class ArtField FINAL {
public:
- ArtField();
-
template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- mirror::Class* GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::Class> GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_);
- void SetDeclaringClass(mirror::Class *new_declaring_class)
+ void SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class)
REQUIRES_SHARED(Locks::mutator_lock_);
uint32_t GetAccessFlags() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -87,68 +86,72 @@
void SetOffset(MemberOffset num_bytes) REQUIRES_SHARED(Locks::mutator_lock_);
// field access, null object for static fields
- uint8_t GetBoolean(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ uint8_t GetBoolean(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetBoolean(mirror::Object* object, uint8_t z) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) REQUIRES_SHARED(Locks::mutator_lock_);
- int8_t GetByte(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ int8_t GetByte(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetByte(mirror::Object* object, int8_t b) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetByte(ObjPtr<mirror::Object> object, int8_t b) REQUIRES_SHARED(Locks::mutator_lock_);
- uint16_t GetChar(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ uint16_t GetChar(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetChar(mirror::Object* object, uint16_t c) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetChar(ObjPtr<mirror::Object> object, uint16_t c) REQUIRES_SHARED(Locks::mutator_lock_);
- int16_t GetShort(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ int16_t GetShort(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetShort(mirror::Object* object, int16_t s) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetShort(ObjPtr<mirror::Object> object, int16_t s) REQUIRES_SHARED(Locks::mutator_lock_);
- int32_t GetInt(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ int32_t GetInt(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetInt(mirror::Object* object, int32_t i) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetInt(ObjPtr<mirror::Object> object, int32_t i) REQUIRES_SHARED(Locks::mutator_lock_);
- int64_t GetLong(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ int64_t GetLong(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetLong(mirror::Object* object, int64_t j) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetLong(ObjPtr<mirror::Object> object, int64_t j) REQUIRES_SHARED(Locks::mutator_lock_);
- float GetFloat(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ float GetFloat(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetFloat(mirror::Object* object, float f) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetFloat(ObjPtr<mirror::Object> object, float f) REQUIRES_SHARED(Locks::mutator_lock_);
- double GetDouble(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ double GetDouble(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetDouble(mirror::Object* object, double d) REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetDouble(ObjPtr<mirror::Object> object, double d) REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::Object* GetObject(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::Object> GetObject(ObjPtr<mirror::Object> object)
+ REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetObject(mirror::Object* object, mirror::Object* l)
+ void SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l)
REQUIRES_SHARED(Locks::mutator_lock_);
// Raw field accesses.
- uint32_t Get32(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ uint32_t Get32(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void Set32(mirror::Object* object, uint32_t new_value)
+ void Set32(ObjPtr<mirror::Object> object, uint32_t new_value)
REQUIRES_SHARED(Locks::mutator_lock_);
- uint64_t Get64(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ uint64_t Get64(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void Set64(mirror::Object* object, uint64_t new_value) REQUIRES_SHARED(Locks::mutator_lock_);
+ void Set64(ObjPtr<mirror::Object> object, uint64_t new_value)
+ REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::Object* GetObj(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_);
+ template<class MirrorType = mirror::Object>
+ ObjPtr<MirrorType> GetObj(ObjPtr<mirror::Object> object)
+ REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void SetObj(mirror::Object* object, mirror::Object* new_value)
+ void SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value)
REQUIRES_SHARED(Locks::mutator_lock_);
// NO_THREAD_SAFETY_ANALYSIS since we don't know what the callback requires.
@@ -163,20 +166,20 @@
// If kExactOffset is true then we only find the matching offset, not the field containing the
// offset.
template <bool kExactOffset = true>
- static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
+ static ArtField* FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass, uint32_t field_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns a static field with this offset in the given class or null if not found.
// If kExactOffset is true then we only find the matching offset, not the field containing the
// offset.
template <bool kExactOffset = true>
- static ArtField* FindStaticFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
+ static ArtField* FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass, uint32_t field_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
const char* GetName() REQUIRES_SHARED(Locks::mutator_lock_);
// Resolves / returns the name from the dex cache.
- mirror::String* GetStringName(Thread* self, bool resolve)
+ ObjPtr<mirror::String> GetStringName(Thread* self, bool resolve)
REQUIRES_SHARED(Locks::mutator_lock_);
const char* GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -186,11 +189,11 @@
bool IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_);
template <bool kResolve>
- mirror::Class* GetType() REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::Class> GetType() REQUIRES_SHARED(Locks::mutator_lock_);
size_t FieldSize() REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::DexCache* GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::DexCache> GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
const DexFile* GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -204,22 +207,24 @@
REQUIRES_SHARED(Locks::mutator_lock_);
private:
- mirror::Class* ProxyFindSystemClass(const char* descriptor)
+ ObjPtr<mirror::Class> ProxyFindSystemClass(const char* descriptor)
REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::Class* ResolveGetType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::String* ResolveGetStringName(Thread* self, const DexFile& dex_file, uint32_t string_idx,
- mirror::DexCache* dex_cache)
+ ObjPtr<mirror::Class> ResolveGetType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::String> ResolveGetStringName(Thread* self,
+ const DexFile& dex_file,
+ uint32_t string_idx,
+ ObjPtr<mirror::DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
GcRoot<mirror::Class> declaring_class_;
- uint32_t access_flags_;
+ uint32_t access_flags_ = 0;
// Dex cache index of field id
- uint32_t field_dex_idx_;
+ uint32_t field_dex_idx_ = 0;
// Offset of field within an instance or in the Class' static fields
- uint32_t offset_;
+ uint32_t offset_ = 0;
};
} // namespace art
diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc
index 17873b5..d09e66f 100644
--- a/runtime/base/logging.cc
+++ b/runtime/base/logging.cc
@@ -27,7 +27,7 @@
// Headers for LogMessage::LogLine.
#ifdef ART_TARGET_ANDROID
-#include "cutils/log.h"
+#include <android/log.h>
#include <android/set_abort_message.h>
#else
#include <sys/types.h>
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 9f07702..c671b81 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -274,7 +274,7 @@
AbortF("field operation on NULL object: %p", java_object);
return false;
}
- if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o.Decode())) {
+ if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) {
Runtime::Current()->GetHeap()->DumpSpaces(LOG_STREAM(ERROR));
AbortF("field operation on invalid %s: %p",
ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(),
@@ -334,7 +334,7 @@
}
if (invoke != kVirtual) {
ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(jc);
- if (!m->GetDeclaringClass()->IsAssignableFrom(c.Decode())) {
+ if (!m->GetDeclaringClass()->IsAssignableFrom(c)) {
AbortF("can't call %s %s with class %s", invoke == kStatic ? "static" : "nonvirtual",
PrettyMethod(m).c_str(), PrettyClass(c).c_str());
return false;
@@ -388,7 +388,7 @@
return false;
}
ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
- if (!m->GetDeclaringClass()->IsAssignableFrom(c.Decode())) {
+ if (!m->GetDeclaringClass()->IsAssignableFrom(c)) {
AbortF("can't call static %s on class %s", PrettyMethod(m).c_str(), PrettyClass(c).c_str());
return false;
}
@@ -939,7 +939,7 @@
ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(jc);
if (c == nullptr) {
*msg += "NULL";
- } else if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(c.Decode())) {
+ } else if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) {
StringAppendF(msg, "INVALID POINTER:%p", jc);
} else if (!c->IsClass()) {
*msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c);
@@ -1108,7 +1108,7 @@
}
ObjPtr<mirror::Array> a = soa.Decode<mirror::Array>(java_array);
- if (UNLIKELY(!Runtime::Current()->GetHeap()->IsValidObjectAddress(a.Decode()))) {
+ if (UNLIKELY(!Runtime::Current()->GetHeap()->IsValidObjectAddress(a))) {
Runtime::Current()->GetHeap()->DumpSpaces(LOG_STREAM(ERROR));
AbortF("jarray is an invalid %s: %p (%p)",
ToStr<IndirectRefKind>(GetIndirectRefKind(java_array)).c_str(),
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 51e5aae..378da57 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -63,6 +63,7 @@
}
inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx, ArtMethod* referrer) {
+ Thread::PoisonObjectPointersIfDebug();
mirror::Class* declaring_class = referrer->GetDeclaringClass();
// MethodVerifier refuses methods with string_idx out of bounds.
DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());;
@@ -70,7 +71,6 @@
mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
string_idx,
mirror::DexCache::kDexCacheStringCacheSize).Read();
- Thread::PoisonObjectPointersIfDebug();
if (UNLIKELY(string == nullptr)) {
StackHandleScope<1> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
@@ -84,8 +84,8 @@
}
inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtMethod* referrer) {
- mirror::Class* resolved_type = referrer->GetDexCacheResolvedType(type_idx, image_pointer_size_);
Thread::PoisonObjectPointersIfDebug();
+ mirror::Class* resolved_type = referrer->GetDexCacheResolvedType(type_idx, image_pointer_size_);
if (UNLIKELY(resolved_type == nullptr)) {
mirror::Class* declaring_class = referrer->GetDeclaringClass();
StackHandleScope<2> hs(Thread::Current());
@@ -100,10 +100,10 @@
}
inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtField* referrer) {
- mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ Thread::PoisonObjectPointersIfDebug();
+ ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
mirror::DexCache* dex_cache_ptr = declaring_class->GetDexCache();
mirror::Class* resolved_type = dex_cache_ptr->GetResolvedType(type_idx);
- Thread::PoisonObjectPointersIfDebug();
if (UNLIKELY(resolved_type == nullptr)) {
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(dex_cache_ptr));
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 7dea614..0d3c012 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1090,7 +1090,7 @@
}
static mirror::String* GetDexPathListElementName(ScopedObjectAccessUnchecked& soa,
- mirror::Object* element)
+ ObjPtr<mirror::Object> element)
REQUIRES_SHARED(Locks::mutator_lock_) {
ArtField* const dex_file_field =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
@@ -1100,11 +1100,11 @@
DCHECK(dex_file_name_field != nullptr);
DCHECK(element != nullptr);
CHECK_EQ(dex_file_field->GetDeclaringClass(), element->GetClass()) << PrettyTypeOf(element);
- mirror::Object* dex_file = dex_file_field->GetObject(element);
+ ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
if (dex_file == nullptr) {
return nullptr;
}
- mirror::Object* const name_object = dex_file_name_field->GetObject(dex_file);
+ ObjPtr<mirror::Object> name_object = dex_file_name_field->GetObject(dex_file);
if (name_object != nullptr) {
return name_object->AsString();
}
@@ -1131,28 +1131,28 @@
// Unsupported class loader.
return false;
}
- mirror::Object* dex_path_list = dex_path_list_field->GetObject(class_loader);
+ ObjPtr<mirror::Object> dex_path_list = dex_path_list_field->GetObject(class_loader);
if (dex_path_list != nullptr) {
// DexPathList has an array dexElements of Elements[] which each contain a dex file.
- mirror::Object* dex_elements_obj = dex_elements_field->GetObject(dex_path_list);
+ ObjPtr<mirror::Object> dex_elements_obj = dex_elements_field->GetObject(dex_path_list);
// Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
// at the mCookie which is a DexFile vector.
if (dex_elements_obj != nullptr) {
- mirror::ObjectArray<mirror::Object>* dex_elements =
+ ObjPtr<mirror::ObjectArray<mirror::Object>> dex_elements =
dex_elements_obj->AsObjectArray<mirror::Object>();
// Reverse order since we insert the parent at the front.
for (int32_t i = dex_elements->GetLength() - 1; i >= 0; --i) {
- mirror::Object* const element = dex_elements->GetWithoutChecks(i);
+ ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
if (element == nullptr) {
*error_msg = StringPrintf("Null dex element at index %d", i);
return false;
}
- mirror::String* const name = GetDexPathListElementName(soa, element);
+ ObjPtr<mirror::String> const name = GetDexPathListElementName(soa, element);
if (name == nullptr) {
*error_msg = StringPrintf("Null name for dex element at index %d", i);
return false;
}
- out_dex_file_names->push_front(name);
+ out_dex_file_names->push_front(name.Decode());
}
}
}
@@ -2395,12 +2395,12 @@
ArtField* const cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie);
ArtField* const dex_file_field =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
- mirror::Object* dex_path_list =
+ ObjPtr<mirror::Object> dex_path_list =
soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList)->
GetObject(class_loader.Get());
if (dex_path_list != nullptr && dex_file_field != nullptr && cookie_field != nullptr) {
// DexPathList has an array dexElements of Elements[] which each contain a dex file.
- mirror::Object* dex_elements_obj =
+ ObjPtr<mirror::Object> dex_elements_obj =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
GetObject(dex_path_list);
// Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
@@ -2409,14 +2409,14 @@
Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
- mirror::Object* element = dex_elements->GetWithoutChecks(i);
+ ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
if (element == nullptr) {
// Should never happen, fall back to java code to throw a NPE.
break;
}
- mirror::Object* dex_file = dex_file_field->GetObject(element);
+ ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
if (dex_file != nullptr) {
- mirror::LongArray* long_array = cookie_field->GetObject(dex_file)->AsLongArray();
+ ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
if (long_array == nullptr) {
// This should never happen so log a warning.
LOG(WARNING) << "Null DexFile::mCookie for " << descriptor;
@@ -7638,6 +7638,32 @@
return string;
}
+ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file,
+ uint16_t type_idx,
+ ObjPtr<mirror::DexCache> dex_cache,
+ ObjPtr<mirror::ClassLoader> class_loader) {
+ ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
+ if (type == nullptr) {
+ const char* descriptor = dex_file.StringByTypeIdx(type_idx);
+ DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
+ if (descriptor[1] == '\0') {
+ // only the descriptors of primitive types should be 1 character long, also avoid class lookup
+ // for primitive classes that aren't backed by dex files.
+ type = FindPrimitiveClass(descriptor[0]);
+ } else {
+ Thread* const self = Thread::Current();
+ DCHECK(self != nullptr);
+ const size_t hash = ComputeModifiedUtf8Hash(descriptor);
+ // Find the class in the loaded classes table.
+ type = LookupClass(self, descriptor, hash, class_loader.Decode());
+ }
+ }
+ if (type != nullptr || type->IsResolved()) {
+ return type;
+ }
+ return nullptr;
+}
+
mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file,
uint16_t type_idx,
mirror::Class* referrer) {
@@ -8256,16 +8282,18 @@
ScopedObjectAccessUnchecked soa(self);
// For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex.
- StackHandleScope<10> hs(self);
+ StackHandleScope<11> hs(self);
ArtField* dex_elements_field =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements);
- mirror::Class* dex_elements_class = dex_elements_field->GetType<true>();
- DCHECK(dex_elements_class != nullptr);
+ Handle<mirror::Class> dex_elements_class(hs.NewHandle(dex_elements_field->GetType<true>()));
+ DCHECK(dex_elements_class.Get() != nullptr);
DCHECK(dex_elements_class->IsArrayClass());
Handle<mirror::ObjectArray<mirror::Object>> h_dex_elements(hs.NewHandle(
- mirror::ObjectArray<mirror::Object>::Alloc(self, dex_elements_class, dex_files.size())));
+ mirror::ObjectArray<mirror::Object>::Alloc(self,
+ dex_elements_class.Get(),
+ dex_files.size())));
Handle<mirror::Class> h_dex_element_class =
hs.NewHandle(dex_elements_class->GetComponentType());
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index df7fb61..f69a576 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -278,6 +278,14 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!dex_lock_, !Roles::uninterruptible_);
+ // Look up a resolved type with the given ID from the DexFile. The ClassLoader is used to search
+ // for the type, since it may be referenced from but not contained within the given DexFile.
+ ObjPtr<mirror::Class> LookupResolvedType(const DexFile& dex_file,
+ uint16_t type_idx,
+ ObjPtr<mirror::DexCache> dex_cache,
+ ObjPtr<mirror::ClassLoader> class_loader)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Resolve a type with the given ID from the DexFile, storing the
// result in DexCache. The ClassLoader is used to search for the
// type, since it may be referenced from but not contained within
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 451b752..4a926e7 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -243,10 +243,10 @@
kRuntimePointerSize));
}
- void AssertField(mirror::Class* klass, ArtField* field)
+ void AssertField(ObjPtr<mirror::Class> klass, ArtField* field)
REQUIRES_SHARED(Locks::mutator_lock_) {
EXPECT_TRUE(field != nullptr);
- EXPECT_EQ(klass, field->GetDeclaringClass());
+ EXPECT_OBJ_PTR_EQ(klass, field->GetDeclaringClass());
EXPECT_TRUE(field->GetName() != nullptr);
EXPECT_TRUE(field->GetType<true>() != nullptr);
}
@@ -358,7 +358,7 @@
MemberOffset current_ref_offset = start_ref_offset;
for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
ArtField* field = klass->GetInstanceField(i);
- mirror::Class* field_type = field->GetType<true>();
+ ObjPtr<mirror::Class> field_type = field->GetType<true>();
ASSERT_TRUE(field_type != nullptr);
if (!field->IsPrimitiveType()) {
ASSERT_TRUE(!field_type->IsPrimitive());
@@ -865,6 +865,28 @@
AssertNonExistentClass("[[[[LNonExistentClass;");
}
+TEST_F(ClassLinkerTest, LookupResolvedType) {
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
+ AssertNonExistentClass("LMyClass;");
+ ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
+ uint32_t type_idx = klass->GetClassDef()->class_idx_;
+ ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
+ const DexFile& dex_file = klass->GetDexFile();
+ EXPECT_EQ(dex_cache->GetResolvedType(type_idx), klass.Decode());
+ EXPECT_OBJ_PTR_EQ(
+ class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache, class_loader.Get()),
+ klass);
+ // Zero out the resolved type and make sure LookupResolvedType still finds it.
+ dex_cache->SetResolvedType(type_idx, nullptr);
+ EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr);
+ EXPECT_OBJ_PTR_EQ(
+ class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache, class_loader.Get()),
+ klass);
+}
+
TEST_F(ClassLinkerTest, LibCore) {
ScopedObjectAccess soa(Thread::Current());
ASSERT_TRUE(java_lang_dex_file_ != nullptr);
@@ -1018,8 +1040,8 @@
"Ljava/lang/String;");
EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
- s8->SetObject<false>(s8->GetDeclaringClass(),
- mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot"));
+ mirror::String* str_value = mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot");
+ s8->SetObject<false>(s8->GetDeclaringClass(), str_value);
// TODO: Remove EXPECT_FALSE when GCC can handle EXPECT_EQ
// http://code.google.com/p/googletest/issues/detail?id=322
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index eda1ddd..ea07195 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -523,12 +523,12 @@
ArtField* cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie);
ArtField* dex_file_field =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
- mirror::Object* dex_path_list =
+ ObjPtr<mirror::Object> dex_path_list =
soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList)->
GetObject(class_loader.Get());
if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
// DexPathList has an array dexElements of Elements[] which each contain a dex file.
- mirror::Object* dex_elements_obj =
+ ObjPtr<mirror::Object> dex_elements_obj =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
GetObject(dex_path_list);
// Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
@@ -537,14 +537,14 @@
Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
- mirror::Object* element = dex_elements->GetWithoutChecks(i);
+ ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
if (element == nullptr) {
// Should never happen, fall back to java code to throw a NPE.
break;
}
- mirror::Object* dex_file = dex_file_field->GetObject(element);
+ ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
if (dex_file != nullptr) {
- mirror::LongArray* long_array = cookie_field->GetObject(dex_file)->AsLongArray();
+ ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
DCHECK(long_array != nullptr);
int32_t long_array_size = long_array->GetLength();
for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index a7948e4..2158d81 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -25,10 +25,18 @@
#include "arch/instruction_set.h"
#include "base/mutex.h"
#include "globals.h"
+// TODO: Add inl file and avoid including inl.
+#include "obj_ptr-inl.h"
#include "os.h"
namespace art {
+// OBJ pointer helpers to avoid needing .Decode everywhere.
+#define EXPECT_OBJ_PTR_EQ(a, b) EXPECT_EQ(MakeObjPtr(a).Decode(), MakeObjPtr(b).Decode());
+#define ASSERT_OBJ_PTR_EQ(a, b) ASSERT_EQ(MakeObjPtr(a).Decode(), MakeObjPtr(b).Decode());
+#define EXPECT_OBJ_PTR_NE(a, b) EXPECT_NE(MakeObjPtr(a).Decode(), MakeObjPtr(b).Decode());
+#define ASSERT_OBJ_PTR_NE(a, b) ASSERT_NE(MakeObjPtr(a).Decode(), MakeObjPtr(b).Decode());
+
class ClassLinker;
class CompilerCallbacks;
class DexFile;
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 0206cae..1bdb0fc 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -46,6 +46,7 @@
#include "mirror/object_array-inl.h"
#include "mirror/string-inl.h"
#include "mirror/throwable.h"
+#include "obj_ptr-inl.h"
#include "reflection.h"
#include "safe_map.h"
#include "scoped_thread_state_change-inl.h"
@@ -985,7 +986,7 @@
gRegistry->DisposeObject(object_id, reference_count);
}
-JDWP::JdwpTypeTag Dbg::GetTypeTag(mirror::Class* klass) {
+JDWP::JdwpTypeTag Dbg::GetTypeTag(ObjPtr<mirror::Class> klass) {
DCHECK(klass != nullptr);
if (klass->IsArrayClass()) {
return JDWP::TT_ARRAY;
@@ -1367,12 +1368,12 @@
return m == event_location.method;
}
-bool Dbg::MatchType(mirror::Class* event_class, JDWP::RefTypeId class_id) {
+bool Dbg::MatchType(ObjPtr<mirror::Class> event_class, JDWP::RefTypeId class_id) {
if (event_class == nullptr) {
return false;
}
JDWP::JdwpError error;
- mirror::Class* expected_class = DecodeClass(class_id, &error);
+ ObjPtr<mirror::Class> expected_class = DecodeClass(class_id, &error);
CHECK(expected_class != nullptr);
return expected_class->IsAssignableFrom(event_class);
}
@@ -1742,7 +1743,7 @@
return field_value;
case Primitive::kPrimNot:
- field_value.SetL(f->GetObject(o));
+ field_value.SetL(f->GetObject(o).Decode());
return field_value;
case Primitive::kPrimVoid:
@@ -1868,7 +1869,7 @@
return JDWP::ERR_INVALID_OBJECT;
}
if (v != nullptr) {
- mirror::Class* field_type;
+ ObjPtr<mirror::Class> field_type;
{
StackHandleScope<2> hs(Thread::Current());
HandleWrapper<mirror::Object> h_v(hs.NewHandleWrapper(&v));
@@ -1994,8 +1995,7 @@
CHECK(thread_object != nullptr) << error;
ArtField* java_lang_Thread_name_field =
soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
- mirror::String* s =
- reinterpret_cast<mirror::String*>(java_lang_Thread_name_field->GetObject(thread_object));
+ ObjPtr<mirror::String> s(java_lang_Thread_name_field->GetObject(thread_object));
if (s != nullptr) {
*name = s->ToModifiedUtf8();
}
@@ -2021,7 +2021,7 @@
CHECK(c != nullptr);
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_group);
CHECK(f != nullptr);
- mirror::Object* group = f->GetObject(thread_object);
+ ObjPtr<mirror::Object> group = f->GetObject(thread_object);
CHECK(group != nullptr);
JDWP::ObjectId thread_group_id = gRegistry->Add(group);
expandBufAddObjectId(pReply, thread_group_id);
@@ -2063,7 +2063,7 @@
ScopedAssertNoThreadSuspension ants("Debugger: GetThreadGroupName");
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
CHECK(f != nullptr);
- mirror::String* s = reinterpret_cast<mirror::String*>(f->GetObject(thread_group));
+ ObjPtr<mirror::String> s = f->GetObject(thread_group)->AsString();
std::string thread_group_name(s->ToModifiedUtf8());
expandBufAddUtf8String(pReply, thread_group_name);
@@ -2077,7 +2077,7 @@
if (error != JDWP::ERR_NONE) {
return error;
}
- mirror::Object* parent;
+ ObjPtr<mirror::Object> parent;
{
ScopedAssertNoThreadSuspension ants("Debugger: GetThreadGroupParent");
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_parent);
@@ -2104,12 +2104,12 @@
// Get the ThreadGroup[] "groups" out of this thread group...
ArtField* groups_field = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_groups);
- mirror::Object* groups_array = groups_field->GetObject(thread_group);
+ ObjPtr<mirror::Object> groups_array = groups_field->GetObject(thread_group);
CHECK(groups_array != nullptr);
CHECK(groups_array->IsObjectArray());
- mirror::ObjectArray<mirror::Object>* groups_array_as_array =
+ ObjPtr<mirror::ObjectArray<mirror::Object>> groups_array_as_array =
groups_array->AsObjectArray<mirror::Object>();
// Copy the first 'size' elements out of the array into the result.
@@ -2154,7 +2154,7 @@
JDWP::ObjectId Dbg::GetSystemThreadGroupId() {
ScopedObjectAccessUnchecked soa(Thread::Current());
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup);
- mirror::Object* group = f->GetObject(f->GetDeclaringClass());
+ ObjPtr<mirror::Object> group = f->GetObject(f->GetDeclaringClass());
return gRegistry->Add(group);
}
@@ -2252,7 +2252,7 @@
}
ArtField* thread_group_field = soa.DecodeField(WellKnownClasses::java_lang_Thread_group);
DCHECK(thread_group_field != nullptr);
- mirror::Object* group = thread_group_field->GetObject(peer);
+ ObjPtr<mirror::Object> group = thread_group_field->GetObject(peer);
return (group == desired_thread_group);
}
diff --git a/runtime/debugger.h b/runtime/debugger.h
index 7398c4e..5d0315e 100644
--- a/runtime/debugger.h
+++ b/runtime/debugger.h
@@ -31,6 +31,7 @@
#include "jdwp/jdwp.h"
#include "jni.h"
#include "jvalue.h"
+#include "obj_ptr.h"
#include "thread.h"
#include "thread_state.h"
@@ -317,7 +318,7 @@
const JDWP::EventLocation& event_location)
REQUIRES_SHARED(Locks::mutator_lock_);
- static bool MatchType(mirror::Class* event_class, JDWP::RefTypeId class_id)
+ static bool MatchType(ObjPtr<mirror::Class> event_class, JDWP::RefTypeId class_id)
REQUIRES_SHARED(Locks::mutator_lock_);
static bool MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
@@ -689,7 +690,7 @@
static JDWP::JdwpTag TagFromObject(const ScopedObjectAccessUnchecked& soa, mirror::Object* o)
REQUIRES_SHARED(Locks::mutator_lock_);
- static JDWP::JdwpTypeTag GetTypeTag(mirror::Class* klass)
+ static JDWP::JdwpTypeTag GetTypeTag(ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::FieldId ToFieldId(const ArtField* f)
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 5763479..feb75a8 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -54,7 +54,7 @@
const DexFile::AnnotationSetItem* FindAnnotationSetForField(ArtField* field)
REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile* dex_file = field->GetDexFile();
- mirror::Class* klass = field->GetDeclaringClass();
+ ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
const DexFile::AnnotationsDirectoryItem* annotations_dir =
dex_file->GetAnnotationsDirectory(*klass->GetClassDef());
if (annotations_dir == nullptr) {
@@ -302,7 +302,7 @@
REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile& dex_file = klass->GetDexFile();
Thread* self = Thread::Current();
- mirror::Object* element_object = nullptr;
+ ObjPtr<mirror::Object> element_object = nullptr;
bool set_object = false;
Primitive::Type primitive_type = Primitive::kPrimVoid;
const uint8_t* annotation = *annotation_ptr;
@@ -577,7 +577,7 @@
}
if (set_object) {
- annotation_value->value_.SetL(element_object);
+ annotation_value->value_.SetL(element_object.Decode());
}
return true;
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 99b8805..e37db7d 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -410,14 +410,15 @@
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return nullptr; // Failure.
}
- mirror::Class* fields_class = resolved_field->GetDeclaringClass();
+ ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
if (access_check) {
if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer);
return nullptr;
}
mirror::Class* referring_class = referrer->GetDeclaringClass();
- if (UNLIKELY(!referring_class->CheckResolvedFieldAccess(fields_class, resolved_field,
+ if (UNLIKELY(!referring_class->CheckResolvedFieldAccess(fields_class,
+ resolved_field,
field_idx))) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return nullptr; // Failure.
@@ -696,7 +697,7 @@
// Incompatible class change.
return nullptr;
}
- mirror::Class* fields_class = resolved_field->GetDeclaringClass();
+ ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
if (is_static) {
// Check class is initialized else fail so that we can contend to initialize the class with
// other threads that may be racing to do this.
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 5b65029..70eb1de 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -151,14 +151,14 @@
StaticObjectRead,
sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr)) {
- return field->GetObj(field->GetDeclaringClass());
+ return field->GetObj(field->GetDeclaringClass()).Decode();
}
field = FindFieldFromCode<StaticObjectRead, true>(field_idx,
referrer,
self,
sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr)) {
- return field->GetObj(field->GetDeclaringClass());
+ return field->GetObj(field->GetDeclaringClass()).Decode();
}
return nullptr; // Will throw exception by checking with Thread::Current.
}
@@ -299,7 +299,7 @@
InstanceObjectRead,
sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr && obj != nullptr)) {
- return field->GetObj(obj);
+ return field->GetObj(obj).Decode();
}
field = FindInstanceField<InstanceObjectRead, true>(field_idx,
referrer,
@@ -307,7 +307,7 @@
sizeof(mirror::HeapReference<mirror::Object>),
&obj);
if (LIKELY(field != nullptr)) {
- return field->GetObj(obj);
+ return field->GetObj(obj).Decode();
}
return nullptr; // Will throw exception by checking with Thread::Current.
}
diff --git a/runtime/gc_root-inl.h b/runtime/gc_root-inl.h
index ae8a38f..11ccd33 100644
--- a/runtime/gc_root-inl.h
+++ b/runtime/gc_root-inl.h
@@ -21,6 +21,7 @@
#include <sstream>
+#include "obj_ptr-inl.h"
#include "read_barrier-inl.h"
namespace art {
@@ -31,10 +32,15 @@
return down_cast<MirrorType*>(
ReadBarrier::BarrierForRoot<mirror::Object, kReadBarrierOption>(&root_, gc_root_source));
}
+
template<class MirrorType>
inline GcRoot<MirrorType>::GcRoot(MirrorType* ref)
: root_(mirror::CompressedReference<mirror::Object>::FromMirrorPtr(ref)) { }
+template<class MirrorType>
+inline GcRoot<MirrorType>::GcRoot(ObjPtr<MirrorType, kIsDebugBuild> ref)
+ : GcRoot(ref.Decode()) { }
+
inline std::string RootInfo::ToString() const {
std::ostringstream oss;
Describe(oss);
diff --git a/runtime/gc_root.h b/runtime/gc_root.h
index 0a98f55..85cd0a4 100644
--- a/runtime/gc_root.h
+++ b/runtime/gc_root.h
@@ -24,6 +24,7 @@
namespace art {
class ArtField;
class ArtMethod;
+template<class MirrorType, bool kPoison> class ObjPtr;
namespace mirror {
class Object;
@@ -196,7 +197,10 @@
}
ALWAYS_INLINE GcRoot() {}
- explicit ALWAYS_INLINE GcRoot(MirrorType* ref) REQUIRES_SHARED(Locks::mutator_lock_);
+ explicit ALWAYS_INLINE GcRoot(MirrorType* ref)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ explicit ALWAYS_INLINE GcRoot(ObjPtr<MirrorType, kIsDebugBuild> ref)
+ REQUIRES_SHARED(Locks::mutator_lock_);
private:
// Root visitors take pointers to root_ and place them in CompressedReference** arrays. We use a
diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h
index 75a0391..1814746 100644
--- a/runtime/handle_scope-inl.h
+++ b/runtime/handle_scope-inl.h
@@ -135,6 +135,12 @@
GetReferences()[i].Assign(object);
}
+template<class MirrorType, bool kPoison>
+inline MutableHandle<MirrorType> StackHandleScopeCollection::NewHandle(
+ ObjPtr<MirrorType, kPoison> ptr) {
+ return NewHandle(ptr.Decode());
+}
+
} // namespace art
#endif // ART_RUNTIME_HANDLE_SCOPE_INL_H_
diff --git a/runtime/handle_scope.h b/runtime/handle_scope.h
index 2b283ae..fc729a5 100644
--- a/runtime/handle_scope.h
+++ b/runtime/handle_scope.h
@@ -252,6 +252,10 @@
return scopes_.top()->NewHandle(object);
}
+ template<class MirrorType, bool kPoison>
+ MutableHandle<MirrorType> NewHandle(ObjPtr<MirrorType, kPoison> ptr)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
static constexpr size_t kNumReferencesPerScope = 4;
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 5934f13..7a6162c 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -46,7 +46,7 @@
CHECK(self->IsExceptionPending());
return false;
}
- Object* obj;
+ ObjPtr<Object> obj;
if (is_static) {
obj = f->GetDeclaringClass();
} else {
@@ -60,9 +60,18 @@
// Report this field access to instrumentation if needed.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
- Object* this_object = f->IsStatic() ? nullptr : obj;
- instrumentation->FieldReadEvent(self, this_object, shadow_frame.GetMethod(),
- shadow_frame.GetDexPC(), f);
+ StackHandleScope<1> hs(self);
+ // Wrap in handle wrapper in case the listener does thread suspension.
+ HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
+ ObjPtr<Object> this_object;
+ if (!f->IsStatic()) {
+ this_object = obj;
+ }
+ instrumentation->FieldReadEvent(self,
+ this_object.Decode(),
+ shadow_frame.GetMethod(),
+ shadow_frame.GetDexPC(),
+ f);
}
uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
switch (field_type) {
@@ -85,7 +94,7 @@
shadow_frame.SetVRegLong(vregA, f->GetLong(obj));
break;
case Primitive::kPrimNot:
- shadow_frame.SetVRegReference(vregA, f->GetObject(obj));
+ shadow_frame.SetVRegReference(vregA, f->GetObject(obj).Decode());
break;
default:
LOG(FATAL) << "Unreachable: " << field_type;
@@ -241,7 +250,7 @@
CHECK(self->IsExceptionPending());
return false;
}
- Object* obj;
+ ObjPtr<Object> obj;
if (is_static) {
obj = f->GetDeclaringClass();
} else {
@@ -257,10 +266,16 @@
// the field from the base of the object, we need to look for it first.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
+ StackHandleScope<1> hs(self);
+ // Wrap in handle wrapper in case the listener does thread suspension.
+ HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA);
- Object* this_object = f->IsStatic() ? nullptr : obj;
- instrumentation->FieldWriteEvent(self, this_object, shadow_frame.GetMethod(),
- shadow_frame.GetDexPC(), f, field_value);
+ ObjPtr<Object> this_object = f->IsStatic() ? nullptr : obj;
+ instrumentation->FieldWriteEvent(self, this_object.Decode(),
+ shadow_frame.GetMethod(),
+ shadow_frame.GetDexPC(),
+ f,
+ field_value);
}
switch (field_type) {
case Primitive::kPrimBoolean:
@@ -286,14 +301,14 @@
if (do_assignability_check && reg != nullptr) {
// FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the
// object in the destructor.
- Class* field_class;
+ ObjPtr<Class> field_class;
{
StackHandleScope<2> hs(self);
HandleWrapper<mirror::Object> h_reg(hs.NewHandleWrapper(®));
- HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
+ HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
field_class = f->GetType<true>();
}
- if (!reg->VerifierInstanceOf(field_class)) {
+ if (!reg->VerifierInstanceOf(field_class.Decode())) {
// This should never happen.
std::string temp1, temp2, temp3;
self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
@@ -489,15 +504,14 @@
// Separate declaration is required solely for the attributes.
template <bool is_range,
- bool do_assignability_check,
- size_t kVarArgMax>
+ bool do_assignability_check>
REQUIRES_SHARED(Locks::mutator_lock_)
static inline bool DoCallCommon(ArtMethod* called_method,
Thread* self,
ShadowFrame& shadow_frame,
JValue* result,
uint16_t number_of_inputs,
- uint32_t (&arg)[kVarArgMax],
+ uint32_t (&arg)[Instruction::kMaxVarArgRegs],
uint32_t vregC) ALWAYS_INLINE;
void ArtInterpreterToCompiledCodeBridge(Thread* self,
@@ -563,14 +577,13 @@
}
template <bool is_range,
- bool do_assignability_check,
- size_t kVarArgMax>
+ bool do_assignability_check>
static inline bool DoCallCommon(ArtMethod* called_method,
Thread* self,
ShadowFrame& shadow_frame,
JValue* result,
uint16_t number_of_inputs,
- uint32_t (&arg)[kVarArgMax],
+ uint32_t (&arg)[Instruction::kMaxVarArgRegs],
uint32_t vregC) {
bool string_init = false;
// Replace calls to String.<init> with equivalent StringFactory call.
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 39846da..eb8cdbc 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -786,9 +786,9 @@
kAndroidHardcodedSystemPropertiesFieldName);
return;
}
- Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(
- hs.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>*>(
- static_properties->GetObject(h_props_class.Get()))));
+ ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
+ Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
+ props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
if (h_2string_array.Get() == nullptr) {
AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
return;
diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc
index 9ba62c9..dc3bf16 100644
--- a/runtime/jdwp/object_registry.cc
+++ b/runtime/jdwp/object_registry.cc
@@ -19,6 +19,7 @@
#include "handle_scope-inl.h"
#include "jni_internal.h"
#include "mirror/class.h"
+#include "obj_ptr-inl.h"
#include "scoped_thread_state_change-inl.h"
namespace art {
@@ -35,7 +36,7 @@
: lock_("ObjectRegistry lock", kJdwpObjectRegistryLock), next_id_(1) {
}
-JDWP::RefTypeId ObjectRegistry::AddRefType(mirror::Class* c) {
+JDWP::RefTypeId ObjectRegistry::AddRefType(ObjPtr<mirror::Class> c) {
return Add(c);
}
@@ -43,7 +44,7 @@
return Add(c_h);
}
-JDWP::ObjectId ObjectRegistry::Add(mirror::Object* o) {
+JDWP::ObjectId ObjectRegistry::Add(ObjPtr<mirror::Object> o) {
if (o == nullptr) {
return 0;
}
@@ -118,7 +119,9 @@
return entry->id;
}
-bool ObjectRegistry::ContainsLocked(Thread* self, mirror::Object* o, int32_t identity_hash_code,
+bool ObjectRegistry::ContainsLocked(Thread* self,
+ ObjPtr<mirror::Object> o,
+ int32_t identity_hash_code,
ObjectRegistryEntry** out_entry) {
DCHECK(o != nullptr);
for (auto it = object_to_entry_.lower_bound(identity_hash_code), end = object_to_entry_.end();
diff --git a/runtime/jdwp/object_registry.h b/runtime/jdwp/object_registry.h
index 7fa57c6..9cacc66 100644
--- a/runtime/jdwp/object_registry.h
+++ b/runtime/jdwp/object_registry.h
@@ -25,6 +25,7 @@
#include "base/casts.h"
#include "handle.h"
#include "jdwp/jdwp.h"
+#include "obj_ptr.h"
#include "safe_map.h"
namespace art {
@@ -62,11 +63,11 @@
public:
ObjectRegistry();
- JDWP::ObjectId Add(mirror::Object* o)
+ JDWP::ObjectId Add(ObjPtr<mirror::Object> o)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, !lock_);
- JDWP::RefTypeId AddRefType(mirror::Class* c)
+ JDWP::RefTypeId AddRefType(ObjPtr<mirror::Class> c)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, !lock_);
@@ -121,7 +122,9 @@
void Promote(ObjectRegistryEntry& entry)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(lock_);
- bool ContainsLocked(Thread* self, mirror::Object* o, int32_t identity_hash_code,
+ bool ContainsLocked(Thread* self,
+ ObjPtr<mirror::Object> o,
+ int32_t identity_hash_code,
ObjectRegistryEntry** out_entry)
REQUIRES(lock_) REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 7b27578..7977815 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -97,15 +97,20 @@
kind, c->GetDescriptor(&temp), name, sig);
}
-static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
- const char* kind, jint idx, bool return_errors)
+static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa,
+ ObjPtr<mirror::Class> c,
+ const char* kind,
+ jint idx,
+ bool return_errors)
REQUIRES_SHARED(Locks::mutator_lock_) {
LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
<< "Failed to register native method in " << PrettyDescriptor(c)
<< " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
<< ": " << kind << " is null at index " << idx;
soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
- "%s is null at index %d", kind, idx);
+ "%s is null at index %d",
+ kind,
+ idx);
}
static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass)
@@ -282,7 +287,7 @@
return JNI_ERR;
}
ScopedObjectAccess soa(env);
- soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()).Decode());
+ soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()));
return JNI_OK;
}
@@ -417,7 +422,7 @@
ScopedObjectAccess soa(env);
ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1);
ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2);
- return c2->IsAssignableFrom(c1.Decode()) ? JNI_TRUE : JNI_FALSE;
+ return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
}
static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
@@ -439,7 +444,7 @@
if (exception == nullptr) {
return JNI_ERR;
}
- soa.Self()->SetException(exception.Decode());
+ soa.Self()->SetException(exception);
return JNI_OK;
}
@@ -1227,7 +1232,7 @@
ScopedObjectAccess soa(env);
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
ArtField* f = soa.DecodeField(fid);
- return soa.AddLocalReference<jobject>(f->GetObject(o.Decode()));
+ return soa.AddLocalReference<jobject>(f->GetObject(o));
}
static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
@@ -1244,7 +1249,7 @@
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
ArtField* f = soa.DecodeField(fid);
- f->SetObject<false>(o.Decode(), v.Decode());
+ f->SetObject<false>(o, v);
}
static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
@@ -1252,7 +1257,7 @@
ScopedObjectAccess soa(env);
ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
ArtField* f = soa.DecodeField(fid);
- f->SetObject<false>(f->GetDeclaringClass(), v.Decode());
+ f->SetObject<false>(f->GetDeclaringClass(), v);
}
#define GET_PRIMITIVE_FIELD(fn, instance) \
@@ -1261,7 +1266,7 @@
ScopedObjectAccess soa(env); \
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
ArtField* f = soa.DecodeField(fid); \
- return f->Get ##fn (o.Decode())
+ return f->Get ##fn (o)
#define GET_STATIC_PRIMITIVE_FIELD(fn) \
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
@@ -1275,7 +1280,7 @@
ScopedObjectAccess soa(env); \
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
ArtField* f = soa.DecodeField(fid); \
- f->Set ##fn <false>(o.Decode(), value)
+ f->Set ##fn <false>(o, value)
#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
@@ -2159,13 +2164,13 @@
const char* sig = methods[i].signature;
const void* fnPtr = methods[i].fnPtr;
if (UNLIKELY(name == nullptr)) {
- ReportInvalidJNINativeMethod(soa, c.Decode(), "method name", i, return_errors);
+ ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
return JNI_ERR;
} else if (UNLIKELY(sig == nullptr)) {
- ReportInvalidJNINativeMethod(soa, c.Decode(), "method signature", i, return_errors);
+ ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
return JNI_ERR;
} else if (UNLIKELY(fnPtr == nullptr)) {
- ReportInvalidJNINativeMethod(soa, c.Decode(), "native function", i, return_errors);
+ ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
return JNI_ERR;
}
bool is_fast = false;
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 5a5f717..3cbd58b 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -341,13 +341,13 @@
// Don't forget about primitive types.
// Object[] = int[] --> false
//
-inline bool Class::IsArrayAssignableFromArray(Class* src) {
+inline bool Class::IsArrayAssignableFromArray(ObjPtr<Class> src) {
DCHECK(IsArrayClass()) << PrettyClass(this);
DCHECK(src->IsArrayClass()) << PrettyClass(src);
return GetComponentType()->IsAssignableFrom(src->GetComponentType());
}
-inline bool Class::IsAssignableFromArray(Class* src) {
+inline bool Class::IsAssignableFromArray(ObjPtr<Class> src) {
DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
DCHECK(src->IsArrayClass()) << PrettyClass(src);
if (!IsArrayClass()) {
@@ -362,34 +362,29 @@
}
template <bool throw_on_failure, bool use_referrers_cache>
-inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field,
- uint32_t field_idx, DexCache* dex_cache) {
+inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to,
+ ArtField* field,
+ uint32_t field_idx,
+ ObjPtr<DexCache> dex_cache) {
DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
if (UNLIKELY(!this->CanAccess(access_to))) {
// The referrer class can't access the field's declaring class but may still be able
// to access the field if the FieldId specifies an accessible subclass of the declaring
// class rather than the declaring class itself.
- DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
+ ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
// The referenced class has already been resolved with the field, but may not be in the dex
- // cache. Using ResolveType here without handles in the caller should be safe since there
+ // cache. Use LookupResolveType here to search the class table if it is not in the dex cache.
// should be no thread suspension due to the class being resolved.
- // TODO: Clean this up to use handles in the caller.
- Class* dex_access_to;
- {
- StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer_dex_cache));
- Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(access_to->GetClassLoader()));
- dex_access_to = Runtime::Current()->GetClassLinker()->ResolveType(
- *referrer_dex_cache->GetDexFile(),
- class_idx,
- h_dex_cache,
- h_class_loader);
- }
+ ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
+ *referrer_dex_cache->GetDexFile(),
+ class_idx,
+ referrer_dex_cache,
+ access_to->GetClassLoader());
DCHECK(dex_access_to != nullptr);
if (UNLIKELY(!this->CanAccess(dex_access_to))) {
if (throw_on_failure) {
- ThrowIllegalAccessErrorClass(this, dex_access_to);
+ ThrowIllegalAccessErrorClass(this, dex_access_to.Decode());
}
return false;
}
@@ -404,36 +399,32 @@
}
template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
-inline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method,
- uint32_t method_idx, DexCache* dex_cache) {
+inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to,
+ ArtMethod* method,
+ uint32_t method_idx,
+ ObjPtr<DexCache> dex_cache) {
static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type");
DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
if (UNLIKELY(!this->CanAccess(access_to))) {
// The referrer class can't access the method's declaring class but may still be able
// to access the method if the MethodId specifies an accessible subclass of the declaring
// class rather than the declaring class itself.
- DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
+ ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
// The referenced class has already been resolved with the method, but may not be in the dex
- // cache. Using ResolveType here without handles in the caller should be safe since there
- // should be no thread suspension due to the class being resolved.
- // TODO: Clean this up to use handles in the caller.
- Class* dex_access_to;
- {
- StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer_dex_cache));
- Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(access_to->GetClassLoader()));
- dex_access_to = Runtime::Current()->GetClassLinker()->ResolveType(
- *referrer_dex_cache->GetDexFile(),
- class_idx,
- h_dex_cache,
- h_class_loader);
- }
+ // cache.
+ ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
+ *referrer_dex_cache->GetDexFile(),
+ class_idx,
+ referrer_dex_cache,
+ access_to->GetClassLoader());
DCHECK(dex_access_to != nullptr);
if (UNLIKELY(!this->CanAccess(dex_access_to))) {
if (throw_on_failure) {
- ThrowIllegalAccessErrorClassForMethodDispatch(this, dex_access_to,
- method, throw_invoke_type);
+ ThrowIllegalAccessErrorClassForMethodDispatch(this,
+ dex_access_to.Decode(),
+ method,
+ throw_invoke_type);
}
return false;
}
@@ -447,14 +438,17 @@
return false;
}
-inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field,
- DexCache* dex_cache, uint32_t field_idx) {
+inline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to,
+ ArtField* field,
+ ObjPtr<DexCache> dex_cache,
+ uint32_t field_idx) {
return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
}
-inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field,
+inline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to,
+ ArtField* field,
uint32_t field_idx) {
- return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
+ return ResolvedFieldAccessTest<true, true>(access_to.Decode(), field, field_idx, nullptr);
}
inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method,
@@ -469,10 +463,10 @@
nullptr);
}
-inline bool Class::IsSubClass(Class* klass) {
+inline bool Class::IsSubClass(ObjPtr<Class> klass) {
DCHECK(!IsInterface()) << PrettyClass(this);
DCHECK(!IsArrayClass()) << PrettyClass(this);
- Class* current = this;
+ ObjPtr<Class> current = this;
do {
if (current == klass) {
return true;
@@ -1032,7 +1026,7 @@
return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr;
}
-inline bool Class::IsAssignableFrom(Class* src) {
+inline bool Class::IsAssignableFrom(ObjPtr<Class> src) {
DCHECK(src != nullptr);
if (this == src) {
// Can always assign to things of the same type.
@@ -1113,6 +1107,34 @@
}
}
+inline bool Class::CanAccess(ObjPtr<Class> that) {
+ return that->IsPublic() || this->IsInSamePackage(that);
+}
+
+
+inline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags) {
+ // Classes can access all of their own members
+ if (this == access_to) {
+ return true;
+ }
+ // Public members are trivially accessible
+ if (member_flags & kAccPublic) {
+ return true;
+ }
+ // Private members are trivially not accessible
+ if (member_flags & kAccPrivate) {
+ return false;
+ }
+ // Check for protected access from a sub-class, which may or may not be in the same package.
+ if (member_flags & kAccProtected) {
+ if (!this->IsInterface() && this->IsSubClass(access_to)) {
+ return true;
+ }
+ }
+ // Allow protected access from other classes in the same package.
+ return this->IsInSamePackage(access_to);
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 2e5f532..40742d2 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -308,9 +308,9 @@
}
}
-bool Class::IsInSamePackage(Class* that) {
- Class* klass1 = this;
- Class* klass2 = that;
+bool Class::IsInSamePackage(ObjPtr<Class> that) {
+ ObjPtr<Class> klass1 = this;
+ ObjPtr<Class> klass2 = that;
if (klass1 == klass2) {
return true;
}
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 6c1259b..a0d6f37 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -611,50 +611,28 @@
}
// Returns true if this class is in the same packages as that class.
- bool IsInSamePackage(Class* that) REQUIRES_SHARED(Locks::mutator_lock_);
+ bool IsInSamePackage(ObjPtr<Class> that) REQUIRES_SHARED(Locks::mutator_lock_);
static bool IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2);
// Returns true if this class can access that class.
- bool CanAccess(Class* that) REQUIRES_SHARED(Locks::mutator_lock_) {
- return that->IsPublic() || this->IsInSamePackage(that);
- }
+ bool CanAccess(ObjPtr<Class> that) REQUIRES_SHARED(Locks::mutator_lock_);
// Can this class access a member in the provided class with the provided member access flags?
// Note that access to the class isn't checked in case the declaring class is protected and the
// method has been exposed by a public sub-class
- bool CanAccessMember(Class* access_to, uint32_t member_flags)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- // Classes can access all of their own members
- if (this == access_to) {
- return true;
- }
- // Public members are trivially accessible
- if (member_flags & kAccPublic) {
- return true;
- }
- // Private members are trivially not accessible
- if (member_flags & kAccPrivate) {
- return false;
- }
- // Check for protected access from a sub-class, which may or may not be in the same package.
- if (member_flags & kAccProtected) {
- if (!this->IsInterface() && this->IsSubClass(access_to)) {
- return true;
- }
- }
- // Allow protected access from other classes in the same package.
- return this->IsInSamePackage(access_to);
- }
+ bool CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags)
+ REQUIRES_SHARED(Locks::mutator_lock_);
// Can this class access a resolved field?
// Note that access to field's class is checked and this may require looking up the class
// referenced by the FieldId in the DexFile in case the declaring class is inaccessible.
- bool CanAccessResolvedField(Class* access_to, ArtField* field,
- DexCache* dex_cache, uint32_t field_idx)
+ bool CanAccessResolvedField(ObjPtr<Class> access_to,
+ ArtField* field,
+ ObjPtr<DexCache> dex_cache,
+ uint32_t field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool CheckResolvedFieldAccess(Class* access_to, ArtField* field,
- uint32_t field_idx)
+ bool CheckResolvedFieldAccess(ObjPtr<Class> access_to, ArtField* field, uint32_t field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
// Can this class access a resolved method?
@@ -668,14 +646,14 @@
uint32_t method_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool IsSubClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
+ bool IsSubClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
// Can src be assigned to this class? For example, String can be assigned to Object (by an
// upcast), however, an Object cannot be assigned to a String as a potentially exception throwing
// downcast would be necessary. Similarly for interfaces, a class that implements (or an interface
// that extends) another can be assigned to its parent, but not vice-versa. All Classes may assign
// to themselves. Classes for primitive types may not assign to each other.
- ALWAYS_INLINE bool IsAssignableFrom(Class* src) REQUIRES_SHARED(Locks::mutator_lock_);
+ ALWAYS_INLINE bool IsAssignableFrom(ObjPtr<Class> src) REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
@@ -1309,17 +1287,22 @@
void SetVerifyError(Object* klass) REQUIRES_SHARED(Locks::mutator_lock_);
template <bool throw_on_failure, bool use_referrers_cache>
- bool ResolvedFieldAccessTest(Class* access_to, ArtField* field,
- uint32_t field_idx, DexCache* dex_cache)
+ bool ResolvedFieldAccessTest(ObjPtr<Class> access_to,
+ ArtField* field,
+ uint32_t field_idx,
+ ObjPtr<DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
+
template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
- bool ResolvedMethodAccessTest(Class* access_to, ArtMethod* resolved_method,
- uint32_t method_idx, DexCache* dex_cache)
+ bool ResolvedMethodAccessTest(ObjPtr<Class> access_to,
+ ArtMethod* resolved_method,
+ uint32_t method_idx,
+ ObjPtr<DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
bool Implements(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
- bool IsArrayAssignableFromArray(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
- bool IsAssignableFromArray(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
+ bool IsArrayAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
+ bool IsAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
void CheckObjectAlloc() REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 8b0f8ce..ec32cb6 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -78,6 +78,11 @@
return ret.Get();
}
+template<bool kTransactionActive>
+void Field::SetDeclaringClass(ObjPtr<mirror::Class> c) {
+ SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), c.Decode());
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index f378568..c5357c9 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -20,6 +20,7 @@
#include "accessible_object.h"
#include "base/enums.h"
#include "gc_root.h"
+#include "obj_ptr.h"
#include "object.h"
#include "object_callbacks.h"
#include "read_barrier_option.h"
@@ -109,9 +110,7 @@
int32_t offset_;
template<bool kTransactionActive>
- void SetDeclaringClass(mirror::Class* c) REQUIRES_SHARED(Locks::mutator_lock_) {
- SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), c);
- }
+ void SetDeclaringClass(ObjPtr<mirror::Class> c) REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive>
void SetType(mirror::Class* type) REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index c37deb5..90b97fd 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -213,7 +213,7 @@
if (field.GetOffset().Int32Value() == field_offset.Int32Value()) {
CHECK_NE(field.GetTypeAsPrimitiveType(), Primitive::kPrimNot);
// TODO: resolve the field type for moving GC.
- mirror::Class* field_type = field.GetType<!kMovingCollector>();
+ ObjPtr<mirror::Class> field_type = field.GetType<!kMovingCollector>();
if (field_type != nullptr) {
CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
}
@@ -230,7 +230,7 @@
if (field.GetOffset().Int32Value() == field_offset.Int32Value()) {
CHECK_NE(field.GetTypeAsPrimitiveType(), Primitive::kPrimNot);
// TODO: resolve the field type for moving GC.
- mirror::Class* field_type = field.GetType<!kMovingCollector>();
+ ObjPtr<mirror::Class> field_type = field.GetType<!kMovingCollector>();
if (field_type != nullptr) {
CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
}
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 40ee3a2..a573ae6 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -384,12 +384,12 @@
ArtField* field = FindFieldFromCode<StaticObjectRead, true>(field_idx, clinit, Thread::Current(),
sizeof(HeapReference<Object>));
- Object* s0 = field->GetObj(klass);
+ ObjPtr<Object> s0 = field->GetObj(klass);
EXPECT_TRUE(s0 != nullptr);
Handle<CharArray> char_array(hs.NewHandle(CharArray::Alloc(soa.Self(), 0)));
field->SetObj<false>(field->GetDeclaringClass(), char_array.Get());
- EXPECT_EQ(char_array.Get(), field->GetObj(klass));
+ EXPECT_OBJ_PTR_EQ(char_array.Get(), field->GetObj(klass));
field->SetObj<false>(field->GetDeclaringClass(), nullptr);
EXPECT_EQ(nullptr, field->GetObj(klass));
@@ -759,7 +759,7 @@
EXPECT_TRUE(!X.IsNull());
EXPECT_TRUE(X.IsValid());
EXPECT_TRUE(X.Decode() != nullptr);
- EXPECT_EQ(h_X.Get(), X.Decode());
+ EXPECT_OBJ_PTR_EQ(h_X.Get(), X);
// FindClass may cause thread suspension, it should invalidate X.
ObjPtr<Class, /*kPoison*/ true> Y(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
EXPECT_TRUE(!Y.IsNull());
@@ -773,7 +773,7 @@
X.Assign(h_X.Get());
EXPECT_TRUE(!X.IsNull());
EXPECT_TRUE(X.IsValid());
- EXPECT_EQ(h_X.Get(), X.Decode());
+ EXPECT_OBJ_PTR_EQ(h_X.Get(), X);
// Allow thread suspension to invalidate Y.
soa.Self()->AllowThreadSuspension();
@@ -793,7 +793,7 @@
unpoisoned = h_X.Get();
EXPECT_FALSE(unpoisoned.IsNull());
EXPECT_TRUE(unpoisoned == h_X.Get());
- EXPECT_EQ(unpoisoned.Decode(), h_X.Get());
+ EXPECT_OBJ_PTR_EQ(unpoisoned, h_X.Get());
}
} // namespace mirror
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc
index 671cb60..0d1839b 100644
--- a/runtime/monitor_android.cc
+++ b/runtime/monitor_android.cc
@@ -21,7 +21,7 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include "cutils/log.h"
+#include <android/log.h>
#define EVENT_LOG_TAG_dvm_lock_sample 20003
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index acad2a9..64e5a63 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -30,6 +30,7 @@
#include "handle_scope-inl.h"
#include "mirror/class_loader.h"
#include "oat_file_assistant.h"
+#include "obj_ptr-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-inl.h"
#include "thread_list.h"
@@ -223,7 +224,7 @@
}
}
-static void IterateOverJavaDexFile(mirror::Object* dex_file,
+static void IterateOverJavaDexFile(ObjPtr<mirror::Object> dex_file,
ArtField* const cookie_field,
std::function<bool(const DexFile*)> fn)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -258,12 +259,12 @@
ArtField* const cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie);
ArtField* const dex_file_field =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
- mirror::Object* dex_path_list =
+ ObjPtr<mirror::Object> dex_path_list =
soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList)->
GetObject(class_loader.Get());
if (dex_path_list != nullptr && dex_file_field != nullptr && cookie_field != nullptr) {
// DexPathList has an array dexElements of Elements[] which each contain a dex file.
- mirror::Object* dex_elements_obj =
+ ObjPtr<mirror::Object> dex_elements_obj =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
GetObject(dex_path_list);
// Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
@@ -276,7 +277,7 @@
// Should never happen, fall back to java code to throw a NPE.
break;
}
- mirror::Object* dex_file = dex_file_field->GetObject(element);
+ ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
IterateOverJavaDexFile(dex_file, cookie_field, fn);
}
}
@@ -360,7 +361,7 @@
// We support this being dalvik.system.DexPathList$Element and dalvik.system.DexFile.
- mirror::Object* dex_file;
+ ObjPtr<mirror::Object> dex_file;
if (element_class == element->GetClass()) {
dex_file = dex_file_field->GetObject(element);
} else if (dexfile_class == element->GetClass()) {
diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h
index d5ac33d..7c0c9df 100644
--- a/runtime/obj_ptr.h
+++ b/runtime/obj_ptr.h
@@ -88,11 +88,13 @@
return Decode() == ptr.Decode();
}
- ALWAYS_INLINE bool operator==(const MirrorType* ptr) const REQUIRES_SHARED(Locks::mutator_lock_) {
+ template <typename PointerType>
+ ALWAYS_INLINE bool operator==(const PointerType* ptr) const
+ REQUIRES_SHARED(Locks::mutator_lock_) {
return Decode() == ptr;
}
- ALWAYS_INLINE bool operator==(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
+ ALWAYS_INLINE bool operator==(std::nullptr_t) const {
return IsNull();
}
@@ -100,16 +102,18 @@
return Decode() != ptr.Decode();
}
- ALWAYS_INLINE bool operator!=(const MirrorType* ptr) const REQUIRES_SHARED(Locks::mutator_lock_) {
+ template <typename PointerType>
+ ALWAYS_INLINE bool operator!=(const PointerType* ptr) const
+ REQUIRES_SHARED(Locks::mutator_lock_) {
return Decode() != ptr;
}
- ALWAYS_INLINE bool operator!=(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
+ ALWAYS_INLINE bool operator!=(std::nullptr_t) const {
return !IsNull();
}
// Decode unchecked does not check that object pointer is valid. Do not use if you can avoid it.
- ALWAYS_INLINE MirrorType* DecodeUnchecked() const REQUIRES_SHARED(Locks::mutator_lock_) {
+ ALWAYS_INLINE MirrorType* DecodeUnchecked() const {
if (kPoison) {
return reinterpret_cast<MirrorType*>(
static_cast<uintptr_t>(static_cast<uint32_t>(reference_ << kObjectAlignmentShift)));
@@ -133,14 +137,40 @@
uintptr_t reference_;
};
+template<class MirrorType, bool kPoison, typename PointerType>
+ALWAYS_INLINE bool operator==(const PointerType* a, const ObjPtr<MirrorType, kPoison>& b)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return b == a;
+}
+
+template<class MirrorType, bool kPoison>
+ALWAYS_INLINE bool operator==(std::nullptr_t, const ObjPtr<MirrorType, kPoison>& b) {
+ return b == nullptr;
+}
+
+template<typename MirrorType, bool kPoison, typename PointerType>
+ALWAYS_INLINE bool operator!=(const PointerType* a, const ObjPtr<MirrorType, kPoison>& b)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return b != a;
+}
+
+template<class MirrorType, bool kPoison>
+ALWAYS_INLINE bool operator!=(std::nullptr_t, const ObjPtr<MirrorType, kPoison>& b) {
+ return b != nullptr;
+}
+
template<class MirrorType, bool kPoison = kIsDebugBuild>
static inline ObjPtr<MirrorType, kPoison> MakeObjPtr(MirrorType* ptr) {
return ObjPtr<MirrorType, kPoison>(ptr);
}
+template<class MirrorType, bool kPoison = kIsDebugBuild>
+static inline ObjPtr<MirrorType, kPoison> MakeObjPtr(ObjPtr<MirrorType, kPoison> ptr) {
+ return ObjPtr<MirrorType, kPoison>(ptr);
+}
+
template<class MirrorType, bool kPoison>
-ALWAYS_INLINE std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType, kPoison> ptr)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ALWAYS_INLINE std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType, kPoison> ptr);
} // namespace art
diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc
index ac348e7..9c42b2f 100644
--- a/runtime/openjdkjvmti/transform.cc
+++ b/runtime/openjdkjvmti/transform.cc
@@ -209,9 +209,9 @@
hs.NewHandle(path_list_field->GetObject(h_class_loader.Get())));
CHECK(path_list.Get() != nullptr);
CHECK(!self->IsExceptionPending());
- art::Handle<art::mirror::ObjectArray<art::mirror::Object>> dex_elements_list(
- hs.NewHandle(art::down_cast<art::mirror::ObjectArray<art::mirror::Object>*>(
- dex_path_list_element_field->GetObject(path_list.Get()))));
+ art::Handle<art::mirror::ObjectArray<art::mirror::Object>> dex_elements_list(hs.NewHandle(
+ dex_path_list_element_field->GetObject(path_list.Get())->
+ AsObjectArray<art::mirror::Object>()));
CHECK(!self->IsExceptionPending());
CHECK(dex_elements_list.Get() != nullptr);
size_t num_elements = dex_elements_list->GetLength();
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 43b0b3d..1119ccf 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -180,7 +180,7 @@
ArtField* field = &static_fields->At(0);
EXPECT_STREQ("interfaces", field->GetName());
EXPECT_STREQ("[Ljava/lang/Class;", field->GetTypeDescriptor());
- EXPECT_EQ(interfacesFieldClass.Get(), field->GetType<true>());
+ EXPECT_OBJ_PTR_EQ(MakeObjPtr(interfacesFieldClass.Get()), field->GetType<true>());
std::string temp;
EXPECT_STREQ("L$Proxy1234;", field->GetDeclaringClass()->GetDescriptor(&temp));
EXPECT_FALSE(field->IsPrimitiveType());
@@ -189,7 +189,7 @@
field = &static_fields->At(1);
EXPECT_STREQ("throws", field->GetName());
EXPECT_STREQ("[[Ljava/lang/Class;", field->GetTypeDescriptor());
- EXPECT_EQ(throwsFieldClass.Get(), field->GetType<true>());
+ EXPECT_OBJ_PTR_EQ(MakeObjPtr(throwsFieldClass.Get()), field->GetType<true>());
EXPECT_STREQ("L$Proxy1234;", field->GetDeclaringClass()->GetDescriptor(&temp));
EXPECT_FALSE(field->IsPrimitiveType());
}
@@ -224,10 +224,10 @@
ASSERT_TRUE(static_fields1 != nullptr);
ASSERT_EQ(2u, static_fields1->size());
- EXPECT_EQ(static_fields0->At(0).GetDeclaringClass(), proxyClass0.Get());
- EXPECT_EQ(static_fields0->At(1).GetDeclaringClass(), proxyClass0.Get());
- EXPECT_EQ(static_fields1->At(0).GetDeclaringClass(), proxyClass1.Get());
- EXPECT_EQ(static_fields1->At(1).GetDeclaringClass(), proxyClass1.Get());
+ EXPECT_OBJ_PTR_EQ(static_fields0->At(0).GetDeclaringClass(), MakeObjPtr(proxyClass0.Get()));
+ EXPECT_OBJ_PTR_EQ(static_fields0->At(1).GetDeclaringClass(), MakeObjPtr(proxyClass0.Get()));
+ EXPECT_OBJ_PTR_EQ(static_fields1->At(0).GetDeclaringClass(), MakeObjPtr(proxyClass1.Get()));
+ EXPECT_OBJ_PTR_EQ(static_fields1->At(1).GetDeclaringClass(), MakeObjPtr(proxyClass1.Get()));
ASSERT_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
ASSERT_FALSE(Runtime::Current()->IsActiveTransaction());
diff --git a/runtime/quick/inline_method_analyser.cc b/runtime/quick/inline_method_analyser.cc
index dc6f4eb..b009b47 100644
--- a/runtime/quick/inline_method_analyser.cc
+++ b/runtime/quick/inline_method_analyser.cc
@@ -738,8 +738,8 @@
if (field == nullptr || field->IsStatic()) {
return false;
}
- mirror::Class* method_class = method->GetDeclaringClass();
- mirror::Class* field_class = field->GetDeclaringClass();
+ ObjPtr<mirror::Class> method_class = method->GetDeclaringClass();
+ ObjPtr<mirror::Class> field_class = field->GetDeclaringClass();
if (!method_class->CanAccessResolvedField(field_class, field, dex_cache, field_idx) ||
(is_put && field->IsFinal() && method_class != field_class)) {
return false;
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index b663b4c..066bc12 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -244,13 +244,13 @@
#define DO_FIRST_ARG(match_descriptor, get_fn, append) { \
if (LIKELY(arg != nullptr && arg->GetClass()->DescriptorEquals(match_descriptor))) { \
ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
- append(primitive_field-> get_fn(arg.Decode()));
+ append(primitive_field-> get_fn(arg));
#define DO_ARG(match_descriptor, get_fn, append) \
} else if (LIKELY(arg != nullptr && \
arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
- append(primitive_field-> get_fn(arg.Decode()));
+ append(primitive_field-> get_fn(arg));
#define DO_FAIL(expected) \
} else { \
@@ -801,28 +801,28 @@
ArtField* primitive_field = &klass->GetIFieldsPtr()->At(0);
if (klass->DescriptorEquals("Ljava/lang/Boolean;")) {
src_class = class_linker->FindPrimitiveClass('Z');
- boxed_value.SetZ(primitive_field->GetBoolean(o.Decode()));
+ boxed_value.SetZ(primitive_field->GetBoolean(o));
} else if (klass->DescriptorEquals("Ljava/lang/Byte;")) {
src_class = class_linker->FindPrimitiveClass('B');
- boxed_value.SetB(primitive_field->GetByte(o.Decode()));
+ boxed_value.SetB(primitive_field->GetByte(o));
} else if (klass->DescriptorEquals("Ljava/lang/Character;")) {
src_class = class_linker->FindPrimitiveClass('C');
- boxed_value.SetC(primitive_field->GetChar(o.Decode()));
+ boxed_value.SetC(primitive_field->GetChar(o));
} else if (klass->DescriptorEquals("Ljava/lang/Float;")) {
src_class = class_linker->FindPrimitiveClass('F');
- boxed_value.SetF(primitive_field->GetFloat(o.Decode()));
+ boxed_value.SetF(primitive_field->GetFloat(o));
} else if (klass->DescriptorEquals("Ljava/lang/Double;")) {
src_class = class_linker->FindPrimitiveClass('D');
- boxed_value.SetD(primitive_field->GetDouble(o.Decode()));
+ boxed_value.SetD(primitive_field->GetDouble(o));
} else if (klass->DescriptorEquals("Ljava/lang/Integer;")) {
src_class = class_linker->FindPrimitiveClass('I');
- boxed_value.SetI(primitive_field->GetInt(o.Decode()));
+ boxed_value.SetI(primitive_field->GetInt(o));
} else if (klass->DescriptorEquals("Ljava/lang/Long;")) {
src_class = class_linker->FindPrimitiveClass('J');
- boxed_value.SetJ(primitive_field->GetLong(o.Decode()));
+ boxed_value.SetJ(primitive_field->GetLong(o));
} else if (klass->DescriptorEquals("Ljava/lang/Short;")) {
src_class = class_linker->FindPrimitiveClass('S');
- boxed_value.SetS(primitive_field->GetShort(o.Decode()));
+ boxed_value.SetS(primitive_field->GetShort(o));
} else {
std::string temp;
ThrowIllegalArgumentException(
@@ -888,13 +888,13 @@
}
if ((access_flags & kAccProtected) != 0) {
if (obj != nullptr && !obj->InstanceOf(calling_class) &&
- !declaring_class->IsInSamePackage(calling_class.Decode())) {
+ !declaring_class->IsInSamePackage(calling_class)) {
return false;
- } else if (declaring_class->IsAssignableFrom(calling_class.Decode())) {
+ } else if (declaring_class->IsAssignableFrom(calling_class)) {
return true;
}
}
- return declaring_class->IsInSamePackage(calling_class.Decode());
+ return declaring_class->IsInSamePackage(calling_class);
}
void InvalidReceiverError(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c) {
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index bb6eb79..d75a788 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -175,9 +175,7 @@
inline void Thread::TransitionFromRunnableToSuspended(ThreadState new_state) {
AssertThreadSuspensionIsAllowable();
- if (kIsDebugBuild) {
- PoisonObjectPointers();
- }
+ PoisonObjectPointersIfDebug();
DCHECK_EQ(this, Thread::Current());
// Change to non-runnable state, thereby appearing suspended to the system.
TransitionToSuspendedAndRunCheckpoints(new_state);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index ec1bb3f..b8c7096 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -563,8 +563,8 @@
ScopedObjectAccess soa(env);
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
- mirror::String* java_name = reinterpret_cast<mirror::String*>(f->GetObject(
- soa.Decode<mirror::Object>(java_peer).Decode()));
+ ObjPtr<mirror::String> java_name =
+ f->GetObject(soa.Decode<mirror::Object>(java_peer))->AsString();
std::string thread_name;
if (java_name != nullptr) {
thread_name = java_name->ToModifiedUtf8();
@@ -845,11 +845,9 @@
soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon)->
SetBoolean<kTransactionActive>(tlsPtr_.opeer, thread_is_daemon);
soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->
- SetObject<kTransactionActive>(tlsPtr_.opeer,
- soa.Decode<mirror::Object>(thread_group).Decode());
+ SetObject<kTransactionActive>(tlsPtr_.opeer, soa.Decode<mirror::Object>(thread_group));
soa.DecodeField(WellKnownClasses::java_lang_Thread_name)->
- SetObject<kTransactionActive>(tlsPtr_.opeer,
- soa.Decode<mirror::Object>(thread_name).Decode());
+ SetObject<kTransactionActive>(tlsPtr_.opeer, soa.Decode<mirror::Object>(thread_name));
soa.DecodeField(WellKnownClasses::java_lang_Thread_priority)->
SetInt<kTransactionActive>(tlsPtr_.opeer, thread_priority);
}
@@ -948,8 +946,11 @@
mirror::String* Thread::GetThreadName(const ScopedObjectAccessAlreadyRunnable& soa) const {
ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
- return (tlsPtr_.opeer != nullptr) ?
- reinterpret_cast<mirror::String*>(f->GetObject(tlsPtr_.opeer)) : nullptr;
+ if (tlsPtr_.opeer == nullptr) {
+ return nullptr;
+ }
+ ObjPtr<mirror::Object> name = f->GetObject(tlsPtr_.opeer);
+ return name == nullptr ? nullptr : name->AsString();
}
void Thread::GetThreadName(std::string& name) const {
@@ -1220,14 +1221,14 @@
is_daemon = soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon)
->GetBoolean(thread->tlsPtr_.opeer);
- mirror::Object* thread_group =
+ ObjPtr<mirror::Object> thread_group =
soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(thread->tlsPtr_.opeer);
if (thread_group != nullptr) {
ArtField* group_name_field =
soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
- mirror::String* group_name_string =
- reinterpret_cast<mirror::String*>(group_name_field->GetObject(thread_group));
+ ObjPtr<mirror::String> group_name_string =
+ group_name_field->GetObject(thread_group)->AsString();
group_name = (group_name_string != nullptr) ? group_name_string->ToModifiedUtf8() : "<null>";
}
} else {
@@ -1711,7 +1712,7 @@
// Thread.join() is implemented as an Object.wait() on the Thread.lock object. Signal anyone
// who is waiting.
- mirror::Object* lock =
+ ObjPtr<mirror::Object> lock =
soa.DecodeField(WellKnownClasses::java_lang_Thread_lock)->GetObject(tlsPtr_.opeer);
// (This conditional is only needed for tests, where Thread.lock won't have been set.)
if (lock != nullptr) {
@@ -1803,7 +1804,7 @@
void Thread::RemoveFromThreadGroup(ScopedObjectAccess& soa) {
// this.group.removeThread(this);
// group can be null if we're in the compiler or a test.
- mirror::Object* ogroup = soa.DecodeField(WellKnownClasses::java_lang_Thread_group)
+ ObjPtr<mirror::Object> ogroup = soa.DecodeField(WellKnownClasses::java_lang_Thread_group)
->GetObject(tlsPtr_.opeer);
if (ogroup != nullptr) {
ScopedLocalRef<jobject> group(soa.Env(), soa.AddLocalReference<jobject>(ogroup));
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 87b6dc3..50466ed 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -4563,9 +4563,11 @@
return nullptr;
} else {
std::string temp;
- mirror::Class* klass = field->GetDeclaringClass();
+ ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
const RegType& field_klass =
- FromClass(klass->GetDescriptor(&temp), klass, klass->CannotBeAssignedFromOtherTypes());
+ FromClass(klass->GetDescriptor(&temp),
+ klass.Decode(),
+ klass->CannotBeAssignedFromOtherTypes());
if (obj_type.IsUninitializedTypes()) {
// Field accesses through uninitialized references are only allowable for constructors where
// the field is declared in this class.
@@ -4662,10 +4664,11 @@
}
}
- mirror::Class* field_type_class =
+ ObjPtr<mirror::Class> field_type_class =
can_load_classes_ ? field->GetType<true>() : field->GetType<false>();
if (field_type_class != nullptr) {
- field_type = &FromClass(field->GetTypeDescriptor(), field_type_class,
+ field_type = &FromClass(field->GetTypeDescriptor(),
+ field_type_class.Decode(),
field_type_class->CannotBeAssignedFromOtherTypes());
} else {
DCHECK(!can_load_classes_ || self_->IsExceptionPending());
@@ -4785,12 +4788,12 @@
// Get the field type.
const RegType* field_type;
{
- mirror::Class* field_type_class = can_load_classes_ ? field->GetType<true>() :
+ ObjPtr<mirror::Class> field_type_class = can_load_classes_ ? field->GetType<true>() :
field->GetType<false>();
if (field_type_class != nullptr) {
field_type = &FromClass(field->GetTypeDescriptor(),
- field_type_class,
+ field_type_class.Decode(),
field_type_class->CannotBeAssignedFromOtherTypes());
} else {
Thread* self = Thread::Current();
diff --git a/runtime/verifier/reg_type-inl.h b/runtime/verifier/reg_type-inl.h
index d93aaa1..10f1be5 100644
--- a/runtime/verifier/reg_type-inl.h
+++ b/runtime/verifier/reg_type-inl.h
@@ -44,7 +44,7 @@
}
}
-inline bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) const {
+inline bool RegType::CanAccessMember(ObjPtr<mirror::Class> klass, uint32_t access_flags) const {
if ((access_flags & kAccPublic) != 0) {
return true;
}
diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h
index 9170bb1..472381d 100644
--- a/runtime/verifier/reg_type.h
+++ b/runtime/verifier/reg_type.h
@@ -29,6 +29,7 @@
#include "base/stringpiece.h"
#include "gc_root.h"
#include "handle_scope.h"
+#include "obj_ptr.h"
#include "object_callbacks.h"
#include "primitive.h"
@@ -205,7 +206,7 @@
REQUIRES_SHARED(Locks::mutator_lock_);
// Can this type access a member with the given properties?
- bool CanAccessMember(mirror::Class* klass, uint32_t access_flags) const
+ bool CanAccessMember(ObjPtr<mirror::Class> klass, uint32_t access_flags) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Can this type be assigned by src?
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index 350c838..3e1958f 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -19,6 +19,7 @@
#include "compiler_callbacks.h"
#include "leb128.h"
#include "mirror/class-inl.h"
+#include "obj_ptr-inl.h"
#include "runtime.h"
namespace art {
@@ -107,10 +108,10 @@
}
}
-bool VerifierDeps::IsInClassPath(mirror::Class* klass) {
+bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) {
DCHECK(klass != nullptr);
- mirror::DexCache* dex_cache = klass->GetDexCache();
+ ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
if (dex_cache == nullptr) {
// This is a synthesized class, in this case always an array. They are not
// defined in the compiled DEX files and therefore are part of the classpath.
diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h
index dc8dfaf..3223f6f 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -26,6 +26,7 @@
#include "base/array_ref.h"
#include "base/mutex.h"
#include "method_resolution_kind.h"
+#include "obj_ptr.h"
#include "os.h"
namespace art {
@@ -176,7 +177,7 @@
// Returns true if `klass` is null or not defined in any of dex files which
// were reported as being compiled.
- bool IsInClassPath(mirror::Class* klass)
+ bool IsInClassPath(ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the index of `str`. If it is defined in `dex_file_`, this is the dex