OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 5739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5750 | 5750 |
5751 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; | 5751 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; |
5752 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5752 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
5753 Runtime::FunctionForId(function_id), | 5753 Runtime::FunctionForId(function_id), |
5754 4); | 5754 4); |
5755 } | 5755 } |
5756 | 5756 |
5757 // The object is expected in the bailout environment during computation | 5757 // The object is expected in the bailout environment during computation |
5758 // of the property values and is the value of the entire expression. | 5758 // of the property values and is the value of the entire expression. |
5759 Push(literal); | 5759 Push(literal); |
5760 | 5760 int store_slot_index = 0; |
5761 for (int i = 0; i < expr->properties()->length(); i++) { | 5761 for (int i = 0; i < expr->properties()->length(); i++) { |
5762 ObjectLiteral::Property* property = expr->properties()->at(i); | 5762 ObjectLiteral::Property* property = expr->properties()->at(i); |
5763 if (property->is_computed_name()) return Bailout(kComputedPropertyName); | 5763 if (property->is_computed_name()) return Bailout(kComputedPropertyName); |
5764 if (property->IsCompileTimeValue()) continue; | 5764 if (property->IsCompileTimeValue()) continue; |
5765 | 5765 |
5766 Literal* key = property->key()->AsLiteral(); | 5766 Literal* key = property->key()->AsLiteral(); |
5767 Expression* value = property->value(); | 5767 Expression* value = property->value(); |
5768 | 5768 |
5769 switch (property->kind()) { | 5769 switch (property->kind()) { |
5770 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 5770 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
5771 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 5771 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
5772 // Fall through. | 5772 // Fall through. |
5773 case ObjectLiteral::Property::COMPUTED: | 5773 case ObjectLiteral::Property::COMPUTED: |
5774 // It is safe to use [[Put]] here because the boilerplate already | 5774 // It is safe to use [[Put]] here because the boilerplate already |
5775 // contains computed properties with an uninitialized value. | 5775 // contains computed properties with an uninitialized value. |
5776 if (key->value()->IsInternalizedString()) { | 5776 if (key->value()->IsInternalizedString()) { |
5777 if (property->emit_store()) { | 5777 if (property->emit_store()) { |
5778 CHECK_ALIVE(VisitForValue(value)); | 5778 CHECK_ALIVE(VisitForValue(value)); |
5779 HValue* value = Pop(); | 5779 HValue* value = Pop(); |
5780 | 5780 |
5781 // Add [[HomeObject]] to function literals. | |
5782 if (FunctionLiteral::NeedsHomeObject(property->value())) { | |
5783 Handle<Symbol> sym = isolate()->factory()->home_object_symbol(); | |
5784 HInstruction* store_home = BuildKeyedGeneric( | |
5785 STORE, NULL, value, Add<HConstant>(sym), literal); | |
5786 AddInstruction(store_home); | |
5787 DCHECK(store_home->HasObservableSideEffects()); | |
5788 Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE); | |
5789 } | |
5790 | |
5791 Handle<Map> map = property->GetReceiverType(); | 5781 Handle<Map> map = property->GetReceiverType(); |
5792 Handle<String> name = key->AsPropertyName(); | 5782 Handle<String> name = key->AsPropertyName(); |
5793 HValue* store; | 5783 HValue* store; |
| 5784 FeedbackVectorICSlot slot = expr->GetNthSlot(store_slot_index++); |
5794 if (map.is_null()) { | 5785 if (map.is_null()) { |
5795 // If we don't know the monomorphic type, do a generic store. | 5786 // If we don't know the monomorphic type, do a generic store. |
5796 CHECK_ALIVE(store = BuildNamedGeneric( | 5787 CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, literal, |
5797 STORE, NULL, literal, name, value)); | 5788 name, value)); |
5798 } else { | 5789 } else { |
5799 PropertyAccessInfo info(this, STORE, map, name); | 5790 PropertyAccessInfo info(this, STORE, map, name); |
5800 if (info.CanAccessMonomorphic()) { | 5791 if (info.CanAccessMonomorphic()) { |
5801 HValue* checked_literal = Add<HCheckMaps>(literal, map); | 5792 HValue* checked_literal = Add<HCheckMaps>(literal, map); |
5802 DCHECK(!info.IsAccessorConstant()); | 5793 DCHECK(!info.IsAccessorConstant()); |
5803 store = BuildMonomorphicAccess( | 5794 store = BuildMonomorphicAccess( |
5804 &info, literal, checked_literal, value, | 5795 &info, literal, checked_literal, value, |
5805 BailoutId::None(), BailoutId::None()); | 5796 BailoutId::None(), BailoutId::None()); |
5806 } else { | 5797 } else { |
5807 CHECK_ALIVE(store = BuildNamedGeneric( | 5798 CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, |
5808 STORE, NULL, literal, name, value)); | 5799 literal, name, value)); |
5809 } | 5800 } |
5810 } | 5801 } |
5811 if (store->IsInstruction()) { | 5802 if (store->IsInstruction()) { |
5812 AddInstruction(HInstruction::cast(store)); | 5803 AddInstruction(HInstruction::cast(store)); |
5813 } | 5804 } |
5814 DCHECK(store->HasObservableSideEffects()); | 5805 DCHECK(store->HasObservableSideEffects()); |
5815 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); | 5806 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); |
| 5807 |
| 5808 // Add [[HomeObject]] to function literals. |
| 5809 if (FunctionLiteral::NeedsHomeObject(property->value())) { |
| 5810 Handle<Symbol> sym = isolate()->factory()->home_object_symbol(); |
| 5811 HInstruction* store_home = BuildNamedGeneric( |
| 5812 STORE, NULL, expr->GetNthSlot(store_slot_index++), value, sym, |
| 5813 literal); |
| 5814 AddInstruction(store_home); |
| 5815 DCHECK(store_home->HasObservableSideEffects()); |
| 5816 Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE); |
| 5817 } |
5816 } else { | 5818 } else { |
5817 CHECK_ALIVE(VisitForEffect(value)); | 5819 CHECK_ALIVE(VisitForEffect(value)); |
5818 } | 5820 } |
5819 break; | 5821 break; |
5820 } | 5822 } |
5821 // Fall through. | 5823 // Fall through. |
5822 case ObjectLiteral::Property::PROTOTYPE: | 5824 case ObjectLiteral::Property::PROTOTYPE: |
5823 case ObjectLiteral::Property::SETTER: | 5825 case ObjectLiteral::Property::SETTER: |
5824 case ObjectLiteral::Property::GETTER: | 5826 case ObjectLiteral::Property::GETTER: |
5825 return Bailout(kObjectLiteralWithComplexProperty); | 5827 return Bailout(kObjectLiteralWithComplexProperty); |
5826 default: UNREACHABLE(); | 5828 default: UNREACHABLE(); |
5827 } | 5829 } |
5828 } | 5830 } |
5829 | 5831 |
| 5832 // Crankshaft may not consume all the slots because it doesn't emit accessors. |
| 5833 DCHECK(!FLAG_vector_stores || store_slot_index <= expr->slot_count()); |
| 5834 |
5830 if (expr->has_function()) { | 5835 if (expr->has_function()) { |
5831 // Return the result of the transformation to fast properties | 5836 // Return the result of the transformation to fast properties |
5832 // instead of the original since this operation changes the map | 5837 // instead of the original since this operation changes the map |
5833 // of the object. This makes sure that the original object won't | 5838 // of the object. This makes sure that the original object won't |
5834 // be used by other optimized code before it is transformed | 5839 // be used by other optimized code before it is transformed |
5835 // (e.g. because of code motion). | 5840 // (e.g. because of code motion). |
5836 HToFastProperties* result = Add<HToFastProperties>(Pop()); | 5841 HToFastProperties* result = Add<HToFastProperties>(Pop()); |
5837 return ast_context()->ReturnValue(result); | 5842 return ast_context()->ReturnValue(result); |
5838 } else { | 5843 } else { |
5839 return ast_context()->ReturnValue(Pop()); | 5844 return ast_context()->ReturnValue(Pop()); |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6454 DCHECK(info->IsDataConstant()); | 6459 DCHECK(info->IsDataConstant()); |
6455 if (info->IsLoad()) { | 6460 if (info->IsLoad()) { |
6456 return New<HConstant>(info->constant()); | 6461 return New<HConstant>(info->constant()); |
6457 } else { | 6462 } else { |
6458 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); | 6463 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); |
6459 } | 6464 } |
6460 } | 6465 } |
6461 | 6466 |
6462 | 6467 |
6463 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( | 6468 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( |
6464 PropertyAccessType access_type, Expression* expr, BailoutId ast_id, | 6469 PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot, |
6465 BailoutId return_id, HValue* object, HValue* value, SmallMapList* maps, | 6470 BailoutId ast_id, BailoutId return_id, HValue* object, HValue* value, |
6466 Handle<String> name) { | 6471 SmallMapList* maps, Handle<String> name) { |
6467 // Something did not match; must use a polymorphic load. | 6472 // Something did not match; must use a polymorphic load. |
6468 int count = 0; | 6473 int count = 0; |
6469 HBasicBlock* join = NULL; | 6474 HBasicBlock* join = NULL; |
6470 HBasicBlock* number_block = NULL; | 6475 HBasicBlock* number_block = NULL; |
6471 bool handled_string = false; | 6476 bool handled_string = false; |
6472 | 6477 |
6473 bool handle_smi = false; | 6478 bool handle_smi = false; |
6474 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); | 6479 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); |
6475 int i; | 6480 int i; |
6476 for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) { | 6481 for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6574 set_current_block(if_false); | 6579 set_current_block(if_false); |
6575 } | 6580 } |
6576 | 6581 |
6577 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 6582 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
6578 // know about and do not want to handle ones we've never seen. Otherwise | 6583 // know about and do not want to handle ones we've never seen. Otherwise |
6579 // use a generic IC. | 6584 // use a generic IC. |
6580 if (count == maps->length() && FLAG_deoptimize_uncommon_cases) { | 6585 if (count == maps->length() && FLAG_deoptimize_uncommon_cases) { |
6581 FinishExitWithHardDeoptimization( | 6586 FinishExitWithHardDeoptimization( |
6582 Deoptimizer::kUnknownMapInPolymorphicAccess); | 6587 Deoptimizer::kUnknownMapInPolymorphicAccess); |
6583 } else { | 6588 } else { |
6584 HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name, | 6589 HInstruction* instr = |
6585 value); | 6590 BuildNamedGeneric(access_type, expr, slot, object, name, value); |
6586 AddInstruction(instr); | 6591 AddInstruction(instr); |
6587 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); | 6592 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); |
6588 | 6593 |
6589 if (join != NULL) { | 6594 if (join != NULL) { |
6590 Goto(join); | 6595 Goto(join); |
6591 } else { | 6596 } else { |
6592 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6597 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6593 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 6598 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
6594 return; | 6599 return; |
6595 } | 6600 } |
(...skipping 27 matching lines...) Expand all Loading... |
6623 | 6628 |
6624 | 6629 |
6625 static bool AreStringTypes(SmallMapList* maps) { | 6630 static bool AreStringTypes(SmallMapList* maps) { |
6626 for (int i = 0; i < maps->length(); i++) { | 6631 for (int i = 0; i < maps->length(); i++) { |
6627 if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; | 6632 if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; |
6628 } | 6633 } |
6629 return true; | 6634 return true; |
6630 } | 6635 } |
6631 | 6636 |
6632 | 6637 |
6633 void HOptimizedGraphBuilder::BuildStore(Expression* expr, | 6638 void HOptimizedGraphBuilder::BuildStore(Expression* expr, Property* prop, |
6634 Property* prop, | 6639 FeedbackVectorICSlot slot, |
6635 BailoutId ast_id, | 6640 BailoutId ast_id, BailoutId return_id, |
6636 BailoutId return_id, | |
6637 bool is_uninitialized) { | 6641 bool is_uninitialized) { |
6638 if (!prop->key()->IsPropertyName()) { | 6642 if (!prop->key()->IsPropertyName()) { |
6639 // Keyed store. | 6643 // Keyed store. |
6640 HValue* value = Pop(); | 6644 HValue* value = Pop(); |
6641 HValue* key = Pop(); | 6645 HValue* key = Pop(); |
6642 HValue* object = Pop(); | 6646 HValue* object = Pop(); |
6643 bool has_side_effects = false; | 6647 bool has_side_effects = false; |
6644 HValue* result = HandleKeyedElementAccess( | 6648 HValue* result = |
6645 object, key, value, expr, ast_id, return_id, STORE, &has_side_effects); | 6649 HandleKeyedElementAccess(object, key, value, expr, slot, ast_id, |
| 6650 return_id, STORE, &has_side_effects); |
6646 if (has_side_effects) { | 6651 if (has_side_effects) { |
6647 if (!ast_context()->IsEffect()) Push(value); | 6652 if (!ast_context()->IsEffect()) Push(value); |
6648 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6653 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6649 if (!ast_context()->IsEffect()) Drop(1); | 6654 if (!ast_context()->IsEffect()) Drop(1); |
6650 } | 6655 } |
6651 if (result == NULL) return; | 6656 if (result == NULL) return; |
6652 return ast_context()->ReturnValue(value); | 6657 return ast_context()->ReturnValue(value); |
6653 } | 6658 } |
6654 | 6659 |
6655 // Named store. | 6660 // Named store. |
6656 HValue* value = Pop(); | 6661 HValue* value = Pop(); |
6657 HValue* object = Pop(); | 6662 HValue* object = Pop(); |
6658 | 6663 |
6659 Literal* key = prop->key()->AsLiteral(); | 6664 Literal* key = prop->key()->AsLiteral(); |
6660 Handle<String> name = Handle<String>::cast(key->value()); | 6665 Handle<String> name = Handle<String>::cast(key->value()); |
6661 DCHECK(!name.is_null()); | 6666 DCHECK(!name.is_null()); |
6662 | 6667 |
6663 HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, object, | 6668 HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, slot, |
6664 name, value, is_uninitialized); | 6669 object, name, value, is_uninitialized); |
6665 if (access == NULL) return; | 6670 if (access == NULL) return; |
6666 | 6671 |
6667 if (!ast_context()->IsEffect()) Push(value); | 6672 if (!ast_context()->IsEffect()) Push(value); |
6668 if (access->IsInstruction()) AddInstruction(HInstruction::cast(access)); | 6673 if (access->IsInstruction()) AddInstruction(HInstruction::cast(access)); |
6669 if (access->HasObservableSideEffects()) { | 6674 if (access->HasObservableSideEffects()) { |
6670 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6675 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6671 } | 6676 } |
6672 if (!ast_context()->IsEffect()) Drop(1); | 6677 if (!ast_context()->IsEffect()) Drop(1); |
6673 return ast_context()->ReturnValue(value); | 6678 return ast_context()->ReturnValue(value); |
6674 } | 6679 } |
6675 | 6680 |
6676 | 6681 |
6677 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 6682 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
6678 Property* prop = expr->target()->AsProperty(); | 6683 Property* prop = expr->target()->AsProperty(); |
6679 DCHECK(prop != NULL); | 6684 DCHECK(prop != NULL); |
6680 CHECK_ALIVE(VisitForValue(prop->obj())); | 6685 CHECK_ALIVE(VisitForValue(prop->obj())); |
6681 if (!prop->key()->IsPropertyName()) { | 6686 if (!prop->key()->IsPropertyName()) { |
6682 CHECK_ALIVE(VisitForValue(prop->key())); | 6687 CHECK_ALIVE(VisitForValue(prop->key())); |
6683 } | 6688 } |
6684 CHECK_ALIVE(VisitForValue(expr->value())); | 6689 CHECK_ALIVE(VisitForValue(expr->value())); |
6685 BuildStore(expr, prop, expr->id(), | 6690 BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), |
6686 expr->AssignmentId(), expr->IsUninitialized()); | 6691 expr->AssignmentId(), expr->IsUninitialized()); |
6687 } | 6692 } |
6688 | 6693 |
6689 | 6694 |
6690 // Because not every expression has a position and there is not common | 6695 // Because not every expression has a position and there is not common |
6691 // superclass of Assignment and CountOperation, we cannot just pass the | 6696 // superclass of Assignment and CountOperation, we cannot just pass the |
6692 // owning expression instead of position and ast_id separately. | 6697 // owning expression instead of position and ast_id separately. |
6693 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6698 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
6694 Variable* var, | 6699 Variable* var, HValue* value, FeedbackVectorICSlot ic_slot, |
6695 HValue* value, | |
6696 BailoutId ast_id) { | 6700 BailoutId ast_id) { |
6697 Handle<GlobalObject> global(current_info()->global_object()); | 6701 Handle<GlobalObject> global(current_info()->global_object()); |
6698 | 6702 |
6699 // Lookup in script contexts. | 6703 // Lookup in script contexts. |
6700 { | 6704 { |
6701 Handle<ScriptContextTable> script_contexts( | 6705 Handle<ScriptContextTable> script_contexts( |
6702 global->native_context()->script_context_table()); | 6706 global->native_context()->script_context_table()); |
6703 ScriptContextTable::LookupResult lookup; | 6707 ScriptContextTable::LookupResult lookup; |
6704 if (ScriptContextTable::Lookup(script_contexts, var->name(), &lookup)) { | 6708 if (ScriptContextTable::Lookup(script_contexts, var->name(), &lookup)) { |
6705 if (lookup.mode == CONST) { | 6709 if (lookup.mode == CONST) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6793 DCHECK(instr->HasObservableSideEffects()); | 6797 DCHECK(instr->HasObservableSideEffects()); |
6794 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6798 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6795 | 6799 |
6796 } else { | 6800 } else { |
6797 HValue* global_object = Add<HLoadNamedField>( | 6801 HValue* global_object = Add<HLoadNamedField>( |
6798 context(), nullptr, | 6802 context(), nullptr, |
6799 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6803 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
6800 HStoreNamedGeneric* instr = | 6804 HStoreNamedGeneric* instr = |
6801 Add<HStoreNamedGeneric>(global_object, var->name(), value, | 6805 Add<HStoreNamedGeneric>(global_object, var->name(), value, |
6802 function_language_mode(), PREMONOMORPHIC); | 6806 function_language_mode(), PREMONOMORPHIC); |
| 6807 if (FLAG_vector_stores) { |
| 6808 Handle<TypeFeedbackVector> vector = |
| 6809 handle(current_feedback_vector(), isolate()); |
| 6810 instr->SetVectorAndSlot(vector, ic_slot); |
| 6811 } |
6803 USE(instr); | 6812 USE(instr); |
6804 DCHECK(instr->HasObservableSideEffects()); | 6813 DCHECK(instr->HasObservableSideEffects()); |
6805 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6814 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6806 } | 6815 } |
6807 } | 6816 } |
6808 | 6817 |
6809 | 6818 |
6810 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 6819 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
6811 Expression* target = expr->target(); | 6820 Expression* target = expr->target(); |
6812 VariableProxy* proxy = target->AsVariableProxy(); | 6821 VariableProxy* proxy = target->AsVariableProxy(); |
6813 Property* prop = target->AsProperty(); | 6822 Property* prop = target->AsProperty(); |
6814 DCHECK(proxy == NULL || prop == NULL); | 6823 DCHECK(proxy == NULL || prop == NULL); |
6815 | 6824 |
6816 // We have a second position recorded in the FullCodeGenerator to have | 6825 // We have a second position recorded in the FullCodeGenerator to have |
6817 // type feedback for the binary operation. | 6826 // type feedback for the binary operation. |
6818 BinaryOperation* operation = expr->binary_operation(); | 6827 BinaryOperation* operation = expr->binary_operation(); |
6819 | 6828 |
6820 if (proxy != NULL) { | 6829 if (proxy != NULL) { |
6821 Variable* var = proxy->var(); | 6830 Variable* var = proxy->var(); |
6822 if (var->mode() == LET) { | 6831 if (var->mode() == LET) { |
6823 return Bailout(kUnsupportedLetCompoundAssignment); | 6832 return Bailout(kUnsupportedLetCompoundAssignment); |
6824 } | 6833 } |
6825 | 6834 |
6826 CHECK_ALIVE(VisitForValue(operation)); | 6835 CHECK_ALIVE(VisitForValue(operation)); |
6827 | 6836 |
6828 switch (var->location()) { | 6837 switch (var->location()) { |
6829 case VariableLocation::GLOBAL: | 6838 case VariableLocation::GLOBAL: |
6830 case VariableLocation::UNALLOCATED: | 6839 case VariableLocation::UNALLOCATED: |
6831 HandleGlobalVariableAssignment(var, | 6840 HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), |
6832 Top(), | |
6833 expr->AssignmentId()); | 6841 expr->AssignmentId()); |
6834 break; | 6842 break; |
6835 | 6843 |
6836 case VariableLocation::PARAMETER: | 6844 case VariableLocation::PARAMETER: |
6837 case VariableLocation::LOCAL: | 6845 case VariableLocation::LOCAL: |
6838 if (var->mode() == CONST_LEGACY) { | 6846 if (var->mode() == CONST_LEGACY) { |
6839 return Bailout(kUnsupportedConstCompoundAssignment); | 6847 return Bailout(kUnsupportedConstCompoundAssignment); |
6840 } | 6848 } |
6841 if (var->mode() == CONST) { | 6849 if (var->mode() == CONST) { |
6842 return Bailout(kNonInitializerAssignmentToConst); | 6850 return Bailout(kNonInitializerAssignmentToConst); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6898 } | 6906 } |
6899 | 6907 |
6900 CHECK_ALIVE(PushLoad(prop, object, key)); | 6908 CHECK_ALIVE(PushLoad(prop, object, key)); |
6901 | 6909 |
6902 CHECK_ALIVE(VisitForValue(expr->value())); | 6910 CHECK_ALIVE(VisitForValue(expr->value())); |
6903 HValue* right = Pop(); | 6911 HValue* right = Pop(); |
6904 HValue* left = Pop(); | 6912 HValue* left = Pop(); |
6905 | 6913 |
6906 Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); | 6914 Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); |
6907 | 6915 |
6908 BuildStore(expr, prop, expr->id(), | 6916 BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), |
6909 expr->AssignmentId(), expr->IsUninitialized()); | 6917 expr->AssignmentId(), expr->IsUninitialized()); |
6910 } else { | 6918 } else { |
6911 return Bailout(kInvalidLhsInCompoundAssignment); | 6919 return Bailout(kInvalidLhsInCompoundAssignment); |
6912 } | 6920 } |
6913 } | 6921 } |
6914 | 6922 |
6915 | 6923 |
6916 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { | 6924 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
6917 DCHECK(!HasStackOverflow()); | 6925 DCHECK(!HasStackOverflow()); |
6918 DCHECK(current_block() != NULL); | 6926 DCHECK(current_block() != NULL); |
(...skipping 30 matching lines...) Expand all Loading... |
6949 } | 6957 } |
6950 } | 6958 } |
6951 | 6959 |
6952 if (proxy->IsArguments()) return Bailout(kAssignmentToArguments); | 6960 if (proxy->IsArguments()) return Bailout(kAssignmentToArguments); |
6953 | 6961 |
6954 // Handle the assignment. | 6962 // Handle the assignment. |
6955 switch (var->location()) { | 6963 switch (var->location()) { |
6956 case VariableLocation::GLOBAL: | 6964 case VariableLocation::GLOBAL: |
6957 case VariableLocation::UNALLOCATED: | 6965 case VariableLocation::UNALLOCATED: |
6958 CHECK_ALIVE(VisitForValue(expr->value())); | 6966 CHECK_ALIVE(VisitForValue(expr->value())); |
6959 HandleGlobalVariableAssignment(var, | 6967 HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), |
6960 Top(), | |
6961 expr->AssignmentId()); | 6968 expr->AssignmentId()); |
6962 return ast_context()->ReturnValue(Pop()); | 6969 return ast_context()->ReturnValue(Pop()); |
6963 | 6970 |
6964 case VariableLocation::PARAMETER: | 6971 case VariableLocation::PARAMETER: |
6965 case VariableLocation::LOCAL: { | 6972 case VariableLocation::LOCAL: { |
6966 // Perform an initialization check for let declared variables | 6973 // Perform an initialization check for let declared variables |
6967 // or parameters. | 6974 // or parameters. |
6968 if (var->mode() == LET && expr->op() == Token::ASSIGN) { | 6975 if (var->mode() == LET && expr->op() == Token::ASSIGN) { |
6969 HValue* env_value = environment()->Lookup(var); | 6976 HValue* env_value = environment()->Lookup(var); |
6970 if (env_value == graph()->GetConstantHole()) { | 6977 if (env_value == graph()->GetConstantHole()) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7097 if (c_string->HasStringValue()) { | 7104 if (c_string->HasStringValue()) { |
7098 return New<HConstant>(c_string->StringValue()->length()); | 7105 return New<HConstant>(c_string->StringValue()->length()); |
7099 } | 7106 } |
7100 } | 7107 } |
7101 return New<HLoadNamedField>(string, nullptr, | 7108 return New<HLoadNamedField>(string, nullptr, |
7102 HObjectAccess::ForStringLength()); | 7109 HObjectAccess::ForStringLength()); |
7103 } | 7110 } |
7104 | 7111 |
7105 | 7112 |
7106 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( | 7113 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
7107 PropertyAccessType access_type, Expression* expr, HValue* object, | 7114 PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot, |
7108 Handle<String> name, HValue* value, bool is_uninitialized) { | 7115 HValue* object, Handle<Name> name, HValue* value, bool is_uninitialized) { |
7109 if (is_uninitialized) { | 7116 if (is_uninitialized) { |
7110 Add<HDeoptimize>( | 7117 Add<HDeoptimize>( |
7111 Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess, | 7118 Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess, |
7112 Deoptimizer::SOFT); | 7119 Deoptimizer::SOFT); |
7113 } | 7120 } |
7114 if (access_type == LOAD) { | 7121 if (access_type == LOAD) { |
7115 Handle<TypeFeedbackVector> vector = | 7122 Handle<TypeFeedbackVector> vector = |
7116 handle(current_feedback_vector(), isolate()); | 7123 handle(current_feedback_vector(), isolate()); |
7117 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); | |
7118 | 7124 |
7119 if (!expr->AsProperty()->key()->IsPropertyName()) { | 7125 if (!expr->AsProperty()->key()->IsPropertyName()) { |
7120 // It's possible that a keyed load of a constant string was converted | 7126 // It's possible that a keyed load of a constant string was converted |
7121 // to a named load. Here, at the last minute, we need to make sure to | 7127 // to a named load. Here, at the last minute, we need to make sure to |
7122 // use a generic Keyed Load if we are using the type vector, because | 7128 // use a generic Keyed Load if we are using the type vector, because |
7123 // it has to share information with full code. | 7129 // it has to share information with full code. |
7124 HConstant* key = Add<HConstant>(name); | 7130 HConstant* key = Add<HConstant>(name); |
7125 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( | 7131 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( |
7126 object, key, function_language_mode(), PREMONOMORPHIC); | 7132 object, key, function_language_mode(), PREMONOMORPHIC); |
7127 result->SetVectorAndSlot(vector, slot); | 7133 result->SetVectorAndSlot(vector, slot); |
7128 return result; | 7134 return result; |
7129 } | 7135 } |
7130 | 7136 |
7131 HLoadNamedGeneric* result = New<HLoadNamedGeneric>( | 7137 HLoadNamedGeneric* result = New<HLoadNamedGeneric>( |
7132 object, name, function_language_mode(), PREMONOMORPHIC); | 7138 object, name, function_language_mode(), PREMONOMORPHIC); |
7133 result->SetVectorAndSlot(vector, slot); | 7139 result->SetVectorAndSlot(vector, slot); |
7134 return result; | 7140 return result; |
7135 } else { | 7141 } else { |
7136 return New<HStoreNamedGeneric>(object, name, value, | 7142 if (FLAG_vector_stores && |
7137 function_language_mode(), PREMONOMORPHIC); | 7143 current_feedback_vector()->GetKind(slot) == Code::KEYED_STORE_IC) { |
| 7144 // It's possible that a keyed store of a constant string was converted |
| 7145 // to a named store. Here, at the last minute, we need to make sure to |
| 7146 // use a generic Keyed Store if we are using the type vector, because |
| 7147 // it has to share information with full code. |
| 7148 HConstant* key = Add<HConstant>(name); |
| 7149 HStoreKeyedGeneric* result = New<HStoreKeyedGeneric>( |
| 7150 object, key, value, function_language_mode(), PREMONOMORPHIC); |
| 7151 Handle<TypeFeedbackVector> vector = |
| 7152 handle(current_feedback_vector(), isolate()); |
| 7153 result->SetVectorAndSlot(vector, slot); |
| 7154 return result; |
| 7155 } |
| 7156 |
| 7157 HStoreNamedGeneric* result = New<HStoreNamedGeneric>( |
| 7158 object, name, value, function_language_mode(), PREMONOMORPHIC); |
| 7159 if (FLAG_vector_stores) { |
| 7160 Handle<TypeFeedbackVector> vector = |
| 7161 handle(current_feedback_vector(), isolate()); |
| 7162 result->SetVectorAndSlot(vector, slot); |
| 7163 } |
| 7164 return result; |
7138 } | 7165 } |
7139 } | 7166 } |
7140 | 7167 |
7141 | 7168 |
7142 | |
7143 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( | 7169 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( |
7144 PropertyAccessType access_type, | 7170 PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot, |
7145 Expression* expr, | 7171 HValue* object, HValue* key, HValue* value) { |
7146 HValue* object, | |
7147 HValue* key, | |
7148 HValue* value) { | |
7149 if (access_type == LOAD) { | 7172 if (access_type == LOAD) { |
7150 InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); | 7173 InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); |
7151 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( | 7174 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( |
7152 object, key, function_language_mode(), initial_state); | 7175 object, key, function_language_mode(), initial_state); |
7153 // HLoadKeyedGeneric with vector ics benefits from being encoded as | 7176 // HLoadKeyedGeneric with vector ics benefits from being encoded as |
7154 // MEGAMORPHIC because the vector/slot combo becomes unnecessary. | 7177 // MEGAMORPHIC because the vector/slot combo becomes unnecessary. |
7155 if (initial_state != MEGAMORPHIC) { | 7178 if (initial_state != MEGAMORPHIC) { |
7156 // We need to pass vector information. | 7179 // We need to pass vector information. |
7157 Handle<TypeFeedbackVector> vector = | 7180 Handle<TypeFeedbackVector> vector = |
7158 handle(current_feedback_vector(), isolate()); | 7181 handle(current_feedback_vector(), isolate()); |
7159 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); | |
7160 result->SetVectorAndSlot(vector, slot); | 7182 result->SetVectorAndSlot(vector, slot); |
7161 } | 7183 } |
7162 return result; | 7184 return result; |
7163 } else { | 7185 } else { |
7164 return New<HStoreKeyedGeneric>(object, key, value, function_language_mode(), | 7186 HStoreKeyedGeneric* result = New<HStoreKeyedGeneric>( |
7165 PREMONOMORPHIC); | 7187 object, key, value, function_language_mode(), PREMONOMORPHIC); |
| 7188 if (FLAG_vector_stores) { |
| 7189 Handle<TypeFeedbackVector> vector = |
| 7190 handle(current_feedback_vector(), isolate()); |
| 7191 result->SetVectorAndSlot(vector, slot); |
| 7192 } |
| 7193 return result; |
7166 } | 7194 } |
7167 } | 7195 } |
7168 | 7196 |
7169 | 7197 |
7170 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { | 7198 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { |
7171 // Loads from a "stock" fast holey double arrays can elide the hole check. | 7199 // Loads from a "stock" fast holey double arrays can elide the hole check. |
7172 // Loads from a "stock" fast holey array can convert the hole to undefined | 7200 // Loads from a "stock" fast holey array can convert the hole to undefined |
7173 // with impunity. | 7201 // with impunity. |
7174 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 7202 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
7175 bool holey_double_elements = | 7203 bool holey_double_elements = |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7292 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 7320 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
7293 checked_object, key, val, | 7321 checked_object, key, val, |
7294 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, | 7322 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
7295 consolidated_elements_kind, | 7323 consolidated_elements_kind, |
7296 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); | 7324 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); |
7297 return instr; | 7325 return instr; |
7298 } | 7326 } |
7299 | 7327 |
7300 | 7328 |
7301 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( | 7329 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
7302 Expression* expr, | 7330 Expression* expr, FeedbackVectorICSlot slot, HValue* object, HValue* key, |
7303 HValue* object, | 7331 HValue* val, SmallMapList* maps, PropertyAccessType access_type, |
7304 HValue* key, | 7332 KeyedAccessStoreMode store_mode, bool* has_side_effects) { |
7305 HValue* val, | |
7306 SmallMapList* maps, | |
7307 PropertyAccessType access_type, | |
7308 KeyedAccessStoreMode store_mode, | |
7309 bool* has_side_effects) { | |
7310 *has_side_effects = false; | 7333 *has_side_effects = false; |
7311 BuildCheckHeapObject(object); | 7334 BuildCheckHeapObject(object); |
7312 | 7335 |
7313 if (access_type == LOAD) { | 7336 if (access_type == LOAD) { |
7314 HInstruction* consolidated_load = | 7337 HInstruction* consolidated_load = |
7315 TryBuildConsolidatedElementLoad(object, key, val, maps); | 7338 TryBuildConsolidatedElementLoad(object, key, val, maps); |
7316 if (consolidated_load != NULL) { | 7339 if (consolidated_load != NULL) { |
7317 *has_side_effects |= consolidated_load->HasObservableSideEffects(); | 7340 *has_side_effects |= consolidated_load->HasObservableSideEffects(); |
7318 return consolidated_load; | 7341 return consolidated_load; |
7319 } | 7342 } |
7320 } | 7343 } |
7321 | 7344 |
7322 // Elements_kind transition support. | 7345 // Elements_kind transition support. |
7323 MapHandleList transition_target(maps->length()); | 7346 MapHandleList transition_target(maps->length()); |
7324 // Collect possible transition targets. | 7347 // Collect possible transition targets. |
7325 MapHandleList possible_transitioned_maps(maps->length()); | 7348 MapHandleList possible_transitioned_maps(maps->length()); |
7326 for (int i = 0; i < maps->length(); ++i) { | 7349 for (int i = 0; i < maps->length(); ++i) { |
7327 Handle<Map> map = maps->at(i); | 7350 Handle<Map> map = maps->at(i); |
7328 // Loads from strings or loads with a mix of string and non-string maps | 7351 // Loads from strings or loads with a mix of string and non-string maps |
7329 // shouldn't be handled polymorphically. | 7352 // shouldn't be handled polymorphically. |
7330 DCHECK(access_type != LOAD || !map->IsStringMap()); | 7353 DCHECK(access_type != LOAD || !map->IsStringMap()); |
7331 ElementsKind elements_kind = map->elements_kind(); | 7354 ElementsKind elements_kind = map->elements_kind(); |
7332 if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) && | 7355 if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) && |
7333 elements_kind != GetInitialFastElementsKind()) { | 7356 elements_kind != GetInitialFastElementsKind()) { |
7334 possible_transitioned_maps.Add(map); | 7357 possible_transitioned_maps.Add(map); |
7335 } | 7358 } |
7336 if (IsSloppyArgumentsElements(elements_kind)) { | 7359 if (IsSloppyArgumentsElements(elements_kind)) { |
7337 HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key, | 7360 HInstruction* result = |
7338 val); | 7361 BuildKeyedGeneric(access_type, expr, slot, object, key, val); |
7339 *has_side_effects = result->HasObservableSideEffects(); | 7362 *has_side_effects = result->HasObservableSideEffects(); |
7340 return AddInstruction(result); | 7363 return AddInstruction(result); |
7341 } | 7364 } |
7342 } | 7365 } |
7343 // Get transition target for each map (NULL == no transition). | 7366 // Get transition target for each map (NULL == no transition). |
7344 for (int i = 0; i < maps->length(); ++i) { | 7367 for (int i = 0; i < maps->length(); ++i) { |
7345 Handle<Map> map = maps->at(i); | 7368 Handle<Map> map = maps->at(i); |
7346 Handle<Map> transitioned_map = | 7369 Handle<Map> transitioned_map = |
7347 Map::FindTransitionedMap(map, &possible_transitioned_maps); | 7370 Map::FindTransitionedMap(map, &possible_transitioned_maps); |
7348 transition_target.Add(transitioned_map); | 7371 transition_target.Add(transitioned_map); |
(...skipping 15 matching lines...) Expand all Loading... |
7364 } | 7387 } |
7365 } | 7388 } |
7366 | 7389 |
7367 // If only one map is left after transitioning, handle this case | 7390 // If only one map is left after transitioning, handle this case |
7368 // monomorphically. | 7391 // monomorphically. |
7369 DCHECK(untransitionable_maps.length() >= 1); | 7392 DCHECK(untransitionable_maps.length() >= 1); |
7370 if (untransitionable_maps.length() == 1) { | 7393 if (untransitionable_maps.length() == 1) { |
7371 Handle<Map> untransitionable_map = untransitionable_maps[0]; | 7394 Handle<Map> untransitionable_map = untransitionable_maps[0]; |
7372 HInstruction* instr = NULL; | 7395 HInstruction* instr = NULL; |
7373 if (!CanInlineElementAccess(untransitionable_map)) { | 7396 if (!CanInlineElementAccess(untransitionable_map)) { |
7374 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, | 7397 instr = AddInstruction( |
7375 val)); | 7398 BuildKeyedGeneric(access_type, expr, slot, object, key, val)); |
7376 } else { | 7399 } else { |
7377 instr = BuildMonomorphicElementAccess( | 7400 instr = BuildMonomorphicElementAccess( |
7378 object, key, val, transition, untransitionable_map, access_type, | 7401 object, key, val, transition, untransitionable_map, access_type, |
7379 store_mode); | 7402 store_mode); |
7380 } | 7403 } |
7381 *has_side_effects |= instr->HasObservableSideEffects(); | 7404 *has_side_effects |= instr->HasObservableSideEffects(); |
7382 return access_type == STORE ? val : instr; | 7405 return access_type == STORE ? val : instr; |
7383 } | 7406 } |
7384 | 7407 |
7385 HBasicBlock* join = graph()->CreateBasicBlock(); | 7408 HBasicBlock* join = graph()->CreateBasicBlock(); |
7386 | 7409 |
7387 for (int i = 0; i < untransitionable_maps.length(); ++i) { | 7410 for (int i = 0; i < untransitionable_maps.length(); ++i) { |
7388 Handle<Map> map = untransitionable_maps[i]; | 7411 Handle<Map> map = untransitionable_maps[i]; |
7389 ElementsKind elements_kind = map->elements_kind(); | 7412 ElementsKind elements_kind = map->elements_kind(); |
7390 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 7413 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
7391 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 7414 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
7392 HCompareMap* mapcompare = | 7415 HCompareMap* mapcompare = |
7393 New<HCompareMap>(object, map, this_map, other_map); | 7416 New<HCompareMap>(object, map, this_map, other_map); |
7394 FinishCurrentBlock(mapcompare); | 7417 FinishCurrentBlock(mapcompare); |
7395 | 7418 |
7396 set_current_block(this_map); | 7419 set_current_block(this_map); |
7397 HInstruction* access = NULL; | 7420 HInstruction* access = NULL; |
7398 if (!CanInlineElementAccess(map)) { | 7421 if (!CanInlineElementAccess(map)) { |
7399 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, | 7422 access = AddInstruction( |
7400 val)); | 7423 BuildKeyedGeneric(access_type, expr, slot, object, key, val)); |
7401 } else { | 7424 } else { |
7402 DCHECK(IsFastElementsKind(elements_kind) || | 7425 DCHECK(IsFastElementsKind(elements_kind) || |
7403 IsFixedTypedArrayElementsKind(elements_kind)); | 7426 IsFixedTypedArrayElementsKind(elements_kind)); |
7404 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 7427 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
7405 // Happily, mapcompare is a checked object. | 7428 // Happily, mapcompare is a checked object. |
7406 access = BuildUncheckedMonomorphicElementAccess( | 7429 access = BuildUncheckedMonomorphicElementAccess( |
7407 mapcompare, key, val, | 7430 mapcompare, key, val, |
7408 map->instance_type() == JS_ARRAY_TYPE, | 7431 map->instance_type() == JS_ARRAY_TYPE, |
7409 elements_kind, access_type, | 7432 elements_kind, access_type, |
7410 load_mode, | 7433 load_mode, |
(...skipping 18 matching lines...) Expand all Loading... |
7429 // Deopt if none of the cases matched. | 7452 // Deopt if none of the cases matched. |
7430 NoObservableSideEffectsScope scope(this); | 7453 NoObservableSideEffectsScope scope(this); |
7431 FinishExitWithHardDeoptimization( | 7454 FinishExitWithHardDeoptimization( |
7432 Deoptimizer::kUnknownMapInPolymorphicElementAccess); | 7455 Deoptimizer::kUnknownMapInPolymorphicElementAccess); |
7433 set_current_block(join); | 7456 set_current_block(join); |
7434 return access_type == STORE ? val : Pop(); | 7457 return access_type == STORE ? val : Pop(); |
7435 } | 7458 } |
7436 | 7459 |
7437 | 7460 |
7438 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( | 7461 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
7439 HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id, | 7462 HValue* obj, HValue* key, HValue* val, Expression* expr, |
7440 BailoutId return_id, PropertyAccessType access_type, | 7463 FeedbackVectorICSlot slot, BailoutId ast_id, BailoutId return_id, |
7441 bool* has_side_effects) { | 7464 PropertyAccessType access_type, bool* has_side_effects) { |
7442 if (key->ActualValue()->IsConstant()) { | 7465 if (key->ActualValue()->IsConstant()) { |
7443 Handle<Object> constant = | 7466 Handle<Object> constant = |
7444 HConstant::cast(key->ActualValue())->handle(isolate()); | 7467 HConstant::cast(key->ActualValue())->handle(isolate()); |
7445 uint32_t array_index; | 7468 uint32_t array_index; |
7446 if (constant->IsString() && | 7469 if (constant->IsString() && |
7447 !Handle<String>::cast(constant)->AsArrayIndex(&array_index)) { | 7470 !Handle<String>::cast(constant)->AsArrayIndex(&array_index)) { |
7448 if (!constant->IsUniqueName()) { | 7471 if (!constant->IsUniqueName()) { |
7449 constant = isolate()->factory()->InternalizeString( | 7472 constant = isolate()->factory()->InternalizeString( |
7450 Handle<String>::cast(constant)); | 7473 Handle<String>::cast(constant)); |
7451 } | 7474 } |
7452 HValue* access = | 7475 HValue* access = |
7453 BuildNamedAccess(access_type, ast_id, return_id, expr, obj, | 7476 BuildNamedAccess(access_type, ast_id, return_id, expr, slot, obj, |
7454 Handle<String>::cast(constant), val, false); | 7477 Handle<String>::cast(constant), val, false); |
7455 if (access == NULL || access->IsPhi() || | 7478 if (access == NULL || access->IsPhi() || |
7456 HInstruction::cast(access)->IsLinked()) { | 7479 HInstruction::cast(access)->IsLinked()) { |
7457 *has_side_effects = false; | 7480 *has_side_effects = false; |
7458 } else { | 7481 } else { |
7459 HInstruction* instr = HInstruction::cast(access); | 7482 HInstruction* instr = HInstruction::cast(access); |
7460 AddInstruction(instr); | 7483 AddInstruction(instr); |
7461 *has_side_effects = instr->HasObservableSideEffects(); | 7484 *has_side_effects = instr->HasObservableSideEffects(); |
7462 } | 7485 } |
7463 return access; | 7486 return access; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7502 if (current_map->IsStringMap()) { | 7525 if (current_map->IsStringMap()) { |
7503 force_generic = true; | 7526 force_generic = true; |
7504 break; | 7527 break; |
7505 } | 7528 } |
7506 } | 7529 } |
7507 } | 7530 } |
7508 | 7531 |
7509 if (monomorphic) { | 7532 if (monomorphic) { |
7510 Handle<Map> map = maps->first(); | 7533 Handle<Map> map = maps->first(); |
7511 if (!CanInlineElementAccess(map)) { | 7534 if (!CanInlineElementAccess(map)) { |
7512 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, | 7535 instr = AddInstruction( |
7513 val)); | 7536 BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); |
7514 } else { | 7537 } else { |
7515 BuildCheckHeapObject(obj); | 7538 BuildCheckHeapObject(obj); |
7516 instr = BuildMonomorphicElementAccess( | 7539 instr = BuildMonomorphicElementAccess( |
7517 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); | 7540 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); |
7518 } | 7541 } |
7519 } else if (!force_generic && (maps != NULL && !maps->is_empty())) { | 7542 } else if (!force_generic && (maps != NULL && !maps->is_empty())) { |
7520 return HandlePolymorphicElementAccess(expr, obj, key, val, maps, | 7543 return HandlePolymorphicElementAccess(expr, slot, obj, key, val, maps, |
7521 access_type, expr->GetStoreMode(), | 7544 access_type, expr->GetStoreMode(), |
7522 has_side_effects); | 7545 has_side_effects); |
7523 } else { | 7546 } else { |
7524 if (access_type == STORE) { | 7547 if (access_type == STORE) { |
7525 if (expr->IsAssignment() && | 7548 if (expr->IsAssignment() && |
7526 expr->AsAssignment()->HasNoTypeInformation()) { | 7549 expr->AsAssignment()->HasNoTypeInformation()) { |
7527 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedStore, | 7550 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedStore, |
7528 Deoptimizer::SOFT); | 7551 Deoptimizer::SOFT); |
7529 } | 7552 } |
7530 } else { | 7553 } else { |
7531 if (expr->AsProperty()->HasNoTypeInformation()) { | 7554 if (expr->AsProperty()->HasNoTypeInformation()) { |
7532 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedLoad, | 7555 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedLoad, |
7533 Deoptimizer::SOFT); | 7556 Deoptimizer::SOFT); |
7534 } | 7557 } |
7535 } | 7558 } |
7536 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val)); | 7559 instr = AddInstruction( |
| 7560 BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); |
7537 } | 7561 } |
7538 *has_side_effects = instr->HasObservableSideEffects(); | 7562 *has_side_effects = instr->HasObservableSideEffects(); |
7539 return instr; | 7563 return instr; |
7540 } | 7564 } |
7541 | 7565 |
7542 | 7566 |
7543 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { | 7567 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { |
7544 // Outermost function already has arguments on the stack. | 7568 // Outermost function already has arguments on the stack. |
7545 if (function_state()->outer() == NULL) return; | 7569 if (function_state()->outer() == NULL) return; |
7546 | 7570 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7614 result = New<HAccessArgumentsAt>(elements, length, checked_key); | 7638 result = New<HAccessArgumentsAt>(elements, length, checked_key); |
7615 } | 7639 } |
7616 } | 7640 } |
7617 ast_context()->ReturnInstruction(result, expr->id()); | 7641 ast_context()->ReturnInstruction(result, expr->id()); |
7618 return true; | 7642 return true; |
7619 } | 7643 } |
7620 | 7644 |
7621 | 7645 |
7622 HValue* HOptimizedGraphBuilder::BuildNamedAccess( | 7646 HValue* HOptimizedGraphBuilder::BuildNamedAccess( |
7623 PropertyAccessType access, BailoutId ast_id, BailoutId return_id, | 7647 PropertyAccessType access, BailoutId ast_id, BailoutId return_id, |
7624 Expression* expr, HValue* object, Handle<String> name, HValue* value, | 7648 Expression* expr, FeedbackVectorICSlot slot, HValue* object, |
7625 bool is_uninitialized) { | 7649 Handle<String> name, HValue* value, bool is_uninitialized) { |
7626 SmallMapList* maps; | 7650 SmallMapList* maps; |
7627 ComputeReceiverTypes(expr, object, &maps, zone()); | 7651 ComputeReceiverTypes(expr, object, &maps, zone()); |
7628 DCHECK(maps != NULL); | 7652 DCHECK(maps != NULL); |
7629 | 7653 |
7630 if (maps->length() > 0) { | 7654 if (maps->length() > 0) { |
7631 PropertyAccessInfo info(this, access, maps->first(), name); | 7655 PropertyAccessInfo info(this, access, maps->first(), name); |
7632 if (!info.CanAccessAsMonomorphic(maps)) { | 7656 if (!info.CanAccessAsMonomorphic(maps)) { |
7633 HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object, | 7657 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, |
7634 value, maps, name); | 7658 object, value, maps, name); |
7635 return NULL; | 7659 return NULL; |
7636 } | 7660 } |
7637 | 7661 |
7638 HValue* checked_object; | 7662 HValue* checked_object; |
7639 // Type::Number() is only supported by polymorphic load/call handling. | 7663 // Type::Number() is only supported by polymorphic load/call handling. |
7640 DCHECK(!info.IsNumberType()); | 7664 DCHECK(!info.IsNumberType()); |
7641 BuildCheckHeapObject(object); | 7665 BuildCheckHeapObject(object); |
7642 if (AreStringTypes(maps)) { | 7666 if (AreStringTypes(maps)) { |
7643 checked_object = | 7667 checked_object = |
7644 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); | 7668 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); |
7645 } else { | 7669 } else { |
7646 checked_object = Add<HCheckMaps>(object, maps); | 7670 checked_object = Add<HCheckMaps>(object, maps); |
7647 } | 7671 } |
7648 return BuildMonomorphicAccess( | 7672 return BuildMonomorphicAccess( |
7649 &info, object, checked_object, value, ast_id, return_id); | 7673 &info, object, checked_object, value, ast_id, return_id); |
7650 } | 7674 } |
7651 | 7675 |
7652 return BuildNamedGeneric(access, expr, object, name, value, is_uninitialized); | 7676 return BuildNamedGeneric(access, expr, slot, object, name, value, |
| 7677 is_uninitialized); |
7653 } | 7678 } |
7654 | 7679 |
7655 | 7680 |
7656 void HOptimizedGraphBuilder::PushLoad(Property* expr, | 7681 void HOptimizedGraphBuilder::PushLoad(Property* expr, |
7657 HValue* object, | 7682 HValue* object, |
7658 HValue* key) { | 7683 HValue* key) { |
7659 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); | 7684 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
7660 Push(object); | 7685 Push(object); |
7661 if (key != NULL) Push(key); | 7686 if (key != NULL) Push(key); |
7662 BuildLoad(expr, expr->LoadId()); | 7687 BuildLoad(expr, expr->LoadId()); |
7663 } | 7688 } |
7664 | 7689 |
7665 | 7690 |
7666 void HOptimizedGraphBuilder::BuildLoad(Property* expr, | 7691 void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
7667 BailoutId ast_id) { | 7692 BailoutId ast_id) { |
7668 HInstruction* instr = NULL; | 7693 HInstruction* instr = NULL; |
7669 if (expr->IsStringAccess()) { | 7694 if (expr->IsStringAccess()) { |
7670 HValue* index = Pop(); | 7695 HValue* index = Pop(); |
7671 HValue* string = Pop(); | 7696 HValue* string = Pop(); |
7672 HInstruction* char_code = BuildStringCharCodeAt(string, index); | 7697 HInstruction* char_code = BuildStringCharCodeAt(string, index); |
7673 AddInstruction(char_code); | 7698 AddInstruction(char_code); |
7674 instr = NewUncasted<HStringCharFromCode>(char_code); | 7699 instr = NewUncasted<HStringCharFromCode>(char_code); |
7675 | 7700 |
7676 } else if (expr->key()->IsPropertyName()) { | 7701 } else if (expr->key()->IsPropertyName()) { |
7677 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7702 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
7678 HValue* object = Pop(); | 7703 HValue* object = Pop(); |
7679 | 7704 |
7680 HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, object, | 7705 HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, |
7681 name, NULL, expr->IsUninitialized()); | 7706 expr->PropertyFeedbackSlot(), object, name, |
| 7707 NULL, expr->IsUninitialized()); |
7682 if (value == NULL) return; | 7708 if (value == NULL) return; |
7683 if (value->IsPhi()) return ast_context()->ReturnValue(value); | 7709 if (value->IsPhi()) return ast_context()->ReturnValue(value); |
7684 instr = HInstruction::cast(value); | 7710 instr = HInstruction::cast(value); |
7685 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); | 7711 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); |
7686 | 7712 |
7687 } else { | 7713 } else { |
7688 HValue* key = Pop(); | 7714 HValue* key = Pop(); |
7689 HValue* obj = Pop(); | 7715 HValue* obj = Pop(); |
7690 | 7716 |
7691 bool has_side_effects = false; | 7717 bool has_side_effects = false; |
7692 HValue* load = HandleKeyedElementAccess( | 7718 HValue* load = HandleKeyedElementAccess( |
7693 obj, key, NULL, expr, ast_id, expr->LoadId(), LOAD, &has_side_effects); | 7719 obj, key, NULL, expr, expr->PropertyFeedbackSlot(), ast_id, |
| 7720 expr->LoadId(), LOAD, &has_side_effects); |
7694 if (has_side_effects) { | 7721 if (has_side_effects) { |
7695 if (ast_context()->IsEffect()) { | 7722 if (ast_context()->IsEffect()) { |
7696 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 7723 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
7697 } else { | 7724 } else { |
7698 Push(load); | 7725 Push(load); |
7699 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 7726 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
7700 Drop(1); | 7727 Drop(1); |
7701 } | 7728 } |
7702 } | 7729 } |
7703 if (load == NULL) return; | 7730 if (load == NULL) return; |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7966 set_current_block(if_false); | 7993 set_current_block(if_false); |
7967 } | 7994 } |
7968 | 7995 |
7969 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 7996 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
7970 // know about and do not want to handle ones we've never seen. Otherwise | 7997 // know about and do not want to handle ones we've never seen. Otherwise |
7971 // use a generic IC. | 7998 // use a generic IC. |
7972 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { | 7999 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { |
7973 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); | 8000 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); |
7974 } else { | 8001 } else { |
7975 Property* prop = expr->expression()->AsProperty(); | 8002 Property* prop = expr->expression()->AsProperty(); |
7976 HInstruction* function = BuildNamedGeneric( | 8003 HInstruction* function = |
7977 LOAD, prop, receiver, name, NULL, prop->IsUninitialized()); | 8004 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, |
| 8005 name, NULL, prop->IsUninitialized()); |
7978 AddInstruction(function); | 8006 AddInstruction(function); |
7979 Push(function); | 8007 Push(function); |
7980 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 8008 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
7981 | 8009 |
7982 environment()->SetExpressionStackAt(1, function); | 8010 environment()->SetExpressionStackAt(1, function); |
7983 environment()->SetExpressionStackAt(0, receiver); | 8011 environment()->SetExpressionStackAt(0, receiver); |
7984 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8012 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
7985 | 8013 |
7986 CallFunctionFlags flags = receiver->type().IsJSObject() | 8014 CallFunctionFlags flags = receiver->type().IsJSObject() |
7987 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; | 8015 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; |
(...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10424 if (!is_strong(function_language_mode())) { | 10452 if (!is_strong(function_language_mode())) { |
10425 instr->ClearAllSideEffects(); | 10453 instr->ClearAllSideEffects(); |
10426 } else { | 10454 } else { |
10427 Add<HSimulate>(expr->ToNumberId(), REMOVABLE_SIMULATE); | 10455 Add<HSimulate>(expr->ToNumberId(), REMOVABLE_SIMULATE); |
10428 } | 10456 } |
10429 instr->SetFlag(HInstruction::kCannotBeTagged); | 10457 instr->SetFlag(HInstruction::kCannotBeTagged); |
10430 return instr; | 10458 return instr; |
10431 } | 10459 } |
10432 | 10460 |
10433 | 10461 |
10434 void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, | 10462 void HOptimizedGraphBuilder::BuildStoreForEffect( |
10435 Property* prop, | 10463 Expression* expr, Property* prop, FeedbackVectorICSlot slot, |
10436 BailoutId ast_id, | 10464 BailoutId ast_id, BailoutId return_id, HValue* object, HValue* key, |
10437 BailoutId return_id, | 10465 HValue* value) { |
10438 HValue* object, | |
10439 HValue* key, | |
10440 HValue* value) { | |
10441 EffectContext for_effect(this); | 10466 EffectContext for_effect(this); |
10442 Push(object); | 10467 Push(object); |
10443 if (key != NULL) Push(key); | 10468 if (key != NULL) Push(key); |
10444 Push(value); | 10469 Push(value); |
10445 BuildStore(expr, prop, ast_id, return_id); | 10470 BuildStore(expr, prop, slot, ast_id, return_id); |
10446 } | 10471 } |
10447 | 10472 |
10448 | 10473 |
10449 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { | 10474 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
10450 DCHECK(!HasStackOverflow()); | 10475 DCHECK(!HasStackOverflow()); |
10451 DCHECK(current_block() != NULL); | 10476 DCHECK(current_block() != NULL); |
10452 DCHECK(current_block()->HasPredecessor()); | 10477 DCHECK(current_block()->HasPredecessor()); |
10453 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); | 10478 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); |
10454 Expression* target = expr->expression(); | 10479 Expression* target = expr->expression(); |
10455 VariableProxy* proxy = target->AsVariableProxy(); | 10480 VariableProxy* proxy = target->AsVariableProxy(); |
(...skipping 22 matching lines...) Expand all Loading... |
10478 DCHECK(prop == NULL); | 10503 DCHECK(prop == NULL); |
10479 CHECK_ALIVE(VisitForValue(target)); | 10504 CHECK_ALIVE(VisitForValue(target)); |
10480 | 10505 |
10481 after = BuildIncrement(returns_original_input, expr); | 10506 after = BuildIncrement(returns_original_input, expr); |
10482 input = returns_original_input ? Top() : Pop(); | 10507 input = returns_original_input ? Top() : Pop(); |
10483 Push(after); | 10508 Push(after); |
10484 | 10509 |
10485 switch (var->location()) { | 10510 switch (var->location()) { |
10486 case VariableLocation::GLOBAL: | 10511 case VariableLocation::GLOBAL: |
10487 case VariableLocation::UNALLOCATED: | 10512 case VariableLocation::UNALLOCATED: |
10488 HandleGlobalVariableAssignment(var, | 10513 HandleGlobalVariableAssignment(var, after, expr->CountSlot(), |
10489 after, | |
10490 expr->AssignmentId()); | 10514 expr->AssignmentId()); |
10491 break; | 10515 break; |
10492 | 10516 |
10493 case VariableLocation::PARAMETER: | 10517 case VariableLocation::PARAMETER: |
10494 case VariableLocation::LOCAL: | 10518 case VariableLocation::LOCAL: |
10495 BindIfLive(var, after); | 10519 BindIfLive(var, after); |
10496 break; | 10520 break; |
10497 | 10521 |
10498 case VariableLocation::CONTEXT: { | 10522 case VariableLocation::CONTEXT: { |
10499 // Bail out if we try to mutate a parameter value in a function | 10523 // Bail out if we try to mutate a parameter value in a function |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10545 | 10569 |
10546 CHECK_ALIVE(PushLoad(prop, object, key)); | 10570 CHECK_ALIVE(PushLoad(prop, object, key)); |
10547 | 10571 |
10548 after = BuildIncrement(returns_original_input, expr); | 10572 after = BuildIncrement(returns_original_input, expr); |
10549 | 10573 |
10550 if (returns_original_input) { | 10574 if (returns_original_input) { |
10551 input = Pop(); | 10575 input = Pop(); |
10552 // Drop object and key to push it again in the effect context below. | 10576 // Drop object and key to push it again in the effect context below. |
10553 Drop(key == NULL ? 1 : 2); | 10577 Drop(key == NULL ? 1 : 2); |
10554 environment()->SetExpressionStackAt(0, input); | 10578 environment()->SetExpressionStackAt(0, input); |
10555 CHECK_ALIVE(BuildStoreForEffect( | 10579 CHECK_ALIVE(BuildStoreForEffect(expr, prop, expr->CountSlot(), expr->id(), |
10556 expr, prop, expr->id(), expr->AssignmentId(), object, key, after)); | 10580 expr->AssignmentId(), object, key, after)); |
10557 return ast_context()->ReturnValue(Pop()); | 10581 return ast_context()->ReturnValue(Pop()); |
10558 } | 10582 } |
10559 | 10583 |
10560 environment()->SetExpressionStackAt(0, after); | 10584 environment()->SetExpressionStackAt(0, after); |
10561 return BuildStore(expr, prop, expr->id(), expr->AssignmentId()); | 10585 return BuildStore(expr, prop, expr->CountSlot(), expr->id(), |
| 10586 expr->AssignmentId()); |
10562 } | 10587 } |
10563 | 10588 |
10564 | 10589 |
10565 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( | 10590 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
10566 HValue* string, | 10591 HValue* string, |
10567 HValue* index) { | 10592 HValue* index) { |
10568 if (string->IsConstant() && index->IsConstant()) { | 10593 if (string->IsConstant() && index->IsConstant()) { |
10569 HConstant* c_string = HConstant::cast(string); | 10594 HConstant* c_string = HConstant::cast(string); |
10570 HConstant* c_index = HConstant::cast(index); | 10595 HConstant* c_index = HConstant::cast(index); |
10571 if (c_string->HasStringValue() && c_index->HasNumberValue()) { | 10596 if (c_string->HasStringValue() && c_index->HasNumberValue()) { |
(...skipping 2748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13320 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13345 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13321 } | 13346 } |
13322 | 13347 |
13323 #ifdef DEBUG | 13348 #ifdef DEBUG |
13324 graph_->Verify(false); // No full verify. | 13349 graph_->Verify(false); // No full verify. |
13325 #endif | 13350 #endif |
13326 } | 13351 } |
13327 | 13352 |
13328 } // namespace internal | 13353 } // namespace internal |
13329 } // namespace v8 | 13354 } // namespace v8 |
OLD | NEW |