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 |