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:
ulan 2014-12-19 06:51:10 -08:00 committed by Commit bot
parent c05d7b059d
commit 31de02151b
6 changed files with 32 additions and 12 deletions

View File

@ -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()) {

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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,

View File

@ -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()) {

View File

@ -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]);