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

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 #define Z (T->zone())
27
28 DEFINE_FLAG(bool, trace_kernel, false, "Trace Kernel service requests.");
29
30
31 const char* KernelIsolate::kName = "kernel-service";
32 Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
33 Monitor* KernelIsolate::monitor_ = NULL;
34 Isolate* KernelIsolate::isolate_ = NULL;
35 bool KernelIsolate::initializing_ = true;
36 bool KernelIsolate::shutting_down_ = false;
37 Dart_Port KernelIsolate::kernel_port_ = ILLEGAL_PORT;
38
39
40 class RunKernelTask : public ThreadPool::Task {
41 public:
42 virtual void Run() {
43 ASSERT(Isolate::Current() == NULL);
44
45 #ifndef PRODUCT
46 TimelineDurationScope tds(Timeline::GetVMStream(), "KernelIsolateStartup");
47 #endif // !PRODUCT
48 char* error = NULL;
49 Isolate* isolate = NULL;
50
51 Dart_IsolateCreateCallback create_callback =
52 KernelIsolate::create_callback();
53
54 if (create_callback == NULL) {
55 KernelIsolate::FinishedInitializing();
56 return;
57 }
58
59 Dart_IsolateFlags api_flags;
60 Isolate::FlagsInitialize(&api_flags);
61
62 isolate = reinterpret_cast<Isolate*>(create_callback(
63 KernelIsolate::kName, NULL, NULL, NULL, &api_flags, NULL, &error));
64 if (isolate == NULL) {
65 if (FLAG_trace_kernel) {
66 OS::PrintErr("kernel-service: Isolate creation error: %s\n", error);
67 }
68 KernelIsolate::SetKernelIsolate(NULL);
69 KernelIsolate::FinishedInitializing();
70 KernelIsolate::FinishedExiting();
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 ShutdownIsolate(reinterpret_cast<uword>(isolate));
83 return;
84 }
85
86 KernelIsolate::FinishedInitializing();
87
88 // isolate_ was set as side effect of create callback.
89 ASSERT(KernelIsolate::isolate_ == isolate);
90
91 isolate->message_handler()->Run(Dart::thread_pool(), NULL, ShutdownIsolate,
92 reinterpret_cast<uword>(isolate));
93 }
94
95 protected:
96 static void ShutdownIsolate(uword parameter) {
97 if (FLAG_trace_kernel) {
98 OS::Print("kernel-service: ShutdownIsolate\n");
99 }
100 Isolate* I = reinterpret_cast<Isolate*>(parameter);
101 ASSERT(KernelIsolate::IsKernelIsolate(I));
102 KernelIsolate::SetKernelIsolate(NULL);
103 KernelIsolate::SetLoadPort(ILLEGAL_PORT);
104 I->WaitForOutstandingSpawns();
105 {
106 // Print the error if there is one. This may execute dart code to
107 // print the exception object, so we need to use a StartIsolateScope.
108 ASSERT(Isolate::Current() == NULL);
109 StartIsolateScope start_scope(I);
110 Thread* T = Thread::Current();
111 ASSERT(I == T->isolate());
112 StackZone zone(T);
113 HandleScope handle_scope(T);
114 Error& error = Error::Handle(Z);
115 error = T->sticky_error();
116 if (!error.IsNull() && !error.IsUnwindError()) {
117 OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString());
118 }
119 error = I->sticky_error();
120 if (!error.IsNull() && !error.IsUnwindError()) {
121 OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString());
122 }
123 Dart::RunShutdownCallback();
124 }
125 // Shut the isolate down.
126 Dart::ShutdownIsolate(I);
127 if (FLAG_trace_kernel) {
128 OS::Print("kernel-service: Shutdown.\n");
129 }
130 KernelIsolate::FinishedExiting();
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;
siva 2016/12/02 00:39:23 This false return is weird here as we will continu
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;
siva 2016/12/02 00:39:23 ditto comment here about the false return.
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;
siva 2016/12/02 00:39:23 ditto comment here about the false return
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 void KernelIsolate::FinishedExiting() {
225 MonitorLocker ml(monitor_);
226 shutting_down_ = false;
227 ml.NotifyAll();
228 }
229
230
231 bool KernelIsolate::Exists() {
232 MonitorLocker ml(monitor_);
233 return isolate_ != NULL;
234 }
235
236
237 void KernelIsolate::SetKernelIsolate(Isolate* isolate) {
238 MonitorLocker ml(monitor_);
239 isolate_ = isolate;
240 }
241
242 void KernelIsolate::SetLoadPort(Dart_Port port) {
243 MonitorLocker ml(monitor_);
244 kernel_port_ = port;
245 }
246
247 void KernelIsolate::FinishedInitializing() {
248 MonitorLocker ml(monitor_);
249 initializing_ = false;
250 ml.NotifyAll();
251 }
252
253
254 Dart_Port KernelIsolate::WaitForKernelPort() {
255 MonitorLocker ml(monitor_);
256 while (initializing_ && (kernel_port_ == ILLEGAL_PORT)) {
257 ml.Wait();
258 }
259 return kernel_port_;
260 }
261
262 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698