From d5111bf05fc0a9974280a80eeb43db6d5227a81e Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Fri, 22 May 2015 15:37:09 +0100 Subject: [PATCH] Do not use dex_compilation_unit after inlining. It's incompatible with inlining, as inlined invokes/load class/new can be from another dex file. Change-Id: I8897b6a012942bc8e136f2bea70252d3fb3a7fa5 --- compiler/optimizing/builder.cc | 22 +++++++++++++++------- compiler/optimizing/intrinsics.cc | 8 ++++---- compiler/optimizing/intrinsics.h | 5 ++--- compiler/optimizing/nodes.h | 14 +++++++++++++- compiler/optimizing/optimizing_compiler.cc | 10 +++------- compiler/optimizing/reference_type_propagation.cc | 6 ++++-- compiler/optimizing/reference_type_propagation.h | 9 +-------- 7 files changed, 42 insertions(+), 32 deletions(-) diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index c4eaabf89..49a0444f9 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -711,8 +711,8 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone; } else { clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit; - HLoadClass* load_class = - new (arena_) HLoadClass(storage_index, is_referrer_class, dex_pc); + HLoadClass* load_class = new (arena_) HLoadClass( + storage_index, *dex_compilation_unit_->GetDexFile(), is_referrer_class, dex_pc); current_block_->AddInstruction(load_class); clinit_check = new (arena_) HClinitCheck(load_class, dex_pc); current_block_->AddInstruction(clinit_check); @@ -915,7 +915,8 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, *outer_compilation_unit_->GetDexFile(), storage_index); bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache; - HLoadClass* constant = new (arena_) HLoadClass(storage_index, is_referrer_class, dex_pc); + HLoadClass* constant = new (arena_) HLoadClass( + storage_index, *dex_compilation_unit_->GetDexFile(), is_referrer_class, dex_pc); current_block_->AddInstruction(constant); HInstruction* cls = constant; @@ -1151,7 +1152,10 @@ bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction, } HInstruction* object = LoadLocal(reference, Primitive::kPrimNot); HLoadClass* cls = new (arena_) HLoadClass( - type_index, IsOutermostCompilingClass(type_index), dex_pc); + type_index, + *dex_compilation_unit_->GetDexFile(), + IsOutermostCompilingClass(type_index), + dex_pc); current_block_->AddInstruction(cls); // The class needs a temporary before being used by the type check. Temporaries temps(graph_); @@ -1976,7 +1980,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 ? kQuickAllocObjectWithAccessCheck : kQuickAllocObject; - current_block_->AddInstruction(new (arena_) HNewInstance(dex_pc, type_index, entrypoint)); + current_block_->AddInstruction(new (arena_) HNewInstance( + dex_pc, type_index, *dex_compilation_unit_->GetDexFile(), entrypoint)); UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); } break; @@ -2161,8 +2166,11 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType); return false; } - current_block_->AddInstruction( - new (arena_) HLoadClass(type_index, IsOutermostCompilingClass(type_index), dex_pc)); + current_block_->AddInstruction(new (arena_) HLoadClass( + type_index, + *dex_compilation_unit_->GetDexFile(), + IsOutermostCompilingClass(type_index), + dex_pc)); UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); break; } diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 43fe3746a..4e3436e32 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -326,9 +326,6 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke) { // TODO: Refactor DexFileMethodInliner and have something nicer than InlineMethod. void IntrinsicsRecognizer::Run() { - DexFileMethodInliner* inliner = driver_->GetMethodInlinerMap()->GetMethodInliner(dex_file_); - DCHECK(inliner != nullptr); - for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { HBasicBlock* block = it.Current(); for (HInstructionIterator inst_it(block->GetInstructions()); !inst_it.Done(); @@ -337,6 +334,9 @@ void IntrinsicsRecognizer::Run() { if (inst->IsInvoke()) { HInvoke* invoke = inst->AsInvoke(); InlineMethod method; + DexFileMethodInliner* inliner = + driver_->GetMethodInlinerMap()->GetMethodInliner(&invoke->GetDexFile()); + DCHECK(inliner != nullptr); if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) { Intrinsics intrinsic = GetIntrinsic(method); @@ -344,7 +344,7 @@ void IntrinsicsRecognizer::Run() { if (!CheckInvokeType(intrinsic, invoke)) { LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " << intrinsic << " for " - << PrettyMethod(invoke->GetDexMethodIndex(), *dex_file_); + << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()); } else { invoke->SetIntrinsic(intrinsic); } diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h index c243ef3f8..741fb64fd 100644 --- a/compiler/optimizing/intrinsics.h +++ b/compiler/optimizing/intrinsics.h @@ -30,16 +30,15 @@ class DexFile; // Recognize intrinsics from HInvoke nodes. class IntrinsicsRecognizer : public HOptimization { public: - IntrinsicsRecognizer(HGraph* graph, const DexFile* dex_file, CompilerDriver* driver) + IntrinsicsRecognizer(HGraph* graph, CompilerDriver* driver) : HOptimization(graph, true, kIntrinsicsRecognizerPassName), - dex_file_(dex_file), driver_(driver) {} + driver_(driver) {} void Run() OVERRIDE; static constexpr const char* kIntrinsicsRecognizerPassName = "intrinsics_recognition"; private: - const DexFile* dex_file_; CompilerDriver* driver_; DISALLOW_COPY_AND_ASSIGN(IntrinsicsRecognizer); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 12ace413b..67c6b3c1d 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2387,6 +2387,7 @@ class HInvoke : public HInstruction { uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint32_t GetDexMethodIndex() const { return dex_method_index_; } + const DexFile& GetDexFile() const { return GetEnvironment()->GetDexFile(); } InvokeType GetOriginalInvokeType() const { return original_invoke_type_; } @@ -2598,14 +2599,19 @@ class HInvokeInterface : public HInvoke { class HNewInstance : public HExpression<0> { public: - HNewInstance(uint32_t dex_pc, uint16_t type_index, QuickEntrypointEnum entrypoint) + HNewInstance(uint32_t dex_pc, + uint16_t type_index, + const DexFile& dex_file, + QuickEntrypointEnum entrypoint) : HExpression(Primitive::kPrimNot, SideEffects::None()), dex_pc_(dex_pc), type_index_(type_index), + dex_file_(dex_file), entrypoint_(entrypoint) {} uint32_t GetDexPc() const OVERRIDE { return dex_pc_; } uint16_t GetTypeIndex() const { return type_index_; } + const DexFile& GetDexFile() const { return dex_file_; } // Calls runtime so needs an environment. bool NeedsEnvironment() const OVERRIDE { return true; } @@ -2624,6 +2630,7 @@ class HNewInstance : public HExpression<0> { private: const uint32_t dex_pc_; const uint16_t type_index_; + const DexFile& dex_file_; const QuickEntrypointEnum entrypoint_; DISALLOW_COPY_AND_ASSIGN(HNewInstance); @@ -3428,10 +3435,12 @@ class HSuspendCheck : public HTemplateInstruction<0> { class HLoadClass : public HExpression<0> { public: HLoadClass(uint16_t type_index, + const DexFile& dex_file, bool is_referrers_class, uint32_t dex_pc) : HExpression(Primitive::kPrimNot, SideEffects::None()), type_index_(type_index), + dex_file_(dex_file), is_referrers_class_(is_referrers_class), dex_pc_(dex_pc), generate_clinit_check_(false), @@ -3487,12 +3496,15 @@ class HLoadClass : public HExpression<0> { return loaded_class_rti_.IsExact(); } + const DexFile& GetDexFile() { return dex_file_; } + bool NeedsDexCache() const OVERRIDE { return !is_referrers_class_; } DECLARE_INSTRUCTION(LoadClass); private: const uint16_t type_index_; + const DexFile& dex_file_; const bool is_referrers_class_; const uint32_t dex_pc_; // Whether this instruction must generate the initialization check. diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index b2e8ecd74..fa3c31081 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -223,7 +223,6 @@ class OptimizingCompiler FINAL : public Compiler { CompiledMethod* CompileOptimized(HGraph* graph, CodeGenerator* codegen, CompilerDriver* driver, - const DexFile& dex_file, const DexCompilationUnit& dex_compilation_unit, PassInfoPrinter* pass_info) const; @@ -316,7 +315,6 @@ static void RunOptimizations(HOptimization* optimizations[], static void RunOptimizations(HGraph* graph, CompilerDriver* driver, OptimizingCompilerStats* stats, - const DexFile& dex_file, const DexCompilationUnit& dex_compilation_unit, PassInfoPrinter* pass_info_printer, StackHandleScopeCollection* handles) { @@ -335,10 +333,10 @@ static void RunOptimizations(HGraph* graph, GVNOptimization gvn(graph, side_effects); LICM licm(graph, side_effects); BoundsCheckElimination bce(graph); - ReferenceTypePropagation type_propagation(graph, dex_file, dex_compilation_unit, handles); + ReferenceTypePropagation type_propagation(graph, handles); InstructionSimplifier simplify2(graph, stats, "instruction_simplifier_after_types"); - IntrinsicsRecognizer intrinsics(graph, dex_compilation_unit.GetDexFile(), driver); + IntrinsicsRecognizer intrinsics(graph, driver); HOptimization* optimizations[] = { &intrinsics, @@ -391,12 +389,11 @@ static void AllocateRegisters(HGraph* graph, CompiledMethod* OptimizingCompiler::CompileOptimized(HGraph* graph, CodeGenerator* codegen, CompilerDriver* compiler_driver, - const DexFile& dex_file, const DexCompilationUnit& dex_compilation_unit, PassInfoPrinter* pass_info_printer) const { StackHandleScopeCollection handles(Thread::Current()); RunOptimizations(graph, compiler_driver, compilation_stats_.get(), - dex_file, dex_compilation_unit, pass_info_printer, &handles); + dex_compilation_unit, pass_info_printer, &handles); AllocateRegisters(graph, codegen, pass_info_printer); @@ -585,7 +582,6 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite return CompileOptimized(graph, codegen.get(), compiler_driver, - dex_file, dex_compilation_unit, &pass_info_printer); } else if (shouldOptimize && can_allocate_registers) { diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 12b1c2b9b..601b48aaf 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -161,7 +161,8 @@ void ReferenceTypePropagation::BoundTypeForIfInstanceOf(HBasicBlock* block) { void ReferenceTypePropagation::VisitNewInstance(HNewInstance* instr) { ScopedObjectAccess soa(Thread::Current()); - mirror::DexCache* dex_cache = dex_compilation_unit_.GetClassLinker()->FindDexCache(dex_file_); + mirror::DexCache* dex_cache = + Runtime::Current()->GetClassLinker()->FindDexCache(instr->GetDexFile()); // Get type from dex cache assuming it was populated by the verifier. mirror::Class* resolved_class = dex_cache->GetResolvedType(instr->GetTypeIndex()); if (resolved_class != nullptr) { @@ -172,7 +173,8 @@ void ReferenceTypePropagation::VisitNewInstance(HNewInstance* instr) { void ReferenceTypePropagation::VisitLoadClass(HLoadClass* instr) { ScopedObjectAccess soa(Thread::Current()); - mirror::DexCache* dex_cache = dex_compilation_unit_.GetClassLinker()->FindDexCache(dex_file_); + mirror::DexCache* dex_cache = + Runtime::Current()->GetClassLinker()->FindDexCache(instr->GetDexFile()); // Get type from dex cache assuming it was populated by the verifier. mirror::Class* resolved_class = dex_cache->GetResolvedType(instr->GetTypeIndex()); if (resolved_class != nullptr) { diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 733e18e68..b68fc6757 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -30,13 +30,8 @@ namespace art { */ class ReferenceTypePropagation : public HOptimization { public: - ReferenceTypePropagation(HGraph* graph, - const DexFile& dex_file, - const DexCompilationUnit& dex_compilation_unit, - StackHandleScopeCollection* handles) + ReferenceTypePropagation(HGraph* graph, StackHandleScopeCollection* handles) : HOptimization(graph, true, kReferenceTypePropagationPassName), - dex_file_(dex_file), - dex_compilation_unit_(dex_compilation_unit), handles_(handles), worklist_(graph->GetArena(), kDefaultWorklistSize) {} @@ -66,8 +61,6 @@ class ReferenceTypePropagation : public HOptimization { ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, const ReferenceTypeInfo& b) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const DexFile& dex_file_; - const DexCompilationUnit& dex_compilation_unit_; StackHandleScopeCollection* handles_; GrowableArray worklist_; -- 2.11.0