diff options
27 files changed, 263 insertions, 336 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index b04392918d..7e118d5d85 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -32,13 +32,13 @@ namespace art { -inline mirror::Class* CompilerDriver::ResolveClass( +inline ObjPtr<mirror::Class> CompilerDriver::ResolveClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); - mirror::Class* cls = mUnit->GetClassLinker()->ResolveType( + ObjPtr<mirror::Class> cls = mUnit->GetClassLinker()->ResolveType( *mUnit->GetDexFile(), cls_index, dex_cache, class_loader); DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending()); if (UNLIKELY(cls == nullptr)) { @@ -48,7 +48,7 @@ inline mirror::Class* CompilerDriver::ResolveClass( return cls; } -inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( +inline ObjPtr<mirror::Class> CompilerDriver::ResolveCompilingMethodsClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); @@ -89,8 +89,10 @@ inline ArtField* CompilerDriver::ResolveField( } inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( - mirror::DexCache* dex_cache, mirror::Class* referrer_class, - ArtField* resolved_field, uint16_t field_idx) { + ObjPtr<mirror::DexCache> dex_cache, + ObjPtr<mirror::Class> referrer_class, + ArtField* resolved_field, + uint16_t field_idx) { DCHECK(!resolved_field->IsStatic()); ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass(); bool fast_get = referrer_class != nullptr && diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 0ca3c8f613..f49d119900 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -717,7 +717,8 @@ static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache, dex::StringIndex string_index((inst->Opcode() == Instruction::CONST_STRING) ? inst->VRegB_21c() : inst->VRegB_31c()); - mirror::String* string = class_linker->ResolveString(dex_file, string_index, dex_cache); + ObjPtr<mirror::String> string = + class_linker->ResolveString(dex_file, string_index, dex_cache); CHECK(string != nullptr) << "Could not allocate a string when forcing determinism"; break; } @@ -1371,7 +1372,7 @@ ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const ScopedObjectAccess& soa) { // Try to resolve the field and compiling method's class. ArtField* resolved_field; - mirror::Class* referrer_class; + ObjPtr<mirror::Class> referrer_class; Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache()); { Handle<mirror::ClassLoader> class_loader_handle = mUnit->GetClassLoader(); @@ -1542,7 +1543,7 @@ class ParallelCompilationManager { // A fast version of SkipClass above if the class pointer is available // that avoids the expensive FindInClassPath search. -static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Class* klass) +static bool SkipClass(jobject class_loader, const DexFile& dex_file, ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(klass != nullptr); const DexFile& original_dex_file = *klass->GetDexCache()->GetDexFile(); @@ -1636,8 +1637,8 @@ class ResolveClassFieldsAndMethodsVisitor : public CompilationVisitor { Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache( soa.Self(), dex_file))); // Resolve the class. - mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache, - class_loader); + ObjPtr<mirror::Class> klass = + class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache, class_loader); bool resolve_fields_and_methods; if (klass == nullptr) { // Class couldn't be resolved, for example, super-class is in a different dex file. Don't diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index d2141e8bc7..ce7ec4520d 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -219,12 +219,12 @@ class CompilerDriver { REQUIRES_SHARED(Locks::mutator_lock_); // Resolve compiling method's class. Returns null on failure. - mirror::Class* ResolveCompilingMethodsClass( + ObjPtr<mirror::Class> ResolveCompilingMethodsClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) REQUIRES_SHARED(Locks::mutator_lock_); - mirror::Class* ResolveClass( + ObjPtr<mirror::Class> ResolveClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, dex::TypeIndex type_index, const DexCompilationUnit* mUnit) @@ -247,7 +247,8 @@ class CompilerDriver { // 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, + ObjPtr<mirror::DexCache> dex_cache, + ObjPtr<mirror::Class> referrer_class, ArtField* resolved_field, uint16_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 560372e22e..a175c21760 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -876,9 +876,9 @@ HInstruction* HInliner::AddTypeGuard(HInstruction* receiver, load_class, codegen_, compiler_driver_, caller_compilation_unit_); DCHECK(kind != HLoadClass::LoadKind::kInvalid) << "We should always be able to reference a class for inline caches"; - // Insert before setting the kind, as setting the kind affects the inputs. - bb_cursor->InsertInstructionAfter(load_class, receiver_class); + // Load kind must be set before inserting the instruction into the graph. load_class->SetLoadKind(kind); + bb_cursor->InsertInstructionAfter(load_class, receiver_class); // In AOT mode, we will most likely load the class from BSS, which will involve a call // to the runtime. In this case, the load instruction will need an environment so copy // it from the invoke instruction. @@ -1932,7 +1932,7 @@ void HInliner::RunOptimizations(HGraph* callee_graph, // optimization that could lead to a HDeoptimize. The following optimizations do not. HDeadCodeElimination dce(callee_graph, inline_stats_, "dead_code_elimination$inliner"); HConstantFolding fold(callee_graph, "constant_folding$inliner"); - HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_, handles_); + HSharpening sharpening(callee_graph, codegen_, compiler_driver_); InstructionSimplifier simplify(callee_graph, codegen_, compiler_driver_, inline_stats_); IntrinsicsRecognizer intrinsics(callee_graph, inline_stats_); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 782546c9d8..4485f064c6 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1128,7 +1128,7 @@ void HInstructionBuilder::BuildConstructorFenceForAllocation(HInstruction* alloc MethodCompilationStat::kConstructorFenceGeneratedNew); } -static bool IsSubClass(mirror::Class* to_test, mirror::Class* super_class) +static bool IsSubClass(ObjPtr<mirror::Class> to_test, ObjPtr<mirror::Class> super_class) REQUIRES_SHARED(Locks::mutator_lock_) { return to_test != nullptr && !to_test->IsInterface() && to_test->IsSubClass(super_class); } @@ -1424,7 +1424,7 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio return true; } -static mirror::Class* GetClassFrom(CompilerDriver* driver, +static ObjPtr<mirror::Class> GetClassFrom(CompilerDriver* driver, const DexCompilationUnit& compilation_unit) { ScopedObjectAccess soa(Thread::Current()); Handle<mirror::ClassLoader> class_loader = compilation_unit.GetClassLoader(); @@ -1433,11 +1433,11 @@ static mirror::Class* GetClassFrom(CompilerDriver* driver, return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); } -mirror::Class* HInstructionBuilder::GetOutermostCompilingClass() const { +ObjPtr<mirror::Class> HInstructionBuilder::GetOutermostCompilingClass() const { return GetClassFrom(compiler_driver_, *outer_compilation_unit_); } -mirror::Class* HInstructionBuilder::GetCompilingClass() const { +ObjPtr<mirror::Class> HInstructionBuilder::GetCompilingClass() const { return GetClassFrom(compiler_driver_, *dex_compilation_unit_); } @@ -1799,6 +1799,17 @@ static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls) } } +void HInstructionBuilder::BuildLoadString(dex::StringIndex string_index, uint32_t dex_pc) { + HLoadString* load_string = + new (allocator_) HLoadString(graph_->GetCurrentMethod(), string_index, *dex_file_, dex_pc); + HSharpening::ProcessLoadString(load_string, + code_generator_, + compiler_driver_, + *dex_compilation_unit_, + handles_); + AppendInstruction(load_string); +} + HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); @@ -1811,7 +1822,7 @@ HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint3 if (klass->IsPublic()) { needs_access_check = false; } else { - mirror::Class* compiling_class = GetCompilingClass(); + ObjPtr<mirror::Class> compiling_class = GetCompilingClass(); if (compiling_class != nullptr && compiling_class->CanAccess(klass.Get())) { needs_access_check = false; } @@ -1856,9 +1867,9 @@ HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, // We actually cannot reference this class, we're forced to bail. return nullptr; } - // Append the instruction first, as setting the load kind affects the inputs. - AppendInstruction(load_class); + // Load kind must be set before inserting the instruction into the graph. load_class->SetLoadKind(load_kind); + AppendInstruction(load_class); return load_class; } @@ -2837,20 +2848,14 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::CONST_STRING: { dex::StringIndex string_index(instruction.VRegB_21c()); - AppendInstruction(new (allocator_) HLoadString(graph_->GetCurrentMethod(), - string_index, - *dex_file_, - dex_pc)); + BuildLoadString(string_index, dex_pc); UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); break; } case Instruction::CONST_STRING_JUMBO: { dex::StringIndex string_index(instruction.VRegB_31c()); - AppendInstruction(new (allocator_) HLoadString(graph_->GetCurrentMethod(), - string_index, - *dex_file_, - dex_pc)); + BuildLoadString(string_index, dex_pc); UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction()); break; } diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 2446ddb86a..0500d40cd3 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -240,9 +240,10 @@ class HInstructionBuilder : public ValueObject { // Builds an instruction sequence for a switch statement. void BuildSwitch(const Instruction& instruction, uint32_t dex_pc); - // Builds a `HLoadClass` loading the given `type_index`. If `outer` is true, - // this method will use the outer class's dex file to lookup the type at - // `type_index`. + // Builds a `HLoadString` loading the given `string_index`. + void BuildLoadString(dex::StringIndex string_index, uint32_t dex_pc); + + // Builds a `HLoadClass` loading the given `type_index`. HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc); HLoadClass* BuildLoadClass(dex::TypeIndex type_index, @@ -253,10 +254,10 @@ class HInstructionBuilder : public ValueObject { REQUIRES_SHARED(Locks::mutator_lock_); // Returns the outer-most compiling method's class. - mirror::Class* GetOutermostCompilingClass() const; + ObjPtr<mirror::Class> GetOutermostCompilingClass() const; // Returns the class whose method is being compiled. - mirror::Class* GetCompilingClass() const; + ObjPtr<mirror::Class> GetCompilingClass() const; // Returns whether `type_index` points to the outer-most compiling method's class. bool IsOutermostCompilingClass(dex::TypeIndex type_index) const; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index d117bfb67d..5f33ed6303 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2831,21 +2831,6 @@ bool HLoadClass::InstructionDataEquals(const HInstruction* other) const { } } -void HLoadClass::SetLoadKind(LoadKind load_kind) { - SetPackedField<LoadKindField>(load_kind); - - if (load_kind != LoadKind::kRuntimeCall && - load_kind != LoadKind::kReferrersClass) { - RemoveAsUserOfInput(0u); - SetRawInputAt(0u, nullptr); - } - - if (!NeedsEnvironment()) { - RemoveEnvironment(); - SetSideEffects(SideEffects::None()); - } -} - std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs) { switch (rhs) { case HLoadClass::LoadKind::kReferrersClass: @@ -2888,21 +2873,6 @@ bool HLoadString::InstructionDataEquals(const HInstruction* other) const { } } -void HLoadString::SetLoadKind(LoadKind load_kind) { - // Once sharpened, the load kind should not be changed again. - DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); - SetPackedField<LoadKindField>(load_kind); - - if (load_kind != LoadKind::kRuntimeCall) { - RemoveAsUserOfInput(0u); - SetRawInputAt(0u, nullptr); - } - if (!NeedsEnvironment()) { - RemoveEnvironment(); - SetSideEffects(SideEffects::None()); - } -} - std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs) { switch (rhs) { case HLoadString::LoadKind::kBootImageLinkTimePcRelative: diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 7fbd7f48a2..42a9d95b9a 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -6061,6 +6061,20 @@ class HLoadClass FINAL : public HInstruction { std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadClass::LoadKind). +inline void HLoadClass::SetLoadKind(LoadKind load_kind) { + // The load kind should be determined before inserting the instruction to the graph. + DCHECK(GetBlock() == nullptr); + DCHECK(GetEnvironment() == nullptr); + SetPackedField<LoadKindField>(load_kind); + if (load_kind != LoadKind::kRuntimeCall && load_kind != LoadKind::kReferrersClass) { + special_input_ = HUserRecord<HInstruction*>(nullptr); + } + if (!NeedsEnvironment()) { + SetSideEffects(SideEffects::None()); + } +} + +// Note: defined outside class to see operator<<(., HLoadClass::LoadKind). inline void HLoadClass::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. @@ -6208,6 +6222,21 @@ class HLoadString FINAL : public HInstruction { std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadString::LoadKind). +inline void HLoadString::SetLoadKind(LoadKind load_kind) { + // The load kind should be determined before inserting the instruction to the graph. + DCHECK(GetBlock() == nullptr); + DCHECK(GetEnvironment() == nullptr); + DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); + SetPackedField<LoadKindField>(load_kind); + if (load_kind != LoadKind::kRuntimeCall) { + special_input_ = HUserRecord<HInstruction*>(nullptr); + } + if (!NeedsEnvironment()) { + SetSideEffects(SideEffects::None()); + } +} + +// Note: defined outside class to see operator<<(., HLoadString::LoadKind). inline void HLoadString::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index 7edb642c5b..7149d93d07 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -258,8 +258,7 @@ ArenaVector<HOptimization*> ConstructOptimizations( break; } case OptimizationPass::kSharpening: - opt = new (allocator) HSharpening( - graph, codegen, dex_compilation_unit, driver, handles, name); + opt = new (allocator) HSharpening(graph, codegen, driver, name); break; case OptimizationPass::kSelectGenerator: opt = new (allocator) HSelectGenerator(graph, handles, stats, name); diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index e46c9a7081..64092d307d 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -45,8 +45,6 @@ void HSharpening::Run() { SharpenInvokeStaticOrDirect(instruction->AsInvokeStaticOrDirect(), codegen_, compiler_driver_); - } else if (instruction->IsLoadString()) { - ProcessLoadString(instruction->AsLoadString()); } // TODO: Move the sharpening of invoke-virtual/-interface/-super from HGraphBuilder // here. Rewrite it to avoid the CompilerDriver's reliance on verifier data @@ -147,10 +145,11 @@ void HSharpening::SharpenInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke, invoke->SetDispatchInfo(dispatch_info); } -HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(HLoadClass* load_class, - CodeGenerator* codegen, - CompilerDriver* compiler_driver, - const DexCompilationUnit& dex_compilation_unit) { +HLoadClass::LoadKind HSharpening::ComputeLoadClassKind( + HLoadClass* load_class, + CodeGenerator* codegen, + CompilerDriver* compiler_driver, + const DexCompilationUnit& dex_compilation_unit) { Handle<mirror::Class> klass = load_class->GetClass(); DCHECK(load_class->GetLoadKind() == HLoadClass::LoadKind::kRuntimeCall || load_class->GetLoadKind() == HLoadClass::LoadKind::kReferrersClass) @@ -237,7 +236,12 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(HLoadClass* load_class, return load_kind; } -void HSharpening::ProcessLoadString(HLoadString* load_string) { +void HSharpening::ProcessLoadString( + HLoadString* load_string, + CodeGenerator* codegen, + CompilerDriver* compiler_driver, + const DexCompilationUnit& dex_compilation_unit, + VariableSizedHandleScope* handles) { DCHECK_EQ(load_string->GetLoadKind(), HLoadString::LoadKind::kRuntimeCall); const DexFile& dex_file = load_string->GetDexFile(); @@ -249,26 +253,26 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { ClassLinker* class_linker = runtime->GetClassLinker(); ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *compilation_unit_.GetDexFile()) - ? compilation_unit_.GetDexCache() + Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *dex_compilation_unit.GetDexFile()) + ? dex_compilation_unit.GetDexCache() : hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file)); - mirror::String* string = nullptr; + ObjPtr<mirror::String> string = nullptr; - if (codegen_->GetCompilerOptions().IsBootImage()) { + if (codegen->GetCompilerOptions().IsBootImage()) { // Compiling boot image. Resolve the string and allocate it if needed, to ensure // the string will be added to the boot image. DCHECK(!runtime->UseJitCompilation()); string = class_linker->ResolveString(dex_file, string_index, dex_cache); CHECK(string != nullptr); - if (compiler_driver_->GetSupportBootImageFixup()) { - DCHECK(ContainsElement(compiler_driver_->GetDexFilesForOatFile(), &dex_file)); + if (compiler_driver->GetSupportBootImageFixup()) { + DCHECK(ContainsElement(compiler_driver->GetDexFilesForOatFile(), &dex_file)); desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative; } else { // compiler_driver_test. Do not sharpen. desired_load_kind = HLoadString::LoadKind::kRuntimeCall; } } else if (runtime->UseJitCompilation()) { - DCHECK(!codegen_->GetCompilerOptions().GetCompilePic()); + DCHECK(!codegen->GetCompilerOptions().GetCompilePic()); string = class_linker->LookupString(dex_file, string_index, dex_cache.Get()); if (string != nullptr) { if (runtime->GetHeap()->ObjectIsInBootImageSpace(string)) { @@ -283,7 +287,7 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { // AOT app compilation. Try to lookup the string without allocating if not found. string = class_linker->LookupString(dex_file, string_index, dex_cache.Get()); if (string != nullptr && runtime->GetHeap()->ObjectIsInBootImageSpace(string)) { - if (codegen_->GetCompilerOptions().GetCompilePic()) { + if (codegen->GetCompilerOptions().GetCompilePic()) { desired_load_kind = HLoadString::LoadKind::kBootImageInternTable; } else { desired_load_kind = HLoadString::LoadKind::kBootImageAddress; @@ -293,12 +297,12 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { } } if (string != nullptr) { - load_string->SetString(handles_->NewHandle(string)); + load_string->SetString(handles->NewHandle(string)); } } DCHECK_NE(desired_load_kind, static_cast<HLoadString::LoadKind>(-1)); - HLoadString::LoadKind load_kind = codegen_->GetSupportedLoadStringKind(desired_load_kind); + HLoadString::LoadKind load_kind = codegen->GetSupportedLoadStringKind(desired_load_kind); load_string->SetLoadKind(load_kind); } diff --git a/compiler/optimizing/sharpening.h b/compiler/optimizing/sharpening.h index bb1954eeeb..6df7d6d91e 100644 --- a/compiler/optimizing/sharpening.h +++ b/compiler/optimizing/sharpening.h @@ -34,26 +34,29 @@ class HSharpening : public HOptimization { public: HSharpening(HGraph* graph, CodeGenerator* codegen, - const DexCompilationUnit& compilation_unit, CompilerDriver* compiler_driver, - VariableSizedHandleScope* handles, const char* name = kSharpeningPassName) : HOptimization(graph, name), codegen_(codegen), - compilation_unit_(compilation_unit), - compiler_driver_(compiler_driver), - handles_(handles) { } + compiler_driver_(compiler_driver) { } void Run() OVERRIDE; static constexpr const char* kSharpeningPassName = "sharpening"; + // Used by the builder. + static void ProcessLoadString(HLoadString* load_string, + CodeGenerator* codegen, + CompilerDriver* compiler_driver, + const DexCompilationUnit& dex_compilation_unit, + VariableSizedHandleScope* handles); + // Used by the builder and the inliner. static HLoadClass::LoadKind ComputeLoadClassKind(HLoadClass* load_class, CodeGenerator* codegen, CompilerDriver* compiler_driver, const DexCompilationUnit& dex_compilation_unit) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_); // Used by Sharpening and InstructionSimplifier. static void SharpenInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke, @@ -61,12 +64,8 @@ class HSharpening : public HOptimization { CompilerDriver* compiler_driver); private: - void ProcessLoadString(HLoadString* load_string); - CodeGenerator* codegen_; - const DexCompilationUnit& compilation_unit_; CompilerDriver* compiler_driver_; - VariableSizedHandleScope* handles_; }; } // namespace art diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 293078acee..ca7f1b37ab 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -1951,20 +1951,22 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { : class_linker_->FindDexCache(Thread::Current(), *target_dex_file); } - mirror::Class* GetTargetType(const LinkerPatch& patch) REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> GetTargetType(const LinkerPatch& patch) + REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(writer_->HasImage()); ObjPtr<mirror::DexCache> dex_cache = GetDexCache(patch.TargetTypeDexFile()); ObjPtr<mirror::Class> type = ClassLinker::LookupResolvedType(patch.TargetTypeIndex(), dex_cache, class_loader_); CHECK(type != nullptr); - return type.Ptr(); + return type; } - mirror::String* GetTargetString(const LinkerPatch& patch) REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::String> GetTargetString(const LinkerPatch& patch) + REQUIRES_SHARED(Locks::mutator_lock_) { ClassLinker* linker = Runtime::Current()->GetClassLinker(); - mirror::String* string = linker->LookupString(*patch.TargetStringDexFile(), - patch.TargetStringIndex(), - GetDexCache(patch.TargetStringDexFile())); + ObjPtr<mirror::String> string = linker->LookupString(*patch.TargetStringDexFile(), + patch.TargetStringIndex(), + GetDexCache(patch.TargetStringDexFile())); DCHECK(string != nullptr); DCHECK(writer_->HasBootImage() || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(string)); @@ -1980,13 +1982,14 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method) - oat_data_begin); } - uint32_t GetTargetObjectOffset(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_) { + uint32_t GetTargetObjectOffset(ObjPtr<mirror::Object> object) + REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(writer_->HasBootImage()); - object = writer_->image_writer_->GetImageAddress(object); + object = writer_->image_writer_->GetImageAddress(object.Ptr()); size_t oat_index = writer_->image_writer_->GetOatIndexForDexFile(dex_file_); uintptr_t oat_data_begin = writer_->image_writer_->GetOatDataBegin(oat_index); // TODO: Clean up offset types. The target offset must be treated as signed. - return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object) - oat_data_begin); + return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object.Ptr()) - oat_data_begin); } void PatchObjectAddress(std::vector<uint8_t>* code, uint32_t offset, mirror::Object* object) diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 43a51391b9..ebfa4feefa 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -134,7 +134,7 @@ uint16_t ArtMethod::FindObsoleteDexClassDefIndex() { return dex_file->GetIndexForClassDef(*class_def); } -mirror::String* ArtMethod::GetNameAsString(Thread* self) { +ObjPtr<mirror::String> ArtMethod::GetNameAsString(Thread* self) { CHECK(!IsProxyMethod()); StackHandleScope<1> hs(self); Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache())); @@ -550,8 +550,8 @@ bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> param } auto* cl = Runtime::Current()->GetClassLinker(); for (size_t i = 0; i < count; ++i) { - auto type_idx = proto_params->GetTypeItem(i).type_idx_; - auto* type = cl->ResolveType(type_idx, this); + dex::TypeIndex type_idx = proto_params->GetTypeItem(i).type_idx_; + ObjPtr<mirror::Class> type = cl->ResolveType(type_idx, this); if (type == nullptr) { Thread::Current()->AssertPendingException(); return false; diff --git a/runtime/art_method.h b/runtime/art_method.h index 0a592e0528..60e436cc7e 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -575,7 +575,7 @@ class ArtMethod FINAL { ALWAYS_INLINE const char* GetName() REQUIRES_SHARED(Locks::mutator_lock_); - mirror::String* GetNameAsString(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<mirror::String> GetNameAsString(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_); const DexFile::CodeItem* GetCodeItem() REQUIRES_SHARED(Locks::mutator_lock_); diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index d6f003027b..648b455e50 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -73,7 +73,8 @@ inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType( return type; } -inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) { +inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx, + ArtMethod* referrer) { Thread::PoisonObjectPointersIfDebug(); if (kIsDebugBuild) { Thread::Current()->AssertNoPendingException(); @@ -87,7 +88,7 @@ inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMetho const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); } - return resolved_type.Ptr(); + return resolved_type; } template <bool kThrowOnError, typename ClassGetter> diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index e5bb7862cb..80d4bb15b8 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -7727,14 +7727,14 @@ void ClassLinker::CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) { klass->SetReferenceInstanceOffsets(reference_offsets); } -mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, - dex::StringIndex string_idx, - Handle<mirror::DexCache> dex_cache) { +ObjPtr<mirror::String> ClassLinker::ResolveString(const DexFile& dex_file, + dex::StringIndex string_idx, + Handle<mirror::DexCache> dex_cache) { DCHECK(dex_cache != nullptr); Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx); if (resolved != nullptr) { - return resolved.Ptr(); + return resolved; } uint32_t utf16_length; const char* utf8_data = dex_file.StringDataAndUtf16LengthByIdx(string_idx, &utf16_length); @@ -7742,16 +7742,16 @@ mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, if (string != nullptr) { dex_cache->SetResolvedString(string_idx, string); } - return string.Ptr(); + return string; } -mirror::String* ClassLinker::LookupString(const DexFile& dex_file, - dex::StringIndex string_idx, - ObjPtr<mirror::DexCache> dex_cache) { +ObjPtr<mirror::String> ClassLinker::LookupString(const DexFile& dex_file, + dex::StringIndex string_idx, + ObjPtr<mirror::DexCache> dex_cache) { DCHECK(dex_cache != nullptr); ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx); if (resolved != nullptr) { - return resolved.Ptr(); + return resolved; } uint32_t utf16_length; const char* utf8_data = dex_file.StringDataAndUtf16LengthByIdx(string_idx, &utf16_length); @@ -7760,7 +7760,7 @@ mirror::String* ClassLinker::LookupString(const DexFile& dex_file, if (string != nullptr) { dex_cache->SetResolvedString(string_idx, string); } - return string.Ptr(); + return string; } ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, @@ -7794,19 +7794,19 @@ ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, return type; } -mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, - dex::TypeIndex type_idx, - ObjPtr<mirror::Class> referrer) { +ObjPtr<mirror::Class> ClassLinker::ResolveType(const DexFile& dex_file, + dex::TypeIndex type_idx, + ObjPtr<mirror::Class> referrer) { StackHandleScope<2> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache())); Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader())); return ResolveType(dex_file, type_idx, dex_cache, class_loader); } -mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, - dex::TypeIndex type_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) { +ObjPtr<mirror::Class> ClassLinker::ResolveType(const DexFile& dex_file, + dex::TypeIndex type_idx, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader) { DCHECK(dex_cache != nullptr); Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::Class> resolved = dex_cache->GetResolvedType(type_idx); @@ -7835,7 +7835,7 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, } DCHECK((resolved == nullptr) || resolved->IsResolved()) << resolved->PrettyDescriptor() << " " << resolved->GetStatus(); - return resolved.Ptr(); + return resolved; } template <ClassLinker::ResolveMode kResolveMode> @@ -8410,7 +8410,7 @@ mirror::MethodHandle* ClassLinker::ResolveMethodHandleForMethod( DexFileParameterIterator it(*dex_file, target_method->GetPrototype()); while (it.HasNext()) { const dex::TypeIndex type_idx = it.GetTypeIdx(); - mirror::Class* klass = ResolveType(*dex_file, type_idx, dex_cache, class_loader); + ObjPtr<mirror::Class> klass = ResolveType(*dex_file, type_idx, dex_cache, class_loader); if (nullptr == klass) { DCHECK(self->IsExceptionPending()); return nullptr; diff --git a/runtime/class_linker.h b/runtime/class_linker.h index a4c4f3d9ab..16255f4542 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -245,31 +245,31 @@ class ClassLinker { // Resolve a String with the given index from the DexFile, storing the // result in the DexCache. - mirror::String* ResolveString(const DexFile& dex_file, - dex::StringIndex string_idx, - Handle<mirror::DexCache> dex_cache) + ObjPtr<mirror::String> ResolveString(const DexFile& dex_file, + dex::StringIndex string_idx, + Handle<mirror::DexCache> dex_cache) REQUIRES_SHARED(Locks::mutator_lock_); // Find a String with the given index from the DexFile, storing the // result in the DexCache if found. Return null if not found. - mirror::String* LookupString(const DexFile& dex_file, - dex::StringIndex string_idx, - ObjPtr<mirror::DexCache> dex_cache) + ObjPtr<mirror::String> LookupString(const DexFile& dex_file, + dex::StringIndex string_idx, + ObjPtr<mirror::DexCache> dex_cache) REQUIRES_SHARED(Locks::mutator_lock_); // Resolve a Type with the given index from the DexFile, storing the // result in the DexCache. The referrer is used to identify the // target DexCache and ClassLoader to use for resolution. - mirror::Class* ResolveType(const DexFile& dex_file, - dex::TypeIndex type_idx, - ObjPtr<mirror::Class> referrer) + ObjPtr<mirror::Class> ResolveType(const DexFile& dex_file, + dex::TypeIndex type_idx, + ObjPtr<mirror::Class> referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); // Resolve a Type with the given index from the DexFile, storing the // result in the DexCache. The referrer is used to identify the // target DexCache and ClassLoader to use for resolution. - mirror::Class* ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) + ObjPtr<mirror::Class> ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); @@ -289,10 +289,10 @@ class ClassLinker { // result in DexCache. The ClassLoader is used to search for the // type, since it may be referenced from but not contained within // the given DexFile. - mirror::Class* ResolveType(const DexFile& dex_file, - dex::TypeIndex type_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) + ObjPtr<mirror::Class> ResolveType(const DexFile& dex_file, + dex::TypeIndex type_idx, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 892a850997..94125507ef 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -1304,10 +1304,18 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) { const DexFile::TypeId* type_id = dex_file->FindTypeId("LStaticsFromCode;"); ASSERT_TRUE(type_id != nullptr); dex::TypeIndex type_idx = dex_file->GetIndexForTypeId(*type_id); - mirror::Class* uninit = ResolveVerifyAndClinit(type_idx, clinit, soa.Self(), true, false); + ObjPtr<mirror::Class> uninit = ResolveVerifyAndClinit(type_idx, + clinit, + soa.Self(), + /* can_run_clinit */ true, + /* verify_access */ false); EXPECT_TRUE(uninit != nullptr); EXPECT_FALSE(uninit->IsInitialized()); - mirror::Class* init = ResolveVerifyAndClinit(type_idx, getS0, soa.Self(), true, false); + ObjPtr<mirror::Class> init = ResolveVerifyAndClinit(type_idx, + getS0, + soa.Self(), + /* can_run_clinit */ true, + /* verify_access */ false); EXPECT_TRUE(init != nullptr); EXPECT_TRUE(init->IsInitialized()); } diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index b44bd51643..27b9202d25 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -783,9 +783,8 @@ const DexFile::AnnotationItem* GetAnnotationItemFromAnnotationSet( uint32_t type_index = DecodeUnsignedLeb128(&annotation); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Thread* self = Thread::Current(); - mirror::Class* resolved_class; StackHandleScope<2> hs(self); - resolved_class = class_linker->ResolveType( + ObjPtr<mirror::Class> resolved_class = class_linker->ResolveType( klass.GetDexFile(), dex::TypeIndex(type_index), hs.NewHandle(klass.GetDexCache()), @@ -1594,17 +1593,17 @@ void RuntimeEncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) c case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break; case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break; case kString: { - mirror::String* resolved = linker_->ResolveString(dex_file_, - dex::StringIndex(jval_.i), - *dex_cache_); + ObjPtr<mirror::String> resolved = linker_->ResolveString(dex_file_, + dex::StringIndex(jval_.i), + *dex_cache_); field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); break; } case kType: { - mirror::Class* resolved = linker_->ResolveType(dex_file_, - dex::TypeIndex(jval_.i), - *dex_cache_, - *class_loader_); + ObjPtr<mirror::Class> resolved = linker_->ResolveType(dex_file_, + dex::TypeIndex(jval_.i), + *dex_cache_, + *class_loader_); field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); break; } diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 8253739427..475c1e7e90 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -245,7 +245,7 @@ inline mirror::Class* CheckArrayAlloc(dex::TypeIndex type_idx, *slow_path = true; return nullptr; // Failure } - mirror::Class* klass = method->GetDexCache()->GetResolvedType(type_idx); + ObjPtr<mirror::Class> klass = method->GetDexCache()->GetResolvedType(type_idx); if (UNLIKELY(klass == nullptr)) { // Not in dex cache so try to resolve ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); klass = class_linker->ResolveType(type_idx, method); @@ -264,7 +264,7 @@ inline mirror::Class* CheckArrayAlloc(dex::TypeIndex type_idx, return nullptr; // Failure } } - return klass; + return klass.Ptr(); } // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If @@ -500,7 +500,8 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, Handle<mirror::Class> h_referring_class(hs2.NewHandle(referrer->GetDeclaringClass())); const dex::TypeIndex method_type_idx = referrer->GetDexFile()->GetMethodId(method_idx).class_idx_; - mirror::Class* method_reference_class = class_linker->ResolveType(method_type_idx, referrer); + ObjPtr<mirror::Class> method_reference_class = + class_linker->ResolveType(method_type_idx, referrer); if (UNLIKELY(method_reference_class == nullptr)) { // Bad type idx. CHECK(self->IsExceptionPending()); @@ -711,13 +712,13 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, } } -inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, - ArtMethod* referrer, - Thread* self, - bool can_run_clinit, - bool verify_access) { +inline ObjPtr<mirror::Class> ResolveVerifyAndClinit(dex::TypeIndex type_idx, + ArtMethod* referrer, + Thread* self, + bool can_run_clinit, + bool verify_access) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - mirror::Class* klass = class_linker->ResolveType(type_idx, referrer); + ObjPtr<mirror::Class> klass = class_linker->ResolveType(type_idx, referrer); if (UNLIKELY(klass == nullptr)) { CHECK(self->IsExceptionPending()); return nullptr; // Failure - Indicate to caller to deliver exception @@ -748,9 +749,9 @@ inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, return h_class.Get(); } -static inline mirror::String* ResolveString(ClassLinker* class_linker, - dex::StringIndex string_idx, - ArtMethod* referrer) +static inline ObjPtr<mirror::String> ResolveString(ClassLinker* class_linker, + dex::StringIndex string_idx, + ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_) { Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::String> string = referrer->GetDexCache()->GetResolvedString(string_idx); @@ -760,10 +761,11 @@ static inline mirror::String* ResolveString(ClassLinker* class_linker, const DexFile& dex_file = *dex_cache->GetDexFile(); string = class_linker->ResolveString(dex_file, string_idx, dex_cache); } - return string.Ptr(); + return string; } -inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, dex::StringIndex string_idx) { +inline ObjPtr<mirror::String> ResolveStringFromCode(ArtMethod* referrer, + dex::StringIndex string_idx) { Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::String> string = referrer->GetDexCache()->GetResolvedString(string_idx); if (UNLIKELY(string == nullptr)) { @@ -773,7 +775,7 @@ inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, dex::StringInd ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); string = class_linker->ResolveString(dex_file, string_idx, dex_cache); } - return string.Ptr(); + return string; } inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self) { diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index cda70ea265..830ef84250 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -143,15 +143,16 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_); -inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx, - ArtMethod* referrer, - Thread* self, - bool can_run_clinit, - bool verify_access) +inline ObjPtr<mirror::Class> ResolveVerifyAndClinit(dex::TypeIndex type_idx, + ArtMethod* referrer, + Thread* self, + bool can_run_clinit, + bool verify_access) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); -inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, dex::StringIndex string_idx) +inline ObjPtr<mirror::String> ResolveStringFromCode(ArtMethod* referrer, + dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc index 238ada94ff..98378382c5 100644 --- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc @@ -138,15 +138,15 @@ extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod( self, CalleeSaveType::kSaveEverythingForClinit); ArtMethod* caller = caller_and_outer.caller; - mirror::Class* result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), - caller, - self, - /* can_run_clinit */ true, - /* verify_access */ false); + ObjPtr<mirror::Class> result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), + caller, + self, + /* can_run_clinit */ true, + /* verify_access */ false); if (LIKELY(result != nullptr) && CanReferenceBss(caller_and_outer.outer_method, caller)) { StoreTypeInBss(caller_and_outer.outer_method, dex::TypeIndex(type_idx), result); } - return result; + return result.Ptr(); } extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* self) @@ -156,15 +156,15 @@ extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* s auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod( self, CalleeSaveType::kSaveEverythingForClinit); ArtMethod* caller = caller_and_outer.caller; - mirror::Class* result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), - caller, - self, - /* can_run_clinit */ false, - /* verify_access */ false); + ObjPtr<mirror::Class> result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), + caller, + self, + /* can_run_clinit */ false, + /* verify_access */ false); if (LIKELY(result != nullptr) && CanReferenceBss(caller_and_outer.outer_method, caller)) { StoreTypeInBss(caller_and_outer.outer_method, dex::TypeIndex(type_idx), result); } - return result; + return result.Ptr(); } extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Thread* self) @@ -174,13 +174,13 @@ extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, CalleeSaveType::kSaveEverything); ArtMethod* caller = caller_and_outer.caller; - mirror::Class* result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), - caller, - self, - /* can_run_clinit */ false, - /* verify_access */ true); + ObjPtr<mirror::Class> result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), + caller, + self, + /* can_run_clinit */ false, + /* verify_access */ true); // Do not StoreTypeInBss(); access check entrypoint is never used together with .bss. - return result; + return result.Ptr(); } extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* self) @@ -189,11 +189,11 @@ extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, CalleeSaveType::kSaveEverything); ArtMethod* caller = caller_and_outer.caller; - mirror::String* result = ResolveStringFromCode(caller, dex::StringIndex(string_idx)); + ObjPtr<mirror::String> result = ResolveStringFromCode(caller, dex::StringIndex(string_idx)); if (LIKELY(result != nullptr) && CanReferenceBss(caller_and_outer.outer_method, caller)) { StoreStringInBss(caller_and_outer.outer_method, dex::StringIndex(string_idx), result); } - return result; + return result.Ptr(); } } // namespace art diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index 987298bd8a..9c7645af9e 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -376,15 +376,15 @@ extern "C" size_t MterpConstClass(uint32_t index, ShadowFrame* shadow_frame, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = ResolveVerifyAndClinit(dex::TypeIndex(index), - shadow_frame->GetMethod(), - self, - false, - false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(index), + shadow_frame->GetMethod(), + self, + /* can_run_clinit */ false, + /* verify_access */ false); if (UNLIKELY(c == nullptr)) { return true; } - shadow_frame->SetVRegReference(tgt_vreg, c); + shadow_frame->SetVRegReference(tgt_vreg, c.Ptr()); return false; } @@ -463,17 +463,17 @@ extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(shadow_frame->GetDexPCPtr()); mirror::Object* obj = nullptr; - mirror::Class* c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), - shadow_frame->GetMethod(), - self, - false, - false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()), + shadow_frame->GetMethod(), + self, + /* can_run_clinit */ false, + /* verify_access */ false); if (LIKELY(c != nullptr)) { if (UNLIKELY(c->IsStringClass())) { gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); obj = mirror::String::AllocEmptyString<true>(self, allocator_type); } else { - obj = AllocObjectFromCode<true>(c, + obj = AllocObjectFromCode<true>(c.Ptr(), self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); } diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc index e52dd08540..f922dd317b 100644 --- a/runtime/transaction_test.cc +++ b/runtime/transaction_test.cc @@ -502,10 +502,11 @@ TEST_F(TransactionTest, ResolveString) { ASSERT_TRUE(h_klass->IsInitialized()); // Make sure the string got resolved by the transaction. { - mirror::String* s = class_linker_->LookupString(*dex_file, string_idx, h_dex_cache.Get()); + ObjPtr<mirror::String> s = + class_linker_->LookupString(*dex_file, string_idx, h_dex_cache.Get()); ASSERT_TRUE(s != nullptr); EXPECT_STREQ(s->ToModifiedUtf8().c_str(), kResolvedString); - EXPECT_EQ(s, h_dex_cache->GetResolvedString(string_idx)); + EXPECT_EQ(s.Ptr(), h_dex_cache->GetResolvedString(string_idx)); } Runtime::Current()->RollbackAndExitTransactionMode(); // Check that the string did not stay resolved. diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index fefb4f6526..b6b152fd76 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -1074,9 +1074,9 @@ bool MethodVerifier::ScanTryCatchBlocks() { // Ensure exception types are resolved so that they don't need resolution to be delivered, // unresolved exception types will be ignored by exception delivery if (iterator.GetHandlerTypeIndex().IsValid()) { - mirror::Class* exception_type = linker->ResolveType(*dex_file_, - iterator.GetHandlerTypeIndex(), - dex_cache_, class_loader_); + ObjPtr<mirror::Class> exception_type = linker->ResolveType(*dex_file_, + iterator.GetHandlerTypeIndex(), + dex_cache_, class_loader_); if (exception_type == nullptr) { DCHECK(self_->IsExceptionPending()); self_->ClearException(); @@ -3639,8 +3639,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { has_catch_all_handler = true; } else { // It is also a catch-all if it is java.lang.Throwable. - mirror::Class* klass = linker->ResolveType(*dex_file_, handler_type_idx, dex_cache_, - class_loader_); + ObjPtr<mirror::Class> klass = + linker->ResolveType(*dex_file_, handler_type_idx, dex_cache_, class_loader_); if (klass != nullptr) { if (klass == mirror::Throwable::GetJavaLangThrowable()) { has_catch_all_handler = true; @@ -3758,16 +3758,16 @@ void MethodVerifier::UninstantiableError(const char* descriptor) { << "non-instantiable klass " << descriptor; } -inline bool MethodVerifier::IsInstantiableOrPrimitive(mirror::Class* klass) { +inline bool MethodVerifier::IsInstantiableOrPrimitive(ObjPtr<mirror::Class> klass) { return klass->IsInstantiable() || klass->IsPrimitive(); } template <MethodVerifier::CheckAccess C> const RegType& MethodVerifier::ResolveClass(dex::TypeIndex class_idx) { - mirror::Class* klass = can_load_classes_ + ObjPtr<mirror::Class> klass = can_load_classes_ ? Runtime::Current()->GetClassLinker()->ResolveType( *dex_file_, class_idx, dex_cache_, class_loader_) - : ClassLinker::LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get()).Ptr(); + : ClassLinker::LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get()); if (can_load_classes_ && klass == nullptr) { DCHECK(self_->IsExceptionPending()); self_->ClearException(); @@ -3780,10 +3780,10 @@ const RegType& MethodVerifier::ResolveClass(dex::TypeIndex class_idx) { UninstantiableError(descriptor); precise = false; } - result = reg_types_.FindClass(klass, precise); + result = reg_types_.FindClass(klass.Ptr(), precise); if (result == nullptr) { const char* descriptor = dex_file_->StringByTypeIdx(class_idx); - result = reg_types_.InsertClass(descriptor, klass, precise); + result = reg_types_.InsertClass(descriptor, klass.Ptr(), precise); } } else { const char* descriptor = dex_file_->StringByTypeIdx(class_idx); @@ -3798,7 +3798,7 @@ const RegType& MethodVerifier::ResolveClass(dex::TypeIndex class_idx) { } // Record result of class resolution attempt. - VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass); + VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass.Ptr()); // If requested, check if access is allowed. Unresolved types are included in this check, as the // interpreter only tests whether access is allowed when a class is not pre-verified and runs in diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index c885914633..f26f3e2655 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -257,7 +257,8 @@ class MethodVerifier { REQUIRES_SHARED(Locks::mutator_lock_); void UninstantiableError(const char* descriptor); - static bool IsInstantiableOrPrimitive(mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_); + static bool IsInstantiableOrPrimitive(ObjPtr<mirror::Class> klass) + REQUIRES_SHARED(Locks::mutator_lock_); // Is the method being verified a constructor? See the comment on the field. bool IsConstructor() const { diff --git a/test/552-checker-sharpening/src/Main.java b/test/552-checker-sharpening/src/Main.java index 55873eabf0..3173afdfcd 100644 --- a/test/552-checker-sharpening/src/Main.java +++ b/test/552-checker-sharpening/src/Main.java @@ -44,24 +44,11 @@ public class Main { /// CHECK-START: int Main.testSimple(int) sharpening (before) /// CHECK: InvokeStaticOrDirect method_load_kind:RuntimeCall - /// CHECK-START-ARM: int Main.testSimple(int) sharpening (after) + /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: int Main.testSimple(int) sharpening (after) /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK-START-ARM64: int Main.testSimple(int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-MIPS: int Main.testSimple(int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-MIPS64: int Main.testSimple(int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-X86: int Main.testSimple(int) sharpening (after) + /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (before) /// CHECK-NOT: X86ComputeBaseMethodAddress - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-X86_64: int Main.testSimple(int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress @@ -74,31 +61,14 @@ public class Main { /// CHECK-START: int Main.testDiamond(boolean, int) sharpening (before) /// CHECK: InvokeStaticOrDirect method_load_kind:RuntimeCall + /// CHECK: InvokeStaticOrDirect method_load_kind:RuntimeCall - /// CHECK-START-ARM: int Main.testDiamond(boolean, int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-ARM64: int Main.testDiamond(boolean, int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-MIPS64: int Main.testDiamond(boolean, int) sharpening (after) + /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: int Main.testDiamond(boolean, int) sharpening (after) /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK-START-X86: int Main.testDiamond(boolean, int) sharpening (after) + /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (before) /// CHECK-NOT: X86ComputeBaseMethodAddress - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - - /// CHECK-START-X86_64: int Main.testDiamond(boolean, int) sharpening (after) - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry - /// CHECK: InvokeStaticOrDirect method_load_kind:BssEntry /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress @@ -169,30 +139,7 @@ public class Main { return x; } - /// CHECK-START: java.lang.String Main.$noinline$getBootImageString() sharpening (before) - /// CHECK: LoadString load_kind:RuntimeCall - - /// CHECK-START-X86: java.lang.String Main.$noinline$getBootImageString() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadString load_kind:{{BootImageAddress|BootImageInternTable}} - - /// CHECK-START-X86_64: java.lang.String Main.$noinline$getBootImageString() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadString load_kind:{{BootImageAddress|BootImageInternTable}} - - /// CHECK-START-ARM: java.lang.String Main.$noinline$getBootImageString() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadString load_kind:{{BootImageAddress|BootImageInternTable}} - - /// CHECK-START-ARM64: java.lang.String Main.$noinline$getBootImageString() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadString load_kind:{{BootImageAddress|BootImageInternTable}} - - /// CHECK-START-MIPS: java.lang.String Main.$noinline$getBootImageString() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadString load_kind:{{BootImageAddress|BootImageInternTable}} - - /// CHECK-START-MIPS64: java.lang.String Main.$noinline$getBootImageString() sharpening (after) + /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.String Main.$noinline$getBootImageString() builder (after) // Note: load kind depends on PIC/non-PIC /// CHECK: LoadString load_kind:{{BootImageAddress|BootImageInternTable}} @@ -203,31 +150,16 @@ public class Main { return ""; } - /// CHECK-START: java.lang.String Main.$noinline$getNonBootImageString() sharpening (before) - /// CHECK: LoadString load_kind:RuntimeCall - - /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) + /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.String Main.$noinline$getNonBootImageString() builder (after) /// CHECK: LoadString load_kind:BssEntry + /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (before) + /// CHECK-NOT: X86ComputeBaseMethodAddress + /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (after) /// CHECK-DAG: X86ComputeBaseMethodAddress /// CHECK-DAG: LoadString load_kind:BssEntry - /// CHECK-START-X86_64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) - /// CHECK: LoadString load_kind:BssEntry - - /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) - /// CHECK: LoadString load_kind:BssEntry - - /// CHECK-START-ARM64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) - /// CHECK: LoadString load_kind:BssEntry - - /// CHECK-START-MIPS: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) - /// CHECK: LoadString load_kind:BssEntry - - /// CHECK-START-MIPS64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) - /// CHECK: LoadString load_kind:BssEntry - public static String $noinline$getNonBootImageString() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } @@ -235,27 +167,7 @@ public class Main { return "non-boot-image-string"; } - /// CHECK-START-X86: java.lang.Class Main.$noinline$getStringClass() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadClass load_kind:{{BootImageAddress|BootImageClassTable}} class_name:java.lang.String - - /// CHECK-START-X86_64: java.lang.Class Main.$noinline$getStringClass() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadClass load_kind:{{BootImageAddress|BootImageClassTable}} class_name:java.lang.String - - /// CHECK-START-ARM: java.lang.Class Main.$noinline$getStringClass() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadClass load_kind:{{BootImageAddress|BootImageClassTable}} class_name:java.lang.String - - /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getStringClass() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadClass load_kind:{{BootImageAddress|BootImageClassTable}} class_name:java.lang.String - - /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getStringClass() sharpening (after) - // Note: load kind depends on PIC/non-PIC - /// CHECK: LoadClass load_kind:{{BootImageAddress|BootImageClassTable}} class_name:java.lang.String - - /// CHECK-START-MIPS64: java.lang.Class Main.$noinline$getStringClass() sharpening (after) + /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.Class Main.$noinline$getStringClass() builder (after) // Note: load kind depends on PIC/non-PIC /// CHECK: LoadClass load_kind:{{BootImageAddress|BootImageClassTable}} class_name:java.lang.String @@ -266,28 +178,16 @@ public class Main { return String.class; } - /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.Class Main.$noinline$getOtherClass() builder (after) /// CHECK: LoadClass load_kind:BssEntry class_name:Other + /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (before) + /// CHECK-NOT: X86ComputeBaseMethodAddress + /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (after) /// CHECK-DAG: X86ComputeBaseMethodAddress /// CHECK-DAG: LoadClass load_kind:BssEntry class_name:Other - /// CHECK-START-X86_64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) - /// CHECK: LoadClass load_kind:BssEntry class_name:Other - - /// CHECK-START-ARM: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) - /// CHECK: LoadClass load_kind:BssEntry class_name:Other - - /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) - /// CHECK: LoadClass load_kind:BssEntry class_name:Other - - /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) - /// CHECK: LoadClass load_kind:BssEntry class_name:Other - - /// CHECK-START-MIPS64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) - /// CHECK: LoadClass load_kind:BssEntry class_name:Other - public static Class<?> $noinline$getOtherClass() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } |