[cleanup] Drop FLAG_eliminate_prototype_chain_checks
This flag has been on by default for a while, along with FLAG_track_prototype_users which provides the prerequisite infrastructure. We are now sure that this is the direction we want to go in, so in order to simplify the code, this CL drops the respective flag-off code paths. Review-Url: https://codereview.chromium.org/1993913002 Cr-Commit-Position: refs/heads/master@{#36445}
This commit is contained in:
parent
1292721f92
commit
eac1b38d9a
@ -785,13 +785,8 @@ DEFINE_INT(random_seed, 0,
|
||||
|
||||
// objects.cc
|
||||
DEFINE_BOOL(trace_weak_arrays, false, "Trace WeakFixedArray usage")
|
||||
DEFINE_BOOL(track_prototype_users, false,
|
||||
"Keep track of which maps refer to a given prototype object")
|
||||
DEFINE_BOOL(trace_prototype_users, false,
|
||||
"Trace updates to prototype user tracking")
|
||||
DEFINE_BOOL(eliminate_prototype_chain_checks, true,
|
||||
"Collapse prototype chain checks into single-cell checks")
|
||||
DEFINE_IMPLICATION(eliminate_prototype_chain_checks, track_prototype_users)
|
||||
DEFINE_BOOL(use_verbose_printer, true, "allows verbose printing")
|
||||
DEFINE_BOOL(trace_for_in_enumerate, false, "Trace for-in enumerate slow-paths")
|
||||
#if TRACE_MAPS
|
||||
|
@ -437,28 +437,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
__ mov(scratch1, Operand(validity_cell));
|
||||
__ ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ b(ne, miss);
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
__ mov(scratch1, Operand(validity_cell));
|
||||
__ ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ b(ne, miss);
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ b(ne, miss);
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ b(ne, miss);
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -494,8 +491,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -505,33 +504,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
__ ldr(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(map_reg, cell, scratch2);
|
||||
__ b(ne, miss);
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ ldr(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -545,17 +523,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ b(ne, miss);
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -467,28 +467,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!AreAliased(object_reg, scratch1, scratch2));
|
||||
DCHECK(!AreAliased(holder_reg, scratch1, scratch2));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
__ Mov(scratch1, Operand(validity_cell));
|
||||
__ Ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ Cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ B(ne, miss);
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
__ Mov(scratch1, Operand(validity_cell));
|
||||
__ Ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ Cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ B(ne, miss);
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ Ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ B(ne, miss);
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ Ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ B(ne, miss);
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -525,8 +522,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -535,34 +534,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(current.is_null() || (current->property_dictionary()->FindEntry(
|
||||
name) == NameDictionary::kNotFound));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
__ Ldr(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ Ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(map_reg, cell, scratch2);
|
||||
__ B(ne, miss);
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ Ldr(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -576,17 +553,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ B(ne, miss);
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -439,28 +439,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
// Operand::ForCell(...) points to the cell's payload!
|
||||
__ cmp(Operand::ForCell(validity_cell),
|
||||
Immediate(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
// Operand::ForCell(...) points to the cell's payload!
|
||||
__ cmp(Operand::ForCell(validity_cell),
|
||||
Immediate(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ mov(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ mov(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -496,8 +493,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -507,34 +506,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
__ mov(holder_reg, FieldOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(map_reg, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ mov(holder_reg, FieldOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -548,17 +525,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -423,28 +423,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
__ li(scratch1, Operand(validity_cell));
|
||||
__ lw(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ Branch(miss, ne, scratch1,
|
||||
Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
__ li(scratch1, Operand(validity_cell));
|
||||
__ lw(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ Branch(miss, ne, scratch1,
|
||||
Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ lw(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch1, Operand(scratch2));
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ lw(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch1, Operand(scratch2));
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -480,8 +477,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -491,33 +490,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
__ lw(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch2, Operand(map_reg));
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ lw(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -531,17 +509,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch2, Operand(scratch1));
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -423,28 +423,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
__ li(scratch1, Operand(validity_cell));
|
||||
__ ld(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ Branch(miss, ne, scratch1,
|
||||
Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
__ li(scratch1, Operand(validity_cell));
|
||||
__ ld(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ Branch(miss, ne, scratch1,
|
||||
Operand(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ ld(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch1, Operand(scratch2));
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ ld(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch1, Operand(scratch2));
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -480,8 +477,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -491,33 +490,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
__ ld(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ ld(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch2, Operand(map_reg));
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ ld(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -531,17 +509,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ GetWeakValue(scratch2, cell);
|
||||
__ Branch(miss, ne, scratch2, Operand(scratch1));
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -432,28 +432,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
__ mov(scratch1, Operand(validity_cell));
|
||||
__ LoadP(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ CmpSmiLiteral(scratch1, Smi::FromInt(Map::kPrototypeChainValid), r0);
|
||||
__ bne(miss);
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
__ mov(scratch1, Operand(validity_cell));
|
||||
__ LoadP(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
|
||||
__ CmpSmiLiteral(scratch1, Smi::FromInt(Map::kPrototypeChainValid), r0);
|
||||
__ bne(miss);
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ LoadP(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ b(ne, miss);
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ LoadP(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ b(ne, miss);
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -488,8 +485,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -499,33 +498,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
__ LoadP(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(map_reg, cell, scratch2);
|
||||
__ bne(miss);
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ LoadP(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -539,17 +517,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ bne(miss);
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -440,29 +440,26 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
__ Move(scratch1, validity_cell, RelocInfo::CELL);
|
||||
// Move(..., CELL) loads the payload's address!
|
||||
__ SmiCompare(Operand(scratch1, 0),
|
||||
Smi::FromInt(Map::kPrototypeChainValid));
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
__ Move(scratch1, validity_cell, RelocInfo::CELL);
|
||||
// Move(..., CELL) loads the payload's address!
|
||||
__ SmiCompare(Operand(scratch1, 0),
|
||||
Smi::FromInt(Map::kPrototypeChainValid));
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ movp(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ movp(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg. On the first
|
||||
@ -500,8 +497,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -511,34 +510,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
__ movp(holder_reg, FieldOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ movp(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(map_reg, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ movp(holder_reg, FieldOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -552,17 +529,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -439,28 +439,25 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
|
||||
!scratch2.is(scratch1));
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks) {
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
|
||||
validity_cell->value());
|
||||
// Operand::ForCell(...) points to the cell's payload!
|
||||
__ cmp(Operand::ForCell(validity_cell),
|
||||
Immediate(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
Handle<Cell> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (!validity_cell.is_null()) {
|
||||
DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
|
||||
// Operand::ForCell(...) points to the cell's payload!
|
||||
__ cmp(Operand::ForCell(validity_cell),
|
||||
Immediate(Smi::FromInt(Map::kPrototypeChainValid)));
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ mov(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
// The prototype chain of primitives (and their JSValue wrappers) depends
|
||||
// on the native context, which can't be guarded by validity cells.
|
||||
// |object_reg| holds the native context specific prototype in this case;
|
||||
// we need to check its map.
|
||||
if (check == CHECK_ALL_MAPS) {
|
||||
__ mov(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
// Keep track of the current object in register reg.
|
||||
@ -496,8 +493,10 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
!current_map->is_access_check_needed());
|
||||
|
||||
prototype = handle(JSObject::cast(current_map->prototype()));
|
||||
if (current_map->is_dictionary_map() &&
|
||||
!current_map->IsJSGlobalObjectMap()) {
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (current_map->is_dictionary_map()) {
|
||||
DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
|
||||
if (!name->IsUniqueName()) {
|
||||
DCHECK(name->IsString());
|
||||
@ -507,34 +506,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
current->property_dictionary()->FindEntry(name) ==
|
||||
NameDictionary::kNotFound);
|
||||
|
||||
if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
|
||||
if (depth > 1) {
|
||||
// TODO(jkummerow): Cache and re-use weak cell.
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
|
||||
scratch2);
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
__ mov(holder_reg, FieldOperand(scratch1, Map::kPrototypeOffset));
|
||||
}
|
||||
} else {
|
||||
Register map_reg = scratch1;
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
}
|
||||
if (current_map->IsJSGlobalObjectMap()) {
|
||||
GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
|
||||
name, scratch2, miss);
|
||||
} else if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 1 || check == CHECK_ALL_MAPS)) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(map_reg, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
if (!FLAG_eliminate_prototype_chain_checks) {
|
||||
__ mov(holder_reg, FieldOperand(map_reg, Map::kPrototypeOffset));
|
||||
}
|
||||
}
|
||||
|
||||
reg = holder_reg; // From now on the object will be in holder_reg.
|
||||
@ -548,17 +525,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
||||
// Log the check depth.
|
||||
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
||||
|
||||
if (!FLAG_eliminate_prototype_chain_checks &&
|
||||
(depth != 0 || check == CHECK_ALL_MAPS)) {
|
||||
// Check the holder map.
|
||||
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
|
||||
__ CmpWeakValue(scratch1, cell, scratch2);
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
|
||||
bool return_holder = return_what == RETURN_HOLDER;
|
||||
if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
|
||||
if (return_holder && depth != 0) {
|
||||
__ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
|
||||
}
|
||||
|
||||
|
@ -2797,7 +2797,6 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
|
||||
void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
|
||||
Handle<Map> new_map,
|
||||
Isolate* isolate) {
|
||||
if (!FLAG_track_prototype_users) return;
|
||||
if (!old_map->is_prototype_map()) return;
|
||||
DCHECK(new_map->is_prototype_map());
|
||||
bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
|
||||
@ -11598,7 +11597,6 @@ void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
|
||||
|
||||
// static
|
||||
void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
|
||||
DCHECK(FLAG_track_prototype_users);
|
||||
// Contract: In line with InvalidatePrototypeChains()'s requirements,
|
||||
// leaf maps don't need to register as users, only prototypes do.
|
||||
DCHECK(user->is_prototype_map());
|
||||
@ -11704,7 +11702,6 @@ static void InvalidatePrototypeChainsInternal(Map* map) {
|
||||
|
||||
// static
|
||||
void JSObject::InvalidatePrototypeChains(Map* map) {
|
||||
if (!FLAG_eliminate_prototype_chain_checks) return;
|
||||
DisallowHeapAllocation no_gc;
|
||||
InvalidatePrototypeChainsInternal(map);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user