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 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); | 1551 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); |
1552 mask->ChangeRepresentation(Representation::Integer32()); | 1552 mask->ChangeRepresentation(Representation::Integer32()); |
1553 mask->ClearFlag(HValue::kCanOverflow); | 1553 mask->ClearFlag(HValue::kCanOverflow); |
1554 | 1554 |
1555 return BuildUncheckedDictionaryElementLoadHelper(elements, key, | 1555 return BuildUncheckedDictionaryElementLoadHelper(elements, key, |
1556 hash, mask, 0); | 1556 hash, mask, 0); |
1557 } | 1557 } |
1558 | 1558 |
1559 | 1559 |
1560 HValue* HGraphBuilder::BuildNumberToString(HValue* object, | 1560 HValue* HGraphBuilder::BuildNumberToString(HValue* object, |
1561 Handle<Type> type) { | 1561 Type* type) { |
1562 NoObservableSideEffectsScope scope(this); | 1562 NoObservableSideEffectsScope scope(this); |
1563 | 1563 |
1564 // Convert constant numbers at compile time. | 1564 // Convert constant numbers at compile time. |
1565 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { | 1565 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { |
1566 Handle<Object> number = HConstant::cast(object)->handle(isolate()); | 1566 Handle<Object> number = HConstant::cast(object)->handle(isolate()); |
1567 Handle<String> result = isolate()->factory()->NumberToString(number); | 1567 Handle<String> result = isolate()->factory()->NumberToString(number); |
1568 return Add<HConstant>(result); | 1568 return Add<HConstant>(result); |
1569 } | 1569 } |
1570 | 1570 |
1571 // Create a joinable continuation. | 1571 // Create a joinable continuation. |
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2527 Add<HStoreKeyed>(object_elements, key_constant, value, kind); | 2527 Add<HStoreKeyed>(object_elements, key_constant, value, kind); |
2528 } | 2528 } |
2529 } | 2529 } |
2530 | 2530 |
2531 return object; | 2531 return object; |
2532 } | 2532 } |
2533 | 2533 |
2534 | 2534 |
2535 void HGraphBuilder::BuildCompareNil( | 2535 void HGraphBuilder::BuildCompareNil( |
2536 HValue* value, | 2536 HValue* value, |
2537 Handle<Type> type, | 2537 Type* type, |
2538 HIfContinuation* continuation) { | 2538 HIfContinuation* continuation) { |
2539 IfBuilder if_nil(this); | 2539 IfBuilder if_nil(this); |
2540 bool some_case_handled = false; | 2540 bool some_case_handled = false; |
2541 bool some_case_missing = false; | 2541 bool some_case_missing = false; |
2542 | 2542 |
2543 if (type->Maybe(Type::Null())) { | 2543 if (type->Maybe(Type::Null())) { |
2544 if (some_case_handled) if_nil.Or(); | 2544 if (some_case_handled) if_nil.Or(); |
2545 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); | 2545 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); |
2546 some_case_handled = true; | 2546 some_case_handled = true; |
2547 } else { | 2547 } else { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2825 ast_context_(NULL), | 2825 ast_context_(NULL), |
2826 break_scope_(NULL), | 2826 break_scope_(NULL), |
2827 inlined_count_(0), | 2827 inlined_count_(0), |
2828 globals_(10, info->zone()), | 2828 globals_(10, info->zone()), |
2829 inline_bailout_(false), | 2829 inline_bailout_(false), |
2830 osr_(new(info->zone()) HOsrBuilder(this)) { | 2830 osr_(new(info->zone()) HOsrBuilder(this)) { |
2831 // This is not initialized in the initializer list because the | 2831 // This is not initialized in the initializer list because the |
2832 // constructor for the initial state relies on function_state_ == NULL | 2832 // constructor for the initial state relies on function_state_ == NULL |
2833 // to know it's the initial state. | 2833 // to know it's the initial state. |
2834 function_state_= &initial_function_state_; | 2834 function_state_= &initial_function_state_; |
2835 InitializeAstVisitor(info->isolate()); | 2835 InitializeAstVisitor(info->zone()); |
2836 if (FLAG_emit_opt_code_positions) { | 2836 if (FLAG_emit_opt_code_positions) { |
2837 SetSourcePosition(info->shared_info()->start_position()); | 2837 SetSourcePosition(info->shared_info()->start_position()); |
2838 } | 2838 } |
2839 } | 2839 } |
2840 | 2840 |
2841 | 2841 |
2842 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, | 2842 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, |
2843 HBasicBlock* second, | 2843 HBasicBlock* second, |
2844 BailoutId join_id) { | 2844 BailoutId join_id) { |
2845 if (first == NULL) { | 2845 if (first == NULL) { |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4152 ZoneList<CaseClause*>* clauses = stmt->cases(); | 4152 ZoneList<CaseClause*>* clauses = stmt->cases(); |
4153 int clause_count = clauses->length(); | 4153 int clause_count = clauses->length(); |
4154 ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); | 4154 ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); |
4155 if (clause_count > kCaseClauseLimit) { | 4155 if (clause_count > kCaseClauseLimit) { |
4156 return Bailout(kSwitchStatementTooManyClauses); | 4156 return Bailout(kSwitchStatementTooManyClauses); |
4157 } | 4157 } |
4158 | 4158 |
4159 CHECK_ALIVE(VisitForValue(stmt->tag())); | 4159 CHECK_ALIVE(VisitForValue(stmt->tag())); |
4160 Add<HSimulate>(stmt->EntryId()); | 4160 Add<HSimulate>(stmt->EntryId()); |
4161 HValue* tag_value = Top(); | 4161 HValue* tag_value = Top(); |
4162 Handle<Type> tag_type = stmt->tag()->bounds().lower; | 4162 Type* tag_type = stmt->tag()->bounds().lower; |
4163 | 4163 |
4164 // 1. Build all the tests, with dangling true branches | 4164 // 1. Build all the tests, with dangling true branches |
4165 BailoutId default_id = BailoutId::None(); | 4165 BailoutId default_id = BailoutId::None(); |
4166 for (int i = 0; i < clause_count; ++i) { | 4166 for (int i = 0; i < clause_count; ++i) { |
4167 CaseClause* clause = clauses->at(i); | 4167 CaseClause* clause = clauses->at(i); |
4168 if (clause->is_default()) { | 4168 if (clause->is_default()) { |
4169 body_blocks.Add(NULL, zone()); | 4169 body_blocks.Add(NULL, zone()); |
4170 if (default_id.IsNone()) default_id = clause->EntryId(); | 4170 if (default_id.IsNone()) default_id = clause->EntryId(); |
4171 continue; | 4171 continue; |
4172 } | 4172 } |
4173 | 4173 |
4174 // Generate a compare and branch. | 4174 // Generate a compare and branch. |
4175 CHECK_ALIVE(VisitForValue(clause->label())); | 4175 CHECK_ALIVE(VisitForValue(clause->label())); |
4176 HValue* label_value = Pop(); | 4176 HValue* label_value = Pop(); |
4177 | 4177 |
4178 Handle<Type> label_type = clause->label()->bounds().lower; | 4178 Type* label_type = clause->label()->bounds().lower; |
4179 Handle<Type> combined_type = clause->compare_type(); | 4179 Type* combined_type = clause->compare_type(); |
4180 HControlInstruction* compare = BuildCompareInstruction( | 4180 HControlInstruction* compare = BuildCompareInstruction( |
4181 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, | 4181 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, |
4182 combined_type, stmt->tag()->position(), clause->label()->position(), | 4182 combined_type, stmt->tag()->position(), clause->label()->position(), |
4183 clause->id()); | 4183 clause->id()); |
4184 | 4184 |
4185 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 4185 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
4186 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 4186 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
4187 body_blocks.Add(body_block, zone()); | 4187 body_blocks.Add(body_block, zone()); |
4188 compare->SetSuccessorAt(0, body_block); | 4188 compare->SetSuccessorAt(0, body_block); |
4189 compare->SetSuccessorAt(1, next_test_block); | 4189 compare->SetSuccessorAt(1, next_test_block); |
(...skipping 4177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8367 CreateJoin(materialize_false, materialize_true, expr->id()); | 8367 CreateJoin(materialize_false, materialize_true, expr->id()); |
8368 set_current_block(join); | 8368 set_current_block(join); |
8369 if (join != NULL) return ast_context()->ReturnValue(Pop()); | 8369 if (join != NULL) return ast_context()->ReturnValue(Pop()); |
8370 } | 8370 } |
8371 | 8371 |
8372 | 8372 |
8373 HInstruction* HOptimizedGraphBuilder::BuildIncrement( | 8373 HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
8374 bool returns_original_input, | 8374 bool returns_original_input, |
8375 CountOperation* expr) { | 8375 CountOperation* expr) { |
8376 // The input to the count operation is on top of the expression stack. | 8376 // The input to the count operation is on top of the expression stack. |
8377 Handle<Type> info = expr->type(); | 8377 Representation rep = Representation::FromType(expr->type()); |
8378 Representation rep = Representation::FromType(info); | |
8379 if (rep.IsNone() || rep.IsTagged()) { | 8378 if (rep.IsNone() || rep.IsTagged()) { |
8380 rep = Representation::Smi(); | 8379 rep = Representation::Smi(); |
8381 } | 8380 } |
8382 | 8381 |
8383 if (returns_original_input) { | 8382 if (returns_original_input) { |
8384 // We need an explicit HValue representing ToNumber(input). The | 8383 // We need an explicit HValue representing ToNumber(input). The |
8385 // actual HChange instruction we need is (sometimes) added in a later | 8384 // actual HChange instruction we need is (sometimes) added in a later |
8386 // phase, so it is not available now to be used as an input to HAdd and | 8385 // phase, so it is not available now to be used as an input to HAdd and |
8387 // as the return value. | 8386 // as the return value. |
8388 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); | 8387 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8623 if (right_const->HasInteger32Value() && | 8622 if (right_const->HasInteger32Value() && |
8624 (right_const->Integer32Value() & 0x1f) != 0) { | 8623 (right_const->Integer32Value() & 0x1f) != 0) { |
8625 return false; | 8624 return false; |
8626 } | 8625 } |
8627 } | 8626 } |
8628 return true; | 8627 return true; |
8629 } | 8628 } |
8630 | 8629 |
8631 | 8630 |
8632 HValue* HGraphBuilder::EnforceNumberType(HValue* number, | 8631 HValue* HGraphBuilder::EnforceNumberType(HValue* number, |
8633 Handle<Type> expected) { | 8632 Type* expected) { |
8634 if (expected->Is(Type::Smi())) { | 8633 if (expected->Is(Type::Smi())) { |
8635 return AddUncasted<HForceRepresentation>(number, Representation::Smi()); | 8634 return AddUncasted<HForceRepresentation>(number, Representation::Smi()); |
8636 } | 8635 } |
8637 if (expected->Is(Type::Signed32())) { | 8636 if (expected->Is(Type::Signed32())) { |
8638 return AddUncasted<HForceRepresentation>(number, | 8637 return AddUncasted<HForceRepresentation>(number, |
8639 Representation::Integer32()); | 8638 Representation::Integer32()); |
8640 } | 8639 } |
8641 return number; | 8640 return number; |
8642 } | 8641 } |
8643 | 8642 |
8644 | 8643 |
8645 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { | 8644 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { |
8646 if (value->IsConstant()) { | 8645 if (value->IsConstant()) { |
8647 HConstant* constant = HConstant::cast(value); | 8646 HConstant* constant = HConstant::cast(value); |
8648 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); | 8647 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); |
8649 if (number.has_value) { | 8648 if (number.has_value) { |
8650 *expected = Type::Number(isolate()); | 8649 *expected = Type::Number(zone()); |
8651 return AddInstruction(number.value); | 8650 return AddInstruction(number.value); |
8652 } | 8651 } |
8653 } | 8652 } |
8654 | 8653 |
8655 // We put temporary values on the stack, which don't correspond to anything | 8654 // We put temporary values on the stack, which don't correspond to anything |
8656 // in baseline code. Since nothing is observable we avoid recording those | 8655 // in baseline code. Since nothing is observable we avoid recording those |
8657 // pushes with a NoObservableSideEffectsScope. | 8656 // pushes with a NoObservableSideEffectsScope. |
8658 NoObservableSideEffectsScope no_effects(this); | 8657 NoObservableSideEffectsScope no_effects(this); |
8659 | 8658 |
8660 Handle<Type> expected_type = *expected; | 8659 Type* expected_type = *expected; |
8661 | 8660 |
8662 // Separate the number type from the rest. | 8661 // Separate the number type from the rest. |
8663 Handle<Type> expected_obj = Type::Intersect( | 8662 Type* expected_obj = |
8664 expected_type, Type::NonNumber(isolate()), isolate()); | 8663 Type::Intersect(expected_type, Type::NonNumber(zone()), zone()); |
8665 Handle<Type> expected_number = Type::Intersect( | 8664 Type* expected_number = |
8666 expected_type, Type::Number(isolate()), isolate()); | 8665 Type::Intersect(expected_type, Type::Number(zone()), zone()); |
8667 | 8666 |
8668 // We expect to get a number. | 8667 // We expect to get a number. |
8669 // (We need to check first, since Type::None->Is(Type::Any()) == true. | 8668 // (We need to check first, since Type::None->Is(Type::Any()) == true. |
8670 if (expected_obj->Is(Type::None())) { | 8669 if (expected_obj->Is(Type::None())) { |
8671 ASSERT(!expected_number->Is(Type::None())); | 8670 ASSERT(!expected_number->Is(Type::None(zone()))); |
8672 return value; | 8671 return value; |
8673 } | 8672 } |
8674 | 8673 |
8675 if (expected_obj->Is(Type::Undefined())) { | 8674 if (expected_obj->Is(Type::Undefined(zone()))) { |
8676 // This is already done by HChange. | 8675 // This is already done by HChange. |
8677 *expected = Type::Union( | 8676 *expected = Type::Union(expected_number, Type::Double(zone()), zone()); |
8678 expected_number, Type::Double(isolate()), isolate()); | |
8679 return value; | 8677 return value; |
8680 } | 8678 } |
8681 | 8679 |
8682 return value; | 8680 return value; |
8683 } | 8681 } |
8684 | 8682 |
8685 | 8683 |
8686 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( | 8684 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( |
8687 BinaryOperation* expr, | 8685 BinaryOperation* expr, |
8688 HValue* left, | 8686 HValue* left, |
8689 HValue* right) { | 8687 HValue* right) { |
8690 Handle<Type> left_type = expr->left()->bounds().lower; | 8688 Type* left_type = expr->left()->bounds().lower; |
8691 Handle<Type> right_type = expr->right()->bounds().lower; | 8689 Type* right_type = expr->right()->bounds().lower; |
8692 Handle<Type> result_type = expr->bounds().lower; | 8690 Type* result_type = expr->bounds().lower; |
8693 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 8691 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
8694 | 8692 |
8695 HValue* result = HGraphBuilder::BuildBinaryOperation( | 8693 HValue* result = HGraphBuilder::BuildBinaryOperation( |
8696 expr->op(), left, right, left_type, right_type, | 8694 expr->op(), left, right, left_type, right_type, |
8697 result_type, fixed_right_arg); | 8695 result_type, fixed_right_arg); |
8698 // Add a simulate after instructions with observable side effects, and | 8696 // Add a simulate after instructions with observable side effects, and |
8699 // after phis, which are the result of BuildBinaryOperation when we | 8697 // after phis, which are the result of BuildBinaryOperation when we |
8700 // inlined some complex subgraph. | 8698 // inlined some complex subgraph. |
8701 if (result->HasObservableSideEffects() || result->IsPhi()) { | 8699 if (result->HasObservableSideEffects() || result->IsPhi()) { |
8702 Push(result); | 8700 Push(result); |
8703 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8701 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
8704 Drop(1); | 8702 Drop(1); |
8705 } | 8703 } |
8706 return result; | 8704 return result; |
8707 } | 8705 } |
8708 | 8706 |
8709 | 8707 |
8710 HValue* HGraphBuilder::BuildBinaryOperation( | 8708 HValue* HGraphBuilder::BuildBinaryOperation( |
8711 Token::Value op, | 8709 Token::Value op, |
8712 HValue* left, | 8710 HValue* left, |
8713 HValue* right, | 8711 HValue* right, |
8714 Handle<Type> left_type, | 8712 Type* left_type, |
8715 Handle<Type> right_type, | 8713 Type* right_type, |
8716 Handle<Type> result_type, | 8714 Type* result_type, |
8717 Maybe<int> fixed_right_arg) { | 8715 Maybe<int> fixed_right_arg) { |
8718 | 8716 |
8719 Representation left_rep = Representation::FromType(left_type); | 8717 Representation left_rep = Representation::FromType(left_type); |
8720 Representation right_rep = Representation::FromType(right_type); | 8718 Representation right_rep = Representation::FromType(right_type); |
8721 | 8719 |
8722 bool maybe_string_add = op == Token::ADD && | 8720 bool maybe_string_add = op == Token::ADD && |
8723 (left_type->Maybe(Type::String()) || | 8721 (left_type->Maybe(Type::String()) || |
8724 right_type->Maybe(Type::String())); | 8722 right_type->Maybe(Type::String())); |
8725 | 8723 |
8726 if (left_type->Is(Type::None())) { | 8724 if (left_type->Is(Type::None())) { |
8727 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", | 8725 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", |
8728 Deoptimizer::SOFT); | 8726 Deoptimizer::SOFT); |
8729 // TODO(rossberg): we should be able to get rid of non-continuous | 8727 // TODO(rossberg): we should be able to get rid of non-continuous |
8730 // defaults. | 8728 // defaults. |
8731 left_type = Type::Any(isolate()); | 8729 left_type = Type::Any(zone()); |
8732 } else { | 8730 } else { |
8733 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); | 8731 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); |
8734 left_rep = Representation::FromType(left_type); | 8732 left_rep = Representation::FromType(left_type); |
8735 } | 8733 } |
8736 | 8734 |
8737 if (right_type->Is(Type::None())) { | 8735 if (right_type->Is(Type::None())) { |
8738 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", | 8736 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", |
8739 Deoptimizer::SOFT); | 8737 Deoptimizer::SOFT); |
8740 right_type = Type::Any(isolate()); | 8738 right_type = Type::Any(zone()); |
8741 } else { | 8739 } else { |
8742 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); | 8740 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); |
8743 right_rep = Representation::FromType(right_type); | 8741 right_rep = Representation::FromType(right_type); |
8744 } | 8742 } |
8745 | 8743 |
8746 // Special case for string addition here. | 8744 // Special case for string addition here. |
8747 if (op == Token::ADD && | 8745 if (op == Token::ADD && |
8748 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 8746 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { |
8749 // Validate type feedback for left argument. | 8747 // Validate type feedback for left argument. |
8750 if (left_type->Is(Type::String())) { | 8748 if (left_type->Is(Type::String())) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9096 CallRuntime* call = expr->left()->AsCallRuntime(); | 9094 CallRuntime* call = expr->left()->AsCallRuntime(); |
9097 ASSERT(call->arguments()->length() == 1); | 9095 ASSERT(call->arguments()->length() == 1); |
9098 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9096 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9099 HValue* value = Pop(); | 9097 HValue* value = Pop(); |
9100 Literal* literal = expr->right()->AsLiteral(); | 9098 Literal* literal = expr->right()->AsLiteral(); |
9101 Handle<String> rhs = Handle<String>::cast(literal->value()); | 9099 Handle<String> rhs = Handle<String>::cast(literal->value()); |
9102 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); | 9100 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); |
9103 return ast_context()->ReturnControl(instr, expr->id()); | 9101 return ast_context()->ReturnControl(instr, expr->id()); |
9104 } | 9102 } |
9105 | 9103 |
9106 Handle<Type> left_type = expr->left()->bounds().lower; | 9104 Type* left_type = expr->left()->bounds().lower; |
9107 Handle<Type> right_type = expr->right()->bounds().lower; | 9105 Type* right_type = expr->right()->bounds().lower; |
9108 Handle<Type> combined_type = expr->combined_type(); | 9106 Type* combined_type = expr->combined_type(); |
9109 | 9107 |
9110 CHECK_ALIVE(VisitForValue(expr->left())); | 9108 CHECK_ALIVE(VisitForValue(expr->left())); |
9111 CHECK_ALIVE(VisitForValue(expr->right())); | 9109 CHECK_ALIVE(VisitForValue(expr->right())); |
9112 | 9110 |
9113 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9111 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); |
9114 | 9112 |
9115 HValue* right = Pop(); | 9113 HValue* right = Pop(); |
9116 HValue* left = Pop(); | 9114 HValue* left = Pop(); |
9117 Token::Value op = expr->op(); | 9115 Token::Value op = expr->op(); |
9118 | 9116 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9175 expr->left()->position(), expr->right()->position(), expr->id()); | 9173 expr->left()->position(), expr->right()->position(), expr->id()); |
9176 if (compare == NULL) return; // Bailed out. | 9174 if (compare == NULL) return; // Bailed out. |
9177 return ast_context()->ReturnControl(compare, expr->id()); | 9175 return ast_context()->ReturnControl(compare, expr->id()); |
9178 } | 9176 } |
9179 | 9177 |
9180 | 9178 |
9181 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( | 9179 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( |
9182 Token::Value op, | 9180 Token::Value op, |
9183 HValue* left, | 9181 HValue* left, |
9184 HValue* right, | 9182 HValue* right, |
9185 Handle<Type> left_type, | 9183 Type* left_type, |
9186 Handle<Type> right_type, | 9184 Type* right_type, |
9187 Handle<Type> combined_type, | 9185 Type* combined_type, |
9188 int left_position, | 9186 int left_position, |
9189 int right_position, | 9187 int right_position, |
9190 BailoutId bailout_id) { | 9188 BailoutId bailout_id) { |
9191 // Cases handled below depend on collected type feedback. They should | 9189 // Cases handled below depend on collected type feedback. They should |
9192 // soft deoptimize when there is no type feedback. | 9190 // soft deoptimize when there is no type feedback. |
9193 if (combined_type->Is(Type::None())) { | 9191 if (combined_type->Is(Type::None())) { |
9194 Add<HDeoptimize>("Insufficient type feedback for combined type " | 9192 Add<HDeoptimize>("Insufficient type feedback for combined type " |
9195 "of binary operation", | 9193 "of binary operation", |
9196 Deoptimizer::SOFT); | 9194 Deoptimizer::SOFT); |
9197 combined_type = left_type = right_type = Type::Any(isolate()); | 9195 combined_type = left_type = right_type = Type::Any(zone()); |
9198 } | 9196 } |
9199 | 9197 |
9200 Representation left_rep = Representation::FromType(left_type); | 9198 Representation left_rep = Representation::FromType(left_type); |
9201 Representation right_rep = Representation::FromType(right_type); | 9199 Representation right_rep = Representation::FromType(right_type); |
9202 Representation combined_rep = Representation::FromType(combined_type); | 9200 Representation combined_rep = Representation::FromType(combined_type); |
9203 | 9201 |
9204 if (combined_type->Is(Type::Receiver())) { | 9202 if (combined_type->Is(Type::Receiver())) { |
9205 if (Token::IsEqualityOp(op)) { | 9203 if (Token::IsEqualityOp(op)) { |
9206 // Can we get away with map check and not instance type check? | 9204 // Can we get away with map check and not instance type check? |
9207 HValue* operand_to_check = | 9205 HValue* operand_to_check = |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9283 HValue* value = Pop(); | 9281 HValue* value = Pop(); |
9284 if (expr->op() == Token::EQ_STRICT) { | 9282 if (expr->op() == Token::EQ_STRICT) { |
9285 HConstant* nil_constant = nil == kNullValue | 9283 HConstant* nil_constant = nil == kNullValue |
9286 ? graph()->GetConstantNull() | 9284 ? graph()->GetConstantNull() |
9287 : graph()->GetConstantUndefined(); | 9285 : graph()->GetConstantUndefined(); |
9288 HCompareObjectEqAndBranch* instr = | 9286 HCompareObjectEqAndBranch* instr = |
9289 New<HCompareObjectEqAndBranch>(value, nil_constant); | 9287 New<HCompareObjectEqAndBranch>(value, nil_constant); |
9290 return ast_context()->ReturnControl(instr, expr->id()); | 9288 return ast_context()->ReturnControl(instr, expr->id()); |
9291 } else { | 9289 } else { |
9292 ASSERT_EQ(Token::EQ, expr->op()); | 9290 ASSERT_EQ(Token::EQ, expr->op()); |
9293 Handle<Type> type = expr->combined_type()->Is(Type::None()) | 9291 Type* type = expr->combined_type()->Is(Type::None()) |
9294 ? Type::Any(isolate_) : expr->combined_type(); | 9292 ? Type::Any(zone()) : expr->combined_type(); |
9295 HIfContinuation continuation; | 9293 HIfContinuation continuation; |
9296 BuildCompareNil(value, type, &continuation); | 9294 BuildCompareNil(value, type, &continuation); |
9297 return ast_context()->ReturnContinuation(&continuation, expr->id()); | 9295 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
9298 } | 9296 } |
9299 } | 9297 } |
9300 | 9298 |
9301 | 9299 |
9302 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { | 9300 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
9303 // If we share optimized code between different closures, the | 9301 // If we share optimized code between different closures, the |
9304 // this-function is not a constant, except inside an inlined body. | 9302 // this-function is not a constant, except inside an inlined body. |
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10058 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { | 10056 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
10059 return Bailout(kInlinedRuntimeFunctionGetFromCache); | 10057 return Bailout(kInlinedRuntimeFunctionGetFromCache); |
10060 } | 10058 } |
10061 | 10059 |
10062 | 10060 |
10063 // Fast support for number to string. | 10061 // Fast support for number to string. |
10064 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { | 10062 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
10065 ASSERT_EQ(1, call->arguments()->length()); | 10063 ASSERT_EQ(1, call->arguments()->length()); |
10066 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10064 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
10067 HValue* number = Pop(); | 10065 HValue* number = Pop(); |
10068 HValue* result = BuildNumberToString(number, Type::Number(isolate())); | 10066 HValue* result = BuildNumberToString(number, Type::Number(zone())); |
10069 return ast_context()->ReturnValue(result); | 10067 return ast_context()->ReturnValue(result); |
10070 } | 10068 } |
10071 | 10069 |
10072 | 10070 |
10073 // Fast call for custom callbacks. | 10071 // Fast call for custom callbacks. |
10074 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { | 10072 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
10075 // 1 ~ The function to call is not itself an argument to the call. | 10073 // 1 ~ The function to call is not itself an argument to the call. |
10076 int arg_count = call->arguments()->length() - 1; | 10074 int arg_count = call->arguments()->length() - 1; |
10077 ASSERT(arg_count >= 1); // There's always at least a receiver. | 10075 ASSERT(arg_count >= 1); // There's always at least a receiver. |
10078 | 10076 |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10790 if (ShouldProduceTraceOutput()) { | 10788 if (ShouldProduceTraceOutput()) { |
10791 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10789 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10792 } | 10790 } |
10793 | 10791 |
10794 #ifdef DEBUG | 10792 #ifdef DEBUG |
10795 graph_->Verify(false); // No full verify. | 10793 graph_->Verify(false); // No full verify. |
10796 #endif | 10794 #endif |
10797 } | 10795 } |
10798 | 10796 |
10799 } } // namespace v8::internal | 10797 } } // namespace v8::internal |
OLD | NEW |