OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |