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