Handle keyed stores after elements transition monomorphically if possible

Review URL: http://codereview.chromium.org/8354003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9712 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3edfb4bb
...@@ -4034,11 +4034,8 @@ HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, ...@@ -4034,11 +4034,8 @@ HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements,
HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
HValue* key, HValue* key,
HValue* val, HValue* val,
Expression* expr, Handle<Map> map,
bool is_store) { bool is_store) {
ASSERT(expr->IsMonomorphic());
Handle<Map> map = expr->GetMonomorphicReceiverType();
AddInstruction(new(zone()) HCheckNonSmi(object));
HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map));
bool fast_smi_only_elements = map->has_fast_smi_only_elements(); bool fast_smi_only_elements = map->has_fast_smi_only_elements();
bool fast_elements = map->has_fast_elements(); bool fast_elements = map->has_fast_elements();
...@@ -4088,7 +4085,6 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, ...@@ -4088,7 +4085,6 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
bool* has_side_effects) { bool* has_side_effects) {
*has_side_effects = false; *has_side_effects = false;
AddInstruction(new(zone()) HCheckNonSmi(object)); AddInstruction(new(zone()) HCheckNonSmi(object));
AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
SmallMapList* maps = prop->GetReceiverTypes(); SmallMapList* maps = prop->GetReceiverTypes();
bool todo_external_array = false; bool todo_external_array = false;
...@@ -4120,6 +4116,8 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, ...@@ -4120,6 +4116,8 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
} }
} }
int num_untransitionable_maps = 0;
Handle<Map> untransitionable_map;
for (int i = 0; i < maps->length(); ++i) { for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i); Handle<Map> map = maps->at(i);
ASSERT(map->IsMap()); ASSERT(map->IsMap());
...@@ -4132,9 +4130,22 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, ...@@ -4132,9 +4130,22 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) {
todo_external_array = true; todo_external_array = true;
} }
num_untransitionable_maps++;
untransitionable_map = map;
} }
} }
// If only one map is left after transitioning, handle this case
// monomorphically.
if (num_untransitionable_maps == 1) {
HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess(
object, key, val, untransitionable_map, is_store));
*has_side_effects |= instr->HasSideEffects();
instr->set_position(position);
return is_store ? NULL : instr;
}
AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
HBasicBlock* join = graph()->CreateBasicBlock(); HBasicBlock* join = graph()->CreateBasicBlock();
HInstruction* elements_kind_instr = HInstruction* elements_kind_instr =
...@@ -4266,7 +4277,9 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj, ...@@ -4266,7 +4277,9 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
ASSERT(!expr->IsPropertyName()); ASSERT(!expr->IsPropertyName());
HInstruction* instr = NULL; HInstruction* instr = NULL;
if (expr->IsMonomorphic()) { if (expr->IsMonomorphic()) {
instr = BuildMonomorphicElementAccess(obj, key, val, expr, is_store); Handle<Map> map = expr->GetMonomorphicReceiverType();
AddInstruction(new(zone()) HCheckNonSmi(obj));
instr = BuildMonomorphicElementAccess(obj, key, val, map, is_store);
} else if (expr->GetReceiverTypes() != NULL && } else if (expr->GetReceiverTypes() != NULL &&
!expr->GetReceiverTypes()->is_empty()) { !expr->GetReceiverTypes()->is_empty()) {
return HandlePolymorphicElementAccess( return HandlePolymorphicElementAccess(
......
...@@ -950,7 +950,7 @@ class HGraphBuilder: public AstVisitor { ...@@ -950,7 +950,7 @@ class HGraphBuilder: public AstVisitor {
HInstruction* BuildMonomorphicElementAccess(HValue* object, HInstruction* BuildMonomorphicElementAccess(HValue* object,
HValue* key, HValue* key,
HValue* val, HValue* val,
Expression* expr, Handle<Map> map,
bool is_store); bool is_store);
HValue* HandlePolymorphicElementAccess(HValue* object, HValue* HandlePolymorphicElementAccess(HValue* object,
HValue* key, HValue* key,
......
...@@ -423,6 +423,14 @@ void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id, ...@@ -423,6 +423,14 @@ void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
} }
static void AddMapIfMissing(Handle<Map> map, SmallMapList* list) {
for (int i = 0; i < list->length(); ++i) {
if (list->at(i).is_identical_to(map)) return;
}
list->Add(map);
}
void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id, void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
SmallMapList* types) { SmallMapList* types) {
Handle<Object> object = GetInfo(ast_id); Handle<Object> object = GetInfo(ast_id);
...@@ -436,7 +444,7 @@ void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id, ...@@ -436,7 +444,7 @@ void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
RelocInfo* info = it.rinfo(); RelocInfo* info = it.rinfo();
Object* object = info->target_object(); Object* object = info->target_object();
if (object->IsMap()) { if (object->IsMap()) {
types->Add(Handle<Map>(Map::cast(object))); AddMapIfMissing(Handle<Map>(Map::cast(object)), types);
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment