Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(558)

Side by Side Diff: test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc

Issue 2573493002: Use idle time to make progress on scheduled compilation jobs (Closed)
Patch Set: updates Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory>
6
7 #include "src/compiler-dispatcher/compiler-dispatcher.h" 5 #include "src/compiler-dispatcher/compiler-dispatcher.h"
6 #include "include/v8-platform.h"
vogelheim 2016/12/15 15:24:12 "includ..." < "src/..." (If you want to include t
jochen (gone - plz use gerrit) 2016/12/15 15:37:59 done
7 #include "src/compiler-dispatcher/compiler-dispatcher-job.h"
8 #include "src/flags.h" 8 #include "src/flags.h"
9 #include "src/handles.h" 9 #include "src/handles.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
11 #include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h" 11 #include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h"
12 #include "test/unittests/test-utils.h" 12 #include "test/unittests/test-utils.h"
13 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
14 14
15 namespace v8 { 15 namespace v8 {
16 namespace internal { 16 namespace internal {
17 17
18 typedef TestWithContext CompilerDispatcherTest; 18 typedef TestWithContext CompilerDispatcherTest;
19 19
20 namespace {
21
22 class MockPlatform : public v8::Platform {
23 public:
24 MockPlatform() : task_(nullptr), time_(0.0), time_step_(0.0) {}
25 ~MockPlatform() override = default;
26
27 void CallOnBackgroundThread(Task* task,
28 ExpectedRuntime expected_runtime) override {
29 UNREACHABLE();
30 }
31
32 void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
33 UNREACHABLE();
34 }
35
36 void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
37 double delay_in_seconds) override {
38 UNREACHABLE();
39 }
40
41 void CallIdleOnForegroundThread(v8::Isolate* isolate,
42 IdleTask* task) override {
43 task_ = task;
44 }
45
46 bool IdleTasksEnabled(v8::Isolate* isolate) override { return true; }
47
48 double MonotonicallyIncreasingTime() override {
49 time_ += time_step_;
50 return time_;
51 }
52
53 void RunIdleTask(double deadline_in_seconds, double time_step) {
54 ASSERT_TRUE(task_ != nullptr);
55 time_step_ = time_step;
56 IdleTask* task = task_;
57 task_ = nullptr;
58 task->Run(deadline_in_seconds);
59 delete task;
60 }
61
62 bool IdleTaskPending() const { return !!task_; }
63
64 private:
65 IdleTask* task_;
66 double time_;
67 double time_step_;
68
69 DISALLOW_COPY_AND_ASSIGN(MockPlatform);
70 };
71
72 } // namespace
73
20 TEST_F(CompilerDispatcherTest, Construct) { 74 TEST_F(CompilerDispatcherTest, Construct) {
21 std::unique_ptr<CompilerDispatcher> dispatcher( 75 MockPlatform platform;
22 new CompilerDispatcher(i_isolate(), FLAG_stack_size)); 76 CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
23 } 77 }
24 78
25 TEST_F(CompilerDispatcherTest, IsEnqueued) { 79 TEST_F(CompilerDispatcherTest, IsEnqueued) {
26 std::unique_ptr<CompilerDispatcher> dispatcher( 80 MockPlatform platform;
27 new CompilerDispatcher(i_isolate(), FLAG_stack_size)); 81 CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
28 82
29 const char script[] = 83 const char script[] =
30 "function g() { var y = 1; function f(x) { return x * y }; return f; } " 84 "function g() { var y = 1; function f1(x) { return x * y }; return f1; } "
31 "g();"; 85 "g();";
32 Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script)); 86 Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
33 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate()); 87 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
34 88
35 ASSERT_FALSE(dispatcher->IsEnqueued(shared)); 89 ASSERT_FALSE(dispatcher.IsEnqueued(shared));
36 ASSERT_TRUE(dispatcher->Enqueue(shared)); 90 ASSERT_TRUE(dispatcher.Enqueue(shared));
37 ASSERT_TRUE(dispatcher->IsEnqueued(shared)); 91 ASSERT_TRUE(dispatcher.IsEnqueued(shared));
38 dispatcher->Abort(shared, CompilerDispatcher::BlockingBehavior::kBlock); 92 dispatcher.Abort(shared, CompilerDispatcher::BlockingBehavior::kBlock);
39 ASSERT_FALSE(dispatcher->IsEnqueued(shared)); 93 ASSERT_FALSE(dispatcher.IsEnqueued(shared));
40 } 94 }
41 95
42 TEST_F(CompilerDispatcherTest, FinishNow) { 96 TEST_F(CompilerDispatcherTest, FinishNow) {
43 std::unique_ptr<CompilerDispatcher> dispatcher( 97 MockPlatform platform;
44 new CompilerDispatcher(i_isolate(), FLAG_stack_size)); 98 CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
45 99
46 const char script[] = 100 const char script[] =
47 "function g() { var y = 1; function f(x) { return x * y }; return f; } " 101 "function g() { var y = 1; function f2(x) { return x * y }; return f2; } "
48 "g();"; 102 "g();";
49 Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script)); 103 Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
50 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate()); 104 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
51 105
52 ASSERT_FALSE(shared->HasBaselineCode()); 106 ASSERT_FALSE(shared->HasBaselineCode());
53 ASSERT_TRUE(dispatcher->Enqueue(shared)); 107 ASSERT_TRUE(dispatcher.Enqueue(shared));
54 ASSERT_TRUE(dispatcher->FinishNow(shared)); 108 ASSERT_TRUE(dispatcher.FinishNow(shared));
55 // Finishing removes the SFI from the queue. 109 // Finishing removes the SFI from the queue.
56 ASSERT_FALSE(dispatcher->IsEnqueued(shared)); 110 ASSERT_FALSE(dispatcher.IsEnqueued(shared));
57 ASSERT_TRUE(shared->HasBaselineCode()); 111 ASSERT_TRUE(shared->HasBaselineCode());
58 } 112 }
59 113
114 TEST_F(CompilerDispatcherTest, IdleTask) {
115 MockPlatform platform;
116 CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
117
118 const char script[] =
119 "function g() { var y = 1; function f3(x) { return x * y }; return f3; } "
120 "g();";
121 Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
122 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
123
124 ASSERT_FALSE(platform.IdleTaskPending());
125 ASSERT_TRUE(dispatcher.Enqueue(shared));
126 ASSERT_TRUE(platform.IdleTaskPending());
127
128 // Since time doesn't progress on the MockPlatform, this is enough idle time
129 // to finish compiling the function.
130 platform.RunIdleTask(1000.0, 0.0);
131
132 ASSERT_FALSE(dispatcher.IsEnqueued(shared));
133 ASSERT_TRUE(shared->HasBaselineCode());
134 }
135
136 TEST_F(CompilerDispatcherTest, IdleTaskSmallIdleTime) {
137 MockPlatform platform;
138 CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
139
140 const char script[] =
141 "function g() { var y = 1; function f4(x) { return x * y }; return f4; } "
142 "g();";
143 Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
144 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
145
146 ASSERT_FALSE(platform.IdleTaskPending());
147 ASSERT_TRUE(dispatcher.Enqueue(shared));
148 ASSERT_TRUE(platform.IdleTaskPending());
149
150 // The job should be scheduled for the main thread.
151 ASSERT_EQ(dispatcher.jobs_.size(), 1u);
152 ASSERT_TRUE(dispatcher.jobs_.begin()->second->status() ==
153 CompileJobStatus::kInitial);
154 ASSERT_TRUE(dispatcher.jobs_for_main_thread_.find(dispatcher.jobs_.begin()) !=
155 dispatcher.jobs_for_main_thread_.end());
156
157 // Only grant a little idle time and have time advance beyond it in one step.
158 platform.RunIdleTask(2.0, 1.0);
159
160 ASSERT_TRUE(dispatcher.IsEnqueued(shared));
161 ASSERT_FALSE(shared->HasBaselineCode());
162 ASSERT_TRUE(platform.IdleTaskPending());
163
164 // The job should be still scheduled for the main thread, but ready for
165 // parsing.
166 ASSERT_EQ(dispatcher.jobs_.size(), 1u);
167 ASSERT_TRUE(dispatcher.jobs_.begin()->second->status() ==
168 CompileJobStatus::kReadyToParse);
169 ASSERT_TRUE(dispatcher.jobs_for_main_thread_.find(dispatcher.jobs_.begin()) !=
170 dispatcher.jobs_for_main_thread_.end());
171
172 // Only grant a lot of idle time and freeze time.
173 platform.RunIdleTask(1000.0, 0.0);
174
175 ASSERT_FALSE(dispatcher.IsEnqueued(shared));
176 ASSERT_TRUE(shared->HasBaselineCode());
177 ASSERT_FALSE(platform.IdleTaskPending());
178 }
179
180 TEST_F(CompilerDispatcherTest, IdleTaskException) {
181 MockPlatform platform;
182 CompilerDispatcher dispatcher(i_isolate(), &platform, 50);
183
184 std::string script("function g() { function f5(x) { var a = ");
185 for (int i = 0; i < 1000; i++) {
186 script += "'x' + ";
187 }
188 script += " 'x'; }; return f5; } g();";
189 Handle<JSFunction> f =
190 Handle<JSFunction>::cast(RunJS(isolate(), script.c_str()));
191 Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
192
193 ASSERT_FALSE(platform.IdleTaskPending());
194 ASSERT_TRUE(dispatcher.Enqueue(shared));
195 ASSERT_TRUE(platform.IdleTaskPending());
196
197 // Idle tasks shouldn't leave exceptions behind.
198 v8::TryCatch try_catch(isolate());
199
200 // Since time doesn't progress on the MockPlatform, this is enough idle time
201 // to finish compiling the function.
202 platform.RunIdleTask(1000.0, 0.0);
203
204 ASSERT_FALSE(dispatcher.IsEnqueued(shared));
205 ASSERT_FALSE(shared->HasBaselineCode());
206 ASSERT_FALSE(try_catch.HasCaught());
207 }
208
60 } // namespace internal 209 } // namespace internal
61 } // namespace v8 210 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698