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

Side by Side Diff: src/hydrogen.cc

Issue 6708085: Enable GVN for polymorphic loads by not expanding them at the HIR level. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3427 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 HValue* value = environment()->Pop(); 3438 HValue* value = environment()->Pop();
3439 HThrow* instr = new HThrow(value); 3439 HThrow* instr = new HThrow(value);
3440 instr->set_position(expr->position()); 3440 instr->set_position(expr->position());
3441 AddInstruction(instr); 3441 AddInstruction(instr);
3442 AddSimulate(expr->id()); 3442 AddSimulate(expr->id());
3443 current_block()->FinishExit(new HAbnormalExit); 3443 current_block()->FinishExit(new HAbnormalExit);
3444 set_current_block(NULL); 3444 set_current_block(NULL);
3445 } 3445 }
3446 3446
3447 3447
3448 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
3449 HValue* object,
3450 ZoneMapList* types,
3451 Handle<String> name) {
3452 // TODO(ager): We should recognize when the prototype chains for different
3453 // maps are identical. In that case we can avoid repeatedly generating the
3454 // same prototype map checks.
3455 int count = 0;
3456 HBasicBlock* join = NULL;
3457 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
3458 Handle<Map> map = types->at(i);
3459 LookupResult lookup;
3460 map->LookupInDescriptors(NULL, *name, &lookup);
3461 if (lookup.IsProperty() && lookup.type() == FIELD) {
3462 if (count == 0) {
3463 AddInstruction(new HCheckNonSmi(object)); // Only needed once.
3464 join = graph()->CreateBasicBlock();
3465 }
3466 ++count;
3467 HBasicBlock* if_true = graph()->CreateBasicBlock();
3468 HBasicBlock* if_false = graph()->CreateBasicBlock();
3469 HCompareMap* compare = new HCompareMap(object, map, if_true, if_false);
3470 current_block()->Finish(compare);
3471
3472 set_current_block(if_true);
3473 HLoadNamedField* instr =
3474 BuildLoadNamedField(object, expr, map, &lookup, false);
3475 instr->set_position(expr->position());
3476 instr->ClearFlag(HValue::kUseGVN);
3477 AddInstruction(instr);
3478 if (!ast_context()->IsEffect()) Push(instr);
3479 current_block()->Goto(join);
3480
3481 set_current_block(if_false);
3482 }
3483 }
3484
3485 // Finish up. Unconditionally deoptimize if we've handled all the maps we
3486 // know about and do not want to handle ones we've never seen. Otherwise
3487 // use a generic IC.
3488 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
3489 current_block()->FinishExitWithDeoptimization();
3490 } else {
3491 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3492 instr->set_position(expr->position());
3493
3494 if (join != NULL) {
3495 AddInstruction(instr);
3496 if (!ast_context()->IsEffect()) Push(instr);
3497 current_block()->Goto(join);
3498 } else {
3499 ast_context()->ReturnInstruction(instr, expr->id());
3500 return;
3501 }
3502 }
3503
3504 ASSERT(join != NULL);
3505 join->SetJoinId(expr->id());
3506 set_current_block(join);
3507 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
3508 }
3509
3510
3511 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 3448 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
3512 Property* expr, 3449 Property* expr,
3513 Handle<Map> type, 3450 Handle<Map> type,
3514 LookupResult* lookup, 3451 LookupResult* lookup,
3515 bool smi_and_map_check) { 3452 bool smi_and_map_check) {
3516 if (smi_and_map_check) { 3453 if (smi_and_map_check) {
3517 AddInstruction(new HCheckNonSmi(object)); 3454 AddInstruction(new HCheckNonSmi(object));
3518 AddInstruction(new HCheckMap(object, type)); 3455 AddInstruction(new HCheckMap(object, type));
3519 } 3456 }
3520 3457
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
3741 instr = new HLoadFunctionPrototype(function); 3678 instr = new HLoadFunctionPrototype(function);
3742 3679
3743 } else if (expr->key()->IsPropertyName()) { 3680 } else if (expr->key()->IsPropertyName()) {
3744 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3681 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3745 ZoneMapList* types = expr->GetReceiverTypes(); 3682 ZoneMapList* types = expr->GetReceiverTypes();
3746 3683
3747 HValue* obj = Pop(); 3684 HValue* obj = Pop();
3748 if (expr->IsMonomorphic()) { 3685 if (expr->IsMonomorphic()) {
3749 instr = BuildLoadNamed(obj, expr, types->first(), name); 3686 instr = BuildLoadNamed(obj, expr, types->first(), name);
3750 } else if (types != NULL && types->length() > 1) { 3687 } else if (types != NULL && types->length() > 1) {
3751 HandlePolymorphicLoadNamedField(expr, obj, types, name); 3688 AddInstruction(new HCheckNonSmi(obj));
3752 return; 3689 instr = new HLoadNamedFieldPolymorphic(obj, types, name);
3753
3754 } else { 3690 } else {
3755 instr = BuildLoadNamedGeneric(obj, expr); 3691 instr = BuildLoadNamedGeneric(obj, expr);
3756 } 3692 }
3757 3693
3758 } else { 3694 } else {
3759 VISIT_FOR_VALUE(expr->key()); 3695 VISIT_FOR_VALUE(expr->key());
3760 3696
3761 HValue* key = Pop(); 3697 HValue* key = Pop();
3762 HValue* obj = Pop(); 3698 HValue* obj = Pop();
3763 3699
(...skipping 2178 matching lines...) Expand 10 before | Expand all | Expand 10 after
5942 } 5878 }
5943 } 5879 }
5944 5880
5945 #ifdef DEBUG 5881 #ifdef DEBUG
5946 if (graph_ != NULL) graph_->Verify(); 5882 if (graph_ != NULL) graph_->Verify();
5947 if (allocator_ != NULL) allocator_->Verify(); 5883 if (allocator_ != NULL) allocator_->Verify();
5948 #endif 5884 #endif
5949 } 5885 }
5950 5886
5951 } } // namespace v8::internal 5887 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698