Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/hydrogen.cc

Issue 11359104: Consolidate polymorphic calls due to elements transitions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 7494 matching lines...) Expand 10 before | Expand all | Expand 10 after
7505 function, 7505 function,
7506 parameter_count); 7506 parameter_count);
7507 Drop(parameter_count); 7507 Drop(parameter_count);
7508 call->set_position(expr->position()); 7508 call->set_position(expr->position());
7509 ast_context()->ReturnInstruction(call, expr->id()); 7509 ast_context()->ReturnInstruction(call, expr->id());
7510 return true; 7510 return true;
7511 } 7511 }
7512 } 7512 }
7513 7513
7514 7514
7515 // Checks if all maps in |types| are from the same family, i.e., are elements
7516 // transitions of each other. Returns either NULL if they are not from the same
7517 // family, or a Map* indicating the map with the first elements kind of the
7518 // family that is in the list.
7519 static Map* CheckSameElementsFamily(SmallMapList* types) {
7520 if (types->length() <= 1) return NULL;
7521 // Check if all maps belong to the same transition family.
7522 Map* kinds[kFastElementsKindCount];
7523 Map* first_map = *types->first();
7524 ElementsKind first_kind = first_map->elements_kind();
7525 if (!IsFastElementsKind(first_kind)) return NULL;
7526 int first_index = GetSequenceIndexFromFastElementsKind(first_kind);
7527 int last_index = first_index;
7528
7529 for (int i = 0; i < kFastElementsKindCount; i++) kinds[i] = NULL;
7530
7531 kinds[first_index] = first_map;
7532
7533 for (int i = 1; i < types->length(); ++i) {
7534 Map* map = *types->at(i);
7535 ElementsKind elements_kind = map->elements_kind();
7536 if (!IsFastElementsKind(elements_kind)) return NULL;
7537 int index = GetSequenceIndexFromFastElementsKind(elements_kind);
7538 if (index < first_index) {
7539 first_index = index;
7540 } else if (index > last_index) {
7541 last_index = index;
7542 } else if (kinds[index] != map) {
7543 return NULL;
7544 }
7545 kinds[index] = map;
7546 }
7547
7548 Map* current = kinds[first_index];
7549 for (int i = first_index + 1; i <= last_index; i++) {
7550 Map* next = kinds[i];
7551 if (next != NULL) {
7552 ElementsKind current_kind = next->elements_kind();
7553 if (next != current->LookupElementsTransitionMap(current_kind)) {
7554 return NULL;
7555 }
7556 current = next;
7557 }
7558 }
7559
7560 return kinds[first_index];
7561 }
7562
7563
7515 void HGraphBuilder::VisitCall(Call* expr) { 7564 void HGraphBuilder::VisitCall(Call* expr) {
7516 ASSERT(!HasStackOverflow()); 7565 ASSERT(!HasStackOverflow());
7517 ASSERT(current_block() != NULL); 7566 ASSERT(current_block() != NULL);
7518 ASSERT(current_block()->HasPredecessor()); 7567 ASSERT(current_block()->HasPredecessor());
7519 Expression* callee = expr->expression(); 7568 Expression* callee = expr->expression();
7520 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 7569 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
7521 HInstruction* call = NULL; 7570 HInstruction* call = NULL;
7522 7571
7523 Property* prop = callee->AsProperty(); 7572 Property* prop = callee->AsProperty();
7524 if (prop != NULL) { 7573 if (prop != NULL) {
(...skipping 19 matching lines...) Expand all
7544 7593
7545 // Named function call. 7594 // Named function call.
7546 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 7595 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
7547 7596
7548 if (TryCallApply(expr)) return; 7597 if (TryCallApply(expr)) return;
7549 7598
7550 CHECK_ALIVE(VisitForValue(prop->obj())); 7599 CHECK_ALIVE(VisitForValue(prop->obj()));
7551 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7600 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7552 7601
7553 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 7602 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
7603 SmallMapList* types = expr->GetReceiverTypes();
7554 7604
7555 SmallMapList* types = expr->GetReceiverTypes(); 7605 bool monomorphic = expr->IsMonomorphic();
7606 Handle<Map> receiver_map;
7607 if (monomorphic) {
7608 receiver_map = (types == NULL || types->is_empty())
7609 ? Handle<Map>::null()
7610 : types->first();
7611 } else {
7612 Map* family_map = CheckSameElementsFamily(types);
7613 if (family_map != NULL) {
7614 receiver_map = Handle<Map>(family_map);
7615 monomorphic = expr->ComputeTarget(receiver_map, name);
7616 }
7617 }
7556 7618
7557 HValue* receiver = 7619 HValue* receiver =
7558 environment()->ExpressionStackAt(expr->arguments()->length()); 7620 environment()->ExpressionStackAt(expr->arguments()->length());
7559 if (expr->IsMonomorphic()) { 7621 if (monomorphic) {
7560 Handle<Map> receiver_map = (types == NULL || types->is_empty())
7561 ? Handle<Map>::null()
7562 : types->first();
7563 if (TryInlineBuiltinMethodCall(expr, 7622 if (TryInlineBuiltinMethodCall(expr,
7564 receiver, 7623 receiver,
7565 receiver_map, 7624 receiver_map,
7566 expr->check_type())) { 7625 expr->check_type())) {
7567 if (FLAG_trace_inlining) { 7626 if (FLAG_trace_inlining) {
7568 PrintF("Inlining builtin "); 7627 PrintF("Inlining builtin ");
7569 expr->target()->ShortPrint(); 7628 expr->target()->ShortPrint();
7570 PrintF("\n"); 7629 PrintF("\n");
7571 } 7630 }
7572 return; 7631 return;
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after
10011 } 10070 }
10012 } 10071 }
10013 10072
10014 #ifdef DEBUG 10073 #ifdef DEBUG
10015 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10074 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10016 if (allocator_ != NULL) allocator_->Verify(); 10075 if (allocator_ != NULL) allocator_->Verify();
10017 #endif 10076 #endif
10018 } 10077 }
10019 10078
10020 } } // namespace v8::internal 10079 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698