| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 | 6 |
| 7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #include "vm/profiler.h" | 10 #include "vm/profiler.h" |
| (...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 StackZone zone(isolate); | 908 StackZone zone(isolate); |
| 909 HANDLESCOPE(isolate); | 909 HANDLESCOPE(isolate); |
| 910 Profile profile(isolate); | 910 Profile profile(isolate); |
| 911 AllocationFilter filter(isolate, one_byte_string_class.id()); | 911 AllocationFilter filter(isolate, one_byte_string_class.id()); |
| 912 profile.Build(&filter, Profile::kNoTags); | 912 profile.Build(&filter, Profile::kNoTags); |
| 913 // We should now have two allocation samples. | 913 // We should now have two allocation samples. |
| 914 EXPECT_EQ(2, profile.sample_count()); | 914 EXPECT_EQ(2, profile.sample_count()); |
| 915 } | 915 } |
| 916 } | 916 } |
| 917 | 917 |
| 918 |
| 919 TEST_CASE(Profiler_FunctionInline) { |
| 920 const char* kScript = |
| 921 "class A {\n" |
| 922 " var a;\n" |
| 923 " var b;\n" |
| 924 "}\n" |
| 925 "class B {\n" |
| 926 " static choo(bool alloc) {\n" |
| 927 " if (alloc) return new A();\n" |
| 928 " return alloc && alloc && !alloc;\n" |
| 929 " }\n" |
| 930 " static foo(bool alloc) {\n" |
| 931 " choo(alloc);\n" |
| 932 " }\n" |
| 933 " static boo(bool alloc) {\n" |
| 934 " for (var i = 0; i < 50000; i++) {\n" |
| 935 " foo(alloc);\n" |
| 936 " }\n" |
| 937 " }\n" |
| 938 "}\n" |
| 939 "main() {\n" |
| 940 " B.boo(false);\n" |
| 941 "}\n" |
| 942 "mainA() {\n" |
| 943 " B.boo(true);\n" |
| 944 "}\n"; |
| 945 |
| 946 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 947 EXPECT_VALID(lib); |
| 948 Library& root_library = Library::Handle(); |
| 949 root_library ^= Api::UnwrapHandle(lib); |
| 950 |
| 951 const Class& class_a = Class::Handle(GetClass(root_library, "A")); |
| 952 EXPECT(!class_a.IsNull()); |
| 953 |
| 954 // Compile "main". |
| 955 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 956 EXPECT_VALID(result); |
| 957 // Compile "mainA". |
| 958 result = Dart_Invoke(lib, NewString("mainA"), 0, NULL); |
| 959 EXPECT_VALID(result); |
| 960 // At this point B.boo should be optimized and inlined B.foo and B.choo. |
| 961 |
| 962 { |
| 963 Isolate* isolate = Isolate::Current(); |
| 964 StackZone zone(isolate); |
| 965 HANDLESCOPE(isolate); |
| 966 Profile profile(isolate); |
| 967 AllocationFilter filter(isolate, class_a.id()); |
| 968 profile.Build(&filter, Profile::kNoTags); |
| 969 // We should have no allocation samples. |
| 970 EXPECT_EQ(0, profile.sample_count()); |
| 971 } |
| 972 |
| 973 // Turn on allocation tracing for A. |
| 974 class_a.SetTraceAllocation(true); |
| 975 |
| 976 // Allocate 50,000 instances of A. |
| 977 result = Dart_Invoke(lib, NewString("mainA"), 0, NULL); |
| 978 EXPECT_VALID(result); |
| 979 |
| 980 { |
| 981 Isolate* isolate = Isolate::Current(); |
| 982 StackZone zone(isolate); |
| 983 HANDLESCOPE(isolate); |
| 984 Profile profile(isolate); |
| 985 AllocationFilter filter(isolate, class_a.id()); |
| 986 profile.Build(&filter, Profile::kNoTags); |
| 987 // We should have 50,000 allocation samples. |
| 988 EXPECT_EQ(50000, profile.sample_count()); |
| 989 ProfileTrieWalker walker(&profile); |
| 990 // We have two code objects: mainA and B.boo. |
| 991 walker.Reset(Profile::kExclusiveCode); |
| 992 EXPECT(walker.Down()); |
| 993 EXPECT_STREQ("B.boo", walker.CurrentName()); |
| 994 EXPECT_EQ(1, walker.SiblingCount()); |
| 995 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 996 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 997 EXPECT_EQ(50000, walker.CurrentExclusiveTicks()); |
| 998 EXPECT(walker.Down()); |
| 999 EXPECT_STREQ("mainA", walker.CurrentName()); |
| 1000 EXPECT_EQ(1, walker.SiblingCount()); |
| 1001 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1002 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1003 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1004 EXPECT(!walker.Down()); |
| 1005 // We have two code objects: mainA and B.boo. |
| 1006 walker.Reset(Profile::kInclusiveCode); |
| 1007 EXPECT(walker.Down()); |
| 1008 EXPECT_STREQ("mainA", walker.CurrentName()); |
| 1009 EXPECT_EQ(1, walker.SiblingCount()); |
| 1010 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1011 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1012 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1013 EXPECT(walker.Down()); |
| 1014 EXPECT_STREQ("B.boo", walker.CurrentName()); |
| 1015 EXPECT_EQ(1, walker.SiblingCount()); |
| 1016 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1017 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1018 EXPECT_EQ(50000, walker.CurrentExclusiveTicks()); |
| 1019 EXPECT(!walker.Down()); |
| 1020 |
| 1021 // Inline expansion should show us the complete call chain: |
| 1022 // mainA -> B.boo -> B.foo -> B.choo. |
| 1023 walker.Reset(Profile::kExclusiveFunction); |
| 1024 EXPECT(walker.Down()); |
| 1025 EXPECT_STREQ("B.choo", walker.CurrentName()); |
| 1026 EXPECT_EQ(1, walker.SiblingCount()); |
| 1027 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1028 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1029 EXPECT_EQ(50000, walker.CurrentExclusiveTicks()); |
| 1030 EXPECT(walker.Down()); |
| 1031 EXPECT_STREQ("B.foo", walker.CurrentName()); |
| 1032 EXPECT_EQ(1, walker.SiblingCount()); |
| 1033 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1034 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1035 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1036 EXPECT(walker.Down()); |
| 1037 EXPECT_STREQ("B.boo", walker.CurrentName()); |
| 1038 EXPECT_EQ(1, walker.SiblingCount()); |
| 1039 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1040 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1041 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1042 EXPECT(walker.Down()); |
| 1043 EXPECT_STREQ("mainA", walker.CurrentName()); |
| 1044 EXPECT_EQ(1, walker.SiblingCount()); |
| 1045 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1046 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1047 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1048 EXPECT(!walker.Down()); |
| 1049 |
| 1050 // Inline expansion should show us the complete call chain: |
| 1051 // mainA -> B.boo -> B.foo -> B.choo. |
| 1052 walker.Reset(Profile::kInclusiveFunction); |
| 1053 EXPECT(walker.Down()); |
| 1054 EXPECT_STREQ("mainA", walker.CurrentName()); |
| 1055 EXPECT_EQ(1, walker.SiblingCount()); |
| 1056 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1057 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1058 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1059 EXPECT(walker.Down()); |
| 1060 EXPECT_STREQ("B.boo", walker.CurrentName()); |
| 1061 EXPECT_EQ(1, walker.SiblingCount()); |
| 1062 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1063 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1064 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1065 EXPECT(walker.Down()); |
| 1066 EXPECT_STREQ("B.foo", walker.CurrentName()); |
| 1067 EXPECT_EQ(1, walker.SiblingCount()); |
| 1068 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1069 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1070 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); |
| 1071 EXPECT(walker.Down()); |
| 1072 EXPECT_STREQ("B.choo", walker.CurrentName()); |
| 1073 EXPECT_EQ(1, walker.SiblingCount()); |
| 1074 EXPECT_EQ(50000, walker.CurrentNodeTickCount()); |
| 1075 EXPECT_EQ(50000, walker.CurrentInclusiveTicks()); |
| 1076 EXPECT_EQ(50000, walker.CurrentExclusiveTicks()); |
| 1077 EXPECT(!walker.Down()); |
| 1078 } |
| 1079 } |
| 1080 |
| 918 } // namespace dart | 1081 } // namespace dart |
| OLD | NEW |