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 4960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4971 HStoreGlobalGeneric* instr = | 4971 HStoreGlobalGeneric* instr = |
4972 Add<HStoreGlobalGeneric>(global_object, var->name(), | 4972 Add<HStoreGlobalGeneric>(global_object, var->name(), |
4973 value, function_strict_mode_flag()); | 4973 value, function_strict_mode_flag()); |
4974 instr->set_position(position); | 4974 instr->set_position(position); |
4975 ASSERT(instr->HasObservableSideEffects()); | 4975 ASSERT(instr->HasObservableSideEffects()); |
4976 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 4976 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
4977 } | 4977 } |
4978 } | 4978 } |
4979 | 4979 |
4980 | 4980 |
| 4981 static bool ComputeReceiverTypes(Expression* expr, |
| 4982 HValue* receiver, |
| 4983 SmallMapList** t) { |
| 4984 SmallMapList* types = expr->GetReceiverTypes(); |
| 4985 *t = types; |
| 4986 bool monomorphic = expr->IsMonomorphic(); |
| 4987 if (types != NULL && receiver->HasMonomorphicJSObjectType()) { |
| 4988 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); |
| 4989 types->FilterForPossibleTransitions(root_map); |
| 4990 monomorphic = types->length() == 1; |
| 4991 } |
| 4992 return monomorphic && CanInlinePropertyAccess(*types->first()); |
| 4993 } |
| 4994 |
| 4995 |
4981 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, | 4996 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
4982 BailoutId id, | 4997 BailoutId id, |
4983 BailoutId assignment_id, | 4998 BailoutId assignment_id, |
4984 Property* prop, | 4999 Property* prop, |
4985 HValue* object, | 5000 HValue* object, |
4986 HValue* value) { | 5001 HValue* value) { |
4987 Literal* key = prop->key()->AsLiteral(); | 5002 Literal* key = prop->key()->AsLiteral(); |
4988 Handle<String> name = Handle<String>::cast(key->value()); | 5003 Handle<String> name = Handle<String>::cast(key->value()); |
4989 ASSERT(!name.is_null()); | 5004 ASSERT(!name.is_null()); |
4990 | 5005 |
4991 HInstruction* instr = NULL; | 5006 HInstruction* instr = NULL; |
4992 SmallMapList* types = expr->GetReceiverTypes(); | 5007 |
4993 bool monomorphic = expr->IsMonomorphic(); | 5008 SmallMapList* types; |
4994 Handle<Map> map; | 5009 bool monomorphic = ComputeReceiverTypes(expr, object, &types); |
| 5010 |
4995 if (monomorphic) { | 5011 if (monomorphic) { |
4996 map = types->first(); | 5012 Handle<Map> map = types->first(); |
4997 monomorphic = CanInlinePropertyAccess(*map); | |
4998 } | |
4999 if (monomorphic) { | |
5000 Handle<JSFunction> setter; | 5013 Handle<JSFunction> setter; |
5001 Handle<JSObject> holder; | 5014 Handle<JSObject> holder; |
5002 if (LookupSetter(map, name, &setter, &holder)) { | 5015 if (LookupSetter(map, name, &setter, &holder)) { |
5003 AddCheckConstantFunction(holder, object, map); | 5016 AddCheckConstantFunction(holder, object, map); |
5004 if (FLAG_inline_accessors && | 5017 if (FLAG_inline_accessors && |
5005 TryInlineSetter(setter, id, assignment_id, value)) { | 5018 TryInlineSetter(setter, id, assignment_id, value)) { |
5006 return; | 5019 return; |
5007 } | 5020 } |
5008 Drop(2); | 5021 Drop(2); |
5009 Add<HPushArgument>(object); | 5022 Add<HPushArgument>(object); |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5685 HValue* obj, | 5698 HValue* obj, |
5686 HValue* key, | 5699 HValue* key, |
5687 HValue* val, | 5700 HValue* val, |
5688 Expression* expr, | 5701 Expression* expr, |
5689 BailoutId ast_id, | 5702 BailoutId ast_id, |
5690 int position, | 5703 int position, |
5691 bool is_store, | 5704 bool is_store, |
5692 bool* has_side_effects) { | 5705 bool* has_side_effects) { |
5693 ASSERT(!expr->IsPropertyName()); | 5706 ASSERT(!expr->IsPropertyName()); |
5694 HInstruction* instr = NULL; | 5707 HInstruction* instr = NULL; |
5695 if (expr->IsMonomorphic()) { | 5708 |
5696 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 5709 SmallMapList* types; |
| 5710 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); |
| 5711 |
| 5712 if (monomorphic) { |
| 5713 Handle<Map> map = types->first(); |
5697 if (map->has_slow_elements_kind()) { | 5714 if (map->has_slow_elements_kind()) { |
5698 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 5715 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
5699 : BuildLoadKeyedGeneric(obj, key); | 5716 : BuildLoadKeyedGeneric(obj, key); |
5700 AddInstruction(instr); | 5717 AddInstruction(instr); |
5701 } else { | 5718 } else { |
5702 BuildCheckHeapObject(obj); | 5719 BuildCheckHeapObject(obj); |
5703 instr = BuildMonomorphicElementAccess( | 5720 instr = BuildMonomorphicElementAccess( |
5704 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); | 5721 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); |
5705 } | 5722 } |
5706 } else if (expr->GetReceiverTypes() != NULL && | 5723 } else if (expr->GetReceiverTypes() != NULL && |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5851 AddInstruction(char_code); | 5868 AddInstruction(char_code); |
5852 instr = HStringCharFromCode::New(zone(), context, char_code); | 5869 instr = HStringCharFromCode::New(zone(), context, char_code); |
5853 | 5870 |
5854 } else if (expr->IsFunctionPrototype()) { | 5871 } else if (expr->IsFunctionPrototype()) { |
5855 HValue* function = Pop(); | 5872 HValue* function = Pop(); |
5856 BuildCheckHeapObject(function); | 5873 BuildCheckHeapObject(function); |
5857 instr = new(zone()) HLoadFunctionPrototype(function); | 5874 instr = new(zone()) HLoadFunctionPrototype(function); |
5858 | 5875 |
5859 } else if (expr->key()->IsPropertyName()) { | 5876 } else if (expr->key()->IsPropertyName()) { |
5860 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 5877 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
5861 SmallMapList* types = expr->GetReceiverTypes(); | |
5862 HValue* object = Top(); | 5878 HValue* object = Top(); |
5863 | 5879 |
5864 Handle<Map> map; | 5880 SmallMapList* types; |
5865 bool monomorphic = false; | 5881 bool monomorphic = ComputeReceiverTypes(expr, object, &types); |
5866 if (expr->IsMonomorphic()) { | 5882 |
5867 map = types->first(); | |
5868 monomorphic = CanInlinePropertyAccess(*map); | |
5869 } else if (object->HasMonomorphicJSObjectType()) { | |
5870 map = object->GetMonomorphicJSObjectMap(); | |
5871 monomorphic = CanInlinePropertyAccess(*map); | |
5872 } | |
5873 if (monomorphic) { | 5883 if (monomorphic) { |
| 5884 Handle<Map> map = types->first(); |
5874 Handle<JSFunction> getter; | 5885 Handle<JSFunction> getter; |
5875 Handle<JSObject> holder; | 5886 Handle<JSObject> holder; |
5876 if (LookupGetter(map, name, &getter, &holder)) { | 5887 if (LookupGetter(map, name, &getter, &holder)) { |
5877 AddCheckConstantFunction(holder, Top(), map); | 5888 AddCheckConstantFunction(holder, Top(), map); |
5878 if (FLAG_inline_accessors && | 5889 if (FLAG_inline_accessors && |
5879 TryInlineGetter(getter, ast_id, expr->LoadId())) { | 5890 TryInlineGetter(getter, ast_id, expr->LoadId())) { |
5880 return; | 5891 return; |
5881 } | 5892 } |
5882 Add<HPushArgument>(Pop()); | 5893 Add<HPushArgument>(Pop()); |
5883 instr = new(zone()) HCallConstantFunction(getter, 1); | 5894 instr = new(zone()) HCallConstantFunction(getter, 1); |
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6958 return ast_context()->ReturnInstruction(call, expr->id()); | 6969 return ast_context()->ReturnInstruction(call, expr->id()); |
6959 } | 6970 } |
6960 | 6971 |
6961 // Named function call. | 6972 // Named function call. |
6962 if (TryCallApply(expr)) return; | 6973 if (TryCallApply(expr)) return; |
6963 | 6974 |
6964 CHECK_ALIVE(VisitForValue(prop->obj())); | 6975 CHECK_ALIVE(VisitForValue(prop->obj())); |
6965 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 6976 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
6966 | 6977 |
6967 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 6978 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
6968 SmallMapList* types = expr->GetReceiverTypes(); | 6979 HValue* receiver = |
| 6980 environment()->ExpressionStackAt(expr->arguments()->length()); |
6969 | 6981 |
6970 bool monomorphic = expr->IsMonomorphic(); | 6982 SmallMapList* types; |
6971 Handle<Map> receiver_map; | 6983 bool was_monomorphic = expr->IsMonomorphic(); |
6972 if (monomorphic) { | 6984 bool monomorphic = ComputeReceiverTypes(expr, receiver, &types); |
6973 receiver_map = (types == NULL || types->is_empty()) | 6985 if (!was_monomorphic && monomorphic) { |
6974 ? Handle<Map>::null() | 6986 monomorphic = expr->ComputeTarget(types->first(), name); |
6975 : types->first(); | |
6976 } | 6987 } |
6977 | 6988 |
6978 HValue* receiver = | |
6979 environment()->ExpressionStackAt(expr->arguments()->length()); | |
6980 if (monomorphic) { | 6989 if (monomorphic) { |
6981 if (TryInlineBuiltinMethodCall(expr, | 6990 Handle<Map> map = types->first(); |
6982 receiver, | 6991 if (TryInlineBuiltinMethodCall(expr, receiver, map, expr->check_type())) { |
6983 receiver_map, | |
6984 expr->check_type())) { | |
6985 if (FLAG_trace_inlining) { | 6992 if (FLAG_trace_inlining) { |
6986 PrintF("Inlining builtin "); | 6993 PrintF("Inlining builtin "); |
6987 expr->target()->ShortPrint(); | 6994 expr->target()->ShortPrint(); |
6988 PrintF("\n"); | 6995 PrintF("\n"); |
6989 } | 6996 } |
6990 return; | 6997 return; |
6991 } | 6998 } |
6992 | 6999 |
6993 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || | 7000 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || |
6994 expr->check_type() != RECEIVER_MAP_CHECK) { | 7001 expr->check_type() != RECEIVER_MAP_CHECK) { |
6995 // When the target has a custom call IC generator, use the IC, | 7002 // When the target has a custom call IC generator, use the IC, |
6996 // because it is likely to generate better code. Also use the IC | 7003 // because it is likely to generate better code. Also use the IC |
6997 // when a primitive receiver check is required. | 7004 // when a primitive receiver check is required. |
6998 HValue* context = environment()->context(); | 7005 HValue* context = environment()->context(); |
6999 call = PreProcessCall( | 7006 call = PreProcessCall( |
7000 new(zone()) HCallNamed(context, name, argument_count)); | 7007 new(zone()) HCallNamed(context, name, argument_count)); |
7001 } else { | 7008 } else { |
7002 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7009 AddCheckConstantFunction(expr->holder(), receiver, map); |
7003 | 7010 |
7004 if (TryInlineCall(expr)) return; | 7011 if (TryInlineCall(expr)) return; |
7005 call = PreProcessCall( | 7012 call = PreProcessCall( |
7006 new(zone()) HCallConstantFunction(expr->target(), | 7013 new(zone()) HCallConstantFunction(expr->target(), |
7007 argument_count)); | 7014 argument_count)); |
7008 } | 7015 } |
7009 } else if (types != NULL && types->length() > 1) { | 7016 } else if (types != NULL && types->length() > 1) { |
7010 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 7017 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
7011 HandlePolymorphicCallNamed(expr, receiver, types, name); | 7018 HandlePolymorphicCallNamed(expr, receiver, types, name); |
7012 return; | 7019 return; |
(...skipping 2709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9722 if (ShouldProduceTraceOutput()) { | 9729 if (ShouldProduceTraceOutput()) { |
9723 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9730 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9724 } | 9731 } |
9725 | 9732 |
9726 #ifdef DEBUG | 9733 #ifdef DEBUG |
9727 graph_->Verify(false); // No full verify. | 9734 graph_->Verify(false); // No full verify. |
9728 #endif | 9735 #endif |
9729 } | 9736 } |
9730 | 9737 |
9731 } } // namespace v8::internal | 9738 } } // namespace v8::internal |
OLD | NEW |