Reviewers: danno,
Message:
PTAL.
Description:
Handle keyed stores after elements transition monomorphically if possible
Please review this at http://codereview.chromium.org/8354003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/hydrogen.h
M src/hydrogen.cc
M src/type-info.cc
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
435c08fa8aef200e46eedb34d6f61b081d957b1f..8a35ed61b6295f60df7214b75a3d9490a6507ea1
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4034,11 +4034,8 @@ HInstruction*
HGraphBuilder::BuildFastElementAccess(HValue* elements,
HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
HValue* key,
HValue* val,
- Expression*
expr,
+ Handle<Map> map,
bool is_store) {
- ASSERT(expr->IsMonomorphic());
- Handle<Map> map = expr->GetMonomorphicReceiverType();
- AddInstruction(new(zone()) HCheckNonSmi(object));
HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object,
map));
bool fast_smi_only_elements = map->has_fast_smi_only_elements();
bool fast_elements = map->has_fast_elements();
@@ -4088,7 +4085,6 @@ HValue*
HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
bool*
has_side_effects) {
*has_side_effects = false;
AddInstruction(new(zone()) HCheckNonSmi(object));
- AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
SmallMapList* maps = prop->GetReceiverTypes();
bool todo_external_array = false;
@@ -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) {
Handle<Map> map = maps->at(i);
ASSERT(map->IsMap());
@@ -4132,9 +4130,22 @@ HValue*
HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) {
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();
HInstruction* elements_kind_instr =
@@ -4266,7 +4277,9 @@ HValue*
HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
ASSERT(!expr->IsPropertyName());
HInstruction* instr = NULL;
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 &&
!expr->GetReceiverTypes()->is_empty()) {
return HandlePolymorphicElementAccess(
Index: src/hydrogen.h
diff --git a/src/hydrogen.h b/src/hydrogen.h
index
c7155ad4f93641d1d1bb9854634366c1f2926e2b..8ed112119ca97d26ae4a203179b3b0327a2d86ea
100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -950,7 +950,7 @@ class HGraphBuilder: public AstVisitor {
HInstruction* BuildMonomorphicElementAccess(HValue* object,
HValue* key,
HValue* val,
- Expression* expr,
+ Handle<Map> map,
bool is_store);
HValue* HandlePolymorphicElementAccess(HValue* object,
HValue* key,
Index: src/type-info.cc
diff --git a/src/type-info.cc b/src/type-info.cc
index
a4b16f4f30a984cf35f0591e52130166541ceec6..48fc676ef53bfed8dc034d684284d95da790c842
100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -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,
SmallMapList* types) {
Handle<Object> object = GetInfo(ast_id);
@@ -436,7 +444,7 @@ void
TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
RelocInfo* info = it.rinfo();
Object* object = info->target_object();
if (object->IsMap()) {
- types->Add(Handle<Map>(Map::cast(object)));
+ AddMapIfMissing(Handle<Map>(Map::cast(object)), types);
}
}
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev