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 |