Revision: 12960
Author: [email protected]
Date: Wed Nov 14 04:10:51 2012
Log: Consolidate polymorphic calls due to elements transitions.
Review URL: https://chromiumcodereview.appspot.com/11359104
http://code.google.com/p/v8/source/detail?r=12960
Modified:
/branches/bleeding_edge/src/hydrogen.cc
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Nov 5 06:37:28 2012
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Nov 14 04:10:51 2012
@@ -7510,6 +7510,55 @@
return true;
}
}
+
+
+// Checks if all maps in |types| are from the same family, i.e., are
elements
+// transitions of each other. Returns either NULL if they are not from the
same
+// family, or a Map* indicating the map with the first elements kind of the
+// family that is in the list.
+static Map* CheckSameElementsFamily(SmallMapList* types) {
+ if (types->length() <= 1) return NULL;
+ // Check if all maps belong to the same transition family.
+ Map* kinds[kFastElementsKindCount];
+ Map* first_map = *types->first();
+ ElementsKind first_kind = first_map->elements_kind();
+ if (!IsFastElementsKind(first_kind)) return NULL;
+ int first_index = GetSequenceIndexFromFastElementsKind(first_kind);
+ int last_index = first_index;
+
+ for (int i = 0; i < kFastElementsKindCount; i++) kinds[i] = NULL;
+
+ kinds[first_index] = first_map;
+
+ for (int i = 1; i < types->length(); ++i) {
+ Map* map = *types->at(i);
+ ElementsKind elements_kind = map->elements_kind();
+ if (!IsFastElementsKind(elements_kind)) return NULL;
+ int index = GetSequenceIndexFromFastElementsKind(elements_kind);
+ if (index < first_index) {
+ first_index = index;
+ } else if (index > last_index) {
+ last_index = index;
+ } else if (kinds[index] != map) {
+ return NULL;
+ }
+ kinds[index] = map;
+ }
+
+ Map* current = kinds[first_index];
+ for (int i = first_index + 1; i <= last_index; i++) {
+ Map* next = kinds[i];
+ if (next != NULL) {
+ ElementsKind current_kind = next->elements_kind();
+ if (next != current->LookupElementsTransitionMap(current_kind)) {
+ return NULL;
+ }
+ current = next;
+ }
+ }
+
+ return kinds[first_index];
+}
void HGraphBuilder::VisitCall(Call* expr) {
@@ -7551,15 +7600,25 @@
CHECK_ALIVE(VisitExpressions(expr->arguments()));
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
-
SmallMapList* types = expr->GetReceiverTypes();
- HValue* receiver =
- environment()->ExpressionStackAt(expr->arguments()->length());
- if (expr->IsMonomorphic()) {
- Handle<Map> receiver_map = (types == NULL || types->is_empty())
+ bool monomorphic = expr->IsMonomorphic();
+ Handle<Map> receiver_map;
+ if (monomorphic) {
+ receiver_map = (types == NULL || types->is_empty())
? Handle<Map>::null()
: types->first();
+ } else {
+ Map* family_map = CheckSameElementsFamily(types);
+ if (family_map != NULL) {
+ receiver_map = Handle<Map>(family_map);
+ monomorphic = expr->ComputeTarget(receiver_map, name);
+ }
+ }
+
+ HValue* receiver =
+ environment()->ExpressionStackAt(expr->arguments()->length());
+ if (monomorphic) {
if (TryInlineBuiltinMethodCall(expr,
receiver,
receiver_map,
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev