Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1057 CheckChildrenNames(root, names); | 1057 CheckChildrenNames(root, names); |
| 1058 | 1058 |
| 1059 const v8::CpuProfileNode* startNode = | 1059 const v8::CpuProfileNode* startNode = |
| 1060 GetChild(env->GetIsolate(), root, "start"); | 1060 GetChild(env->GetIsolate(), root, "start"); |
| 1061 GetChild(env->GetIsolate(), startNode, "foo"); | 1061 GetChild(env->GetIsolate(), startNode, "foo"); |
| 1062 | 1062 |
| 1063 profile->Delete(); | 1063 profile->Delete(); |
| 1064 } | 1064 } |
| 1065 | 1065 |
| 1066 | 1066 |
| 1067 // Check that the profile tree for the script below will look like the | |
| 1068 // following: | |
| 1069 // | |
| 1070 // [Top down]: | |
| 1071 // 0 (root)0 #1 | |
| 1072 // 15 start 20 #3 no reason | |
| 1073 // 3 foo 20 #4 TryCatchStatement | |
| 1074 // 121 bar 20 #5 TryCatchStatement | |
| 1075 // 223 loop 20 #6 no reason | |
| 1076 // | |
| 1077 // This tests checks distribution of the samples through the source lines. | |
| 1078 // The optimizing compiler is disabled for the hotest function to make | |
| 1079 // the test deterministic. | |
| 1080 | |
| 1081 static int GetHitLineSampleCount(const v8::CpuProfileNode* node) { | |
| 1082 int sampleCount = 0; | |
| 1083 unsigned int lineCount = node->GetHitLineCount(); | |
| 1084 if (lineCount) { | |
| 1085 v8::LineTick* entries = new v8::LineTick[lineCount]; | |
| 1086 CHECK_EQ(true, node->GetLineTicks(entries, lineCount)); | |
| 1087 for (unsigned int i = 0; i < lineCount; i++) { | |
| 1088 sampleCount += entries[i].ticks; | |
| 1089 } | |
| 1090 delete [] entries; | |
|
yurys
2014/07/29 13:15:10
Can be handled using a smart pointer from src/smar
| |
| 1091 } | |
| 1092 return sampleCount; | |
| 1093 } | |
| 1094 | |
| 1095 | |
| 1096 void CheckHitLine(unsigned int lineNo, | |
| 1097 const v8::CpuProfileNode* node, | |
| 1098 unsigned int sampleTotal, | |
| 1099 unsigned int threshold) { | |
| 1100 bool found = false; | |
| 1101 | |
| 1102 unsigned int lineCount = node->GetHitLineCount(); | |
| 1103 CHECK_GT(lineCount, 0); | |
| 1104 | |
| 1105 v8::LineTick* entries = new v8::LineTick[lineCount]; | |
| 1106 CHECK_EQ(true, node->GetLineTicks(entries, lineCount)); | |
| 1107 | |
| 1108 unsigned int i = 0; | |
| 1109 for (i = 0; i < lineCount; i++) { | |
| 1110 if (entries[i].line == lineNo) { | |
| 1111 found = true; | |
| 1112 break; | |
| 1113 } | |
| 1114 } | |
| 1115 CHECK_EQ(true, found); | |
| 1116 CHECK_GT(entries[i].ticks * 100 / sampleTotal, threshold); | |
| 1117 | |
| 1118 delete[] entries; | |
| 1119 } | |
| 1120 | |
| 1121 | |
| 1122 static void CheckBranchWithTickLines(v8::Isolate* isolate, | |
| 1123 const v8::CpuProfile* profile) { | |
| 1124 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); | |
| 1125 | |
| 1126 const v8::CpuProfileNode* startNode = | |
| 1127 GetChild(isolate, root, "start"); | |
| 1128 CHECK_EQ(1, startNode->GetChildrenCount()); | |
| 1129 CHECK_EQ(startNode->GetHitCount(), GetHitLineSampleCount(startNode)); | |
| 1130 | |
| 1131 const v8::CpuProfileNode* fooNode = | |
| 1132 GetChild(isolate, startNode, "foo"); | |
| 1133 CHECK_EQ(1, fooNode->GetChildrenCount()); | |
| 1134 CHECK_EQ(fooNode->GetHitCount(), GetHitLineSampleCount(fooNode)); | |
| 1135 | |
| 1136 const v8::CpuProfileNode* barNode = | |
| 1137 GetChild(isolate, fooNode, "bar"); | |
| 1138 CHECK_EQ(1, barNode->GetChildrenCount()); | |
| 1139 CHECK_EQ(barNode->GetHitCount(), GetHitLineSampleCount(barNode)); | |
| 1140 // Check that line #14 collects at least 90% of the samples. | |
| 1141 CheckHitLine(14, barNode, barNode->GetHitCount(), 90); | |
| 1142 | |
| 1143 const v8::CpuProfileNode* loopNode = | |
| 1144 GetChild(isolate, barNode, "loop"); | |
| 1145 CHECK_EQ(0, loopNode->GetChildrenCount()); | |
| 1146 CHECK_EQ(loopNode->GetHitCount(), GetHitLineSampleCount(loopNode)); | |
| 1147 | |
| 1148 // Check that line #8 collects at least 60% of the samples | |
| 1149 CheckHitLine(8, loopNode, loopNode->GetHitCount(), 60); | |
| 1150 } | |
| 1151 | |
| 1152 | |
| 1153 static const char* cpu_profiler_test_source3 = "function loop(timeout) {\n" | |
| 1154 " with({}); // disable the optimizing compiler for this function" | |
| 1155 " this.mmm = 0;\n" | |
| 1156 " var start = Date.now();\n" | |
| 1157 " while (Date.now() - start < timeout) {\n" | |
| 1158 " var n = 100*1000;\n" | |
| 1159 " while(n > 1) {\n" | |
| 1160 " n--;\n" | |
| 1161 " this.mmm += n * n * n;\n" | |
| 1162 " }\n" | |
| 1163 " }\n" | |
| 1164 "}\n" | |
| 1165 "function bar() {\n" | |
| 1166 " try {\n" | |
| 1167 " loop(10);\n" | |
| 1168 " } catch(e) { }\n" | |
| 1169 "}\n" | |
| 1170 "function foo() {\n" | |
| 1171 " try {\n" | |
| 1172 " bar();\n" | |
| 1173 " } catch (e) { }\n" | |
| 1174 "}\n" | |
| 1175 "function start(timeout) {\n" | |
| 1176 " var start = Date.now();\n" | |
| 1177 " do {\n" | |
| 1178 " foo();\n" | |
| 1179 " var duration = Date.now() - start;\n" | |
| 1180 " } while (duration < timeout);\n" | |
| 1181 " return duration;\n" | |
| 1182 "}\n"; | |
| 1183 | |
| 1184 | |
| 1185 TEST(TickLines) { | |
|
yurys
2014/07/29 13:15:10
The test is bound to be flaky like other CPU profi
| |
| 1186 LocalContext env; | |
| 1187 v8::HandleScope scope(env->GetIsolate()); | |
| 1188 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), | |
| 1189 cpu_profiler_test_source3))->Run(); | |
| 1190 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( | |
| 1191 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); | |
| 1192 | |
| 1193 int32_t profiling_interval_ms = 200; | |
| 1194 v8::Handle<v8::Value> args[] = { | |
| 1195 v8::Integer::New(env->GetIsolate(), profiling_interval_ms) | |
| 1196 }; | |
| 1197 | |
| 1198 // The first run tests distribution of the samples through the source | |
| 1199 // line information taken from "relocation info" created during code | |
| 1200 // generation. | |
| 1201 v8::CpuProfile* profile = | |
| 1202 RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200); | |
| 1203 function->Call(env->Global(), ARRAY_SIZE(args), args); | |
| 1204 CheckBranchWithTickLines(env->GetIsolate(), profile); | |
| 1205 profile->Delete(); | |
| 1206 | |
| 1207 // This is a case when the precompiled functions located on the heap | |
| 1208 // are profiled. The second run tests that same source lines collect | |
| 1209 // the expected number of samples. | |
| 1210 profile = RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200); | |
| 1211 function->Call(env->Global(), ARRAY_SIZE(args), args); | |
| 1212 CheckBranchWithTickLines(env->GetIsolate(), profile); | |
| 1213 profile->Delete(); | |
| 1214 } | |
| 1215 | |
| 1216 | |
| 1067 static const char* call_function_test_source = "function bar(iterations) {\n" | 1217 static const char* call_function_test_source = "function bar(iterations) {\n" |
| 1068 "}\n" | 1218 "}\n" |
| 1069 "function start(duration) {\n" | 1219 "function start(duration) {\n" |
| 1070 " var start = Date.now();\n" | 1220 " var start = Date.now();\n" |
| 1071 " while (Date.now() - start < duration) {\n" | 1221 " while (Date.now() - start < duration) {\n" |
| 1072 " try {\n" | 1222 " try {\n" |
| 1073 " bar.call(this, 10 * 1000);\n" | 1223 " bar.call(this, 10 * 1000);\n" |
| 1074 " } catch(e) {}\n" | 1224 " } catch(e) {}\n" |
| 1075 " }\n" | 1225 " }\n" |
| 1076 "}"; | 1226 "}"; |
| (...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1676 inner_profile = NULL; | 1826 inner_profile = NULL; |
| 1677 CHECK_EQ(0, iprofiler->GetProfilesCount()); | 1827 CHECK_EQ(0, iprofiler->GetProfilesCount()); |
| 1678 | 1828 |
| 1679 v8::CpuProfile* outer_profile = profiler->StopProfiling(outer); | 1829 v8::CpuProfile* outer_profile = profiler->StopProfiling(outer); |
| 1680 CHECK(outer_profile); | 1830 CHECK(outer_profile); |
| 1681 CHECK_EQ(1, iprofiler->GetProfilesCount()); | 1831 CHECK_EQ(1, iprofiler->GetProfilesCount()); |
| 1682 outer_profile->Delete(); | 1832 outer_profile->Delete(); |
| 1683 outer_profile = NULL; | 1833 outer_profile = NULL; |
| 1684 CHECK_EQ(0, iprofiler->GetProfilesCount()); | 1834 CHECK_EQ(0, iprofiler->GetProfilesCount()); |
| 1685 } | 1835 } |
| OLD | NEW |