OLD | NEW |
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 "src/compiler-dispatcher/compiler-dispatcher.h" | 5 #include "src/compiler-dispatcher/compiler-dispatcher.h" |
6 | 6 |
7 #include "include/v8-platform.h" | 7 #include "include/v8-platform.h" |
| 8 #include "src/api.h" |
8 #include "src/base/platform/semaphore.h" | 9 #include "src/base/platform/semaphore.h" |
9 #include "src/compiler-dispatcher/compiler-dispatcher-job.h" | 10 #include "src/compiler-dispatcher/compiler-dispatcher-job.h" |
10 #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" | 11 #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" |
11 #include "src/compiler.h" | 12 #include "src/compiler.h" |
12 #include "src/flags.h" | 13 #include "src/flags.h" |
13 #include "src/handles.h" | 14 #include "src/handles.h" |
14 #include "src/objects-inl.h" | 15 #include "src/objects-inl.h" |
15 #include "src/parsing/parse-info.h" | 16 #include "src/parsing/parse-info.h" |
16 #include "src/parsing/parsing.h" | 17 #include "src/parsing/parsing.h" |
17 #include "src/v8.h" | 18 #include "src/v8.h" |
18 #include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h" | 19 #include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h" |
19 #include "test/unittests/test-utils.h" | 20 #include "test/unittests/test-utils.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
21 | 22 |
22 namespace v8 { | 23 namespace v8 { |
23 namespace internal { | 24 namespace internal { |
24 | 25 |
| 26 class CompilerDispatcherTestFlags { |
| 27 public: |
| 28 static void SetFlagsForTest() { |
| 29 old_compiler_dispatcher_flag_ = i::FLAG_compiler_dispatcher; |
| 30 i::FLAG_compiler_dispatcher = true; |
| 31 old_ignition_flag_ = i::FLAG_ignition; |
| 32 i::FLAG_ignition = true; |
| 33 } |
| 34 |
| 35 static void RestoreFlags() { |
| 36 i::FLAG_compiler_dispatcher = old_compiler_dispatcher_flag_; |
| 37 i::FLAG_ignition = old_ignition_flag_; |
| 38 } |
| 39 |
| 40 private: |
| 41 static bool old_compiler_dispatcher_flag_; |
| 42 static bool old_ignition_flag_; |
| 43 |
| 44 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilerDispatcherTestFlags); |
| 45 }; |
| 46 |
| 47 bool CompilerDispatcherTestFlags::old_compiler_dispatcher_flag_; |
| 48 bool CompilerDispatcherTestFlags::old_ignition_flag_; |
| 49 |
25 class CompilerDispatcherTest : public TestWithContext { | 50 class CompilerDispatcherTest : public TestWithContext { |
26 public: | 51 public: |
27 CompilerDispatcherTest() = default; | 52 CompilerDispatcherTest() = default; |
28 ~CompilerDispatcherTest() override = default; | 53 ~CompilerDispatcherTest() override = default; |
29 | 54 |
30 static void SetUpTestCase() { | 55 static void SetUpTestCase() { |
31 old_flag_ = i::FLAG_ignition; | 56 CompilerDispatcherTestFlags::SetFlagsForTest(); |
32 i::FLAG_compiler_dispatcher = true; | |
33 old_ignition_flag_ = i::FLAG_ignition; | |
34 i::FLAG_ignition = true; | |
35 TestWithContext::SetUpTestCase(); | 57 TestWithContext::SetUpTestCase(); |
36 } | 58 } |
37 | 59 |
38 static void TearDownTestCase() { | 60 static void TearDownTestCase() { |
39 TestWithContext::TearDownTestCase(); | 61 TestWithContext::TearDownTestCase(); |
40 i::FLAG_compiler_dispatcher = old_flag_; | 62 CompilerDispatcherTestFlags::RestoreFlags(); |
41 i::FLAG_ignition = old_ignition_flag_; | |
42 } | 63 } |
43 | 64 |
44 private: | 65 private: |
45 static bool old_flag_; | |
46 static bool old_ignition_flag_; | |
47 | |
48 DISALLOW_COPY_AND_ASSIGN(CompilerDispatcherTest); | 66 DISALLOW_COPY_AND_ASSIGN(CompilerDispatcherTest); |
49 }; | 67 }; |
50 | 68 |
51 bool CompilerDispatcherTest::old_flag_; | 69 class CompilerDispatcherTestWithoutContext : public v8::TestWithIsolate { |
52 bool CompilerDispatcherTest::old_ignition_flag_; | 70 public: |
| 71 CompilerDispatcherTestWithoutContext() = default; |
| 72 ~CompilerDispatcherTestWithoutContext() override = default; |
| 73 |
| 74 static void SetUpTestCase() { |
| 75 CompilerDispatcherTestFlags::SetFlagsForTest(); |
| 76 TestWithContext::SetUpTestCase(); |
| 77 } |
| 78 |
| 79 static void TearDownTestCase() { |
| 80 TestWithContext::TearDownTestCase(); |
| 81 CompilerDispatcherTestFlags::RestoreFlags(); |
| 82 } |
| 83 |
| 84 private: |
| 85 DISALLOW_COPY_AND_ASSIGN(CompilerDispatcherTestWithoutContext); |
| 86 }; |
53 | 87 |
54 namespace { | 88 namespace { |
55 | 89 |
56 class MockPlatform : public v8::Platform { | 90 class MockPlatform : public v8::Platform { |
57 public: | 91 public: |
58 MockPlatform() : time_(0.0), time_step_(0.0), idle_task_(nullptr), sem_(0) {} | 92 MockPlatform() : time_(0.0), time_step_(0.0), idle_task_(nullptr), sem_(0) {} |
59 ~MockPlatform() override { | 93 ~MockPlatform() override { |
60 base::LockGuard<base::Mutex> lock(&mutex_); | 94 base::LockGuard<base::Mutex> lock(&mutex_); |
61 EXPECT_TRUE(foreground_tasks_.empty()); | 95 EXPECT_TRUE(foreground_tasks_.empty()); |
62 EXPECT_TRUE(background_tasks_.empty()); | 96 EXPECT_TRUE(background_tasks_.empty()); |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 // Exit the handles scope and destroy ParseInfo before running the idle task. | 966 // Exit the handles scope and destroy ParseInfo before running the idle task. |
933 | 967 |
934 // Since time doesn't progress on the MockPlatform, this is enough idle time | 968 // Since time doesn't progress on the MockPlatform, this is enough idle time |
935 // to finish compiling the function. | 969 // to finish compiling the function. |
936 platform.RunIdleTask(1000.0, 0.0); | 970 platform.RunIdleTask(1000.0, 0.0); |
937 | 971 |
938 ASSERT_FALSE(dispatcher.IsEnqueued(shared)); | 972 ASSERT_FALSE(dispatcher.IsEnqueued(shared)); |
939 ASSERT_TRUE(shared->is_compiled()); | 973 ASSERT_TRUE(shared->is_compiled()); |
940 } | 974 } |
941 | 975 |
| 976 namespace { |
| 977 |
| 978 const char kExtensionSource[] = "native function Dummy();"; |
| 979 |
| 980 class MockNativeFunctionExtension : public Extension { |
| 981 public: |
| 982 MockNativeFunctionExtension() |
| 983 : Extension("mock-extension", kExtensionSource), function_(&Dummy) {} |
| 984 |
| 985 virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( |
| 986 v8::Isolate* isolate, v8::Local<v8::String> name) { |
| 987 return v8::FunctionTemplate::New(isolate, function_); |
| 988 } |
| 989 |
| 990 static void Dummy(const v8::FunctionCallbackInfo<v8::Value>& args) { return; } |
| 991 |
| 992 private: |
| 993 v8::FunctionCallback function_; |
| 994 |
| 995 DISALLOW_COPY_AND_ASSIGN(MockNativeFunctionExtension); |
| 996 }; |
| 997 |
| 998 } // namespace |
| 999 |
| 1000 TEST_F(CompilerDispatcherTestWithoutContext, CompileExtensionWithoutContext) { |
| 1001 MockPlatform platform; |
| 1002 CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size); |
| 1003 Local<v8::Context> context = v8::Context::New(isolate()); |
| 1004 |
| 1005 MockNativeFunctionExtension extension; |
| 1006 Handle<String> script_str = |
| 1007 i_isolate() |
| 1008 ->factory() |
| 1009 ->NewStringFromUtf8(CStrVector(kExtensionSource)) |
| 1010 .ToHandleChecked(); |
| 1011 Handle<Script> script = i_isolate()->factory()->NewScript(script_str); |
| 1012 script->set_type(Script::TYPE_EXTENSION); |
| 1013 |
| 1014 Handle<SharedFunctionInfo> shared; |
| 1015 { |
| 1016 v8::Context::Scope scope(context); |
| 1017 |
| 1018 ParseInfo parse_info(script); |
| 1019 parse_info.set_extension(&extension); |
| 1020 |
| 1021 ASSERT_TRUE(parsing::ParseAny(&parse_info)); |
| 1022 Handle<FixedArray> shared_infos_array(i_isolate()->factory()->NewFixedArray( |
| 1023 parse_info.max_function_literal_id() + 1)); |
| 1024 parse_info.script()->set_shared_function_infos(*shared_infos_array); |
| 1025 DeferredHandleScope handles_scope(i_isolate()); |
| 1026 { ASSERT_TRUE(Compiler::Analyze(&parse_info)); } |
| 1027 std::shared_ptr<DeferredHandles> compilation_handles( |
| 1028 handles_scope.Detach()); |
| 1029 |
| 1030 shared = i_isolate()->factory()->NewSharedFunctionInfoForLiteral( |
| 1031 parse_info.literal(), script); |
| 1032 parse_info.set_shared_info(shared); |
| 1033 |
| 1034 ASSERT_FALSE(platform.IdleTaskPending()); |
| 1035 ASSERT_TRUE(dispatcher.Enqueue( |
| 1036 shared, parse_info.literal(), parse_info.zone_shared(), |
| 1037 parse_info.deferred_handles(), compilation_handles)); |
| 1038 ASSERT_TRUE(platform.IdleTaskPending()); |
| 1039 } |
| 1040 // Exit the context scope before running the idle task. |
| 1041 |
| 1042 // Since time doesn't progress on the MockPlatform, this is enough idle time |
| 1043 // to finish compiling the function. |
| 1044 platform.RunIdleTask(1000.0, 0.0); |
| 1045 |
| 1046 ASSERT_FALSE(dispatcher.IsEnqueued(shared)); |
| 1047 ASSERT_TRUE(shared->is_compiled()); |
| 1048 } |
| 1049 |
942 } // namespace internal | 1050 } // namespace internal |
943 } // namespace v8 | 1051 } // namespace v8 |
OLD | NEW |