| 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 |