1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/basic-block-profiler.h"
6 #include "test/cctest/cctest.h"
7 #include "test/cctest/compiler/codegen-tester.h"
8 
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12 
13 class BasicBlockProfilerTest : public RawMachineAssemblerTester<int32_t> {
14  public:
BasicBlockProfilerTest()15   BasicBlockProfilerTest()
16       : RawMachineAssemblerTester<int32_t>(MachineType::Int32()) {
17     FLAG_turbo_profiling = true;
18   }
19 
ResetCounts()20   void ResetCounts() { isolate()->basic_block_profiler()->ResetCounts(); }
21 
Expect(size_t size,uint32_t * expected)22   void Expect(size_t size, uint32_t* expected) {
23     CHECK(isolate()->basic_block_profiler());
24     const BasicBlockProfiler::DataList* l =
25         isolate()->basic_block_profiler()->data_list();
26     CHECK_NE(0, static_cast<int>(l->size()));
27     const BasicBlockProfiler::Data* data = l->back();
28     CHECK_EQ(static_cast<int>(size), static_cast<int>(data->n_blocks()));
29     const uint32_t* counts = data->counts();
30     for (size_t i = 0; i < size; ++i) {
31       CHECK_EQ(static_cast<int>(expected[i]), static_cast<int>(counts[i]));
32     }
33   }
34 };
35 
36 
TEST(ProfileDiamond)37 TEST(ProfileDiamond) {
38   BasicBlockProfilerTest m;
39 
40   RawMachineLabel blocka, blockb, end;
41   m.Branch(m.Parameter(0), &blocka, &blockb);
42   m.Bind(&blocka);
43   m.Goto(&end);
44   m.Bind(&blockb);
45   m.Goto(&end);
46   m.Bind(&end);
47   m.Return(m.Int32Constant(0));
48 
49   m.GenerateCode();
50   {
51     uint32_t expected[] = {0, 0, 0, 0};
52     m.Expect(arraysize(expected), expected);
53   }
54 
55   m.Call(0);
56   {
57     uint32_t expected[] = {1, 1, 0, 1};
58     m.Expect(arraysize(expected), expected);
59   }
60 
61   m.ResetCounts();
62 
63   m.Call(1);
64   {
65     uint32_t expected[] = {1, 0, 1, 1};
66     m.Expect(arraysize(expected), expected);
67   }
68 
69   m.Call(0);
70   {
71     uint32_t expected[] = {2, 1, 1, 2};
72     m.Expect(arraysize(expected), expected);
73   }
74 }
75 
76 
TEST(ProfileLoop)77 TEST(ProfileLoop) {
78   BasicBlockProfilerTest m;
79 
80   RawMachineLabel header, body, end;
81   Node* one = m.Int32Constant(1);
82   m.Goto(&header);
83 
84   m.Bind(&header);
85   Node* count = m.Phi(MachineRepresentation::kWord32, m.Parameter(0), one);
86   m.Branch(count, &body, &end);
87 
88   m.Bind(&body);
89   count->ReplaceInput(1, m.Int32Sub(count, one));
90   m.Goto(&header);
91 
92   m.Bind(&end);
93   m.Return(one);
94 
95   m.GenerateCode();
96   {
97     uint32_t expected[] = {0, 0, 0, 0};
98     m.Expect(arraysize(expected), expected);
99   }
100 
101   uint32_t runs[] = {0, 1, 500, 10000};
102   for (size_t i = 0; i < arraysize(runs); i++) {
103     m.ResetCounts();
104     CHECK_EQ(1, m.Call(static_cast<int>(runs[i])));
105     uint32_t expected[] = {1, runs[i] + 1, runs[i], 1};
106     m.Expect(arraysize(expected), expected);
107   }
108 }
109 
110 }  // namespace compiler
111 }  // namespace internal
112 }  // namespace v8
113