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
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 671f950..c109369 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -305,7 +305,6 @@
HGraph(ArenaAllocator* arena,
const DexFile& dex_file,
uint32_t method_idx,
- bool should_generate_constructor_barrier,
InstructionSet instruction_set,
InvokeType invoke_type = kInvalidInvokeType,
bool debuggable = false,
@@ -332,7 +331,6 @@
method_idx_(method_idx),
invoke_type_(invoke_type),
in_ssa_form_(false),
- should_generate_constructor_barrier_(should_generate_constructor_barrier),
number_of_cha_guards_(0),
instruction_set_(instruction_set),
cached_null_constant_(nullptr),
@@ -504,10 +502,6 @@
has_bounds_checks_ = value;
}
- bool ShouldGenerateConstructorBarrier() const {
- return should_generate_constructor_barrier_;
- }
-
bool IsDebuggable() const { return debuggable_; }
// Returns a constant of the given type and value. If it does not exist
@@ -701,8 +695,6 @@
// for non-SSA form (like the number of temporaries).
bool in_ssa_form_;
- const bool should_generate_constructor_barrier_;
-
// Number of CHA guards in the graph. Used to short-circuit the
// CHA guard optimization pass when there is no CHA guard left.
uint32_t number_of_cha_guards_;
@@ -5073,7 +5065,7 @@
const DexFile& GetDexFile() const { return dex_file_; }
dex::TypeIndex GetTypeIndex() const { return type_index_; }
uint8_t GetIndex() const { return index_; }
- bool IsThis() const { return GetPackedFlag<kFlagIsThis>(); }
+ bool IsThis() const ATTRIBUTE_UNUSED { return GetPackedFlag<kFlagIsThis>(); }
bool CanBeNull() const OVERRIDE { return GetPackedFlag<kFlagCanBeNull>(); }
void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); }