Commit b19a1baf authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ic] Fix storing to JSGlobalProxy having JSProxy in prototype chain.

Bug: chromium:764219
Change-Id: Ic68111e49da508aba255b1c651a85b2b00e62947
Reviewed-on: https://chromium-review.googlesource.com/718108Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48534}
parent caead4da
...@@ -758,7 +758,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -758,7 +758,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
// IC dispatchers rely on these assumptions to be held. // IC dispatchers rely on these assumptions to be held.
STATIC_ASSERT(FixedArray::kLengthOffset == STATIC_ASSERT(FixedArray::kLengthOffset ==
StoreHandler::kTransitionCellOffset); StoreHandler::kTransitionOrHolderCellOffset);
DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex),
StoreHandler::kSmiHandlerOffset); StoreHandler::kSmiHandlerOffset);
DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex),
...@@ -779,18 +779,16 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -779,18 +779,16 @@ void AccessorAssembler::HandleStoreICProtoHandler(
Node* smi_or_code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset); Node* smi_or_code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset);
Node* maybe_transition_cell = Node* maybe_transition_cell =
LoadObjectField(handler, StoreHandler::kTransitionCellOffset); LoadObjectField(handler, StoreHandler::kTransitionOrHolderCellOffset);
Label array_handler(this), tuple_handler(this); Label array_handler(this), tuple_handler(this);
Branch(TaggedIsSmi(maybe_transition_cell), &array_handler, &tuple_handler); Branch(TaggedIsSmi(maybe_transition_cell), &array_handler, &tuple_handler);
VARIABLE(var_transition, MachineRepresentation::kTagged); VARIABLE(var_transition_map_or_holder, MachineRepresentation::kTagged);
Label if_transition(this), if_transition_to_constant(this), Label do_store(this), if_transition_map(this), if_holder_object(this);
if_store_normal(this), if_store_global_proxy(this), if_proxy(this),
do_store(this);
BIND(&tuple_handler); BIND(&tuple_handler);
{ {
Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); Node* transition = LoadWeakCellValue(maybe_transition_cell, miss);
var_transition.Bind(transition); var_transition_map_or_holder.Bind(transition);
Goto(&do_store); Goto(&do_store);
} }
...@@ -831,32 +829,27 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -831,32 +829,27 @@ void AccessorAssembler::HandleStoreICProtoHandler(
}, },
1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
Node* maybe_transition_cell = Node* maybe_transition_cell = LoadFixedArrayElement(
LoadFixedArrayElement(handler, StoreHandler::kTransitionCellIndex); handler, StoreHandler::kTransitionMapOrHolderCellIndex);
Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); Node* transition = LoadWeakCellValue(maybe_transition_cell, miss);
var_transition.Bind(transition); var_transition_map_or_holder.Bind(transition);
Goto(&do_store); Goto(&do_store);
} }
BIND(&do_store); BIND(&do_store);
{ {
Branch(SmiEqual(smi_or_code, SmiConstant(StoreHandler::kProxy)), &if_proxy, Node* transition = var_transition_map_or_holder.value();
&if_transition); Branch(IsMap(transition), &if_transition_map, &if_holder_object);
} }
BIND(&if_proxy); BIND(&if_transition_map);
{ {
Node* proxy = var_transition.value(); Label if_transition_to_constant(this), if_store_normal(this);
HandleStoreToProxy(p, proxy, miss, support_elements);
}
BIND(&if_transition);
{
Node* holder = p->receiver; Node* holder = p->receiver;
Node* transition = var_transition.value(); Node* transition_map = var_transition_map_or_holder.value();
GotoIfNot(IsMap(transition), &if_store_global_proxy); GotoIf(IsDeprecatedMap(transition_map), miss);
GotoIf(IsDeprecatedMap(transition), miss);
if (support_elements == kSupportElements) { if (support_elements == kSupportElements) {
Label if_smi_handler(this); Label if_smi_handler(this);
...@@ -867,7 +860,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -867,7 +860,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
StoreTransitionDescriptor descriptor(isolate()); StoreTransitionDescriptor descriptor(isolate());
TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name,
transition, p->value, p->slot, p->vector); transition_map, p->value, p->slot, p->vector);
BIND(&if_smi_handler); BIND(&if_smi_handler);
} }
...@@ -882,13 +875,12 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -882,13 +875,12 @@ void AccessorAssembler::HandleStoreICProtoHandler(
GotoIf(WordEqual(handler_kind, GotoIf(WordEqual(handler_kind,
IntPtrConstant(StoreHandler::kTransitionToConstant)), IntPtrConstant(StoreHandler::kTransitionToConstant)),
&if_transition_to_constant); &if_transition_to_constant);
// This case is already handled above.
CSA_ASSERT(this, CSA_ASSERT(this,
WordNotEqual(handler_kind, WordEqual(handler_kind,
IntPtrConstant(StoreHandler::kStoreGlobalProxy))); IntPtrConstant(StoreHandler::kTransitionToField)));
// Handle transitioning field stores. // Handle transitioning field stores.
HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition, HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition_map,
miss); miss);
BIND(&if_transition_to_constant); BIND(&if_transition_to_constant);
...@@ -901,7 +893,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -901,7 +893,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
IntPtrAdd(scaled_descriptor, IntPtrAdd(scaled_descriptor,
IntPtrConstant(DescriptorArray::kFirstIndex + IntPtrConstant(DescriptorArray::kFirstIndex +
DescriptorArray::kEntryValueIndex)); DescriptorArray::kEntryValueIndex));
Node* descriptors = LoadMapDescriptors(transition); Node* descriptors = LoadMapDescriptors(transition_map);
CSA_ASSERT( CSA_ASSERT(
this, UintPtrLessThan(descriptor, this, UintPtrLessThan(descriptor,
LoadAndUntagFixedArrayBaseLength(descriptors))); LoadAndUntagFixedArrayBaseLength(descriptors)));
...@@ -909,7 +901,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -909,7 +901,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
Node* constant = LoadFixedArrayElement(descriptors, value_index); Node* constant = LoadFixedArrayElement(descriptors, value_index);
GotoIf(WordNotEqual(p->value, constant), miss); GotoIf(WordNotEqual(p->value, constant), miss);
StoreMap(p->receiver, transition); StoreMap(p->receiver, transition_map);
Return(p->value); Return(p->value);
} }
...@@ -948,10 +940,28 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -948,10 +940,28 @@ void AccessorAssembler::HandleStoreICProtoHandler(
p->receiver, p->name, p->value); p->receiver, p->name, p->value);
} }
} }
}
BIND(&if_holder_object);
{
Label if_store_global_proxy(this);
Node* holder = var_transition_map_or_holder.value();
Node* smi_handler = smi_or_code;
CSA_ASSERT(this, TaggedIsSmi(smi_handler));
Node* handler_word = SmiUntag(smi_handler);
Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word);
GotoIf(WordEqual(handler_kind,
IntPtrConstant(StoreHandler::kStoreGlobalProxy)),
&if_store_global_proxy);
CSA_ASSERT(this,
WordEqual(handler_kind, IntPtrConstant(StoreHandler::kProxy)));
HandleStoreToProxy(p, holder, miss, support_elements);
BIND(&if_store_global_proxy); BIND(&if_store_global_proxy);
{ {
ExitPoint direct_exit(this); ExitPoint direct_exit(this);
StoreGlobalIC_PropertyCellCase(transition, p->value, &direct_exit, miss); StoreGlobalIC_PropertyCellCase(holder, p->value, &direct_exit, miss);
} }
} }
} }
......
...@@ -196,15 +196,15 @@ Handle<Smi> StoreHandler::TransitionToConstant(Isolate* isolate, ...@@ -196,15 +196,15 @@ Handle<Smi> StoreHandler::TransitionToConstant(Isolate* isolate,
// static // static
WeakCell* StoreHandler::GetTransitionCell(Object* handler) { WeakCell* StoreHandler::GetTransitionCell(Object* handler) {
if (handler->IsTuple3()) { if (handler->IsTuple3()) {
STATIC_ASSERT(kTransitionCellOffset == Tuple3::kValue1Offset); STATIC_ASSERT(kTransitionOrHolderCellOffset == Tuple3::kValue1Offset);
WeakCell* cell = WeakCell::cast(Tuple3::cast(handler)->value1()); WeakCell* cell = WeakCell::cast(Tuple3::cast(handler)->value1());
DCHECK(!cell->cleared()); DCHECK(!cell->cleared());
return cell; return cell;
} }
DCHECK(handler->IsFixedArray()); DCHECK(handler->IsFixedArray());
WeakCell* cell = WeakCell* cell = WeakCell::cast(
WeakCell::cast(FixedArray::cast(handler)->get(kTransitionCellIndex)); FixedArray::cast(handler)->get(kTransitionMapOrHolderCellIndex));
DCHECK(!cell->cleared()); DCHECK(!cell->cleared());
return cell; return cell;
} }
......
...@@ -314,7 +314,7 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, ...@@ -314,7 +314,7 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate,
factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED)); factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED));
handler_array->set(kSmiHandlerIndex, *smi_handler); handler_array->set(kSmiHandlerIndex, *smi_handler);
handler_array->set(kValidityCellIndex, *validity_cell); handler_array->set(kValidityCellIndex, *validity_cell);
handler_array->set(kTransitionCellIndex, *transition_cell); handler_array->set(kTransitionMapOrHolderCellIndex, *transition_cell);
InitPrototypeChecks(isolate, receiver_map, holder, name, handler_array, InitPrototypeChecks(isolate, receiver_map, holder, name, handler_array,
kFirstPrototypeIndex); kFirstPrototypeIndex);
return handler_array; return handler_array;
...@@ -363,7 +363,7 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate, ...@@ -363,7 +363,7 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate,
factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED)); factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED));
handler_array->set(kSmiHandlerIndex, *smi_handler); handler_array->set(kSmiHandlerIndex, *smi_handler);
handler_array->set(kValidityCellIndex, *validity_cell); handler_array->set(kValidityCellIndex, *validity_cell);
handler_array->set(kTransitionCellIndex, *holder_cell); handler_array->set(kTransitionMapOrHolderCellIndex, *holder_cell);
InitPrototypeChecks(isolate, receiver_map, proxy, name, handler_array, InitPrototypeChecks(isolate, receiver_map, proxy, name, handler_array,
kFirstPrototypeIndex); kFirstPrototypeIndex);
return handler_array; return handler_array;
......
...@@ -229,7 +229,7 @@ class StoreHandler { ...@@ -229,7 +229,7 @@ class StoreHandler {
// The layout of an Tuple3 handler representing a transitioning store // The layout of an Tuple3 handler representing a transitioning store
// when prototype chain checks do not include non-existing lookups or access // when prototype chain checks do not include non-existing lookups or access
// checks. // checks.
static const int kTransitionCellOffset = Tuple3::kValue1Offset; static const int kTransitionOrHolderCellOffset = Tuple3::kValue1Offset;
static const int kSmiHandlerOffset = Tuple3::kValue2Offset; static const int kSmiHandlerOffset = Tuple3::kValue2Offset;
static const int kValidityCellOffset = Tuple3::kValue3Offset; static const int kValidityCellOffset = Tuple3::kValue3Offset;
...@@ -241,7 +241,7 @@ class StoreHandler { ...@@ -241,7 +241,7 @@ class StoreHandler {
// when prototype chain checks include non-existing lookups and access checks. // when prototype chain checks include non-existing lookups and access checks.
static const int kSmiHandlerIndex = 0; static const int kSmiHandlerIndex = 0;
static const int kValidityCellIndex = 1; static const int kValidityCellIndex = 1;
static const int kTransitionCellIndex = 2; static const int kTransitionMapOrHolderCellIndex = 2;
static const int kFirstPrototypeIndex = 3; static const int kFirstPrototypeIndex = 3;
// Creates a Smi-handler for storing a field to fast object. // Creates a Smi-handler for storing a field to fast object.
......
...@@ -811,14 +811,14 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( ...@@ -811,14 +811,14 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
BIND(&tuple3); BIND(&tuple3);
{ {
var_transition_cell.Bind(LoadObjectField( var_transition_cell.Bind(LoadObjectField(
maybe_handler, StoreHandler::kTransitionCellOffset)); maybe_handler, StoreHandler::kTransitionOrHolderCellOffset));
Goto(&check_key); Goto(&check_key);
} }
BIND(&fixedarray); BIND(&fixedarray);
{ {
var_transition_cell.Bind(LoadFixedArrayElement( var_transition_cell.Bind(LoadFixedArrayElement(
maybe_handler, StoreHandler::kTransitionCellIndex)); maybe_handler, StoreHandler::kTransitionMapOrHolderCellIndex));
Goto(&check_key); Goto(&check_key);
} }
......
...@@ -22,3 +22,14 @@ ...@@ -22,3 +22,14 @@
f(this); f(this);
f(this); f(this);
})(); })();
(function() {
function f(o) {
o.z = 153;
};
Object.setPrototypeOf(this, new Proxy({get z(){}}, {}));
f({});
f(this);
f(this);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment