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

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

Issue 1582683003: Fall back to inlining intervals to generate stack traces in --noopt. Inlined frames will lack line … (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 Isolate* isolate = Isolate::Current(); 132 Isolate* isolate = Isolate::Current();
133 SampleBuffer* sample_buffer = new SampleBuffer(3); 133 SampleBuffer* sample_buffer = new SampleBuffer(3);
134 Sample* sample = sample_buffer->ReserveSample(); 134 Sample* sample = sample_buffer->ReserveSample();
135 sample->Init(isolate, 0, 0); 135 sample->Init(isolate, 0, 0);
136 sample->set_metadata(99); 136 sample->set_metadata(99);
137 sample->set_is_allocation_sample(true); 137 sample->set_is_allocation_sample(true);
138 EXPECT_EQ(99, sample->allocation_cid()); 138 EXPECT_EQ(99, sample->allocation_cid());
139 delete sample_buffer; 139 delete sample_buffer;
140 } 140 }
141 141
142
142 static RawClass* GetClass(const Library& lib, const char* name) { 143 static RawClass* GetClass(const Library& lib, const char* name) {
143 const Class& cls = Class::Handle( 144 const Class& cls = Class::Handle(
144 lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name)))); 145 lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name))));
145 EXPECT(!cls.IsNull()); // No ambiguity error expected. 146 EXPECT(!cls.IsNull()); // No ambiguity error expected.
146 return cls.raw(); 147 return cls.raw();
147 } 148 }
148 149
149 150
151 static RawFunction* GetFunction(const Library& lib, const char* name) {
152 const Function& func = Function::Handle(
153 lib.LookupFunctionAllowPrivate(String::Handle(Symbols::New(name))));
154 EXPECT(!func.IsNull()); // No ambiguity error expected.
155 return func.raw();
156 }
157
158
150 class AllocationFilter : public SampleFilter { 159 class AllocationFilter : public SampleFilter {
151 public: 160 public:
152 AllocationFilter(Isolate* isolate, 161 AllocationFilter(Isolate* isolate,
153 intptr_t cid, 162 intptr_t cid,
154 int64_t time_origin_micros = -1, 163 int64_t time_origin_micros = -1,
155 int64_t time_extent_micros = -1) 164 int64_t time_extent_micros = -1)
156 : SampleFilter(isolate, 165 : SampleFilter(isolate,
157 time_origin_micros, 166 time_origin_micros,
158 time_extent_micros), 167 time_extent_micros),
159 cid_(cid), 168 cid_(cid),
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 EXPECT(walker.Down()); 1404 EXPECT(walker.Down());
1396 EXPECT_STREQ("B.choo", walker.CurrentName()); 1405 EXPECT_STREQ("B.choo", walker.CurrentName());
1397 EXPECT(walker.Down()); 1406 EXPECT(walker.Down());
1398 EXPECT_STREQ("[Inline End]", walker.CurrentName()); 1407 EXPECT_STREQ("[Inline End]", walker.CurrentName());
1399 EXPECT(!walker.Down()); 1408 EXPECT(!walker.Down());
1400 } 1409 }
1401 FLAG_background_compilation = old_flag; 1410 FLAG_background_compilation = old_flag;
1402 } 1411 }
1403 1412
1404 1413
1414 TEST_CASE(Profiler_InliningIntervalBoundry) {
Cutch 2016/01/12 22:27:50 Add a comment here and point out the code in profi
rmacnak 2016/01/13 00:40:49 Done.
1415 DisableNativeProfileScope dnps;
1416 const char* kScript =
1417 "class A {\n"
1418 "}\n"
1419 "bool alloc = false;"
1420 "maybeAlloc() {\n"
1421 " try {\n"
1422 " if (alloc) new A();\n"
1423 " } catch (e) {\n"
1424 " }\n"
1425 "}\n"
1426 "right() => maybeAlloc();\n"
1427 "doNothing() {\n"
1428 " try {\n"
1429 " } catch (e) {\n"
1430 " }\n"
1431 "}\n"
1432 "wrong() => doNothing();\n"
1433 "a() {\n"
1434 " try {\n"
1435 " right();\n"
1436 " wrong();\n"
1437 " } catch (e) {\n"
1438 " }\n"
1439 "}\n"
1440 "mainNoAlloc() {\n"
1441 " for (var i = 0; i < 20000; i++) {\n"
1442 " a();\n"
1443 " }\n"
1444 "}\n"
1445 "mainAlloc() {\n"
1446 " alloc = true;\n"
1447 " a();\n"
1448 "}\n";
1449
1450 const bool old_flag = FLAG_background_compilation;
1451 FLAG_background_compilation = false;
Cutch 2016/01/12 22:27:50 Might want to introduce a Scope object like Disabl
rmacnak 2016/01/13 00:40:49 Done, here and Profiler_FunctionInline
1452 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
1453 EXPECT_VALID(lib);
1454 Library& root_library = Library::Handle();
1455 root_library ^= Api::UnwrapHandle(lib);
1456
1457 const Class& class_a = Class::Handle(GetClass(root_library, "A"));
1458 EXPECT(!class_a.IsNull());
1459
1460 // Compile and optimize.
1461 Dart_Handle result = Dart_Invoke(lib, NewString("mainNoAlloc"), 0, NULL);
1462 EXPECT_VALID(result);
1463 result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
1464 EXPECT_VALID(result);
1465
1466 // At this point a should be optimized and have inlined both right and wrong,
1467 // but not maybeAllocate or doNothing.
1468 Function& func = Function::Handle();
1469 func = GetFunction(root_library, "a");
1470 EXPECT(!func.is_inlinable());
1471 EXPECT(func.HasOptimizedCode());
1472 func = GetFunction(root_library, "right");
1473 EXPECT(func.is_inlinable());
1474 func = GetFunction(root_library, "wrong");
1475 EXPECT(func.is_inlinable());
1476 func = GetFunction(root_library, "doNothing");
1477 EXPECT(!func.is_inlinable());
1478 func = GetFunction(root_library, "maybeAlloc");
1479 EXPECT(!func.is_inlinable());
1480
1481 {
1482 Thread* thread = Thread::Current();
1483 Isolate* isolate = thread->isolate();
1484 StackZone zone(thread);
1485 HANDLESCOPE(thread);
1486 Profile profile(isolate);
1487 AllocationFilter filter(isolate, class_a.id());
1488 profile.Build(thread, &filter, Profile::kNoTags);
1489 // We should have no allocation samples.
1490 EXPECT_EQ(0, profile.sample_count());
1491 }
1492
1493 // Turn on allocation tracing for A.
1494 class_a.SetTraceAllocation(true);
1495
1496 result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
1497 EXPECT_VALID(result);
1498
1499 {
1500 Thread* thread = Thread::Current();
1501 Isolate* isolate = thread->isolate();
1502 StackZone zone(thread);
1503 HANDLESCOPE(thread);
1504 Profile profile(isolate);
1505 AllocationFilter filter(isolate, class_a.id());
1506 profile.Build(thread, &filter, Profile::kNoTags);
1507 EXPECT_EQ(1, profile.sample_count());
1508 ProfileTrieWalker walker(&profile);
1509
1510 // Inline expansion should show us the complete call chain:
1511 walker.Reset(Profile::kExclusiveFunction);
1512 EXPECT(walker.Down());
1513 EXPECT_STREQ("maybeAlloc", walker.CurrentName());
1514 EXPECT(walker.Down());
1515 EXPECT_STREQ("right", walker.CurrentName());
1516 EXPECT(walker.Down());
1517 EXPECT_STREQ("a", walker.CurrentName());
1518 EXPECT(walker.Down());
1519 EXPECT_STREQ("mainAlloc", walker.CurrentName());
1520 EXPECT(!walker.Down());
1521
1522 // Inline expansion should show us the complete call chain:
1523 walker.Reset(Profile::kInclusiveFunction);
1524 EXPECT(walker.Down());
1525 EXPECT_STREQ("mainAlloc", walker.CurrentName());
1526 EXPECT(walker.Down());
1527 EXPECT_STREQ("a", walker.CurrentName());
1528 EXPECT(walker.Down());
1529 EXPECT_STREQ("right", walker.CurrentName());
1530 EXPECT(walker.Down());
1531 EXPECT_STREQ("maybeAlloc", walker.CurrentName());
1532 EXPECT(!walker.Down());
1533 }
1534
1535 FLAG_background_compilation = old_flag;
1536 }
1537
1538
1405 TEST_CASE(Profiler_ChainedSamples) { 1539 TEST_CASE(Profiler_ChainedSamples) {
1406 MaxProfileDepthScope mpds(32); 1540 MaxProfileDepthScope mpds(32);
1407 DisableNativeProfileScope dnps; 1541 DisableNativeProfileScope dnps;
1408 1542
1409 // Each sample holds 8 stack frames. 1543 // Each sample holds 8 stack frames.
1410 // This chain is 20 stack frames deep. 1544 // This chain is 20 stack frames deep.
1411 const char* kScript = 1545 const char* kScript =
1412 "class A {\n" 1546 "class A {\n"
1413 " var a;\n" 1547 " var a;\n"
1414 " var b;\n" 1548 " var b;\n"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 EXPECT(walker.Down()); 1640 EXPECT(walker.Down());
1507 EXPECT_STREQ("go", walker.CurrentName()); 1641 EXPECT_STREQ("go", walker.CurrentName());
1508 EXPECT(walker.Down()); 1642 EXPECT(walker.Down());
1509 EXPECT_STREQ("main", walker.CurrentName()); 1643 EXPECT_STREQ("main", walker.CurrentName());
1510 EXPECT(!walker.Down()); 1644 EXPECT(!walker.Down());
1511 } 1645 }
1512 } 1646 }
1513 1647
1514 } // namespace dart 1648 } // namespace dart
1515 1649
OLDNEW
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698