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