Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #include "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "include/dart_mirrors_api.h" | 6 #include "include/dart_mirrors_api.h" |
| 7 #include "include/dart_native_api.h" | 7 #include "include/dart_native_api.h" |
| 8 | 8 |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "lib/stacktrace.h" | 10 #include "lib/stacktrace.h" |
| 11 #include "vm/class_finalizer.h" | 11 #include "vm/class_finalizer.h" |
| 12 #include "vm/clustered_snapshot.h" | 12 #include "vm/clustered_snapshot.h" |
| 13 #include "vm/compiler.h" | 13 #include "vm/compiler.h" |
| 14 #include "vm/dart.h" | 14 #include "vm/dart.h" |
| 15 #include "vm/dart_api_impl.h" | 15 #include "vm/dart_api_impl.h" |
| 16 #include "vm/dart_api_message.h" | 16 #include "vm/dart_api_message.h" |
| 17 #include "vm/dart_api_state.h" | 17 #include "vm/dart_api_state.h" |
| 18 #include "vm/dart_entry.h" | 18 #include "vm/dart_entry.h" |
| 19 #include "vm/debugger.h" | 19 #include "vm/debugger.h" |
| 20 #if !defined(DART_PRECOMPILED_RUNTIME) | 20 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 21 #include "vm/kernel_reader.h" | 21 #include "vm/kernel_reader.h" |
| 22 #endif | 22 #endif |
| 23 #include "vm/exceptions.h" | 23 #include "vm/exceptions.h" |
| 24 #include "vm/flags.h" | 24 #include "vm/flags.h" |
| 25 #include "vm/growable_array.h" | 25 #include "vm/growable_array.h" |
| 26 #include "vm/lockers.h" | |
| 27 #include "vm/isolate_reload.h" | 26 #include "vm/isolate_reload.h" |
| 28 #include "vm/kernel_isolate.h" | 27 #include "vm/kernel_isolate.h" |
| 28 #include "vm/lockers.h" | |
| 29 #include "vm/message.h" | 29 #include "vm/message.h" |
| 30 #include "vm/message_handler.h" | 30 #include "vm/message_handler.h" |
| 31 #include "vm/native_entry.h" | 31 #include "vm/native_entry.h" |
| 32 #include "vm/object.h" | 32 #include "vm/object.h" |
| 33 #include "vm/object_store.h" | 33 #include "vm/object_store.h" |
| 34 #include "vm/os.h" | |
| 34 #include "vm/os_thread.h" | 35 #include "vm/os_thread.h" |
| 35 #include "vm/os.h" | |
| 36 #include "vm/port.h" | 36 #include "vm/port.h" |
| 37 #include "vm/precompiler.h" | 37 #include "vm/precompiler.h" |
| 38 #include "vm/profiler.h" | 38 #include "vm/profiler.h" |
| 39 #include "vm/program_visitor.h" | 39 #include "vm/program_visitor.h" |
| 40 #include "vm/resolver.h" | 40 #include "vm/resolver.h" |
| 41 #include "vm/reusable_handles.h" | 41 #include "vm/reusable_handles.h" |
| 42 #include "vm/service.h" | |
| 42 #include "vm/service_event.h" | 43 #include "vm/service_event.h" |
| 43 #include "vm/service_isolate.h" | 44 #include "vm/service_isolate.h" |
| 44 #include "vm/service.h" | |
| 45 #include "vm/stack_frame.h" | 45 #include "vm/stack_frame.h" |
| 46 #include "vm/symbols.h" | 46 #include "vm/symbols.h" |
| 47 #include "vm/tags.h" | 47 #include "vm/tags.h" |
| 48 #include "vm/thread_registry.h" | 48 #include "vm/thread_registry.h" |
| 49 #include "vm/timeline.h" | 49 #include "vm/timeline.h" |
| 50 #include "vm/timer.h" | 50 #include "vm/timer.h" |
| 51 #include "vm/unicode.h" | 51 #include "vm/unicode.h" |
| 52 #include "vm/uri.h" | 52 #include "vm/uri.h" |
| 53 #include "vm/verifier.h" | 53 #include "vm/verifier.h" |
| 54 #include "vm/version.h" | 54 #include "vm/version.h" |
| 55 #include "vm/zone_text_buffer.h" | |
| 55 | 56 |
| 56 namespace dart { | 57 namespace dart { |
| 57 | 58 |
| 58 // Facilitate quick access to the current zone once we have the current thread. | 59 // Facilitate quick access to the current zone once we have the current thread. |
| 59 #define Z (T->zone()) | 60 #define Z (T->zone()) |
| 60 | 61 |
| 61 | 62 |
| 62 DECLARE_FLAG(bool, print_class_table); | 63 DECLARE_FLAG(bool, print_class_table); |
| 63 DECLARE_FLAG(bool, verify_handles); | 64 DECLARE_FLAG(bool, verify_handles); |
| 64 #if defined(DART_NO_SNAPSHOT) | 65 #if defined(DART_NO_SNAPSHOT) |
| (...skipping 6416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6481 DART_EXPORT void Dart_SetThreadName(const char* name) { | 6482 DART_EXPORT void Dart_SetThreadName(const char* name) { |
| 6482 OSThread* thread = OSThread::Current(); | 6483 OSThread* thread = OSThread::Current(); |
| 6483 if (thread == NULL) { | 6484 if (thread == NULL) { |
| 6484 // VM is shutting down. | 6485 // VM is shutting down. |
| 6485 return; | 6486 return; |
| 6486 } | 6487 } |
| 6487 thread->SetName(name); | 6488 thread->SetName(name); |
| 6488 } | 6489 } |
| 6489 | 6490 |
| 6490 | 6491 |
| 6492 class CompilationTraceSaver : public FunctionVisitor { | |
|
zra
2017/06/05 22:08:57
Since this source file is already 7k+ lines, consi
rmacnak
2017/06/05 23:14:08
Done.
| |
| 6493 public: | |
| 6494 explicit CompilationTraceSaver(Zone* zone) | |
| 6495 : buf_(zone, 4 * KB), | |
| 6496 func_name_(String::Handle(zone)), | |
| 6497 cls_(Class::Handle(zone)), | |
| 6498 cls_name_(String::Handle(zone)), | |
| 6499 lib_(Library::Handle(zone)), | |
| 6500 uri_(String::Handle(zone)) {} | |
| 6501 | |
| 6502 void Visit(const Function& function) { | |
| 6503 if (!function.HasCode()) return; | |
|
zra
2017/06/05 22:08:57
curly braces.
rmacnak
2017/06/05 23:14:08
Done.
| |
| 6504 | |
| 6505 func_name_ = function.name(); | |
| 6506 func_name_ = String::RemovePrivateKey(func_name_); | |
| 6507 cls_ = function.Owner(); | |
| 6508 cls_name_ = cls_.Name(); | |
| 6509 cls_name_ = String::RemovePrivateKey(cls_name_); | |
| 6510 lib_ = cls_.library(); | |
| 6511 uri_ = lib_.url(); | |
| 6512 buf_.Printf("%s,%s,%s\n", uri_.ToCString(), cls_name_.ToCString(), | |
| 6513 func_name_.ToCString()); | |
| 6514 } | |
| 6515 | |
| 6516 void StealBuffer(uint8_t** buffer, intptr_t* buffer_length) { | |
| 6517 *buffer = reinterpret_cast<uint8_t*>(buf_.buffer()); | |
| 6518 *buffer_length = buf_.length() + 1; // Include terminating NUL. | |
| 6519 } | |
| 6520 | |
| 6521 private: | |
| 6522 ZoneTextBuffer buf_; | |
| 6523 String& func_name_; | |
| 6524 Class& cls_; | |
| 6525 String& cls_name_; | |
| 6526 Library& lib_; | |
| 6527 String& uri_; | |
| 6528 }; | |
| 6529 | |
| 6530 | |
| 6531 DART_EXPORT | |
| 6532 Dart_Handle Dart_SaveCompilationTrace(uint8_t** buffer, | |
| 6533 intptr_t* buffer_length) { | |
| 6534 API_TIMELINE_DURATION; | |
| 6535 Thread* thread = Thread::Current(); | |
| 6536 DARTSCOPE(thread); | |
| 6537 CHECK_NULL(buffer); | |
| 6538 CHECK_NULL(buffer_length); | |
| 6539 CompilationTraceSaver saver(thread->zone()); | |
| 6540 ProgramVisitor::VisitFunctions(&saver); | |
| 6541 saver.StealBuffer(buffer, buffer_length); | |
| 6542 return Api::Success(); | |
| 6543 } | |
| 6544 | |
| 6545 | |
| 6546 class CompilationTraceLoader : public ValueObject { | |
| 6547 public: | |
| 6548 explicit CompilationTraceLoader(Thread* thread) | |
| 6549 : thread_(thread), | |
| 6550 zone_(thread->zone()), | |
| 6551 uri_(String::Handle(zone_)), | |
| 6552 class_name_(String::Handle(zone_)), | |
| 6553 function_name_(String::Handle(zone_)), | |
| 6554 function_name2_(String::Handle(zone_)), | |
| 6555 lib_(Library::Handle(zone_)), | |
| 6556 cls_(Class::Handle(zone_)), | |
| 6557 function_(Function::Handle(zone_)), | |
| 6558 function2_(Function::Handle(zone_)), | |
| 6559 field_(Field::Handle(zone_)), | |
| 6560 error_(Object::Handle(zone_)) {} | |
| 6561 | |
| 6562 RawObject* CompileTrace(char* buffer) { | |
| 6563 // First compile function named in the trace. | |
|
zra
2017/06/05 22:08:57
functions
rmacnak
2017/06/05 23:14:08
Done.
| |
| 6564 char* cursor = buffer; | |
| 6565 while (cursor != NULL) { | |
| 6566 char* uri = cursor; | |
| 6567 char* comma1 = strchr(uri, ','); | |
| 6568 if (comma1 == NULL) break; | |
| 6569 *comma1 = 0; | |
| 6570 char* cls_name = comma1 + 1; | |
| 6571 char* comma2 = strchr(cls_name, ','); | |
| 6572 if (comma2 == NULL) break; | |
| 6573 *comma2 = 0; | |
| 6574 char* func_name = comma2 + 1; | |
| 6575 char* newline = strchr(func_name, '\n'); | |
| 6576 if (newline == NULL) break; | |
| 6577 *newline = 0; | |
| 6578 error_ = CompileTriple(uri, cls_name, func_name); | |
| 6579 if (error_.IsError()) { | |
| 6580 return error_.raw(); | |
| 6581 } | |
| 6582 cursor = newline + 1; | |
| 6583 } | |
| 6584 | |
| 6585 // Next, compile common dispatchers. This aren't found with the normal | |
|
zra
2017/06/05 22:08:57
These aren't
rmacnak
2017/06/05 23:14:08
Done.
| |
| 6586 // lookup above because they have irregular lookup that depends on the | |
| 6587 // arguments descriptor (e.g. call() versus call(x)). | |
| 6588 const Class& closure_class = Class::Handle( | |
| 6589 zone_, thread_->isolate()->object_store()->closure_class()); | |
| 6590 Array& arguments_descriptor = Array::Handle(zone_); | |
| 6591 Function& dispatcher = Function::Handle(zone_); | |
| 6592 for (intptr_t argc = 1; argc <= 4; argc++) { | |
| 6593 const intptr_t kTypeArgsLen = 0; | |
| 6594 arguments_descriptor = ArgumentsDescriptor::New(kTypeArgsLen, argc); | |
| 6595 dispatcher = closure_class.GetInvocationDispatcher( | |
| 6596 Symbols::Call(), arguments_descriptor, | |
| 6597 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */); | |
| 6598 error_ = CompileFunction(dispatcher); | |
| 6599 if (error_.IsError()) { | |
| 6600 return error_.raw(); | |
| 6601 } | |
| 6602 } | |
| 6603 | |
| 6604 // Finally, compile closures in all compiled functions. | |
| 6605 const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle( | |
| 6606 zone_, thread_->isolate()->object_store()->closure_functions()); | |
| 6607 for (intptr_t i = 0; i < closure_functions.Length(); i++) { | |
| 6608 function_ ^= closure_functions.At(i); | |
| 6609 function2_ = function_.parent_function(); | |
| 6610 if (function2_.HasCode()) { | |
| 6611 error_ = CompileFunction(function_); | |
| 6612 if (error_.IsError()) { | |
| 6613 return error_.raw(); | |
| 6614 } | |
| 6615 } | |
| 6616 } | |
| 6617 | |
| 6618 return Object::null(); | |
| 6619 } | |
| 6620 | |
| 6621 private: | |
| 6622 RawObject* CompileTriple(const char* uri_cstr, | |
| 6623 const char* cls_cstr, | |
| 6624 const char* func_cstr) { | |
| 6625 uri_ = Symbols::New(thread_, uri_cstr); | |
| 6626 class_name_ = Symbols::New(thread_, cls_cstr); | |
| 6627 function_name_ = Symbols::New(thread_, func_cstr); | |
| 6628 | |
| 6629 if (function_name_.Equals("_getMainClosure")) { | |
| 6630 // The scheme for invoking main relies on compiling _getMainClosure after | |
| 6631 // synthetically importing the root library. | |
| 6632 return Object::null(); | |
| 6633 } | |
| 6634 | |
| 6635 lib_ = Library::LookupLibrary(thread_, uri_); | |
| 6636 if (lib_.IsNull()) { | |
| 6637 // Missing library. | |
| 6638 return Object::null(); | |
| 6639 } | |
| 6640 | |
| 6641 bool is_getter = Field::IsGetterName(function_name_); | |
| 6642 bool add_closure = false; | |
| 6643 | |
| 6644 if (class_name_.Equals(Symbols::TopLevel())) { | |
| 6645 function_ = lib_.LookupFunctionAllowPrivate(function_name_); | |
| 6646 field_ = lib_.LookupFieldAllowPrivate(function_name_); | |
| 6647 if (function_.IsNull() && is_getter) { | |
| 6648 // Maybe this was a tear off. | |
| 6649 add_closure = true; | |
| 6650 function_name2_ = Field::NameFromGetter(function_name_); | |
| 6651 function_ = lib_.LookupFunctionAllowPrivate(function_name2_); | |
| 6652 field_ = lib_.LookupFieldAllowPrivate(function_name2_); | |
| 6653 } | |
| 6654 } else { | |
| 6655 cls_ = lib_.SlowLookupClassAllowMultiPartPrivate(class_name_); | |
| 6656 if (cls_.IsNull()) { | |
| 6657 // Missing class. | |
| 6658 return Object::null(); | |
| 6659 } | |
| 6660 | |
| 6661 error_ = cls_.EnsureIsFinalized(thread_); | |
| 6662 if (error_.IsError()) { | |
| 6663 return error_.raw(); | |
| 6664 } | |
| 6665 | |
| 6666 function_ = cls_.LookupFunctionAllowPrivate(function_name_); | |
| 6667 field_ = cls_.LookupFieldAllowPrivate(function_name_); | |
| 6668 if (field_.IsNull() && is_getter) { | |
| 6669 // Maybe this is a tear off. | |
| 6670 add_closure = true; | |
| 6671 function_name2_ = Field::NameFromGetter(function_name_); | |
| 6672 function_ = cls_.LookupFunctionAllowPrivate(function_name2_); | |
| 6673 field_ = cls_.LookupFieldAllowPrivate(function_name2_); | |
| 6674 if (!function_.IsNull() && !function_.is_static()) { | |
| 6675 // Maybe this was a method extractor. | |
| 6676 function2_ = | |
| 6677 Resolver::ResolveDynamicAnyArgs(zone_, cls_, function_name_); | |
| 6678 if (!function2_.IsNull()) { | |
| 6679 error_ = CompileFunction(function2_); | |
| 6680 if (error_.IsError()) { | |
| 6681 return error_.raw(); | |
| 6682 } | |
| 6683 } | |
| 6684 } | |
| 6685 } | |
| 6686 } | |
| 6687 | |
| 6688 if (!field_.IsNull() && field_.is_const() && field_.is_static()) { | |
| 6689 if (field_.StaticValue() == Object::sentinel().raw()) { | |
|
zra
2017/06/05 22:08:57
&& instead of nested if?
rmacnak
2017/06/05 23:14:08
Done.
| |
| 6690 // TODO(rmacnak): How to capture an error? | |
| 6691 field_.EvaluateInitializer(); | |
| 6692 } | |
| 6693 } | |
| 6694 | |
| 6695 if (!function_.IsNull()) { | |
| 6696 error_ = CompileFunction(function_); | |
| 6697 if (error_.IsError()) { | |
| 6698 return error_.raw(); | |
| 6699 } | |
| 6700 if (add_closure) { | |
| 6701 function_ = function_.ImplicitClosureFunction(); | |
| 6702 error_ = CompileFunction(function_); | |
| 6703 if (error_.IsError()) { | |
| 6704 return error_.raw(); | |
| 6705 } | |
| 6706 } | |
| 6707 } | |
| 6708 | |
| 6709 return Object::null(); | |
| 6710 } | |
| 6711 | |
| 6712 RawObject* CompileFunction(const Function& function) { | |
| 6713 if (function.is_abstract()) { | |
| 6714 return Object::null(); | |
| 6715 } | |
| 6716 return Compiler::CompileFunction(thread_, function); | |
| 6717 } | |
| 6718 | |
| 6719 Thread* thread_; | |
| 6720 Zone* zone_; | |
| 6721 String& uri_; | |
| 6722 String& class_name_; | |
| 6723 String& function_name_; | |
| 6724 String& function_name2_; | |
| 6725 Library& lib_; | |
| 6726 Class& cls_; | |
| 6727 Function& function_; | |
| 6728 Function& function2_; | |
| 6729 Field& field_; | |
| 6730 Object& error_; | |
| 6731 }; | |
| 6732 | |
| 6733 | |
| 6734 DART_EXPORT | |
| 6735 Dart_Handle Dart_LoadCompilationTrace(uint8_t* buffer, intptr_t buffer_length) { | |
| 6736 Thread* thread = Thread::Current(); | |
| 6737 API_TIMELINE_DURATION; | |
| 6738 DARTSCOPE(thread); | |
| 6739 CHECK_NULL(buffer); | |
| 6740 CompilationTraceLoader loader(thread); | |
| 6741 const Object& error = | |
| 6742 Object::Handle(loader.CompileTrace(reinterpret_cast<char*>(buffer))); | |
| 6743 if (error.IsError()) { | |
| 6744 return Api::NewHandle(T, Error::Cast(error).raw()); | |
| 6745 } | |
| 6746 return Api::Success(); | |
| 6747 } | |
| 6748 | |
| 6749 | |
| 6491 DART_EXPORT | 6750 DART_EXPORT |
| 6492 Dart_Handle Dart_SaveJITFeedback(uint8_t** buffer, intptr_t* buffer_length) { | 6751 Dart_Handle Dart_SaveJITFeedback(uint8_t** buffer, intptr_t* buffer_length) { |
| 6493 #if defined(DART_PRECOMPILED_RUNTIME) | 6752 #if defined(DART_PRECOMPILED_RUNTIME) |
| 6494 return Api::NewError("No JIT feedback to save on an AOT runtime."); | 6753 return Api::NewError("No JIT feedback to save on an AOT runtime."); |
| 6495 #elif defined(PRODUCT) | 6754 #elif defined(PRODUCT) |
| 6496 // TOOD(rmacnak): We'd need to include the JSON printing code again. | 6755 // TOOD(rmacnak): We'd need to include the JSON printing code again. |
| 6497 return Api::NewError("Dart_SaveJITFeedback not supported in PRODUCT mode."); | 6756 return Api::NewError("Dart_SaveJITFeedback not supported in PRODUCT mode."); |
| 6498 #else | 6757 #else |
| 6499 Thread* thread = Thread::Current(); | 6758 Thread* thread = Thread::Current(); |
| 6500 DARTSCOPE(thread); | 6759 DARTSCOPE(thread); |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6916 } | 7175 } |
| 6917 | 7176 |
| 6918 | 7177 |
| 6919 DART_EXPORT void Dart_DumpNativeStackTrace(void* context) { | 7178 DART_EXPORT void Dart_DumpNativeStackTrace(void* context) { |
| 6920 #ifndef PRODUCT | 7179 #ifndef PRODUCT |
| 6921 Profiler::DumpStackTrace(context); | 7180 Profiler::DumpStackTrace(context); |
| 6922 #endif | 7181 #endif |
| 6923 } | 7182 } |
| 6924 | 7183 |
| 6925 } // namespace dart | 7184 } // namespace dart |
| OLD | NEW |