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

Side by Side Diff: runtime/vm/profiler_test.cc

Issue 1779333004: Add profile data to getSourceReport (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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
OLDNEW
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"
11 #include "vm/profiler_service.h" 11 #include "vm/profiler_service.h"
12 #include "vm/source_report.h"
12 #include "vm/unit_test.h" 13 #include "vm/unit_test.h"
13 14
14 namespace dart { 15 namespace dart {
15 16
16 #ifndef PRODUCT 17 #ifndef PRODUCT
17 18
18 DECLARE_FLAG(bool, profile_vm); 19 DECLARE_FLAG(bool, profile_vm);
19 DECLARE_FLAG(int, max_profile_depth); 20 DECLARE_FLAG(int, max_profile_depth);
20 DECLARE_FLAG(bool, enable_inlining_annotations); 21 DECLARE_FLAG(bool, enable_inlining_annotations);
21 DECLARE_FLAG(int, optimization_counter_threshold); 22 DECLARE_FLAG(int, optimization_counter_threshold);
(...skipping 2270 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 EXPECT(walker.Down()); 2293 EXPECT(walker.Down());
2293 EXPECT_STREQ("main", walker.CurrentName()); 2294 EXPECT_STREQ("main", walker.CurrentName());
2294 EXPECT_EQ(1, walker.CurrentNodeTickCount()); 2295 EXPECT_EQ(1, walker.CurrentNodeTickCount());
2295 EXPECT_EQ(1, walker.CurrentInclusiveTicks()); 2296 EXPECT_EQ(1, walker.CurrentInclusiveTicks());
2296 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); 2297 EXPECT_EQ(0, walker.CurrentExclusiveTicks());
2297 EXPECT_STREQ("bacon", walker.CurrentToken()); 2298 EXPECT_STREQ("bacon", walker.CurrentToken());
2298 EXPECT(!walker.Down()); 2299 EXPECT(!walker.Down());
2299 } 2300 }
2300 } 2301 }
2301 2302
2303
2304 static void InsertFakeSample(SampleBuffer* sample_buffer,
2305 uword* pc_offsets) {
2306 ASSERT(sample_buffer != NULL);
2307 Isolate* isolate = Isolate::Current();
2308 Sample* sample = sample_buffer->ReserveSample();
2309 ASSERT(sample != NULL);
2310 sample->Init(isolate,
2311 OS::GetCurrentMonotonicMicros(),
2312 OSThread::Current()->trace_id());
2313
2314 intptr_t i = 0;
2315 while (pc_offsets[i] != 0) {
2316 // To account for a subtraction in profiler.
2317 intptr_t slop = i > 0 ? 1 : 0;
2318 sample->SetAt(i, pc_offsets[i] + slop);
turnidge 2016/03/11 18:31:57 So for the top frame on the stack, we put in an un
Cutch 2016/03/11 20:20:00 When querying the inline tables for a Code object,
2319 i++;
2320 }
2321 sample->SetAt(i, 0);
turnidge 2016/03/11 18:31:57 0 is a sentinel for the SampleBuffer? Maybe a nam
Cutch 2016/03/11 20:20:00 Done.
2322 }
2323
2324
2325 static uword FindPCForTokenPosition(const Code& code,
2326 const CodeSourceMap& code_source_map,
2327 TokenPosition tp) {
2328 CodeSourceMap::Iterator it(code_source_map);
2329
2330 while (it.MoveNext()) {
2331 if (it.TokenPos() == tp) {
2332 return it.PcOffset() + code.EntryPoint();
2333 }
2334 }
2335
2336 return 0;
2337 }
2338
2339
2340 TEST_CASE(Profiler_GetSourceReport) {
2341 const char* kScript =
2342 "doWork(i) => i * i;\n"
2343 "main() {\n"
2344 " var sum = 0;\n"
2345 " for (var i = 0; i < 100; i++) {\n"
2346 " sum += doWork(i);\n"
2347 " }\n"
2348 " return sum;\n"
2349 "}\n";
2350
2351 // Token position of * in `i * i`.
2352 const TokenPosition squarePosition = TokenPosition(6);
2353
2354 // Token position of the call to `doWork`.
2355 const TokenPosition callPosition = TokenPosition(39);
2356
2357 DisableNativeProfileScope dnps;
2358 // Disable profiling for this thread.
2359 DisableThreadInterruptsScope dtis(Thread::Current());
2360
2361 SampleBuffer* sample_buffer = Profiler::sample_buffer();
2362 EXPECT(sample_buffer != NULL);
2363
2364 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
2365 EXPECT_VALID(lib);
2366 Library& root_library = Library::Handle();
2367 root_library ^= Api::UnwrapHandle(lib);
2368
2369 // Invoke main so that it gets compiled.
2370 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
2371 EXPECT_VALID(result);
2372
2373 {
2374 // Clear the profile for this isolate.
2375 ClearProfileVisitor cpv(Isolate::Current());
2376 sample_buffer->VisitSamples(&cpv);
2377 }
2378
2379 // Query the code object for main and determine the PC some token positions.
turnidge 2016/03/11 18:31:57 "PC some" -> "PC at some"?
Cutch 2016/03/11 20:20:00 Done.
2380 const Function& main = Function::Handle(GetFunction(root_library, "main"));
2381 EXPECT(!main.IsNull());
2382
2383 const Function& do_work =
2384 Function::Handle(GetFunction(root_library, "doWork"));
2385 EXPECT(!do_work.IsNull());
2386
2387 const Script& script = Script::Handle(main.script());
2388 EXPECT(!script.IsNull());
2389
2390 const Code& main_code = Code::Handle(main.CurrentCode());
2391 EXPECT(!main_code.IsNull());
2392
2393 const Code& do_work_code = Code::Handle(do_work.CurrentCode());
2394 EXPECT(!do_work_code.IsNull());
2395
2396 const CodeSourceMap& main_code_source_map =
2397 CodeSourceMap::Handle(main_code.code_source_map());
2398 EXPECT(!main_code_source_map.IsNull());
2399
2400 const CodeSourceMap& do_work_code_source_map =
2401 CodeSourceMap::Handle(do_work_code.code_source_map());
2402 EXPECT(!do_work_code_source_map.IsNull());
2403
2404 // Dump code source map.
2405 CodeSourceMap::Dump(do_work_code_source_map, do_work_code, main);
2406 CodeSourceMap::Dump(main_code_source_map, main_code, main);
2407
2408 // Look up some source token position's pc.
2409 uword squarePositionPc =
2410 FindPCForTokenPosition(do_work_code,
2411 do_work_code_source_map,
2412 squarePosition);
2413 EXPECT(squarePositionPc != 0);
2414
2415 uword callPositionPc =
2416 FindPCForTokenPosition(main_code, main_code_source_map, callPosition);
2417 EXPECT(callPositionPc != 0);
2418
2419 // Look up some classifying token position's pc.
2420 uword controlFlowPc =
2421 FindPCForTokenPosition(do_work_code,
2422 do_work_code_source_map,
2423 TokenPosition::kControlFlow);
2424 EXPECT(controlFlowPc != 0);
2425
2426 uword tempMovePc =
2427 FindPCForTokenPosition(main_code,
2428 main_code_source_map,
2429 TokenPosition::kTempMove);
2430 EXPECT(tempMovePc != 0);
2431
2432 // Insert fake samples.
2433
2434 // Sample 1:
2435 // squarePositionPc exclusive.
2436 // callPositionPc inclusive.
2437 uword sample1[] = {
2438 squarePositionPc, // doWork.
2439 callPositionPc, // main.
2440 0
2441 };
2442
2443 // Sample 2:
2444 // squarePositionPc exclusive.
2445 uword sample2[] = {
2446 squarePositionPc, // doWork.
2447 0,
2448 };
2449
2450 // Sample 3:
2451 // controlFlowPc exclusive.
2452 // callPositionPc inclusive.
2453 uword sample3[] = {
2454 controlFlowPc, // doWork.
2455 callPositionPc, // main.
2456 0
2457 };
2458
2459 // Sample 4:
2460 // tempMovePc exclusive.
2461 uword sample4[] = {
2462 tempMovePc, // main.
2463 0
2464 };
2465
2466 InsertFakeSample(sample_buffer, &sample1[0]);
2467 InsertFakeSample(sample_buffer, &sample2[0]);
2468 InsertFakeSample(sample_buffer, &sample3[0]);
2469 InsertFakeSample(sample_buffer, &sample4[0]);
2470
2471 // Generate source report for main.
2472 SourceReport sourceReport(SourceReport::kProfile);
2473 JSONStream js;
2474 sourceReport.PrintJSON(&js,
2475 script,
2476 do_work.token_pos(),
2477 main.end_token_pos());
2478
2479 // Verify positions in do_work.
2480 EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",6]", js.ToCString());
2481 // Verify exclusive ticks in do_work.
2482 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString());
2483 // Verify inclusive ticks in do_work.
2484 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
2485
2486 // Verify positions in main.
2487 EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString());
2488 // Verify exclusive ticks in main.
2489 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString());
2490 // Verify inclusive ticks in main.
2491 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
turnidge 2016/03/11 18:31:57 Nice test.
Cutch 2016/03/11 20:20:00 Acknowledged.
2492 }
2493
2302 #endif // !PRODUCT 2494 #endif // !PRODUCT
2303 2495
2304 } // namespace dart 2496 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698