Line data Source code
1 : // Copyright 2017 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/compiler-dispatcher/optimizing-compile-dispatcher.h"
6 :
7 : #include "src/api-inl.h"
8 : #include "src/base/atomic-utils.h"
9 : #include "src/base/platform/semaphore.h"
10 : #include "src/compiler.h"
11 : #include "src/handles.h"
12 : #include "src/isolate.h"
13 : #include "src/objects-inl.h"
14 : #include "src/optimized-compilation-info.h"
15 : #include "src/parsing/parse-info.h"
16 : #include "test/unittests/test-helpers.h"
17 : #include "test/unittests/test-utils.h"
18 : #include "testing/gtest/include/gtest/gtest.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : typedef TestWithNativeContext OptimizingCompileDispatcherTest;
24 :
25 : namespace {
26 :
27 : class BlockingCompilationJob : public OptimizedCompilationJob {
28 : public:
29 1 : BlockingCompilationJob(Isolate* isolate, Handle<JSFunction> function)
30 : : OptimizedCompilationJob(isolate->stack_guard()->real_climit(), &info_,
31 : "BlockingCompilationJob",
32 : State::kReadyToExecute),
33 : shared_(function->shared(), isolate),
34 : zone_(isolate->allocator(), ZONE_NAME),
35 : info_(&zone_, isolate, shared_, function),
36 : blocking_(false),
37 4 : semaphore_(0) {}
38 3 : ~BlockingCompilationJob() override = default;
39 :
40 : bool IsBlocking() const { return blocking_.Value(); }
41 1 : void Signal() { semaphore_.Signal(); }
42 :
43 : // OptimiziedCompilationJob implementation.
44 0 : Status PrepareJobImpl(Isolate* isolate) override { UNREACHABLE(); }
45 :
46 1 : Status ExecuteJobImpl() override {
47 : blocking_.SetValue(true);
48 1 : semaphore_.Wait();
49 : blocking_.SetValue(false);
50 1 : return SUCCEEDED;
51 : }
52 :
53 0 : Status FinalizeJobImpl(Isolate* isolate) override { return SUCCEEDED; }
54 :
55 : private:
56 : Handle<SharedFunctionInfo> shared_;
57 : Zone zone_;
58 : OptimizedCompilationInfo info_;
59 : base::AtomicValue<bool> blocking_;
60 : base::Semaphore semaphore_;
61 :
62 : DISALLOW_COPY_AND_ASSIGN(BlockingCompilationJob);
63 : };
64 :
65 : } // namespace
66 :
67 15444 : TEST_F(OptimizingCompileDispatcherTest, Construct) {
68 2 : OptimizingCompileDispatcher dispatcher(i_isolate());
69 1 : ASSERT_TRUE(OptimizingCompileDispatcher::Enabled());
70 1 : ASSERT_TRUE(dispatcher.IsQueueAvailable());
71 : }
72 :
73 15444 : TEST_F(OptimizingCompileDispatcherTest, NonBlockingFlush) {
74 : Handle<JSFunction> fun =
75 : RunJS<JSFunction>("function f() { function g() {}; return g;}; f();");
76 : IsCompiledScope is_compiled_scope;
77 2 : ASSERT_TRUE(
78 : Compiler::Compile(fun, Compiler::CLEAR_EXCEPTION, &is_compiled_scope));
79 1 : BlockingCompilationJob* job = new BlockingCompilationJob(i_isolate(), fun);
80 :
81 2 : OptimizingCompileDispatcher dispatcher(i_isolate());
82 1 : ASSERT_TRUE(OptimizingCompileDispatcher::Enabled());
83 1 : ASSERT_TRUE(dispatcher.IsQueueAvailable());
84 1 : dispatcher.QueueForOptimization(job);
85 :
86 : // Busy-wait for the job to run on a background thread.
87 2895204 : while (!job->IsBlocking()) {
88 : }
89 :
90 : // Should not block.
91 1 : dispatcher.Flush(BlockingBehavior::kDontBlock);
92 :
93 : // Unblock the job & finish.
94 : job->Signal();
95 1 : dispatcher.Stop();
96 : }
97 :
98 : } // namespace internal
99 9264 : } // namespace v8
|