[runtime] Make Map::GetOrCreatePrototypeChainValidityCell() return smi instead of empty handle.

Bug: v8:5988
Change-Id: I6f62199f062ea32e66903f5385fc109e47fed374
Reviewed-on: https://chromium-review.googlesource.com/970822
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52363}
This commit is contained in:
Igor Sheludko 2018-04-04 18:21:42 +02:00 committed by Commit Bot
parent 314517106a
commit b6021b983d
5 changed files with 18 additions and 28 deletions

View File

@ -123,9 +123,6 @@ Handle<Object> LoadHandler::LoadFromPrototype(Isolate* isolate,
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) {
validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
}
int data_count = 1 + checks_count;
Handle<LoadHandler> handler = isolate->factory()->NewLoadHandler(data_count);
@ -149,11 +146,10 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) {
if (validity_cell->IsSmi()) {
DCHECK_EQ(0, checks_count);
// Lookup on receiver isn't supported in case of a simple smi handler.
if (!LookupOnReceiverBits::decode(smi_handler->value())) return smi_handler;
validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
}
int data_count = 1 + checks_count;
@ -191,9 +187,6 @@ Handle<Object> StoreHandler::StoreElementTransition(
.GetCode();
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) {
validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
}
Handle<WeakCell> cell = Map::WeakCellForMap(transition);
Handle<StoreHandler> handler = isolate->factory()->NewStoreHandler(1);
handler->set_smi_handler(*stub);
@ -227,9 +220,6 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate,
if (is_dictionary_map || !transition_map->IsPrototypeValidityCellValid()) {
validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(transition_map, isolate);
if (validity_cell.is_null()) {
validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
}
}
if (is_dictionary_map) {
@ -266,10 +256,7 @@ Handle<Object> StoreHandler::StoreThroughPrototype(
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
if (validity_cell.is_null()) {
DCHECK_EQ(0, checks_count);
validity_cell = handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
}
DCHECK_IMPLIES(validity_cell->IsSmi(), checks_count == 0);
int data_count = 1 + checks_count;
Handle<StoreHandler> handler =

View File

@ -1860,7 +1860,10 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
if (validity_cell.is_null()) return stub;
if (validity_cell->IsSmi()) {
// There's no prototype validity cell to check, so we can just use the stub.
return stub;
}
Handle<StoreHandler> handler = isolate()->factory()->NewStoreHandler(0);
handler->set_validity_cell(*validity_cell);
handler->set_smi_handler(*stub);

View File

@ -588,10 +588,6 @@ void LookupIterator::ApplyTransitionToDataProperty(
// configuration can produce valid transition handler maps.
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(transition, isolate());
if (validity_cell.is_null()) {
validity_cell =
handle(Smi::FromInt(Map::kPrototypeChainValid), isolate());
}
transition->set_prototype_validity_cell(*validity_cell);
}

View File

@ -12568,8 +12568,8 @@ void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
}
// static
Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
Isolate* isolate) {
Handle<Object> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
Isolate* isolate) {
Handle<Object> maybe_prototype;
if (map->IsJSGlobalObjectMap()) {
DCHECK(map->is_prototype_map());
@ -12580,7 +12580,9 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
maybe_prototype =
handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
}
if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
if (!maybe_prototype->IsJSObject()) {
return handle(Smi::FromInt(Map::kPrototypeChainValid), isolate);
}
Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
// Ensure the prototype is registered with its own prototypes so its cell
// will be invalidated when necessary.

View File

@ -420,11 +420,13 @@ class Map : public HeapObject {
Isolate* isolate);
// [prototype chain validity cell]: Associated with a prototype object,
// stored in that object's map's PrototypeInfo, indicates that prototype
// chains through this object are currently valid. The cell will be
// invalidated and replaced when the prototype chain changes.
static Handle<Cell> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
Isolate* isolate);
// stored in that object's map, indicates that prototype chains through this
// object are currently valid. The cell will be invalidated and replaced when
// the prototype chain changes. When there's nothing to guard (for example,
// when direct prototype is null or Proxy) this function returns Smi with
// |kPrototypeChainValid| sentinel value.
static Handle<Object> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
Isolate* isolate);
static const int kPrototypeChainValid = 0;
static const int kPrototypeChainInvalid = 1;