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

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

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

Powered by Google App Engine
This is Rietveld 408576698