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

Side by Side Diff: runtime/vm/kernel_isolate.cc

Issue 2558673002: Add Kernel Isolate (Closed)
Patch Set: wip 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
(Empty)
1 // Copyright (c) 2016, 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 #include "vm/kernel_isolate.h"
6
7 #include "vm/compiler.h"
8 #include "vm/dart_api_impl.h"
9 #include "vm/dart_entry.h"
10 #include "vm/isolate.h"
11 #include "vm/lockers.h"
12 #include "vm/message.h"
13 #include "vm/message_handler.h"
14 #include "vm/native_entry.h"
15 #include "vm/native_arguments.h"
16 #include "vm/object.h"
17 #include "vm/object_store.h"
18 #include "vm/port.h"
19 #include "vm/service.h"
20 #include "vm/symbols.h"
21 #include "vm/thread_pool.h"
22 #include "vm/timeline.h"
23
24 namespace dart {
25
26 #if !defined(DART_PRECOMPILED_RUNTIME)
27
28 #define Z (T->zone())
29
30 DEFINE_FLAG(bool, trace_kernel, false, "Trace Kernel service requests.");
31 DEFINE_FLAG(bool,
32 use_dart_frontend,
33 false,
34 "Parse scripts with Dart-to-Kernel parser");
35
36 const char* KernelIsolate::kName = "kernel-service";
37 Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
38 Monitor* KernelIsolate::monitor_ = new Monitor();
39 Isolate* KernelIsolate::isolate_ = NULL;
40 bool KernelIsolate::initializing_ = true;
41 Dart_Port KernelIsolate::kernel_port_ = ILLEGAL_PORT;
42
43
44 class RunKernelTask : public ThreadPool::Task {
45 public:
46 virtual void Run() {
47 ASSERT(Isolate::Current() == NULL);
48
49 if (!FLAG_use_dart_frontend) {
50 ASSERT(FLAG_use_dart_frontend);
51 // In release builds, make this a no-op. In debug builds, the
52 // assert shows that this is not supposed to happen.
53 return;
54 }
55
56 #ifndef PRODUCT
57 TimelineDurationScope tds(Timeline::GetVMStream(), "KernelIsolateStartup");
58 #endif // !PRODUCT
59 char* error = NULL;
60 Isolate* isolate = NULL;
61
62 Dart_IsolateCreateCallback create_callback =
63 KernelIsolate::create_callback();
64
65 if (create_callback == NULL) {
66 KernelIsolate::FinishedInitializing();
67 return;
68 }
69
70 Dart_IsolateFlags api_flags;
71 Isolate::FlagsInitialize(&api_flags);
72
73 isolate = reinterpret_cast<Isolate*>(create_callback(
74 KernelIsolate::kName, NULL, NULL, NULL, &api_flags, NULL, &error));
75 if (isolate == NULL) {
76 if (FLAG_trace_kernel) {
77 OS::PrintErr("kernel-service: Isolate creation error: %s\n", error);
78 }
79 KernelIsolate::SetKernelIsolate(NULL);
80 KernelIsolate::FinishedInitializing();
81 return;
82 }
83
84 bool init_success = false;
85 {
86 ASSERT(Isolate::Current() == NULL);
87 StartIsolateScope start_scope(isolate);
88 init_success = RunMain(isolate);
89 }
90 KernelIsolate::FinishedInitializing();
91
92 if (!init_success) {
93 ShutdownIsolate(reinterpret_cast<uword>(isolate));
94 return;
95 }
96
97 // isolate_ was set as side effect of create callback.
98 ASSERT(KernelIsolate::IsKernelIsolate(isolate));
99
100 isolate->message_handler()->Run(Dart::thread_pool(), NULL, ShutdownIsolate,
101 reinterpret_cast<uword>(isolate));
102 }
103
104 protected:
105 static void ShutdownIsolate(uword parameter) {
106 if (FLAG_trace_kernel) {
107 OS::Print("kernel-service: ShutdownIsolate\n");
108 }
109 Isolate* I = reinterpret_cast<Isolate*>(parameter);
110 ASSERT(KernelIsolate::IsKernelIsolate(I));
111 KernelIsolate::SetKernelIsolate(NULL);
112 KernelIsolate::SetLoadPort(ILLEGAL_PORT);
113 I->WaitForOutstandingSpawns();
114 {
115 // Print the error if there is one. This may execute dart code to
116 // print the exception object, so we need to use a StartIsolateScope.
117 ASSERT(Isolate::Current() == NULL);
118 StartIsolateScope start_scope(I);
119 Thread* T = Thread::Current();
120 ASSERT(I == T->isolate());
121 StackZone zone(T);
122 HandleScope handle_scope(T);
123 Error& error = Error::Handle(Z);
124 error = T->sticky_error();
125 if (!error.IsNull() && !error.IsUnwindError()) {
126 OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString());
127 }
128 error = I->sticky_error();
129 if (!error.IsNull() && !error.IsUnwindError()) {
130 OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString());
131 }
132 Dart::RunShutdownCallback();
133 }
134 // Shut the isolate down.
135 Dart::ShutdownIsolate(I);
136 if (FLAG_trace_kernel) {
137 OS::Print("kernel-service: Shutdown.\n");
138 }
139 }
140
141 bool RunMain(Isolate* I) {
142 Thread* T = Thread::Current();
143 ASSERT(I == T->isolate());
144 StackZone zone(T);
145 HANDLESCOPE(T);
146 // Invoke main which will return the port to which load requests are sent.
147 const Library& root_library =
148 Library::Handle(Z, I->object_store()->root_library());
149 if (root_library.IsNull()) {
150 if (FLAG_trace_kernel) {
151 OS::Print("kernel-service: Embedder did not install a script.");
152 }
153 // Kernel isolate is not supported by embedder.
154 return false;
155 }
156 ASSERT(!root_library.IsNull());
157 const String& entry_name = String::Handle(Z, String::New("main"));
158 ASSERT(!entry_name.IsNull());
159 const Function& entry = Function::Handle(
160 Z, root_library.LookupFunctionAllowPrivate(entry_name));
161 if (entry.IsNull()) {
162 // Kernel isolate is not supported by embedder.
163 if (FLAG_trace_kernel) {
164 OS::Print("kernel-service: Embedder did not provide a main function.");
165 }
166 return false;
167 }
168 ASSERT(!entry.IsNull());
169 const Object& result = Object::Handle(
170 Z, DartEntry::InvokeFunction(entry, Object::empty_array()));
171 ASSERT(!result.IsNull());
172 if (result.IsError()) {
173 // Kernel isolate did not initialize properly.
174 if (FLAG_trace_kernel) {
175 const Error& error = Error::Cast(result);
176 OS::Print("kernel-service: Calling main resulted in an error: %s",
177 error.ToErrorCString());
178 }
179 return false;
180 }
181 ASSERT(result.IsReceivePort());
182 const ReceivePort& rp = ReceivePort::Cast(result);
183 KernelIsolate::SetLoadPort(rp.Id());
184 return true;
185 }
186 };
187
188
189 void KernelIsolate::Run() {
190 if (!FLAG_use_dart_frontend) {
191 return;
192 }
193 // Grab the isolate create callback here to avoid race conditions with tests
194 // that change this after Dart_Initialize returns.
195 create_callback_ = Isolate::CreateCallback();
196 Dart::thread_pool()->Run(new RunKernelTask());
197 }
198
199
200 void KernelIsolate::InitCallback(Isolate* I) {
201 Thread* T = Thread::Current();
202 ASSERT(I == T->isolate());
203 ASSERT(I != NULL);
204 ASSERT(I->name() != NULL);
205 if (!FLAG_use_dart_frontend ||
206 (strstr(I->name(), "kernel-service") == NULL)) {
207 // Not kernel isolate.
208 return;
209 }
210 ASSERT(!Exists());
211 if (FLAG_trace_kernel) {
212 OS::Print("kernel-service: InitCallback for %s.\n", I->name());
213 }
214 SetKernelIsolate(I);
215 }
216
217
218 bool KernelIsolate::IsKernelIsolate(const Isolate* isolate) {
219 MonitorLocker ml(monitor_);
220 return isolate == isolate_;
221 }
222
223
224 bool KernelIsolate::IsRunning() {
225 MonitorLocker ml(monitor_);
226 return (kernel_port_ != ILLEGAL_PORT) && (isolate_ != NULL);
227 }
228
229
230 bool KernelIsolate::Exists() {
231 MonitorLocker ml(monitor_);
232 return isolate_ != NULL;
233 }
234
235
236 void KernelIsolate::SetKernelIsolate(Isolate* isolate) {
237 MonitorLocker ml(monitor_);
238 isolate_ = isolate;
239 }
240
241 void KernelIsolate::SetLoadPort(Dart_Port port) {
242 MonitorLocker ml(monitor_);
243 kernel_port_ = port;
244 }
245
246 void KernelIsolate::FinishedInitializing() {
247 MonitorLocker ml(monitor_);
248 initializing_ = false;
249 ml.NotifyAll();
250 }
251
252
253 Dart_Port KernelIsolate::WaitForKernelPort() {
254 if (!FLAG_use_dart_frontend) {
255 return ILLEGAL_PORT;
256 }
257 MonitorLocker ml(monitor_);
258 while (initializing_ && (kernel_port_ == ILLEGAL_PORT)) {
259 ml.Wait();
260 }
261 return kernel_port_;
262 }
263
264 #endif // DART_PRECOMPILED_RUNTIME
265
266 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698