From 206348cea8b086a484b8bde37b2e281e5f7db638 Mon Sep 17 00:00:00 2001 From: Hans Boehm Date: Wed, 5 Dec 2018 11:11:33 -0800 Subject: Selectively allow dead reference elimination Allow dead reference elimination in methods not containing @ReachabilitySensitive accesses or calls, when the class is marked @DeadReferenceSafe. Add 1339-dead-reference-safe to aggressively check that everything works as intended. Bug: 111453875 Test: art/test/testrunner/testrunner.py --host --64 -t 1339-dead-reference-safe Detect ReachabilitySensitive annotations. Change-Id: I70c20431fdbcfcfd2692b2255d12ad59e37cb669 --- compiler/optimizing/optimizing_compiler.cc | 33 +++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'compiler/optimizing/optimizing_compiler.cc') diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 42dbc77087..e8f8d32525 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -828,6 +828,29 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, } CodeItemDebugInfoAccessor code_item_accessor(dex_file, code_item, method_idx); + + bool dead_reference_safe; + ArrayRef interpreter_metadata; + // For AOT compilation, we may not get a method, for example if its class is erroneous, + // possibly due to an unavailable superclass. JIT should always have a method. + DCHECK(Runtime::Current()->IsAotCompiler() || method != nullptr); + if (method != nullptr) { + const dex::ClassDef* containing_class; + { + ScopedObjectAccess soa(Thread::Current()); + containing_class = &method->GetClassDef(); + interpreter_metadata = method->GetQuickenedInfo(); + } + // MethodContainsRSensitiveAccess is currently slow, but HasDeadReferenceSafeAnnotation() + // is currently rarely true. + dead_reference_safe = + annotations::HasDeadReferenceSafeAnnotation(dex_file, *containing_class) + && !annotations::MethodContainsRSensitiveAccess(dex_file, *containing_class, method_idx); + } else { + // If we could not resolve the class, conservatively assume it's dead-reference unsafe. + dead_reference_safe = false; + } + HGraph* graph = new (allocator) HGraph( allocator, arena_stack, @@ -835,17 +858,12 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, method_idx, compiler_options.GetInstructionSet(), kInvalidInvokeType, + dead_reference_safe, compiler_driver->GetCompilerOptions().GetDebuggable(), - osr); + /* osr= */ osr); - ArrayRef interpreter_metadata; - // For AOT compilation, we may not get a method, for example if its class is erroneous. - // JIT should always have a method. - DCHECK(Runtime::Current()->IsAotCompiler() || method != nullptr); if (method != nullptr) { graph->SetArtMethod(method); - ScopedObjectAccess soa(Thread::Current()); - interpreter_metadata = method->GetQuickenedInfo(); } std::unique_ptr codegen( @@ -963,6 +981,7 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( method_idx, compiler_options.GetInstructionSet(), kInvalidInvokeType, + /* dead_reference_safe= */ true, // Intrinsics don't affect dead reference safety. compiler_options.GetDebuggable(), /* osr= */ false); -- cgit v1.2.3-59-g8ed1b