1 | // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_VM_BENCHMARK_TEST_H_ |
6 | #define RUNTIME_VM_BENCHMARK_TEST_H_ |
7 | |
8 | #include "include/dart_api.h" |
9 | |
10 | #include "vm/dart.h" |
11 | #include "vm/globals.h" |
12 | #include "vm/isolate.h" |
13 | #include "vm/malloc_hooks.h" |
14 | #include "vm/object.h" |
15 | #include "vm/unit_test.h" |
16 | #include "vm/zone.h" |
17 | |
18 | namespace dart { |
19 | |
20 | DECLARE_FLAG(int, code_heap_size); |
21 | DECLARE_FLAG(int, old_gen_growth_space_ratio); |
22 | |
23 | namespace bin { |
24 | // Snapshot pieces if we link in a snapshot, otherwise initialized to NULL. |
25 | extern const uint8_t* vm_snapshot_data; |
26 | extern const uint8_t* vm_snapshot_instructions; |
27 | extern const uint8_t* core_isolate_snapshot_data; |
28 | extern const uint8_t* core_isolate_snapshot_instructions; |
29 | } // namespace bin |
30 | |
31 | // The BENCHMARK macros are used for benchmarking a specific functionality |
32 | // of the VM. |
33 | #define BENCHMARK_HELPER(name, kind) \ |
34 | void Dart_Benchmark##name(Benchmark* benchmark); \ |
35 | static Benchmark kRegister##name(Dart_Benchmark##name, #name, kind); \ |
36 | static void Dart_BenchmarkHelper##name(Benchmark* benchmark, \ |
37 | Thread* thread); \ |
38 | void Dart_Benchmark##name(Benchmark* benchmark) { \ |
39 | bool __stack_trace_collection_enabled__ = \ |
40 | MallocHooks::stack_trace_collection_enabled(); \ |
41 | MallocHooks::set_stack_trace_collection_enabled(false); \ |
42 | FLAG_old_gen_growth_space_ratio = 100; \ |
43 | BenchmarkIsolateScope __isolate__(benchmark); \ |
44 | Thread* __thread__ = Thread::Current(); \ |
45 | ASSERT(__thread__->isolate() == benchmark->isolate()); \ |
46 | Dart_BenchmarkHelper##name(benchmark, __thread__); \ |
47 | MallocHooks::set_stack_trace_collection_enabled( \ |
48 | __stack_trace_collection_enabled__); \ |
49 | } \ |
50 | static void Dart_BenchmarkHelper##name(Benchmark* benchmark, Thread* thread) |
51 | |
52 | #define BENCHMARK(name) BENCHMARK_HELPER(name, "RunTime") |
53 | #define BENCHMARK_SIZE(name) BENCHMARK_HELPER(name, "CodeSize") |
54 | #define BENCHMARK_MEMORY(name) BENCHMARK_HELPER(name, "MemoryUse") |
55 | |
56 | inline Dart_Handle NewString(const char* str) { |
57 | return Dart_NewStringFromCString(str); |
58 | } |
59 | |
60 | class Benchmark { |
61 | public: |
62 | typedef void(RunEntry)(Benchmark* benchmark); |
63 | |
64 | Benchmark(RunEntry* run, const char* name, const char* score_kind) |
65 | : run_(run), |
66 | name_(name), |
67 | score_kind_(score_kind), |
68 | score_(0), |
69 | isolate_(NULL), |
70 | next_(NULL) { |
71 | if (first_ == NULL) { |
72 | first_ = this; |
73 | } else { |
74 | tail_->next_ = this; |
75 | } |
76 | tail_ = this; |
77 | } |
78 | |
79 | // Accessors. |
80 | const char* name() const { return name_; } |
81 | const char* score_kind() const { return score_kind_; } |
82 | void set_score(int64_t value) { score_ = value; } |
83 | int64_t score() const { return score_; } |
84 | Isolate* isolate() const { return reinterpret_cast<Isolate*>(isolate_); } |
85 | |
86 | void Run() { (*run_)(this); } |
87 | void RunBenchmark(); |
88 | |
89 | static void RunAll(const char* executable); |
90 | static void SetExecutable(const char* arg) { executable_ = arg; } |
91 | static const char* Executable() { return executable_; } |
92 | |
93 | void CreateIsolate() { |
94 | isolate_ = TestCase::CreateTestIsolate(); |
95 | EXPECT(isolate_ != NULL); |
96 | } |
97 | |
98 | private: |
99 | static Benchmark* first_; |
100 | static Benchmark* tail_; |
101 | static const char* executable_; |
102 | |
103 | RunEntry* const run_; |
104 | const char* name_; |
105 | const char* score_kind_; |
106 | int64_t score_; |
107 | Dart_Isolate isolate_; |
108 | Benchmark* next_; |
109 | |
110 | DISALLOW_COPY_AND_ASSIGN(Benchmark); |
111 | }; |
112 | |
113 | class BenchmarkIsolateScope { |
114 | public: |
115 | explicit BenchmarkIsolateScope(Benchmark* benchmark) : benchmark_(benchmark) { |
116 | benchmark->CreateIsolate(); |
117 | Dart_EnterScope(); // Create a Dart API scope for unit benchmarks. |
118 | } |
119 | ~BenchmarkIsolateScope() { |
120 | Dart_ExitScope(); // Exit the Dart API scope created for unit tests. |
121 | ASSERT(benchmark_->isolate() == Isolate::Current()); |
122 | Dart_ShutdownIsolate(); |
123 | benchmark_ = NULL; |
124 | } |
125 | Benchmark* benchmark() const { return benchmark_; } |
126 | |
127 | private: |
128 | Benchmark* benchmark_; |
129 | |
130 | DISALLOW_COPY_AND_ASSIGN(BenchmarkIsolateScope); |
131 | }; |
132 | |
133 | } // namespace dart |
134 | |
135 | #endif // RUNTIME_VM_BENCHMARK_TEST_H_ |
136 | |