Home | History | Annotate | Download | only in compiler
      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:
     15   BasicBlockProfilerTest()
     16       : RawMachineAssemblerTester<int32_t>(MachineType::Int32()) {
     17     FLAG_turbo_profiling = true;
     18   }
     19 
     20   void ResetCounts() { isolate()->basic_block_profiler()->ResetCounts(); }
     21 
     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 
     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 
     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