Commit deae08bd authored by verwaest@chromium.org's avatar verwaest@chromium.org

Consolidate polymorphic calls due to elements transitions.

Review URL: https://chromiumcodereview.appspot.com/11359104

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12960 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a590fff7
...@@ -7512,6 +7512,55 @@ bool HGraphBuilder::TryCallApply(Call* expr) { ...@@ -7512,6 +7512,55 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
} }
// 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) { void HGraphBuilder::VisitCall(Call* expr) {
ASSERT(!HasStackOverflow()); ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL); ASSERT(current_block() != NULL);
...@@ -7551,15 +7600,25 @@ void HGraphBuilder::VisitCall(Call* expr) { ...@@ -7551,15 +7600,25 @@ void HGraphBuilder::VisitCall(Call* expr) {
CHECK_ALIVE(VisitExpressions(expr->arguments())); CHECK_ALIVE(VisitExpressions(expr->arguments()));
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
SmallMapList* types = expr->GetReceiverTypes(); SmallMapList* types = expr->GetReceiverTypes();
HValue* receiver = bool monomorphic = expr->IsMonomorphic();
environment()->ExpressionStackAt(expr->arguments()->length()); Handle<Map> receiver_map;
if (expr->IsMonomorphic()) { if (monomorphic) {
Handle<Map> receiver_map = (types == NULL || types->is_empty()) receiver_map = (types == NULL || types->is_empty())
? Handle<Map>::null() ? Handle<Map>::null()
: types->first(); : 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, if (TryInlineBuiltinMethodCall(expr,
receiver, receiver,
receiver_map, receiver_map,
......
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