| Index: src/ic/accessor-assembler.cc
|
| diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc
|
| index 209727d5808f3bdeb793df9debe090aedf1fa0f2..f7bcce2b607391220eeb9ed64717e37225feffe8 100644
|
| --- a/src/ic/accessor-assembler.cc
|
| +++ b/src/ic/accessor-assembler.cc
|
| @@ -629,8 +629,17 @@ void AccessorAssembler::HandleStoreICSmiHandlerCase(Node* handler_word,
|
| WordEqual(handler_kind,
|
| IntPtrConstant(StoreHandler::kTransitionToConstant))));
|
| } else {
|
| - CSA_ASSERT(this, WordEqual(handler_kind,
|
| - IntPtrConstant(StoreHandler::kStoreField)));
|
| + if (FLAG_track_constant_fields) {
|
| + CSA_ASSERT(
|
| + this,
|
| + Word32Or(WordEqual(handler_kind,
|
| + IntPtrConstant(StoreHandler::kStoreField)),
|
| + WordEqual(handler_kind,
|
| + IntPtrConstant(StoreHandler::kStoreConstField))));
|
| + } else {
|
| + CSA_ASSERT(this, WordEqual(handler_kind,
|
| + IntPtrConstant(StoreHandler::kStoreField)));
|
| + }
|
| }
|
| #endif
|
|
|
| @@ -697,7 +706,7 @@ void AccessorAssembler::HandleStoreFieldAndReturn(Node* handler_word,
|
| Bind(&if_inobject);
|
| {
|
| StoreNamedField(handler_word, holder, true, representation, prepared_value,
|
| - transition_to_field);
|
| + transition_to_field, miss);
|
| if (transition_to_field) {
|
| StoreMap(holder, transition);
|
| }
|
| @@ -719,7 +728,7 @@ void AccessorAssembler::HandleStoreFieldAndReturn(Node* handler_word,
|
| }
|
|
|
| StoreNamedField(handler_word, holder, false, representation, prepared_value,
|
| - transition_to_field);
|
| + transition_to_field, miss);
|
| if (transition_to_field) {
|
| StoreMap(holder, transition);
|
| }
|
| @@ -736,6 +745,15 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder,
|
|
|
| } else if (representation.IsHeapObject()) {
|
| GotoIf(TaggedIsSmi(value), bailout);
|
| +
|
| + Label done(this);
|
| + if (FLAG_track_constant_fields && !transition) {
|
| + // Skip field type check in favor of constant value check when storing
|
| + // to constant field.
|
| + GotoIf(WordEqual(DecodeWord<StoreHandler::KindBits>(handler_word),
|
| + IntPtrConstant(StoreHandler::kStoreConstField)),
|
| + &done);
|
| + }
|
| Node* value_index_in_descriptor =
|
| DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
|
| Node* descriptors =
|
| @@ -743,7 +761,6 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder,
|
| Node* maybe_field_type =
|
| LoadFixedArrayElement(descriptors, value_index_in_descriptor);
|
|
|
| - Label done(this);
|
| GotoIf(TaggedIsSmi(maybe_field_type), &done);
|
| // Check that value type matches the field type.
|
| {
|
| @@ -800,7 +817,8 @@ void AccessorAssembler::ExtendPropertiesBackingStore(Node* object) {
|
| void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object,
|
| bool is_inobject,
|
| Representation representation,
|
| - Node* value, bool transition_to_field) {
|
| + Node* value, bool transition_to_field,
|
| + Label* bailout) {
|
| bool store_value_as_double = representation.IsDouble();
|
| Node* property_storage = object;
|
| if (!is_inobject) {
|
| @@ -824,6 +842,27 @@ void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object,
|
| }
|
| }
|
|
|
| + // Do constant value check if necessary.
|
| + if (FLAG_track_constant_fields && !transition_to_field) {
|
| + Label done(this);
|
| + GotoUnless(WordEqual(DecodeWord<StoreHandler::KindBits>(handler_word),
|
| + IntPtrConstant(StoreHandler::kStoreConstField)),
|
| + &done);
|
| + {
|
| + if (store_value_as_double) {
|
| + Node* current_value =
|
| + LoadObjectField(property_storage, offset, MachineType::Float64());
|
| + GotoUnless(Float64Equal(current_value, value), bailout);
|
| + } else {
|
| + Node* current_value = LoadObjectField(property_storage, offset);
|
| + GotoUnless(WordEqual(current_value, value), bailout);
|
| + }
|
| + Goto(&done);
|
| + }
|
| + Bind(&done);
|
| + }
|
| +
|
| + // Do the store.
|
| if (store_value_as_double) {
|
| StoreObjectFieldNoWriteBarrier(property_storage, offset, value,
|
| MachineRepresentation::kFloat64);
|
|
|