Use weak cell to embed map in CompareNil IC.
BUG=v8:3629 LOG=N Review URL: https://codereview.chromium.org/812353002 Cr-Commit-Position: refs/heads/master@{#25905}
This commit is contained in:
parent
c05d7b059d
commit
31de02151b
@ -1102,7 +1102,7 @@ HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
|
||||
HIfContinuation continuation;
|
||||
Handle<Map> 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()) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<HCheckMaps>(value, type->Classes().Current());
|
||||
if (map_embedding == kEmbedMapsViaWeakCells) {
|
||||
HValue* cell =
|
||||
Add<HConstant>(Map::WeakCellForMap(type->Classes().Current()));
|
||||
HValue* expected_map = Add<HLoadNamedField>(
|
||||
cell, nullptr, HObjectAccess::ForWeakCellValue());
|
||||
HValue* map =
|
||||
Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap());
|
||||
IfBuilder map_check(this);
|
||||
map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map);
|
||||
map_check.ThenDeopt("Unknown map");
|
||||
map_check.End();
|
||||
} else {
|
||||
DCHECK(map_embedding == kEmbedMapsDirectly);
|
||||
Add<HCheckMaps>(value, type->Classes().Current());
|
||||
}
|
||||
} else {
|
||||
if_nil.Deopt("Too many undetectable types");
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -244,7 +244,8 @@ Handle<Code> PropertyICCompiler::ComputeCompareNil(Handle<Map> receiver_map,
|
||||
}
|
||||
|
||||
Code::FindAndReplacePattern pattern;
|
||||
pattern.Add(isolate->factory()->meta_map(), receiver_map);
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
pattern.Add(isolate->factory()->meta_map(), cell);
|
||||
Handle<Code> ic = stub->GetCodeCopy(pattern);
|
||||
|
||||
if (!receiver_map->is_dictionary_map()) {
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user