Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(891)

Side by Side Diff: test/cctest/test-cpu-profiler.cc

Issue 424973004: Extend CPU profiler with mapping ticks to source lines (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/profile-generator-inl.h ('K') | « src/profile-generator-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« src/profile-generator-inl.h ('K') | « src/profile-generator-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698