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, ie, are elements | |
danno
2012/11/13 22:52:32
nit: i.e.
Toon Verwaest
2012/11/14 11:57:38
Done.
| |
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) { | |
danno
2012/11/13 22:52:32
Maybe this should be a static method on Map? I kno
Toon Verwaest
2012/11/14 11:57:38
For now I'd keep it here. I doubt that he can reus
| |
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) { | |
danno
2012/11/13 22:52:32
since you handle both cases, why not make it "if (
Toon Verwaest
2012/11/14 11:57:38
Done.
| |
7608 Map* family_map = CheckSameElementsFamily(types); | |
7609 if (family_map != NULL) { | |
7610 receiver_map = Handle<Map>(family_map); | |
7611 monomorphic = expr->ComputeTarget(receiver_map, name); | |
7612 } | |
7613 } else { | |
7614 receiver_map = (types == NULL || types->is_empty()) | |
7615 ? Handle<Map>::null() | |
7616 : types->first(); | |
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 |