| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 ASSERT(!finished_); | 808 ASSERT(!finished_); |
| 809 did_then_ = true; | 809 did_then_ = true; |
| 810 if (needs_compare_) { | 810 if (needs_compare_) { |
| 811 // Handle if's without any expressions, they jump directly to the "else" | 811 // Handle if's without any expressions, they jump directly to the "else" |
| 812 // branch. However, we must pretend that the "then" branch is reachable, | 812 // branch. However, we must pretend that the "then" branch is reachable, |
| 813 // so that the graph builder visits it and sees any live range extending | 813 // so that the graph builder visits it and sees any live range extending |
| 814 // constructs within it. | 814 // constructs within it. |
| 815 HConstant* constant_false = builder_->graph()->GetConstantFalse(); | 815 HConstant* constant_false = builder_->graph()->GetConstantFalse(); |
| 816 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); | 816 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); |
| 817 boolean_type.Add(ToBooleanStub::BOOLEAN); | 817 boolean_type.Add(ToBooleanStub::BOOLEAN); |
| 818 HBranch* branch = | 818 HBranch* branch = builder()->New<HBranch>( |
| 819 new(zone()) HBranch(constant_false, boolean_type, first_true_block_, | 819 constant_false, boolean_type, first_true_block_, first_false_block_); |
| 820 first_false_block_); | |
| 821 builder_->current_block()->Finish(branch); | 820 builder_->current_block()->Finish(branch); |
| 822 } | 821 } |
| 823 builder_->set_current_block(first_true_block_); | 822 builder_->set_current_block(first_true_block_); |
| 824 } | 823 } |
| 825 | 824 |
| 826 | 825 |
| 827 void HGraphBuilder::IfBuilder::Else() { | 826 void HGraphBuilder::IfBuilder::Else() { |
| 828 ASSERT(did_then_); | 827 ASSERT(did_then_); |
| 829 ASSERT(!captured_); | 828 ASSERT(!captured_); |
| 830 ASSERT(!finished_); | 829 ASSERT(!finished_); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 HEnvironment* body_env = env->Copy(); | 941 HEnvironment* body_env = env->Copy(); |
| 943 HEnvironment* exit_env = env->Copy(); | 942 HEnvironment* exit_env = env->Copy(); |
| 944 // Remove the phi from the expression stack | 943 // Remove the phi from the expression stack |
| 945 body_env->Pop(); | 944 body_env->Pop(); |
| 946 exit_env->Pop(); | 945 exit_env->Pop(); |
| 947 body_block_ = builder_->CreateBasicBlock(body_env); | 946 body_block_ = builder_->CreateBasicBlock(body_env); |
| 948 exit_block_ = builder_->CreateBasicBlock(exit_env); | 947 exit_block_ = builder_->CreateBasicBlock(exit_env); |
| 949 | 948 |
| 950 builder_->set_current_block(header_block_); | 949 builder_->set_current_block(header_block_); |
| 951 env->Pop(); | 950 env->Pop(); |
| 952 HCompareNumericAndBranch* compare = | 951 builder_->current_block()->Finish(builder_->New<HCompareNumericAndBranch>( |
| 953 new(zone()) HCompareNumericAndBranch(phi_, terminating, token); | 952 phi_, terminating, token, body_block_, exit_block_)); |
| 954 compare->SetSuccessorAt(0, body_block_); | |
| 955 compare->SetSuccessorAt(1, exit_block_); | |
| 956 builder_->current_block()->Finish(compare); | |
| 957 | 953 |
| 958 builder_->set_current_block(body_block_); | 954 builder_->set_current_block(body_block_); |
| 959 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { | 955 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { |
| 960 HValue* one = builder_->graph()->GetConstant1(); | 956 HValue* one = builder_->graph()->GetConstant1(); |
| 961 if (direction_ == kPreIncrement) { | 957 if (direction_ == kPreIncrement) { |
| 962 increment_ = HAdd::New(zone(), context_, phi_, one); | 958 increment_ = HAdd::New(zone(), context_, phi_, one); |
| 963 } else { | 959 } else { |
| 964 increment_ = HSub::New(zone(), context_, phi_, one); | 960 increment_ = HSub::New(zone(), context_, phi_, one); |
| 965 } | 961 } |
| 966 increment_->ClearFlag(HValue::kCanOverflow); | 962 increment_->ClearFlag(HValue::kCanOverflow); |
| (...skipping 1798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2765 // connects a branch node to a join node. We conservatively ensure that | 2761 // connects a branch node to a join node. We conservatively ensure that |
| 2766 // property by always adding an empty block on the outgoing edges of this | 2762 // property by always adding an empty block on the outgoing edges of this |
| 2767 // branch. | 2763 // branch. |
| 2768 HOptimizedGraphBuilder* builder = owner(); | 2764 HOptimizedGraphBuilder* builder = owner(); |
| 2769 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { | 2765 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { |
| 2770 builder->Bailout(kArgumentsObjectValueInATestContext); | 2766 builder->Bailout(kArgumentsObjectValueInATestContext); |
| 2771 } | 2767 } |
| 2772 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 2768 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
| 2773 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 2769 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
| 2774 ToBooleanStub::Types expected(condition()->to_boolean_types()); | 2770 ToBooleanStub::Types expected(condition()->to_boolean_types()); |
| 2775 HBranch* test = new(zone()) HBranch(value, expected, empty_true, empty_false); | 2771 builder->current_block()->Finish(builder->New<HBranch>( |
| 2776 builder->current_block()->Finish(test); | 2772 value, expected, empty_true, empty_false)); |
| 2777 | 2773 |
| 2778 empty_true->Goto(if_true(), builder->function_state()); | 2774 empty_true->Goto(if_true(), builder->function_state()); |
| 2779 empty_false->Goto(if_false(), builder->function_state()); | 2775 empty_false->Goto(if_false(), builder->function_state()); |
| 2780 builder->set_current_block(NULL); | 2776 builder->set_current_block(NULL); |
| 2781 } | 2777 } |
| 2782 | 2778 |
| 2783 | 2779 |
| 2784 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. | 2780 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. |
| 2785 #define CHECK_BAILOUT(call) \ | 2781 #define CHECK_BAILOUT(call) \ |
| 2786 do { \ | 2782 do { \ |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3367 CHECK_ALIVE(VisitForValue(stmt->tag())); | 3363 CHECK_ALIVE(VisitForValue(stmt->tag())); |
| 3368 Add<HSimulate>(stmt->EntryId()); | 3364 Add<HSimulate>(stmt->EntryId()); |
| 3369 HValue* tag_value = Pop(); | 3365 HValue* tag_value = Pop(); |
| 3370 HBasicBlock* first_test_block = current_block(); | 3366 HBasicBlock* first_test_block = current_block(); |
| 3371 | 3367 |
| 3372 HUnaryControlInstruction* string_check = NULL; | 3368 HUnaryControlInstruction* string_check = NULL; |
| 3373 HBasicBlock* not_string_block = NULL; | 3369 HBasicBlock* not_string_block = NULL; |
| 3374 | 3370 |
| 3375 // Test switch's tag value if all clauses are string literals | 3371 // Test switch's tag value if all clauses are string literals |
| 3376 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { | 3372 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { |
| 3377 string_check = new(zone()) HIsStringAndBranch(tag_value); | |
| 3378 first_test_block = graph()->CreateBasicBlock(); | 3373 first_test_block = graph()->CreateBasicBlock(); |
| 3379 not_string_block = graph()->CreateBasicBlock(); | 3374 not_string_block = graph()->CreateBasicBlock(); |
| 3380 | 3375 string_check = New<HIsStringAndBranch>( |
| 3381 string_check->SetSuccessorAt(0, first_test_block); | 3376 tag_value, first_test_block, not_string_block); |
| 3382 string_check->SetSuccessorAt(1, not_string_block); | |
| 3383 current_block()->Finish(string_check); | 3377 current_block()->Finish(string_check); |
| 3384 | 3378 |
| 3385 set_current_block(first_test_block); | 3379 set_current_block(first_test_block); |
| 3386 } | 3380 } |
| 3387 | 3381 |
| 3388 // 1. Build all the tests, with dangling true branches | 3382 // 1. Build all the tests, with dangling true branches |
| 3389 BailoutId default_id = BailoutId::None(); | 3383 BailoutId default_id = BailoutId::None(); |
| 3390 for (int i = 0; i < clause_count; ++i) { | 3384 for (int i = 0; i < clause_count; ++i) { |
| 3391 CaseClause* clause = clauses->at(i); | 3385 CaseClause* clause = clauses->at(i); |
| 3392 if (clause->is_default()) { | 3386 if (clause->is_default()) { |
| 3393 default_id = clause->EntryId(); | 3387 default_id = clause->EntryId(); |
| 3394 continue; | 3388 continue; |
| 3395 } | 3389 } |
| 3396 | 3390 |
| 3397 // Generate a compare and branch. | 3391 // Generate a compare and branch. |
| 3398 CHECK_ALIVE(VisitForValue(clause->label())); | 3392 CHECK_ALIVE(VisitForValue(clause->label())); |
| 3399 HValue* label_value = Pop(); | 3393 HValue* label_value = Pop(); |
| 3400 | 3394 |
| 3401 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 3395 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
| 3402 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 3396 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
| 3403 | 3397 |
| 3404 HControlInstruction* compare; | 3398 HControlInstruction* compare; |
| 3405 | 3399 |
| 3406 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { | 3400 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { |
| 3407 if (!clause->compare_type()->Is(Type::Smi())) { | 3401 if (!clause->compare_type()->Is(Type::Smi())) { |
| 3408 Add<HDeoptimize>("Non-smi switch type", Deoptimizer::SOFT); | 3402 Add<HDeoptimize>("Non-smi switch type", Deoptimizer::SOFT); |
| 3409 } | 3403 } |
| 3410 | 3404 |
| 3411 HCompareNumericAndBranch* compare_ = | 3405 HCompareNumericAndBranch* compare_ = |
| 3412 new(zone()) HCompareNumericAndBranch(tag_value, | 3406 New<HCompareNumericAndBranch>(tag_value, |
| 3413 label_value, | 3407 label_value, |
| 3414 Token::EQ_STRICT); | 3408 Token::EQ_STRICT); |
| 3415 compare_->set_observed_input_representation( | 3409 compare_->set_observed_input_representation( |
| 3416 Representation::Smi(), Representation::Smi()); | 3410 Representation::Smi(), Representation::Smi()); |
| 3417 compare = compare_; | 3411 compare = compare_; |
| 3418 } else { | 3412 } else { |
| 3419 compare = new(zone()) HStringCompareAndBranch(context, tag_value, | 3413 compare = new(zone()) HStringCompareAndBranch(context, tag_value, |
| 3420 label_value, | 3414 label_value, |
| 3421 Token::EQ_STRICT); | 3415 Token::EQ_STRICT); |
| 3422 } | 3416 } |
| 3423 | 3417 |
| 3424 compare->SetSuccessorAt(0, body_block); | 3418 compare->SetSuccessorAt(0, body_block); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3688 HForInCacheArray::cast(array)->set_index_cache( | 3682 HForInCacheArray::cast(array)->set_index_cache( |
| 3689 HForInCacheArray::cast(index_cache)); | 3683 HForInCacheArray::cast(index_cache)); |
| 3690 | 3684 |
| 3691 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); | 3685 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); |
| 3692 | 3686 |
| 3693 HValue* index = environment()->ExpressionStackAt(0); | 3687 HValue* index = environment()->ExpressionStackAt(0); |
| 3694 HValue* limit = environment()->ExpressionStackAt(1); | 3688 HValue* limit = environment()->ExpressionStackAt(1); |
| 3695 | 3689 |
| 3696 // Check that we still have more keys. | 3690 // Check that we still have more keys. |
| 3697 HCompareNumericAndBranch* compare_index = | 3691 HCompareNumericAndBranch* compare_index = |
| 3698 new(zone()) HCompareNumericAndBranch(index, limit, Token::LT); | 3692 New<HCompareNumericAndBranch>(index, limit, Token::LT); |
| 3699 compare_index->set_observed_input_representation( | 3693 compare_index->set_observed_input_representation( |
| 3700 Representation::Smi(), Representation::Smi()); | 3694 Representation::Smi(), Representation::Smi()); |
| 3701 | 3695 |
| 3702 HBasicBlock* loop_body = graph()->CreateBasicBlock(); | 3696 HBasicBlock* loop_body = graph()->CreateBasicBlock(); |
| 3703 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); | 3697 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); |
| 3704 | 3698 |
| 3705 compare_index->SetSuccessorAt(0, loop_body); | 3699 compare_index->SetSuccessorAt(0, loop_body); |
| 3706 compare_index->SetSuccessorAt(1, loop_successor); | 3700 compare_index->SetSuccessorAt(1, loop_successor); |
| 3707 current_block()->Finish(compare_index); | 3701 current_block()->Finish(compare_index); |
| 3708 | 3702 |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4703 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { | 4697 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { |
| 4704 PropertyAccessInfo info(isolate(), types->at(i), name); | 4698 PropertyAccessInfo info(isolate(), types->at(i), name); |
| 4705 if (info.CanLoadMonomorphic()) { | 4699 if (info.CanLoadMonomorphic()) { |
| 4706 if (count == 0) { | 4700 if (count == 0) { |
| 4707 BuildCheckHeapObject(object); | 4701 BuildCheckHeapObject(object); |
| 4708 join = graph()->CreateBasicBlock(); | 4702 join = graph()->CreateBasicBlock(); |
| 4709 } | 4703 } |
| 4710 ++count; | 4704 ++count; |
| 4711 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4705 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 4712 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4706 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 4713 HCompareMap* compare = new(zone()) HCompareMap( | 4707 HCompareMap* compare = New<HCompareMap>( |
| 4714 object, info.map(), if_true, if_false); | 4708 object, info.map(), if_true, if_false); |
| 4715 current_block()->Finish(compare); | 4709 current_block()->Finish(compare); |
| 4716 | 4710 |
| 4717 set_current_block(if_true); | 4711 set_current_block(if_true); |
| 4718 | 4712 |
| 4719 HInstruction* load = BuildLoadMonomorphic( | 4713 HInstruction* load = BuildLoadMonomorphic( |
| 4720 &info, object, compare, ast_id, return_id, false); | 4714 &info, object, compare, ast_id, return_id, false); |
| 4721 if (load == NULL) { | 4715 if (load == NULL) { |
| 4722 if (HasStackOverflow()) return; | 4716 if (HasStackOverflow()) return; |
| 4723 } else { | 4717 } else { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4842 Handle<Map> map = types->at(i); | 4836 Handle<Map> map = types->at(i); |
| 4843 LookupResult lookup(isolate()); | 4837 LookupResult lookup(isolate()); |
| 4844 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 4838 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
| 4845 if (count == 0) { | 4839 if (count == 0) { |
| 4846 BuildCheckHeapObject(object); | 4840 BuildCheckHeapObject(object); |
| 4847 join = graph()->CreateBasicBlock(); | 4841 join = graph()->CreateBasicBlock(); |
| 4848 } | 4842 } |
| 4849 ++count; | 4843 ++count; |
| 4850 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4844 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 4851 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4845 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 4852 HCompareMap* compare = | 4846 HCompareMap* compare = New<HCompareMap>(object, map, if_true, if_false); |
| 4853 new(zone()) HCompareMap(object, map, if_true, if_false); | |
| 4854 current_block()->Finish(compare); | 4847 current_block()->Finish(compare); |
| 4855 | 4848 |
| 4856 set_current_block(if_true); | 4849 set_current_block(if_true); |
| 4857 HInstruction* instr; | 4850 HInstruction* instr; |
| 4858 CHECK_ALIVE(instr = BuildStoreNamedField( | 4851 CHECK_ALIVE(instr = BuildStoreNamedField( |
| 4859 compare, name, value, map, &lookup)); | 4852 compare, name, value, map, &lookup)); |
| 4860 instr->set_position(position); | 4853 instr->set_position(position); |
| 4861 // Goto will add the HSimulate for the store. | 4854 // Goto will add the HSimulate for the store. |
| 4862 AddInstruction(instr); | 4855 AddInstruction(instr); |
| 4863 if (!ast_context()->IsEffect()) Push(value); | 4856 if (!ast_context()->IsEffect()) Push(value); |
| (...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5565 | 5558 |
| 5566 HBasicBlock* join = graph()->CreateBasicBlock(); | 5559 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 5567 | 5560 |
| 5568 for (int i = 0; i < untransitionable_maps.length(); ++i) { | 5561 for (int i = 0; i < untransitionable_maps.length(); ++i) { |
| 5569 Handle<Map> map = untransitionable_maps[i]; | 5562 Handle<Map> map = untransitionable_maps[i]; |
| 5570 if (!map->IsJSObjectMap()) continue; | 5563 if (!map->IsJSObjectMap()) continue; |
| 5571 ElementsKind elements_kind = map->elements_kind(); | 5564 ElementsKind elements_kind = map->elements_kind(); |
| 5572 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 5565 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
| 5573 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 5566 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
| 5574 HCompareMap* mapcompare = | 5567 HCompareMap* mapcompare = |
| 5575 new(zone()) HCompareMap(object, map, this_map, other_map); | 5568 New<HCompareMap>(object, map, this_map, other_map); |
| 5576 current_block()->Finish(mapcompare); | 5569 current_block()->Finish(mapcompare); |
| 5577 | 5570 |
| 5578 set_current_block(this_map); | 5571 set_current_block(this_map); |
| 5579 HInstruction* access = NULL; | 5572 HInstruction* access = NULL; |
| 5580 if (IsDictionaryElementsKind(elements_kind)) { | 5573 if (IsDictionaryElementsKind(elements_kind)) { |
| 5581 access = is_store | 5574 access = is_store |
| 5582 ? AddInstruction(BuildStoreKeyedGeneric(object, key, val)) | 5575 ? AddInstruction(BuildStoreKeyedGeneric(object, key, val)) |
| 5583 : AddInstruction(BuildLoadKeyedGeneric(object, key)); | 5576 : AddInstruction(BuildLoadKeyedGeneric(object, key)); |
| 5584 } else { | 5577 } else { |
| 5585 ASSERT(IsFastElementsKind(elements_kind) || | 5578 ASSERT(IsFastElementsKind(elements_kind) || |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6033 for (int fn = 0; fn < ordered_functions; ++fn) { | 6026 for (int fn = 0; fn < ordered_functions; ++fn) { |
| 6034 int i = order[fn].index(); | 6027 int i = order[fn].index(); |
| 6035 Handle<Map> map = types->at(i); | 6028 Handle<Map> map = types->at(i); |
| 6036 if (fn == 0) { | 6029 if (fn == 0) { |
| 6037 // Only needed once. | 6030 // Only needed once. |
| 6038 join = graph()->CreateBasicBlock(); | 6031 join = graph()->CreateBasicBlock(); |
| 6039 if (handle_smi) { | 6032 if (handle_smi) { |
| 6040 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); | 6033 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); |
| 6041 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); | 6034 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); |
| 6042 number_block = graph()->CreateBasicBlock(); | 6035 number_block = graph()->CreateBasicBlock(); |
| 6043 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); | 6036 current_block()->Finish(New<HIsSmiAndBranch>( |
| 6044 smicheck->SetSuccessorAt(0, empty_smi_block); | 6037 receiver, empty_smi_block, not_smi_block)); |
| 6045 smicheck->SetSuccessorAt(1, not_smi_block); | |
| 6046 current_block()->Finish(smicheck); | |
| 6047 empty_smi_block->Goto(number_block); | 6038 empty_smi_block->Goto(number_block); |
| 6048 set_current_block(not_smi_block); | 6039 set_current_block(not_smi_block); |
| 6049 } else { | 6040 } else { |
| 6050 BuildCheckHeapObject(receiver); | 6041 BuildCheckHeapObject(receiver); |
| 6051 } | 6042 } |
| 6052 } | 6043 } |
| 6053 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 6044 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 6054 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 6045 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 6055 HUnaryControlInstruction* compare; | 6046 HUnaryControlInstruction* compare; |
| 6056 | 6047 |
| 6057 if (handle_smi && map.is_identical_to(number_marker_map)) { | 6048 if (handle_smi && map.is_identical_to(number_marker_map)) { |
| 6058 compare = new(zone()) HCompareMap( | 6049 compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); |
| 6059 receiver, heap_number_map, if_true, if_false); | |
| 6060 map = initial_number_map; | 6050 map = initial_number_map; |
| 6061 expr->set_number_check( | 6051 expr->set_number_check( |
| 6062 Handle<JSObject>(JSObject::cast(map->prototype()))); | 6052 Handle<JSObject>(JSObject::cast(map->prototype()))); |
| 6063 } else if (map.is_identical_to(string_marker_map)) { | 6053 } else if (map.is_identical_to(string_marker_map)) { |
| 6064 compare = new(zone()) HIsStringAndBranch(receiver); | 6054 compare = New<HIsStringAndBranch>(receiver, if_true, if_false); |
| 6065 compare->SetSuccessorAt(0, if_true); | |
| 6066 compare->SetSuccessorAt(1, if_false); | |
| 6067 map = initial_string_map; | 6055 map = initial_string_map; |
| 6068 expr->set_string_check( | 6056 expr->set_string_check( |
| 6069 Handle<JSObject>(JSObject::cast(map->prototype()))); | 6057 Handle<JSObject>(JSObject::cast(map->prototype()))); |
| 6070 } else { | 6058 } else { |
| 6071 compare = new(zone()) HCompareMap(receiver, map, if_true, if_false); | 6059 compare = New<HCompareMap>(receiver, map, if_true, if_false); |
| 6072 expr->set_map_check(); | 6060 expr->set_map_check(); |
| 6073 } | 6061 } |
| 6074 | 6062 |
| 6075 current_block()->Finish(compare); | 6063 current_block()->Finish(compare); |
| 6076 | 6064 |
| 6077 if (expr->check_type() == NUMBER_CHECK) { | 6065 if (expr->check_type() == NUMBER_CHECK) { |
| 6078 if_true->Goto(number_block); | 6066 if_true->Goto(number_block); |
| 6079 if_true = number_block; | 6067 if_true = number_block; |
| 6080 number_block->SetJoinId(expr->id()); | 6068 number_block->SetJoinId(expr->id()); |
| 6081 } | 6069 } |
| (...skipping 1723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7805 CHECK_ALIVE(VisitForValue(expr->right())); | 7793 CHECK_ALIVE(VisitForValue(expr->right())); |
| 7806 } | 7794 } |
| 7807 return ast_context()->ReturnValue(Pop()); | 7795 return ast_context()->ReturnValue(Pop()); |
| 7808 } | 7796 } |
| 7809 | 7797 |
| 7810 // We need an extra block to maintain edge-split form. | 7798 // We need an extra block to maintain edge-split form. |
| 7811 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | 7799 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| 7812 HBasicBlock* eval_right = graph()->CreateBasicBlock(); | 7800 HBasicBlock* eval_right = graph()->CreateBasicBlock(); |
| 7813 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); | 7801 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); |
| 7814 HBranch* test = is_logical_and | 7802 HBranch* test = is_logical_and |
| 7815 ? new(zone()) HBranch(left_value, expected, eval_right, empty_block) | 7803 ? New<HBranch>(left_value, expected, eval_right, empty_block) |
| 7816 : new(zone()) HBranch(left_value, expected, empty_block, eval_right); | 7804 : New<HBranch>(left_value, expected, empty_block, eval_right); |
| 7817 current_block()->Finish(test); | 7805 current_block()->Finish(test); |
| 7818 | 7806 |
| 7819 set_current_block(eval_right); | 7807 set_current_block(eval_right); |
| 7820 Drop(1); // Value of the left subexpression. | 7808 Drop(1); // Value of the left subexpression. |
| 7821 CHECK_BAILOUT(VisitForValue(expr->right())); | 7809 CHECK_BAILOUT(VisitForValue(expr->right())); |
| 7822 | 7810 |
| 7823 HBasicBlock* join_block = | 7811 HBasicBlock* join_block = |
| 7824 CreateJoin(empty_block, current_block(), expr->id()); | 7812 CreateJoin(empty_block, current_block(), expr->id()); |
| 7825 set_current_block(join_block); | 7813 set_current_block(join_block); |
| 7826 return ast_context()->ReturnValue(Pop()); | 7814 return ast_context()->ReturnValue(Pop()); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8029 HCompareObjectEqAndBranch* result = | 8017 HCompareObjectEqAndBranch* result = |
| 8030 New<HCompareObjectEqAndBranch>(left, right); | 8018 New<HCompareObjectEqAndBranch>(left, right); |
| 8031 result->set_position(expr->position()); | 8019 result->set_position(expr->position()); |
| 8032 return ast_context()->ReturnControl(result, expr->id()); | 8020 return ast_context()->ReturnControl(result, expr->id()); |
| 8033 } else { | 8021 } else { |
| 8034 BuildCheckHeapObject(left); | 8022 BuildCheckHeapObject(left); |
| 8035 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); | 8023 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
| 8036 BuildCheckHeapObject(right); | 8024 BuildCheckHeapObject(right); |
| 8037 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); | 8025 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
| 8038 HCompareObjectEqAndBranch* result = | 8026 HCompareObjectEqAndBranch* result = |
| 8039 new(zone()) HCompareObjectEqAndBranch(left, right); | 8027 New<HCompareObjectEqAndBranch>(left, right); |
| 8040 result->set_position(expr->position()); | 8028 result->set_position(expr->position()); |
| 8041 return ast_context()->ReturnControl(result, expr->id()); | 8029 return ast_context()->ReturnControl(result, expr->id()); |
| 8042 } | 8030 } |
| 8043 } | 8031 } |
| 8044 default: | 8032 default: |
| 8045 return Bailout(kUnsupportedNonPrimitiveCompare); | 8033 return Bailout(kUnsupportedNonPrimitiveCompare); |
| 8046 } | 8034 } |
| 8047 } else if (combined_type->Is(Type::InternalizedString()) && | 8035 } else if (combined_type->Is(Type::InternalizedString()) && |
| 8048 Token::IsEqualityOp(op)) { | 8036 Token::IsEqualityOp(op)) { |
| 8049 BuildCheckHeapObject(left); | 8037 BuildCheckHeapObject(left); |
| 8050 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); | 8038 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); |
| 8051 BuildCheckHeapObject(right); | 8039 BuildCheckHeapObject(right); |
| 8052 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); | 8040 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); |
| 8053 HCompareObjectEqAndBranch* result = | 8041 HCompareObjectEqAndBranch* result = |
| 8054 new(zone()) HCompareObjectEqAndBranch(left, right); | 8042 New<HCompareObjectEqAndBranch>(left, right); |
| 8055 result->set_position(expr->position()); | 8043 result->set_position(expr->position()); |
| 8056 return ast_context()->ReturnControl(result, expr->id()); | 8044 return ast_context()->ReturnControl(result, expr->id()); |
| 8057 } else { | 8045 } else { |
| 8058 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 8046 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
| 8059 HCompareGeneric* result = | 8047 HCompareGeneric* result = |
| 8060 new(zone()) HCompareGeneric(context, left, right, op); | 8048 new(zone()) HCompareGeneric(context, left, right, op); |
| 8061 result->set_observed_input_representation(1, left_rep); | 8049 result->set_observed_input_representation(1, left_rep); |
| 8062 result->set_observed_input_representation(2, right_rep); | 8050 result->set_observed_input_representation(2, right_rep); |
| 8063 result->set_position(expr->position()); | 8051 result->set_position(expr->position()); |
| 8064 return ast_context()->ReturnInstruction(result, expr->id()); | 8052 return ast_context()->ReturnInstruction(result, expr->id()); |
| 8065 } else { | 8053 } else { |
| 8066 HCompareNumericAndBranch* result = | 8054 HCompareNumericAndBranch* result = |
| 8067 new(zone()) HCompareNumericAndBranch(left, right, op); | 8055 New<HCompareNumericAndBranch>(left, right, op); |
| 8068 result->set_observed_input_representation(left_rep, right_rep); | 8056 result->set_observed_input_representation(left_rep, right_rep); |
| 8069 result->set_position(expr->position()); | 8057 result->set_position(expr->position()); |
| 8070 return ast_context()->ReturnControl(result, expr->id()); | 8058 return ast_context()->ReturnControl(result, expr->id()); |
| 8071 } | 8059 } |
| 8072 } | 8060 } |
| 8073 } | 8061 } |
| 8074 | 8062 |
| 8075 | 8063 |
| 8076 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 8064 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 8077 Expression* sub_expr, | 8065 Expression* sub_expr, |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8499 UNREACHABLE(); | 8487 UNREACHABLE(); |
| 8500 } | 8488 } |
| 8501 | 8489 |
| 8502 | 8490 |
| 8503 // Generators for inline runtime functions. | 8491 // Generators for inline runtime functions. |
| 8504 // Support for types. | 8492 // Support for types. |
| 8505 void HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { | 8493 void HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { |
| 8506 ASSERT(call->arguments()->length() == 1); | 8494 ASSERT(call->arguments()->length() == 1); |
| 8507 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8495 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 8508 HValue* value = Pop(); | 8496 HValue* value = Pop(); |
| 8509 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value); | 8497 HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value); |
| 8510 return ast_context()->ReturnControl(result, call->id()); | 8498 return ast_context()->ReturnControl(result, call->id()); |
| 8511 } | 8499 } |
| 8512 | 8500 |
| 8513 | 8501 |
| 8514 void HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { | 8502 void HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { |
| 8515 ASSERT(call->arguments()->length() == 1); | 8503 ASSERT(call->arguments()->length() == 1); |
| 8516 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8504 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 8517 HValue* value = Pop(); | 8505 HValue* value = Pop(); |
| 8518 HHasInstanceTypeAndBranch* result = | 8506 HHasInstanceTypeAndBranch* result = |
| 8519 new(zone()) HHasInstanceTypeAndBranch(value, | 8507 new(zone()) HHasInstanceTypeAndBranch(value, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8560 HHasInstanceTypeAndBranch* result = | 8548 HHasInstanceTypeAndBranch* result = |
| 8561 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE); | 8549 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE); |
| 8562 return ast_context()->ReturnControl(result, call->id()); | 8550 return ast_context()->ReturnControl(result, call->id()); |
| 8563 } | 8551 } |
| 8564 | 8552 |
| 8565 | 8553 |
| 8566 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { | 8554 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { |
| 8567 ASSERT(call->arguments()->length() == 1); | 8555 ASSERT(call->arguments()->length() == 1); |
| 8568 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8556 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 8569 HValue* value = Pop(); | 8557 HValue* value = Pop(); |
| 8570 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value); | 8558 HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value); |
| 8571 return ast_context()->ReturnControl(result, call->id()); | 8559 return ast_context()->ReturnControl(result, call->id()); |
| 8572 } | 8560 } |
| 8573 | 8561 |
| 8574 | 8562 |
| 8575 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { | 8563 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { |
| 8576 return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi); | 8564 return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi); |
| 8577 } | 8565 } |
| 8578 | 8566 |
| 8579 | 8567 |
| 8580 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { | 8568 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { |
| 8581 ASSERT(call->arguments()->length() == 1); | 8569 ASSERT(call->arguments()->length() == 1); |
| 8582 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8570 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 8583 HValue* value = Pop(); | 8571 HValue* value = Pop(); |
| 8584 HIsUndetectableAndBranch* result = | 8572 HIsUndetectableAndBranch* result = New<HIsUndetectableAndBranch>(value); |
| 8585 new(zone()) HIsUndetectableAndBranch(value); | |
| 8586 return ast_context()->ReturnControl(result, call->id()); | 8573 return ast_context()->ReturnControl(result, call->id()); |
| 8587 } | 8574 } |
| 8588 | 8575 |
| 8589 | 8576 |
| 8590 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( | 8577 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( |
| 8591 CallRuntime* call) { | 8578 CallRuntime* call) { |
| 8592 return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf); | 8579 return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf); |
| 8593 } | 8580 } |
| 8594 | 8581 |
| 8595 | 8582 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8697 } | 8684 } |
| 8698 | 8685 |
| 8699 | 8686 |
| 8700 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { | 8687 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { |
| 8701 ASSERT(call->arguments()->length() == 2); | 8688 ASSERT(call->arguments()->length() == 2); |
| 8702 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8689 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 8703 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 8690 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 8704 HValue* value = Pop(); | 8691 HValue* value = Pop(); |
| 8705 HValue* object = Pop(); | 8692 HValue* object = Pop(); |
| 8706 // Check if object is a not a smi. | 8693 // Check if object is a not a smi. |
| 8707 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(object); | |
| 8708 HBasicBlock* if_smi = graph()->CreateBasicBlock(); | 8694 HBasicBlock* if_smi = graph()->CreateBasicBlock(); |
| 8709 HBasicBlock* if_heap_object = graph()->CreateBasicBlock(); | 8695 HBasicBlock* if_heap_object = graph()->CreateBasicBlock(); |
| 8710 HBasicBlock* join = graph()->CreateBasicBlock(); | 8696 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 8711 smicheck->SetSuccessorAt(0, if_smi); | 8697 current_block()->Finish(New<HIsSmiAndBranch>(object, if_smi, if_heap_object)); |
| 8712 smicheck->SetSuccessorAt(1, if_heap_object); | |
| 8713 current_block()->Finish(smicheck); | |
| 8714 if_smi->Goto(join); | 8698 if_smi->Goto(join); |
| 8715 | 8699 |
| 8716 // Check if object is a JSValue. | 8700 // Check if object is a JSValue. |
| 8717 set_current_block(if_heap_object); | 8701 set_current_block(if_heap_object); |
| 8718 HHasInstanceTypeAndBranch* typecheck = | 8702 HHasInstanceTypeAndBranch* typecheck = |
| 8719 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); | 8703 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); |
| 8720 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 8704 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
| 8721 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 8705 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
| 8722 typecheck->SetSuccessorAt(0, if_js_value); | 8706 typecheck->SetSuccessorAt(0, if_js_value); |
| 8723 typecheck->SetSuccessorAt(1, not_js_value); | 8707 typecheck->SetSuccessorAt(1, not_js_value); |
| (...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9632 if (ShouldProduceTraceOutput()) { | 9616 if (ShouldProduceTraceOutput()) { |
| 9633 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9617 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9634 } | 9618 } |
| 9635 | 9619 |
| 9636 #ifdef DEBUG | 9620 #ifdef DEBUG |
| 9637 graph_->Verify(false); // No full verify. | 9621 graph_->Verify(false); // No full verify. |
| 9638 #endif | 9622 #endif |
| 9639 } | 9623 } |
| 9640 | 9624 |
| 9641 } } // namespace v8::internal | 9625 } } // namespace v8::internal |
| OLD | NEW |