| Index: runtime/vm/flow_graph_optimizer.cc
|
| diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
|
| index 22ba02f3634f57a2e3e94b7bd309edfa4f08b701..27843746e5d36cc22b7c4e4c5b92996915f1ace4 100644
|
| --- a/runtime/vm/flow_graph_optimizer.cc
|
| +++ b/runtime/vm/flow_graph_optimizer.cc
|
| @@ -55,6 +55,7 @@ DECLARE_FLAG(bool, trace_cha);
|
| DECLARE_FLAG(bool, trace_field_guards);
|
| DECLARE_FLAG(bool, trace_type_check_elimination);
|
| DECLARE_FLAG(bool, warn_on_javascript_compatibility);
|
| +DECLARE_FLAG(bool, fields_may_be_reset);
|
|
|
| // Quick access to the current isolate and zone.
|
| #define I (isolate())
|
| @@ -5653,8 +5654,13 @@ class Place : public ValueObject {
|
| return "<?>";
|
| }
|
|
|
| - bool IsFinalField() const {
|
| - return (kind() == kField) && field().is_final();
|
| + // Fields that are considered immutable by load optimization.
|
| + // Handle static finals as non-final with precompilation because
|
| + // they may be reset to uninitialized after compilation.
|
| + bool IsImmutableField() const {
|
| + return (kind() == kField)
|
| + && field().is_final()
|
| + && (!field().is_static() || !FLAG_fields_may_be_reset);
|
| }
|
|
|
| intptr_t Hashcode() const {
|
| @@ -5991,7 +5997,7 @@ class AliasedSet : public ZoneAllocated {
|
|
|
| // Compute least generic alias for the place and assign alias id to it.
|
| void AddRepresentative(Place* place) {
|
| - if (!place->IsFinalField()) {
|
| + if (!place->IsImmutableField()) {
|
| const Place* alias = CanonicalizeAlias(place->ToAlias());
|
| EnsureSet(&representatives_, alias->id())->Add(place->id());
|
|
|
| @@ -6197,7 +6203,7 @@ class AliasedSet : public ZoneAllocated {
|
| // This essentially means that no stores to the same location can
|
| // occur in other functions.
|
| bool IsIndependentFromEffects(Place* place) {
|
| - if (place->IsFinalField()) {
|
| + if (place->IsImmutableField()) {
|
| // Note that we can't use LoadField's is_immutable attribute here because
|
| // some VM-fields (those that have no corresponding Field object and
|
| // accessed through offset alone) can share offset but have different
|
| @@ -6631,7 +6637,7 @@ class LoadOptimizer : public ValueObject {
|
| aliased_set_->LookupAliasId(place.ToAlias());
|
| if (alias_id != AliasedSet::kNoAlias) {
|
| killed = aliased_set_->GetKilledSet(alias_id);
|
| - } else if (!place.IsFinalField()) {
|
| + } else if (!place.IsImmutableField()) {
|
| // We encountered unknown alias: this means intrablock load
|
| // forwarding refined parameter of this store, for example
|
| //
|
| @@ -7535,7 +7541,7 @@ class StoreOptimizer : public LivenessAnalysis {
|
| bool is_load = false;
|
| bool is_store = false;
|
| Place place(instr, &is_load, &is_store);
|
| - if (place.IsFinalField()) {
|
| + if (place.IsImmutableField()) {
|
| // Loads/stores of final fields do not participate.
|
| continue;
|
| }
|
| @@ -7624,7 +7630,7 @@ class StoreOptimizer : public LivenessAnalysis {
|
| bool is_store = false;
|
| Place place(instr, &is_load, &is_store);
|
| ASSERT(!is_load && is_store);
|
| - if (place.IsFinalField()) {
|
| + if (place.IsImmutableField()) {
|
| // Final field do not participate in dead store elimination.
|
| continue;
|
| }
|
|
|