From 032cacdbf32c50d3c43590600ed1e171a35fa93c Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Thu, 6 Apr 2017 14:40:08 -0700 Subject: optimizing: do not illegally remove constructor barriers after inlining Remove the illegal optimization that destroyed constructor barriers after inlining invoke-super constructor calls. --- According to JLS 7.5.1, "Note that if one constructor invokes another constructor, and the invoked constructor sets a final field, the freeze for the final field takes place at the end of the invoked constructor." This means if an object is published (stored to a location potentially visible to another thread) inside of an outer constructor, all final field stores from any inner constructors must be visible to other threads. Test: art/test.py Bug: 37001605 Change-Id: I3b55f6c628ff1773dab88022a6475d50a1a6f906 --- compiler/optimizing/instruction_builder.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'compiler/optimizing/instruction_builder.cc') diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 88f67fae04..978c6a2d71 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -589,6 +589,11 @@ void HInstructionBuilder::Binop_22b(const Instruction& instruction, bool reverse } static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, CompilerDriver* driver) { + // Can be null in unit tests only. + if (UNLIKELY(cu == nullptr)) { + return false; + } + Thread* self = Thread::Current(); return cu->IsConstructor() && driver->RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex()); @@ -634,12 +639,9 @@ void HInstructionBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc) { if (type == Primitive::kPrimVoid) { - if (graph_->ShouldGenerateConstructorBarrier()) { - // The compilation unit is null during testing. - if (dex_compilation_unit_ != nullptr) { - DCHECK(RequiresConstructorBarrier(dex_compilation_unit_, compiler_driver_)) - << "Inconsistent use of ShouldGenerateConstructorBarrier. Should not generate a barrier."; - } + // This may insert additional redundant constructor fences from the super constructors. + // TODO: remove redundant constructor fences (b/36656456). + if (RequiresConstructorBarrier(dex_compilation_unit_, compiler_driver_)) { AppendInstruction(new (arena_) HMemoryBarrier(kStoreStore, dex_pc)); } AppendInstruction(new (arena_) HReturnVoid(dex_pc)); -- cgit v1.2.3-59-g8ed1b