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

[ic] Introduce canonical invalid prototype validity cell.

... and use Smi Map::kPrototypeChainValid for the cases where direct receiver's
prototype is not JSObject instead of creating a new valid cell for each such
case. This will make a validity cell checking code simpler.

Bug: v8:5988
Change-Id: I52cf55797171cc8021d80e4e441615d0c8fc8bd4
Reviewed-on: https://chromium-review.googlesource.com/951384
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51803}
parent 501f250c
...@@ -2493,6 +2493,7 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, ...@@ -2493,6 +2493,7 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
map->set_visitor_id(Map::GetVisitorId(map)); map->set_visitor_id(Map::GetVisitorId(map));
map->set_inobject_properties_start_or_constructor_function_index(0); map->set_inobject_properties_start_or_constructor_function_index(0);
DCHECK(!map->IsJSObjectMap()); DCHECK(!map->IsJSObjectMap());
map->set_prototype_validity_cell(Smi::FromInt(Map::kPrototypeChainValid));
map->SetInObjectUnusedPropertyFields(0); map->SetInObjectUnusedPropertyFields(0);
map->set_bit_field(0); map->set_bit_field(0);
map->set_bit_field2(0); map->set_bit_field2(0);
...@@ -2501,7 +2502,6 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, ...@@ -2501,7 +2502,6 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
Map::ConstructionCounterBits::encode(Map::kNoSlackTracking); Map::ConstructionCounterBits::encode(Map::kNoSlackTracking);
map->set_bit_field3(bit_field3); map->set_bit_field3(bit_field3);
map->set_weak_cell_cache(Smi::kZero); map->set_weak_cell_cache(Smi::kZero);
map->set_prototype_validity_cell(Smi::kZero);
map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND); map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
return map; return map;
} }
...@@ -2530,14 +2530,15 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type, ...@@ -2530,14 +2530,15 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type,
map->SetInObjectPropertiesStartInWords(instance_size / kPointerSize - map->SetInObjectPropertiesStartInWords(instance_size / kPointerSize -
inobject_properties); inobject_properties);
DCHECK_EQ(map->GetInObjectProperties(), inobject_properties); DCHECK_EQ(map->GetInObjectProperties(), inobject_properties);
map->set_prototype_validity_cell(invalid_prototype_validity_cell());
} else { } else {
DCHECK_EQ(inobject_properties, 0); DCHECK_EQ(inobject_properties, 0);
map->set_inobject_properties_start_or_constructor_function_index(0); map->set_inobject_properties_start_or_constructor_function_index(0);
map->set_prototype_validity_cell(Smi::FromInt(Map::kPrototypeChainValid));
} }
map->set_dependent_code(DependentCode::cast(empty_fixed_array()), map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
map->set_weak_cell_cache(Smi::kZero); map->set_weak_cell_cache(Smi::kZero);
map->set_prototype_validity_cell(Smi::kZero);
map->set_raw_transitions(Smi::kZero); map->set_raw_transitions(Smi::kZero);
map->SetInObjectUnusedPropertyFields(inobject_properties); map->SetInObjectUnusedPropertyFields(inobject_properties);
map->set_instance_descriptors(empty_descriptor_array()); map->set_instance_descriptors(empty_descriptor_array());
......
...@@ -213,6 +213,7 @@ using v8::MemoryPressureLevel; ...@@ -213,6 +213,7 @@ using v8::MemoryPressureLevel;
V(FixedArray, empty_ordered_hash_set, EmptyOrderedHashSet) \ V(FixedArray, empty_ordered_hash_set, EmptyOrderedHashSet) \
V(PropertyCell, empty_property_cell, EmptyPropertyCell) \ V(PropertyCell, empty_property_cell, EmptyPropertyCell) \
V(WeakCell, empty_weak_cell, EmptyWeakCell) \ V(WeakCell, empty_weak_cell, EmptyWeakCell) \
V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \ V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
/* Protectors */ \ /* Protectors */ \
V(Cell, array_constructor_protector, ArrayConstructorProtector) \ V(Cell, array_constructor_protector, ArrayConstructorProtector) \
......
...@@ -287,7 +287,15 @@ bool Heap::CreateInitialMaps() { ...@@ -287,7 +287,15 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_VARSIZE_MAP(CODE_TYPE, code) ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell) ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell);
{
// The invalid_prototype_validity_cell is needed for JSObject maps.
Smi* value = Smi::FromInt(Map::kPrototypeChainInvalid);
Cell* cell;
if (!AllocateCell(value).To(&cell)) return false;
set_invalid_prototype_validity_cell(cell);
}
ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell) ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell) ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler) ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
......
...@@ -609,15 +609,9 @@ Node* AccessorAssembler::HandleProtoHandler( ...@@ -609,15 +609,9 @@ Node* AccessorAssembler::HandleProtoHandler(
// Check prototype validity cell. // Check prototype validity cell.
// //
{ {
Label done(this); Node* maybe_validity_cell =
Node* validity_cell =
LoadObjectField(handler, ICHandler::kValidityCellOffset); LoadObjectField(handler, ICHandler::kValidityCellOffset);
GotoIf(WordEqual(validity_cell, SmiConstant(0)), &done); CheckPrototypeValidityCell(maybe_validity_cell, miss);
Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
GotoIf(WordNotEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)),
miss);
Goto(&done);
BIND(&done);
} }
// //
...@@ -891,6 +885,20 @@ void AccessorAssembler::HandleStoreICHandlerCase( ...@@ -891,6 +885,20 @@ void AccessorAssembler::HandleStoreICHandlerCase(
} }
} }
void AccessorAssembler::CheckPrototypeValidityCell(Node* maybe_validity_cell,
Label* miss) {
Label done(this);
GotoIf(WordEqual(maybe_validity_cell, SmiConstant(Map::kPrototypeChainValid)),
&done);
CSA_ASSERT(this, TaggedIsNotSmi(maybe_validity_cell));
Node* cell_value = LoadObjectField(maybe_validity_cell, Cell::kValueOffset);
Branch(WordEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)), &done,
miss);
BIND(&done);
}
void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p, void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p,
Node* holder, Node* handler_word) { Node* holder, Node* handler_word) {
Comment("accessor_store"); Comment("accessor_store");
......
...@@ -197,6 +197,7 @@ class AccessorAssembler : public CodeStubAssembler { ...@@ -197,6 +197,7 @@ class AccessorAssembler : public CodeStubAssembler {
Representation representation, Node* value, Representation representation, Node* value,
Node* transition, Label* miss); Node* transition, Label* miss);
void CheckPrototypeValidityCell(Node* maybe_validity_cell, Label* miss);
void HandleStoreICNativeDataProperty(const StoreICParameters* p, Node* holder, void HandleStoreICNativeDataProperty(const StoreICParameters* p, Node* holder,
Node* handler_word); Node* handler_word);
......
...@@ -124,11 +124,7 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate, ...@@ -124,11 +124,7 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate,
Handle<Object> validity_cell = Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) { if (validity_cell.is_null()) {
// Although in case of kApiGetter we load from receiver we still have to validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
// use the "prototype" shape of a handler in order to provide additional
// data to the dispatcher.
DCHECK_EQ(kApiGetter, GetHandlerKind(*smi_handler));
validity_cell = handle(Smi::kZero, isolate);
} }
int data_count = 1 + checks_count; int data_count = 1 + checks_count;
...@@ -157,7 +153,7 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate, ...@@ -157,7 +153,7 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
DCHECK_EQ(0, checks_count); DCHECK_EQ(0, checks_count);
// Lookup on receiver isn't supported in case of a simple smi handler. // Lookup on receiver isn't supported in case of a simple smi handler.
if (!LookupOnReceiverBits::decode(smi_handler->value())) return smi_handler; if (!LookupOnReceiverBits::decode(smi_handler->value())) return smi_handler;
validity_cell = handle(Smi::kZero, isolate); validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
} }
int data_count = 1 + checks_count; int data_count = 1 + checks_count;
...@@ -196,7 +192,7 @@ Handle<Object> StoreHandler::StoreElementTransition( ...@@ -196,7 +192,7 @@ Handle<Object> StoreHandler::StoreElementTransition(
Handle<Object> validity_cell = Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) { if (validity_cell.is_null()) {
validity_cell = handle(Smi::kZero, isolate); validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
} }
Handle<WeakCell> cell = Map::WeakCellForMap(transition); Handle<WeakCell> cell = Map::WeakCellForMap(transition);
Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(1); Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(1);
...@@ -247,7 +243,7 @@ Handle<Object> StoreHandler::StoreThroughPrototype( ...@@ -247,7 +243,7 @@ Handle<Object> StoreHandler::StoreThroughPrototype(
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) { if (validity_cell.is_null()) {
DCHECK_EQ(0, checks_count); DCHECK_EQ(0, checks_count);
validity_cell = handle(Smi::kZero, isolate); validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
} }
int data_count = 1 + checks_count; int data_count = 1 + checks_count;
......
...@@ -12510,13 +12510,8 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, ...@@ -12510,13 +12510,8 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
} else { } else {
maybe_prototype = maybe_prototype =
handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate); handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
if (!maybe_prototype->IsJSReceiver()) return Handle<Cell>::null();
}
if (maybe_prototype->IsJSProxy()) {
Handle<Cell> cell = isolate->factory()->NewCell(
handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
return cell;
} }
if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
// Ensure the prototype is registered with its own prototypes so its cell // Ensure the prototype is registered with its own prototypes so its cell
// will be invalidated when necessary. // will be invalidated when necessary.
......
...@@ -292,33 +292,33 @@ KNOWN_OBJECTS = { ...@@ -292,33 +292,33 @@ KNOWN_OBJECTS = {
("OLD_SPACE", 0x02519): "TerminationException", ("OLD_SPACE", 0x02519): "TerminationException",
("OLD_SPACE", 0x02579): "OptimizedOut", ("OLD_SPACE", 0x02579): "OptimizedOut",
("OLD_SPACE", 0x025d1): "StaleRegister", ("OLD_SPACE", 0x025d1): "StaleRegister",
("OLD_SPACE", 0x02651): "EmptyByteArray", ("OLD_SPACE", 0x02661): "EmptyByteArray",
("OLD_SPACE", 0x02671): "EmptyFixedUint8Array", ("OLD_SPACE", 0x02681): "EmptyFixedUint8Array",
("OLD_SPACE", 0x02691): "EmptyFixedInt8Array", ("OLD_SPACE", 0x026a1): "EmptyFixedInt8Array",
("OLD_SPACE", 0x026b1): "EmptyFixedUint16Array", ("OLD_SPACE", 0x026c1): "EmptyFixedUint16Array",
("OLD_SPACE", 0x026d1): "EmptyFixedInt16Array", ("OLD_SPACE", 0x026e1): "EmptyFixedInt16Array",
("OLD_SPACE", 0x026f1): "EmptyFixedUint32Array", ("OLD_SPACE", 0x02701): "EmptyFixedUint32Array",
("OLD_SPACE", 0x02711): "EmptyFixedInt32Array", ("OLD_SPACE", 0x02721): "EmptyFixedInt32Array",
("OLD_SPACE", 0x02731): "EmptyFixedFloat32Array", ("OLD_SPACE", 0x02741): "EmptyFixedFloat32Array",
("OLD_SPACE", 0x02751): "EmptyFixedFloat64Array", ("OLD_SPACE", 0x02761): "EmptyFixedFloat64Array",
("OLD_SPACE", 0x02771): "EmptyFixedUint8ClampedArray", ("OLD_SPACE", 0x02781): "EmptyFixedUint8ClampedArray",
("OLD_SPACE", 0x027d1): "EmptyScript", ("OLD_SPACE", 0x027e1): "EmptyScript",
("OLD_SPACE", 0x02859): "ManyClosuresCell", ("OLD_SPACE", 0x02869): "ManyClosuresCell",
("OLD_SPACE", 0x02869): "EmptySloppyArgumentsElements", ("OLD_SPACE", 0x02879): "EmptySloppyArgumentsElements",
("OLD_SPACE", 0x02889): "EmptySlowElementDictionary", ("OLD_SPACE", 0x02899): "EmptySlowElementDictionary",
("OLD_SPACE", 0x028d1): "EmptyOrderedHashMap", ("OLD_SPACE", 0x028e1): "EmptyOrderedHashMap",
("OLD_SPACE", 0x028f9): "EmptyOrderedHashSet", ("OLD_SPACE", 0x02909): "EmptyOrderedHashSet",
("OLD_SPACE", 0x02921): "EmptyPropertyCell", ("OLD_SPACE", 0x02931): "EmptyPropertyCell",
("OLD_SPACE", 0x02949): "EmptyWeakCell", ("OLD_SPACE", 0x02959): "EmptyWeakCell",
("OLD_SPACE", 0x029b9): "NoElementsProtector", ("OLD_SPACE", 0x029c9): "NoElementsProtector",
("OLD_SPACE", 0x029e1): "IsConcatSpreadableProtector", ("OLD_SPACE", 0x029f1): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x029f1): "SpeciesProtector", ("OLD_SPACE", 0x02a01): "SpeciesProtector",
("OLD_SPACE", 0x02a19): "StringLengthProtector", ("OLD_SPACE", 0x02a29): "StringLengthProtector",
("OLD_SPACE", 0x02a29): "ArrayIteratorProtector", ("OLD_SPACE", 0x02a39): "ArrayIteratorProtector",
("OLD_SPACE", 0x02a51): "ArrayBufferNeuteringProtector", ("OLD_SPACE", 0x02a61): "ArrayBufferNeuteringProtector",
("OLD_SPACE", 0x02ac9): "InfinityValue", ("OLD_SPACE", 0x02ad9): "InfinityValue",
("OLD_SPACE", 0x02ad9): "MinusZeroValue", ("OLD_SPACE", 0x02ae9): "MinusZeroValue",
("OLD_SPACE", 0x02ae9): "MinusInfinityValue", ("OLD_SPACE", 0x02af9): "MinusInfinityValue",
} }
# List of known V8 Frame Markers. # List of known V8 Frame Markers.
......
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