Chromium Code Reviews| 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 6754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6765 target, static_cast<HValue*>(NULL), | 6765 target, static_cast<HValue*>(NULL), |
| 6766 HObjectAccess::ForFunctionContextPointer()); | 6766 HObjectAccess::ForFunctionContextPointer()); |
| 6767 return NewArgumentAdaptorCall(target, context, | 6767 return NewArgumentAdaptorCall(target, context, |
| 6768 argument_count, param_count_value); | 6768 argument_count, param_count_value); |
| 6769 } | 6769 } |
| 6770 UNREACHABLE(); | 6770 UNREACHABLE(); |
| 6771 return NULL; | 6771 return NULL; |
| 6772 } | 6772 } |
| 6773 | 6773 |
| 6774 | 6774 |
| 6775 class FunctionSorter { | |
| 6776 public: | |
| 6777 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } | |
| 6778 FunctionSorter(int index, int ticks, int ast_length, int src_length) | |
| 6779 : index_(index), | |
| 6780 ticks_(ticks), | |
| 6781 ast_length_(ast_length), | |
| 6782 src_length_(src_length) { } | |
| 6783 | |
| 6784 int index() const { return index_; } | |
| 6785 int ticks() const { return ticks_; } | |
| 6786 int ast_length() const { return ast_length_; } | |
| 6787 int src_length() const { return src_length_; } | |
| 6788 | |
| 6789 private: | |
| 6790 int index_; | |
| 6791 int ticks_; | |
| 6792 int ast_length_; | |
| 6793 int src_length_; | |
| 6794 }; | |
| 6795 | |
| 6796 | |
| 6797 inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { | |
| 6798 int diff = lhs.ticks() - rhs.ticks(); | |
| 6799 if (diff != 0) return diff > 0; | |
| 6800 diff = lhs.ast_length() - rhs.ast_length(); | |
| 6801 if (diff != 0) return diff < 0; | |
| 6802 return lhs.src_length() < rhs.src_length(); | |
| 6803 } | |
| 6804 | |
| 6805 | |
| 6806 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( | 6775 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( |
| 6807 Call* expr, | 6776 Call* expr, |
| 6808 HValue* receiver, | 6777 HValue* receiver, |
| 6809 SmallMapList* types, | 6778 SmallMapList* types, |
| 6810 Handle<String> name) { | 6779 Handle<String> name) { |
| 6811 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 6780 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
| 6812 FunctionSorter order[kMaxCallPolymorphism]; | |
| 6813 | 6781 |
| 6814 bool handle_smi = false; | 6782 bool handle_smi = false; |
| 6815 bool handled_string = false; | 6783 bool handled_string = false; |
| 6816 int ordered_functions = 0; | |
| 6817 | 6784 |
| 6818 for (int i = 0; | 6785 for (int i = 0; i < types->length(); ++i) { |
|
Toon Verwaest
2014/02/11 10:32:48
Please put back the MaxCallPolymorphism; which wil
Benedikt Meurer
2014/02/11 10:34:55
Done.
| |
| 6819 i < types->length() && ordered_functions < kMaxCallPolymorphism; | |
| 6820 ++i) { | |
| 6821 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); | 6786 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); |
| 6822 if (info.CanAccessMonomorphic() && | 6787 if (info.CanAccessMonomorphic() && |
| 6823 info.lookup()->IsConstant() && | 6788 info.lookup()->IsConstant() && |
| 6824 info.constant()->IsJSFunction()) { | 6789 info.constant()->IsJSFunction()) { |
| 6825 if (info.type()->Is(Type::String())) { | |
| 6826 if (handled_string) continue; | |
| 6827 handled_string = true; | |
| 6828 } | |
| 6829 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); | |
| 6830 if (info.type()->Is(Type::Number())) { | 6790 if (info.type()->Is(Type::Number())) { |
| 6831 handle_smi = true; | 6791 handle_smi = true; |
| 6792 break; | |
| 6832 } | 6793 } |
| 6833 expr->set_target(target); | |
| 6834 order[ordered_functions++] = | |
| 6835 FunctionSorter(i, | |
| 6836 expr->target()->shared()->profiler_ticks(), | |
| 6837 InliningAstSize(expr->target()), | |
| 6838 expr->target()->shared()->SourceSize()); | |
| 6839 } | 6794 } |
| 6840 } | 6795 } |
| 6841 | 6796 |
| 6842 std::sort(order, order + ordered_functions); | |
| 6843 | |
| 6844 HBasicBlock* number_block = NULL; | 6797 HBasicBlock* number_block = NULL; |
| 6845 HBasicBlock* join = NULL; | 6798 HBasicBlock* join = NULL; |
| 6846 handled_string = false; | 6799 handled_string = false; |
| 6847 int count = 0; | 6800 int count = 0; |
| 6848 | 6801 |
| 6849 for (int fn = 0; fn < ordered_functions; ++fn) { | 6802 for (int i = 0; i < types->length(); ++i) { |
| 6850 int i = order[fn].index(); | |
| 6851 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); | 6803 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); |
| 6804 if (!info.CanAccessMonomorphic() || | |
| 6805 !info.lookup()->IsConstant() || | |
| 6806 !info.constant()->IsJSFunction()) { | |
| 6807 continue; | |
| 6808 } | |
| 6852 if (info.type()->Is(Type::String())) { | 6809 if (info.type()->Is(Type::String())) { |
| 6853 if (handled_string) continue; | 6810 if (handled_string) continue; |
| 6854 handled_string = true; | 6811 handled_string = true; |
| 6855 } | 6812 } |
| 6856 // Reloads the target. | 6813 // Reloads the target. |
| 6857 info.CanAccessMonomorphic(); | 6814 info.CanAccessMonomorphic(); |
| 6858 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); | 6815 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); |
| 6859 | 6816 |
| 6860 expr->set_target(target); | 6817 expr->set_target(target); |
| 6861 if (count == 0) { | 6818 if (count == 0) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6932 if (!ast_context()->IsEffect()) Push(call); | 6889 if (!ast_context()->IsEffect()) Push(call); |
| 6933 } | 6890 } |
| 6934 | 6891 |
| 6935 if (current_block() != NULL) Goto(join); | 6892 if (current_block() != NULL) Goto(join); |
| 6936 set_current_block(if_false); | 6893 set_current_block(if_false); |
| 6937 } | 6894 } |
| 6938 | 6895 |
| 6939 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 6896 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 6940 // know about and do not want to handle ones we've never seen. Otherwise | 6897 // know about and do not want to handle ones we've never seen. Otherwise |
| 6941 // use a generic IC. | 6898 // use a generic IC. |
| 6942 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { | 6899 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
| 6943 // Because the deopt may be the only path in the polymorphic call, make sure | 6900 // Because the deopt may be the only path in the polymorphic call, make sure |
| 6944 // that the environment stack matches the depth on deopt that it otherwise | 6901 // that the environment stack matches the depth on deopt that it otherwise |
| 6945 // would have had after a successful call. | 6902 // would have had after a successful call. |
| 6946 Drop(1); // Drop receiver. | 6903 Drop(1); // Drop receiver. |
| 6947 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); | 6904 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); |
| 6948 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); | 6905 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); |
| 6949 } else { | 6906 } else { |
| 6950 Property* prop = expr->expression()->AsProperty(); | 6907 Property* prop = expr->expression()->AsProperty(); |
| 6951 HInstruction* function = BuildNamedGeneric( | 6908 HInstruction* function = BuildNamedGeneric( |
| 6952 LOAD, receiver, name, NULL, prop->IsUninitialized()); | 6909 LOAD, receiver, name, NULL, prop->IsUninitialized()); |
| (...skipping 4242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11195 if (ShouldProduceTraceOutput()) { | 11152 if (ShouldProduceTraceOutput()) { |
| 11196 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11153 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11197 } | 11154 } |
| 11198 | 11155 |
| 11199 #ifdef DEBUG | 11156 #ifdef DEBUG |
| 11200 graph_->Verify(false); // No full verify. | 11157 graph_->Verify(false); // No full verify. |
| 11201 #endif | 11158 #endif |
| 11202 } | 11159 } |
| 11203 | 11160 |
| 11204 } } // namespace v8::internal | 11161 } } // namespace v8::internal |
| OLD | NEW |