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

Side by Side Diff: runtime/bin/loader.cc

Issue 2073173002: Use the new loader mechanism to resolve URIs and load script files in gen_snapshot. This should all… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address issues that were found while testing with the flutter engine. Created 4 years, 6 months 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
« no previous file with comments | « runtime/bin/loader.h ('k') | runtime/bin/vmservice/loader.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 5
6 #include "bin/loader.h" 6 #include "bin/loader.h"
7 7
8 #include "bin/builtin.h" 8 #include "bin/builtin.h"
9 #include "bin/dartutils.h" 9 #include "bin/dartutils.h"
10 #include "bin/extensions.h" 10 #include "bin/extensions.h"
11 #include "bin/lockers.h" 11 #include "bin/lockers.h"
12 #include "bin/utils.h" 12 #include "bin/utils.h"
13 13
14 namespace dart { 14 namespace dart {
15 namespace bin { 15 namespace bin {
16 16
17 // Development flag. 17 // Development flag.
18 static bool trace_loader = false; 18 static bool trace_loader = false;
19 19
20 Loader::Loader(IsolateData* isolate_data) 20 Loader::Loader(IsolateData* isolate_data)
21 : port_(ILLEGAL_PORT), 21 : port_(ILLEGAL_PORT),
22 isolate_data_(isolate_data), 22 isolate_data_(isolate_data),
23 error_(Dart_Null()), 23 error_(Dart_Null()),
24 monitor_(NULL), 24 monitor_(NULL),
25 pending_operations_(0), 25 pending_operations_(0),
26 results_(NULL), 26 results_(NULL),
27 results_length_(0), 27 results_length_(0),
28 results_capacity_(0) { 28 results_capacity_(0),
29 payload_(NULL),
30 payload_length_(0) {
29 monitor_ = new Monitor(); 31 monitor_ = new Monitor();
30 ASSERT(isolate_data_ != NULL); 32 ASSERT(isolate_data_ != NULL);
31 port_ = Dart_NewNativePort("Loader", 33 port_ = Dart_NewNativePort("Loader",
32 Loader::NativeMessageHandler, 34 Loader::NativeMessageHandler,
33 false); 35 false);
34 isolate_data_->set_loader(this); 36 isolate_data_->set_loader(this);
35 AddLoader(port_, isolate_data_); 37 AddLoader(port_, isolate_data_);
36 } 38 }
37 39
38 40
39 Loader::~Loader() { 41 Loader::~Loader() {
40 ASSERT(port_ != ILLEGAL_PORT); 42 ASSERT(port_ != ILLEGAL_PORT);
41 // Enter the monitor while we close the Dart port. After the Dart port is 43 // Enter the monitor while we close the Dart port. After the Dart port is
42 // closed, no more results can be queued. 44 // closed, no more results can be queued.
43 monitor_->Enter(); 45 monitor_->Enter();
44 Dart_CloseNativePort(port_); 46 Dart_CloseNativePort(port_);
45 monitor_->Exit(); 47 monitor_->Exit();
46 RemoveLoader(port_); 48 RemoveLoader(port_);
47 port_ = ILLEGAL_PORT; 49 port_ = ILLEGAL_PORT;
48 isolate_data_->set_loader(NULL); 50 isolate_data_->set_loader(NULL);
49 isolate_data_ = NULL; 51 isolate_data_ = NULL;
50 delete monitor_; 52 delete monitor_;
51 monitor_ = NULL; 53 monitor_ = NULL;
52 for (intptr_t i = 0; i < results_length_; i++) { 54 for (intptr_t i = 0; i < results_length_; i++) {
53 results_[i].Cleanup(); 55 results_[i].Cleanup();
54 } 56 }
55 free(results_); 57 free(results_);
56 results_ = NULL; 58 results_ = NULL;
59 payload_ = NULL;
60 payload_length_ = 0;
57 } 61 }
58 62
59 63
60 // Copy the contents of |message| into an |IOResult|. 64 // Copy the contents of |message| into an |IOResult|.
61 void Loader::IOResult::Setup(Dart_CObject* message) { 65 void Loader::IOResult::Setup(Dart_CObject* message) {
62 ASSERT(message->type == Dart_CObject_kArray); 66 ASSERT(message->type == Dart_CObject_kArray);
63 ASSERT(message->value.as_array.length == 4); 67 ASSERT(message->value.as_array.length == 4);
64 Dart_CObject* tag_message = message->value.as_array.values[0]; 68 Dart_CObject* tag_message = message->value.as_array.values[0];
65 ASSERT(tag_message != NULL); 69 ASSERT(tag_message != NULL);
66 Dart_CObject* uri_message = message->value.as_array.values[1]; 70 Dart_CObject* uri_message = message->value.as_array.values[1];
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 ASSERT(results_ != NULL); 188 ASSERT(results_ != NULL);
185 } 189 }
186 ASSERT(results_ != NULL); 190 ASSERT(results_ != NULL);
187 ASSERT(results_length_ < results_capacity_); 191 ASSERT(results_length_ < results_capacity_);
188 results_[results_length_].Setup(message); 192 results_[results_length_].Setup(message);
189 results_length_++; 193 results_length_++;
190 ml.Notify(); 194 ml.Notify();
191 } 195 }
192 196
193 197
194 void Loader::BlockUntilComplete() { 198 void Loader::BlockUntilComplete(ProcessResult process_result) {
195 MonitorLocker ml(monitor_); 199 MonitorLocker ml(monitor_);
196 200
197 while (true) { 201 while (true) {
198 // If |ProcessQueueLocked| returns false, we've hit an error and should 202 // If |ProcessQueueLocked| returns false, we've hit an error and should
199 // stop loading. 203 // stop loading.
200 if (!ProcessQueueLocked()) { 204 if (!ProcessQueueLocked(process_result)) {
201 break; 205 break;
202 } 206 }
203 207
204 // When |pending_operations_| hits 0, we are done loading. 208 // When |pending_operations_| hits 0, we are done loading.
205 if (pending_operations_ == 0) { 209 if (pending_operations_ == 0) {
206 break; 210 break;
207 } 211 }
208 212
209 // Wait to be notified about new I/O results. 213 // Wait to be notified about new I/O results.
210 ml.Wait(); 214 ml.Wait();
211 } 215 }
212 } 216 }
213 217
214 218
215 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) { 219 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) {
216 if (!Dart_IsNull(library) && !Dart_IsError(library)) { 220 if (!Dart_IsNull(library) && !Dart_IsError(library)) {
217 ASSERT(Dart_IsLibrary(library)); 221 ASSERT(Dart_IsLibrary(library));
218 Dart_Handle res = Dart_LibraryHandleError(library, error); 222 Dart_Handle res = Dart_LibraryHandleError(library, error);
219 if (Dart_IsNull(res)) { 223 if (Dart_IsNull(res)) {
220 // Error was handled by library. 224 // Error was handled by library.
221 return true; 225 return true;
222 } 226 }
223 } 227 }
224 return false; 228 return false;
225 } 229 }
226 230
227 231
228 bool Loader::ProcessResultLocked(Loader::IOResult* result) { 232 bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) {
229 // We have to copy everything we care about out of |result| because after 233 // We have to copy everything we care about out of |result| because after
230 // dropping the lock below |result| may no longer valid. 234 // dropping the lock below |result| may no longer valid.
231 Dart_Handle uri = 235 Dart_Handle uri =
232 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); 236 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri));
233 Dart_Handle library_uri = Dart_Null(); 237 Dart_Handle library_uri = Dart_Null();
234 if (result->library_uri != NULL) { 238 if (result->library_uri != NULL) {
235 library_uri = 239 library_uri =
236 Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri)); 240 Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri));
237 } 241 }
238 242
239 // A negative result tag indicates a loading error occurred in the service 243 // A negative result tag indicates a loading error occurred in the service
240 // isolate. The payload is a C string of the error message. 244 // isolate. The payload is a C string of the error message.
241 if (result->tag < 0) { 245 if (result->tag < 0) {
242 Dart_Handle library = Dart_LookupLibrary(uri); 246 Dart_Handle library = Dart_LookupLibrary(uri);
243 Dart_Handle error = Dart_NewStringFromUTF8(result->payload, 247 Dart_Handle error = Dart_NewStringFromUTF8(result->payload,
244 result->payload_length); 248 result->payload_length);
245 // If a library with the given uri exists, give it a chance to handle 249 // If a library with the given uri exists, give it a chance to handle
246 // the error. If the load requests stems from a deferred library load, 250 // the error. If the load requests stems from a deferred library load,
247 // an IO error is not fatal. 251 // an IO error is not fatal.
248 if (LibraryHandleError(library, error)) { 252 if (LibraryHandleError(library, error)) {
249 return true; 253 return true;
250 } 254 }
251 // Fall through 255 // Fall through
252 error_ = Dart_NewUnhandledExceptionError(error); 256 loader->error_ = Dart_NewUnhandledExceptionError(error);
253 return false; 257 return false;
254 } 258 }
255 259
256 260
257 // Check for payload and load accordingly. 261 // Check for payload and load accordingly.
258 bool is_snapshot = false; 262 bool is_snapshot = false;
259 const uint8_t* payload = result->payload; 263 const uint8_t* payload = result->payload;
260 intptr_t payload_length = result->payload_length; 264 intptr_t payload_length = result->payload_length;
261 payload = 265 payload =
262 DartUtils::SniffForMagicNumber(payload, 266 DartUtils::SniffForMagicNumber(payload,
263 &payload_length, 267 &payload_length,
264 &is_snapshot); 268 &is_snapshot);
265 Dart_Handle source = Dart_Null(); 269 Dart_Handle source = Dart_Null();
266 if (!is_snapshot) { 270 if (!is_snapshot) {
267 source = Dart_NewStringFromUTF8(result->payload, 271 source = Dart_NewStringFromUTF8(result->payload,
268 result->payload_length); 272 result->payload_length);
269 if (Dart_IsError(source)) { 273 if (Dart_IsError(source)) {
270 error_ = DartUtils::NewError("%s is not a valid UTF-8 script", 274 loader->error_ = DartUtils::NewError(
271 reinterpret_cast<char*>(result->uri)); 275 "%s is not a valid UTF-8 script",
276 reinterpret_cast<char*>(result->uri));
272 return false; 277 return false;
273 } 278 }
274 } 279 }
275 intptr_t tag = result->tag; 280 intptr_t tag = result->tag;
276 281
277 // No touching. 282 // No touching.
278 result = NULL; 283 result = NULL;
279 284
280 // We must drop the lock here because the tag handler may be recursively 285 // We must drop the lock here because the tag handler may be recursively
281 // invoked and it will attempt to acquire the lock to queue more work. 286 // invoked and it will attempt to acquire the lock to queue more work.
282 monitor_->Exit(); 287 loader->monitor_->Exit();
283 288
284 Dart_Handle dart_result = Dart_Null(); 289 Dart_Handle dart_result = Dart_Null();
285 290
286 switch (tag) { 291 switch (tag) {
287 case Dart_kImportTag: 292 case Dart_kImportTag:
288 dart_result = Dart_LoadLibrary(uri, source, 0, 0); 293 dart_result = Dart_LoadLibrary(uri, source, 0, 0);
289 break; 294 break;
290 case Dart_kSourceTag: { 295 case Dart_kSourceTag: {
291 ASSERT(library_uri != Dart_Null()); 296 ASSERT(library_uri != Dart_Null());
292 Dart_Handle library = Dart_LookupLibrary(library_uri); 297 Dart_Handle library = Dart_LookupLibrary(library_uri);
293 ASSERT(!Dart_IsError(library)); 298 ASSERT(!Dart_IsError(library));
294 dart_result = Dart_LoadSource(library, uri, source, 0, 0); 299 dart_result = Dart_LoadSource(library, uri, source, 0, 0);
295 } 300 }
296 break; 301 break;
297 case Dart_kScriptTag: 302 case Dart_kScriptTag:
298 if (is_snapshot) { 303 if (is_snapshot) {
299 dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length); 304 dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length);
300 } else { 305 } else {
301 dart_result = Dart_LoadScript(uri, source, 0, 0); 306 dart_result = Dart_LoadScript(uri, source, 0, 0);
302 } 307 }
303 break; 308 break;
304 default: 309 default:
305 UNREACHABLE(); 310 UNREACHABLE();
306 } 311 }
307 312
308 // Re-acquire the lock before exiting the function (it was held before entry), 313 // Re-acquire the lock before exiting the function (it was held before entry),
309 monitor_->Enter(); 314 loader->monitor_->Enter();
310 if (Dart_IsError(dart_result)) { 315 if (Dart_IsError(dart_result)) {
311 // Remember the error if we encountered one. 316 // Remember the error if we encountered one.
312 error_ = dart_result; 317 loader->error_ = dart_result;
313 return false; 318 return false;
314 } 319 }
315 320
316 return true; 321 return true;
317 } 322 }
318 323
319 324
320 bool Loader::ProcessQueueLocked() { 325 bool Loader::ProcessUrlLoadResultLocked(Loader* loader,
326 Loader::IOResult* result) {
327 // A negative result tag indicates a loading error occurred in the service
328 // isolate. The payload is a C string of the error message.
329 if (result->tag < 0) {
330 Dart_Handle error = Dart_NewStringFromUTF8(result->payload,
331 result->payload_length);
332 loader->error_ = Dart_NewUnhandledExceptionError(error);
333 return false;
334 }
335 loader->payload_length_ = result->payload_length;
336 loader->payload_ =
337 reinterpret_cast<uint8_t*>(::malloc(loader->payload_length_));
338 memmove(loader->payload_, result->payload, loader->payload_length_);
339 return true;
340 }
341
342
343 bool Loader::ProcessQueueLocked(ProcessResult process_result) {
321 bool hit_error = false; 344 bool hit_error = false;
322 for (intptr_t i = 0; i < results_length(); i++) { 345 for (intptr_t i = 0; i < results_length(); i++) {
323 if (!hit_error) { 346 if (!hit_error) {
324 hit_error = !ProcessResultLocked(&results_[i]); 347 hit_error = !(*process_result)(this, &results_[i]);
325 } 348 }
326 pending_operations_--; 349 pending_operations_--;
327 ASSERT(hit_error || (pending_operations_ >= 0)); 350 ASSERT(hit_error || (pending_operations_ >= 0));
328 results_[i].Cleanup(); 351 results_[i].Cleanup();
329 } 352 }
330 results_length_ = 0; 353 results_length_ = 0;
331 return !hit_error; 354 return !hit_error;
332 } 355 }
333 356
334 357
(...skipping 16 matching lines...) Expand all
351 // Send the init message. 374 // Send the init message.
352 loader->Init(isolate_data->package_root, 375 loader->Init(isolate_data->package_root,
353 isolate_data->packages_file, 376 isolate_data->packages_file,
354 DartUtils::original_working_directory, 377 DartUtils::original_working_directory,
355 snapshot_uri); 378 snapshot_uri);
356 // Destroy the loader. The destructor does a bunch of leg work. 379 // Destroy the loader. The destructor does a bunch of leg work.
357 delete loader; 380 delete loader;
358 } 381 }
359 382
360 383
384 Dart_Handle Loader::LoadUrlContents(Dart_Handle url,
385 uint8_t** payload,
386 intptr_t* payload_length) {
387 IsolateData* isolate_data =
388 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
389 ASSERT(isolate_data != NULL);
390 ASSERT(!isolate_data->HasLoader());
391 Loader* loader = NULL;
392
393 // Setup the loader. The constructor does a bunch of leg work.
394 loader = new Loader(isolate_data);
395 loader->Init(isolate_data->package_root,
396 isolate_data->packages_file,
397 DartUtils::original_working_directory,
398 NULL);
399 ASSERT(loader != NULL);
400 ASSERT(isolate_data->HasLoader());
401
402 // Now send a load request to the service isolate.
403 loader->SendRequest(Dart_kScriptTag, url, Dart_Null());
404
405 // Wait for a reply to the load request.
406 loader->BlockUntilComplete(ProcessUrlLoadResultLocked);
407
408 // Copy fields from the loader before deleting it.
409 // The payload array itself which was malloced above is freed by
410 // the caller of LoadUrlContents.
411 Dart_Handle error = loader->error();
412 *payload = loader->payload_;
413 *payload_length = loader->payload_length_;
414
415 // Destroy the loader. The destructor does a bunch of leg work.
416 delete loader;
417
418 // An error occurred during loading.
419 if (!Dart_IsNull(error)) {
420 return error;
421 }
422 return Dart_Null();
423 }
424
425
361 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, 426 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
362 Dart_Handle library, 427 Dart_Handle library,
363 Dart_Handle url) { 428 Dart_Handle url) {
364 if (tag == Dart_kCanonicalizeUrl) { 429 if (tag == Dart_kCanonicalizeUrl) {
365 Dart_Handle library_url = Dart_LibraryUrl(library); 430 Dart_Handle library_url = Dart_LibraryUrl(library);
366 if (Dart_IsError(library_url)) { 431 if (Dart_IsError(library_url)) {
367 return library_url; 432 return library_url;
368 } 433 }
369 return Dart_DefaultCanonicalizeUrl(library_url, url); 434 return Dart_DefaultCanonicalizeUrl(library_url, url);
370 } 435 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 ASSERT(isolate_data->HasLoader()); 524 ASSERT(isolate_data->HasLoader());
460 525
461 loader->SendRequest(tag, 526 loader->SendRequest(tag,
462 url, 527 url,
463 (library != Dart_Null()) ? 528 (library != Dart_Null()) ?
464 Dart_LibraryUrl(library) : Dart_Null()); 529 Dart_LibraryUrl(library) : Dart_Null());
465 530
466 if (blocking_call) { 531 if (blocking_call) {
467 // The outer invocation of the tag handler will block here until all nested 532 // The outer invocation of the tag handler will block here until all nested
468 // invocations complete. 533 // invocations complete.
469 loader->BlockUntilComplete(); 534 loader->BlockUntilComplete(ProcessResultLocked);
470 535
471 // Remember the error (if any). 536 // Remember the error (if any).
472 Dart_Handle error = loader->error(); 537 Dart_Handle error = loader->error();
473 // Destroy the loader. The destructor does a bunch of leg work. 538 // Destroy the loader. The destructor does a bunch of leg work.
474 delete loader; 539 delete loader;
475 540
476 // An error occurred during loading. 541 // An error occurred during loading.
477 if (!Dart_IsNull(error)) { 542 if (!Dart_IsNull(error)) {
478 if (false && is_deferred_import) { 543 if (false && is_deferred_import) {
479 // This blocks handles transitive load errors caused by a deferred 544 // This blocks handles transitive load errors caused by a deferred
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 MutexLocker ml(&loader_infos_lock_); 690 MutexLocker ml(&loader_infos_lock_);
626 Loader* loader = LoaderForLocked(dest_port_id); 691 Loader* loader = LoaderForLocked(dest_port_id);
627 if (loader == NULL) { 692 if (loader == NULL) {
628 return; 693 return;
629 } 694 }
630 loader->QueueMessage(message); 695 loader->QueueMessage(message);
631 } 696 }
632 697
633 } // namespace bin 698 } // namespace bin
634 } // namespace dart 699 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/loader.h ('k') | runtime/bin/vmservice/loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698