| 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 5782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5793 } | 5793 } |
| 5794 | 5794 |
| 5795 // Named store. | 5795 // Named store. |
| 5796 HValue* value = Pop(); | 5796 HValue* value = Pop(); |
| 5797 HValue* object = Pop(); | 5797 HValue* object = Pop(); |
| 5798 | 5798 |
| 5799 Literal* key = prop->key()->AsLiteral(); | 5799 Literal* key = prop->key()->AsLiteral(); |
| 5800 Handle<String> name = Handle<String>::cast(key->value()); | 5800 Handle<String> name = Handle<String>::cast(key->value()); |
| 5801 ASSERT(!name.is_null()); | 5801 ASSERT(!name.is_null()); |
| 5802 | 5802 |
| 5803 HInstruction* instr = NULL; | 5803 HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr, |
| 5804 | 5804 object, name, value, is_uninitialized); |
| 5805 SmallMapList* types; | 5805 if (instr == NULL) return; |
| 5806 ComputeReceiverTypes(expr, object, &types, zone()); | |
| 5807 | |
| 5808 if (types->length() > 0) { | |
| 5809 PropertyAccessInfo info(this, STORE, ToType(types->first()), name); | |
| 5810 if (!info.CanAccessAsMonomorphic(types)) { | |
| 5811 return HandlePolymorphicNamedFieldAccess( | |
| 5812 STORE, ast_id, return_id, object, value, types, name); | |
| 5813 } | |
| 5814 | |
| 5815 ASSERT(!info.type()->Is(Type::Number())); | |
| 5816 BuildCheckHeapObject(object); | |
| 5817 HValue* checked_object; | |
| 5818 if (AreStringTypes(types)) { | |
| 5819 checked_object = Add<HCheckInstanceType>( | |
| 5820 object, HCheckInstanceType::IS_STRING); | |
| 5821 } else { | |
| 5822 checked_object = Add<HCheckMaps>(object, types); | |
| 5823 } | |
| 5824 instr = BuildMonomorphicAccess( | |
| 5825 &info, object, checked_object, value, ast_id, return_id); | |
| 5826 if (instr == NULL) return; | |
| 5827 ASSERT(!instr->IsLinked()); | |
| 5828 } else { | |
| 5829 instr = BuildStoreNamedGeneric(object, name, value, is_uninitialized); | |
| 5830 } | |
| 5831 | 5806 |
| 5832 if (!ast_context()->IsEffect()) Push(value); | 5807 if (!ast_context()->IsEffect()) Push(value); |
| 5833 AddInstruction(instr); | 5808 AddInstruction(instr); |
| 5834 if (instr->HasObservableSideEffects()) { | 5809 if (instr->HasObservableSideEffects()) { |
| 5835 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 5810 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 5836 } | 5811 } |
| 5837 if (!ast_context()->IsEffect()) Drop(1); | 5812 if (!ast_context()->IsEffect()) Drop(1); |
| 5838 return ast_context()->ReturnValue(value); | 5813 return ast_context()->ReturnValue(value); |
| 5839 } | 5814 } |
| 5840 | 5815 |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6201 return Add<HConstant>(c_string->StringValue()->length()); | 6176 return Add<HConstant>(c_string->StringValue()->length()); |
| 6202 } | 6177 } |
| 6203 } | 6178 } |
| 6204 return AddLoadNamedField(string, HObjectAccess::ForStringLength()); | 6179 return AddLoadNamedField(string, HObjectAccess::ForStringLength()); |
| 6205 } | 6180 } |
| 6206 | 6181 |
| 6207 | 6182 |
| 6208 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 6183 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
| 6209 HValue* object, | 6184 HValue* object, |
| 6210 Handle<String> name, | 6185 Handle<String> name, |
| 6211 Property* expr) { | 6186 bool is_uninitialized) { |
| 6212 if (!expr->IsForCall() && expr->IsUninitialized()) { | 6187 if (is_uninitialized) { |
| 6213 Add<HDeoptimize>("Insufficient type feedback for generic named load", | 6188 Add<HDeoptimize>("Insufficient type feedback for generic named load", |
| 6214 Deoptimizer::SOFT); | 6189 Deoptimizer::SOFT); |
| 6215 } | 6190 } |
| 6216 return New<HLoadNamedGeneric>(object, name); | 6191 return New<HLoadNamedGeneric>(object, name); |
| 6217 } | 6192 } |
| 6218 | 6193 |
| 6219 | 6194 |
| 6220 | 6195 |
| 6221 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 6196 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| 6222 HValue* key) { | 6197 HValue* key) { |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6617 HInstruction* length = Add<HConstant>(argument_count); | 6592 HInstruction* length = Add<HConstant>(argument_count); |
| 6618 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 6593 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 6619 result = New<HAccessArgumentsAt>(elements, length, checked_key); | 6594 result = New<HAccessArgumentsAt>(elements, length, checked_key); |
| 6620 } | 6595 } |
| 6621 } | 6596 } |
| 6622 ast_context()->ReturnInstruction(result, expr->id()); | 6597 ast_context()->ReturnInstruction(result, expr->id()); |
| 6623 return true; | 6598 return true; |
| 6624 } | 6599 } |
| 6625 | 6600 |
| 6626 | 6601 |
| 6602 HInstruction* HOptimizedGraphBuilder::BuildNamedAccess( |
| 6603 PropertyAccessType access, |
| 6604 BailoutId ast_id, |
| 6605 BailoutId return_id, |
| 6606 Expression* expr, |
| 6607 HValue* object, |
| 6608 Handle<String> name, |
| 6609 HValue* value, |
| 6610 bool is_uninitialized) { |
| 6611 SmallMapList* types; |
| 6612 ComputeReceiverTypes(expr, object, &types, zone()); |
| 6613 ASSERT(types != NULL); |
| 6614 |
| 6615 if (types->length() > 0) { |
| 6616 PropertyAccessInfo info(this, access, ToType(types->first()), name); |
| 6617 if (!info.CanAccessAsMonomorphic(types)) { |
| 6618 HandlePolymorphicNamedFieldAccess( |
| 6619 access, ast_id, return_id, object, value, types, name); |
| 6620 return NULL; |
| 6621 } |
| 6622 |
| 6623 HValue* checked_object; |
| 6624 // Type::Number() is only supported by polymorphic load/call handling. |
| 6625 ASSERT(!info.type()->Is(Type::Number())); |
| 6626 BuildCheckHeapObject(object); |
| 6627 if (AreStringTypes(types)) { |
| 6628 checked_object = |
| 6629 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); |
| 6630 } else { |
| 6631 checked_object = Add<HCheckMaps>(object, types); |
| 6632 } |
| 6633 return BuildMonomorphicAccess( |
| 6634 &info, object, checked_object, value, ast_id, return_id); |
| 6635 } |
| 6636 |
| 6637 if (access == LOAD) { |
| 6638 return BuildLoadNamedGeneric(object, name, is_uninitialized); |
| 6639 } else { |
| 6640 return BuildStoreNamedGeneric(object, name, value, is_uninitialized); |
| 6641 } |
| 6642 } |
| 6643 |
| 6644 |
| 6627 void HOptimizedGraphBuilder::PushLoad(Property* expr, | 6645 void HOptimizedGraphBuilder::PushLoad(Property* expr, |
| 6628 HValue* object, | 6646 HValue* object, |
| 6629 HValue* key) { | 6647 HValue* key) { |
| 6630 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); | 6648 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
| 6631 Push(object); | 6649 Push(object); |
| 6632 if (key != NULL) Push(key); | 6650 if (key != NULL) Push(key); |
| 6633 BuildLoad(expr, expr->LoadId()); | 6651 BuildLoad(expr, expr->LoadId()); |
| 6634 } | 6652 } |
| 6635 | 6653 |
| 6636 | 6654 |
| 6637 void HOptimizedGraphBuilder::BuildLoad(Property* expr, | 6655 void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
| 6638 BailoutId ast_id) { | 6656 BailoutId ast_id) { |
| 6639 HInstruction* instr = NULL; | 6657 HInstruction* instr = NULL; |
| 6640 if (expr->IsStringAccess()) { | 6658 if (expr->IsStringAccess()) { |
| 6641 HValue* index = Pop(); | 6659 HValue* index = Pop(); |
| 6642 HValue* string = Pop(); | 6660 HValue* string = Pop(); |
| 6643 HInstruction* char_code = BuildStringCharCodeAt(string, index); | 6661 HInstruction* char_code = BuildStringCharCodeAt(string, index); |
| 6644 AddInstruction(char_code); | 6662 AddInstruction(char_code); |
| 6645 instr = NewUncasted<HStringCharFromCode>(char_code); | 6663 instr = NewUncasted<HStringCharFromCode>(char_code); |
| 6646 | 6664 |
| 6647 } else if (expr->IsFunctionPrototype()) { | 6665 } else if (expr->IsFunctionPrototype()) { |
| 6648 HValue* function = Pop(); | 6666 HValue* function = Pop(); |
| 6649 BuildCheckHeapObject(function); | 6667 BuildCheckHeapObject(function); |
| 6650 instr = New<HLoadFunctionPrototype>(function); | 6668 instr = New<HLoadFunctionPrototype>(function); |
| 6651 | 6669 |
| 6652 } else if (expr->key()->IsPropertyName()) { | 6670 } else if (expr->key()->IsPropertyName()) { |
| 6653 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 6671 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 6654 HValue* object = Pop(); | 6672 HValue* object = Pop(); |
| 6655 | 6673 |
| 6656 SmallMapList* types; | 6674 instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, |
| 6657 ComputeReceiverTypes(expr, object, &types, zone()); | 6675 object, name, NULL, expr->IsUninitialized()); |
| 6658 ASSERT(types != NULL); | 6676 if (instr == NULL) return; |
| 6659 | 6677 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); |
| 6660 if (types->length() > 0) { | |
| 6661 PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); | |
| 6662 if (!info.CanAccessAsMonomorphic(types)) { | |
| 6663 return HandlePolymorphicNamedFieldAccess( | |
| 6664 LOAD, ast_id, expr->LoadId(), object, NULL, types, name); | |
| 6665 } | |
| 6666 | |
| 6667 HValue* checked_object; | |
| 6668 // Type::Number() is only supported by polymorphic load/call handling. | |
| 6669 ASSERT(!info.type()->Is(Type::Number())); | |
| 6670 BuildCheckHeapObject(object); | |
| 6671 if (AreStringTypes(types)) { | |
| 6672 checked_object = | |
| 6673 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); | |
| 6674 } else { | |
| 6675 checked_object = Add<HCheckMaps>(object, types); | |
| 6676 } | |
| 6677 instr = BuildMonomorphicAccess( | |
| 6678 &info, object, checked_object, NULL, ast_id, expr->LoadId()); | |
| 6679 if (instr == NULL) return; | |
| 6680 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); | |
| 6681 } else { | |
| 6682 instr = BuildLoadNamedGeneric(object, name, expr); | |
| 6683 } | |
| 6684 | 6678 |
| 6685 } else { | 6679 } else { |
| 6686 HValue* key = Pop(); | 6680 HValue* key = Pop(); |
| 6687 HValue* obj = Pop(); | 6681 HValue* obj = Pop(); |
| 6688 | 6682 |
| 6689 bool has_side_effects = false; | 6683 bool has_side_effects = false; |
| 6690 HValue* load = HandleKeyedElementAccess( | 6684 HValue* load = HandleKeyedElementAccess( |
| 6691 obj, key, NULL, expr, | 6685 obj, key, NULL, expr, |
| 6692 false, // is_store | 6686 false, // is_store |
| 6693 &has_side_effects); | 6687 &has_side_effects); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6989 // use a generic IC. | 6983 // use a generic IC. |
| 6990 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { | 6984 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { |
| 6991 // Because the deopt may be the only path in the polymorphic call, make sure | 6985 // Because the deopt may be the only path in the polymorphic call, make sure |
| 6992 // that the environment stack matches the depth on deopt that it otherwise | 6986 // that the environment stack matches the depth on deopt that it otherwise |
| 6993 // would have had after a successful call. | 6987 // would have had after a successful call. |
| 6994 Drop(1); // Drop receiver. | 6988 Drop(1); // Drop receiver. |
| 6995 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); | 6989 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); |
| 6996 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); | 6990 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); |
| 6997 } else { | 6991 } else { |
| 6998 Property* prop = expr->expression()->AsProperty(); | 6992 Property* prop = expr->expression()->AsProperty(); |
| 6999 HInstruction* function = BuildLoadNamedGeneric(receiver, name, prop); | 6993 HInstruction* function = BuildLoadNamedGeneric( |
| 6994 receiver, name, prop->IsUninitialized()); |
| 7000 AddInstruction(function); | 6995 AddInstruction(function); |
| 7001 Push(function); | 6996 Push(function); |
| 7002 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 6997 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 7003 | 6998 |
| 7004 environment()->SetExpressionStackAt(1, function); | 6999 environment()->SetExpressionStackAt(1, function); |
| 7005 environment()->SetExpressionStackAt(0, receiver); | 7000 environment()->SetExpressionStackAt(0, receiver); |
| 7006 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7001 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 7007 | 7002 |
| 7008 CallFunctionFlags flags = receiver->type().IsJSObject() | 7003 CallFunctionFlags flags = receiver->type().IsJSObject() |
| 7009 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; | 7004 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; |
| (...skipping 4138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11148 if (ShouldProduceTraceOutput()) { | 11143 if (ShouldProduceTraceOutput()) { |
| 11149 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11144 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11150 } | 11145 } |
| 11151 | 11146 |
| 11152 #ifdef DEBUG | 11147 #ifdef DEBUG |
| 11153 graph_->Verify(false); // No full verify. | 11148 graph_->Verify(false); // No full verify. |
| 11154 #endif | 11149 #endif |
| 11155 } | 11150 } |
| 11156 | 11151 |
| 11157 } } // namespace v8::internal | 11152 } } // namespace v8::internal |
| OLD | NEW |