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

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