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