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 |