diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 0ede93b4de..3b5002b7ff 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -1102,7 +1102,7 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { HIfContinuation continuation; Handle sentinel_map(isolate->heap()->meta_map()); Type* type = stub->GetType(zone(), sentinel_map); - BuildCompareNil(GetParameter(0), type, &continuation); + BuildCompareNil(GetParameter(0), type, &continuation, kEmbedMapsViaWeakCells); IfBuilder if_nil(this, &continuation); if_nil.Then(); if (continuation.IsFalseReachable()) { diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 800fa49a32..74f2711814 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -6256,6 +6256,10 @@ class HObjectAccess FINAL { return HObjectAccess(kInobject, Cell::kValueOffset); } + static HObjectAccess ForWeakCellValue() { + return HObjectAccess(kInobject, WeakCell::kValueOffset); + } + static HObjectAccess ForAllocationMementoSite() { return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 987d60b334..a6843115bb 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -3016,10 +3016,9 @@ HValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate, } -void HGraphBuilder::BuildCompareNil( - HValue* value, - Type* type, - HIfContinuation* continuation) { +void HGraphBuilder::BuildCompareNil(HValue* value, Type* type, + HIfContinuation* continuation, + MapEmbedding map_embedding) { IfBuilder if_nil(this); bool some_case_handled = false; bool some_case_missing = false; @@ -3058,7 +3057,21 @@ void HGraphBuilder::BuildCompareNil( // the monomorphic map when the code is used as a template to generate a // new IC. For optimized functions, there is no sentinel map, the map // emitted below is the actual monomorphic map. - Add(value, type->Classes().Current()); + if (map_embedding == kEmbedMapsViaWeakCells) { + HValue* cell = + Add(Map::WeakCellForMap(type->Classes().Current())); + HValue* expected_map = Add( + cell, nullptr, HObjectAccess::ForWeakCellValue()); + HValue* map = + Add(value, nullptr, HObjectAccess::ForMap()); + IfBuilder map_check(this); + map_check.IfNot(expected_map, map); + map_check.ThenDeopt("Unknown map"); + map_check.End(); + } else { + DCHECK(map_embedding == kEmbedMapsDirectly); + Add(value, type->Classes().Current()); + } } else { if_nil.Deopt("Too many undetectable types"); } diff --git a/src/hydrogen.h b/src/hydrogen.h index af7671b38b..c1ed797c96 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1864,10 +1864,10 @@ class HGraphBuilder { HValue* BuildElementIndexHash(HValue* index); - void BuildCompareNil( - HValue* value, - Type* type, - HIfContinuation* continuation); + enum MapEmbedding { kEmbedMapsDirectly, kEmbedMapsViaWeakCells }; + + void BuildCompareNil(HValue* value, Type* type, HIfContinuation* continuation, + MapEmbedding map_embedding = kEmbedMapsDirectly); void BuildCreateAllocationMemento(HValue* previous_object, HValue* previous_object_size, diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc index 69d707b035..3a1731268f 100644 --- a/src/ic/ic-compiler.cc +++ b/src/ic/ic-compiler.cc @@ -244,7 +244,8 @@ Handle PropertyICCompiler::ComputeCompareNil(Handle receiver_map, } Code::FindAndReplacePattern pattern; - pattern.Add(isolate->factory()->meta_map(), receiver_map); + Handle cell = Map::WeakCellForMap(receiver_map); + pattern.Add(isolate->factory()->meta_map(), cell); Handle ic = stub->GetCodeCopy(pattern); if (!receiver_map->is_dictionary_map()) { diff --git a/src/objects.cc b/src/objects.cc index 9d17f1f8bd..f309001180 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -10824,7 +10824,9 @@ void Code::FindAndReplace(const FindAndReplacePattern& pattern) { RelocInfo* info = it.rinfo(); Object* object = info->target_object(); if (object->IsHeapObject()) { - DCHECK(!object->IsWeakCell()); + if (object->IsWeakCell()) { + object = HeapObject::cast(WeakCell::cast(object)->value()); + } Map* map = HeapObject::cast(object)->map(); if (map == *pattern.find_[current_pattern]) { info->set_target_object(*pattern.replace_[current_pattern]);