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 "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 5650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5661 } | 5661 } |
5662 | 5662 |
5663 | 5663 |
5664 DART_EXPORT void Dart_TimelineSetRecordedStreams(int64_t stream_mask) { | 5664 DART_EXPORT void Dart_TimelineSetRecordedStreams(int64_t stream_mask) { |
5665 Isolate* isolate = Isolate::Current(); | 5665 Isolate* isolate = Isolate::Current(); |
5666 CHECK_ISOLATE(isolate); | 5666 CHECK_ISOLATE(isolate); |
5667 isolate->GetAPIStream()->set_enabled( | 5667 isolate->GetAPIStream()->set_enabled( |
5668 (stream_mask & DART_TIMELINE_STREAM_API) != 0); | 5668 (stream_mask & DART_TIMELINE_STREAM_API) != 0); |
5669 isolate->GetCompilerStream()->set_enabled( | 5669 isolate->GetCompilerStream()->set_enabled( |
5670 (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0); | 5670 (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0); |
| 5671 isolate->GetDartStream()->set_enabled( |
| 5672 (stream_mask & DART_TIMELINE_STREAM_DART) != 0); |
5671 isolate->GetEmbedderStream()->set_enabled( | 5673 isolate->GetEmbedderStream()->set_enabled( |
5672 (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0); | 5674 (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0); |
5673 isolate->GetGCStream()->set_enabled( | 5675 isolate->GetGCStream()->set_enabled( |
5674 (stream_mask & DART_TIMELINE_STREAM_GC) != 0); | 5676 (stream_mask & DART_TIMELINE_STREAM_GC) != 0); |
5675 isolate->GetIsolateStream()->set_enabled( | 5677 isolate->GetIsolateStream()->set_enabled( |
5676 (stream_mask & DART_TIMELINE_STREAM_ISOLATE) != 0); | 5678 (stream_mask & DART_TIMELINE_STREAM_ISOLATE) != 0); |
5677 } | 5679 } |
5678 | 5680 |
5679 | 5681 |
5680 DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) { | 5682 DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) { |
5681 // Per isolate overrides. | 5683 // Per isolate overrides. |
5682 const bool api_enabled = (stream_mask & DART_TIMELINE_STREAM_API) != 0; | 5684 const bool api_enabled = (stream_mask & DART_TIMELINE_STREAM_API) != 0; |
5683 const bool compiler_enabled = | 5685 const bool compiler_enabled = |
5684 (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0; | 5686 (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0; |
| 5687 const bool dart_enabled = |
| 5688 (stream_mask & DART_TIMELINE_STREAM_DART) != 0; |
5685 const bool embedder_enabled = | 5689 const bool embedder_enabled = |
5686 (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0; | 5690 (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0; |
5687 const bool gc_enabled = (stream_mask & DART_TIMELINE_STREAM_GC) != 0; | 5691 const bool gc_enabled = (stream_mask & DART_TIMELINE_STREAM_GC) != 0; |
5688 const bool isolate_enabled = | 5692 const bool isolate_enabled = |
5689 (stream_mask & DART_TIMELINE_STREAM_ISOLATE) != 0; | 5693 (stream_mask & DART_TIMELINE_STREAM_ISOLATE) != 0; |
5690 Timeline::SetStreamAPIEnabled(api_enabled); | 5694 Timeline::SetStreamAPIEnabled(api_enabled); |
5691 Timeline::SetStreamCompilerEnabled(compiler_enabled); | 5695 Timeline::SetStreamCompilerEnabled(compiler_enabled); |
| 5696 Timeline::SetStreamDartEnabled(dart_enabled); |
5692 Timeline::SetStreamEmbedderEnabled(embedder_enabled); | 5697 Timeline::SetStreamEmbedderEnabled(embedder_enabled); |
5693 Timeline::SetStreamGCEnabled(gc_enabled); | 5698 Timeline::SetStreamGCEnabled(gc_enabled); |
5694 Timeline::SetStreamIsolateEnabled(isolate_enabled); | 5699 Timeline::SetStreamIsolateEnabled(isolate_enabled); |
5695 // VM wide. | 5700 // VM wide. |
5696 const bool vm_enabled = | 5701 const bool vm_enabled = |
5697 (stream_mask & DART_TIMELINE_STREAM_VM) != 0; | 5702 (stream_mask & DART_TIMELINE_STREAM_VM) != 0; |
5698 Timeline::GetVMStream()->set_enabled(vm_enabled); | 5703 Timeline::GetVMStream()->set_enabled(vm_enabled); |
5699 } | 5704 } |
5700 | 5705 |
5701 | 5706 |
5702 // '[' + ']' + '\0'. | 5707 // '[' + ']' + '\0'. |
5703 #define MINIMUM_OUTPUT_LENGTH 3 | 5708 #define MINIMUM_OUTPUT_LENGTH 3 |
5704 | 5709 |
5705 static void StreamToConsumer(Dart_StreamConsumer consumer, | 5710 // Trims the '[' and ']' characters and, depending on whether or not more events |
5706 void* user_data, | 5711 // will follow, adjusts the last character of the string to either a '\0' or |
5707 char* output, | 5712 // ','. |
5708 intptr_t output_length) { | 5713 static char* TrimOutput(char* output, |
| 5714 intptr_t* output_length, |
| 5715 bool events_will_follow) { |
| 5716 ASSERT(output != NULL); |
| 5717 ASSERT(output_length != NULL); |
| 5718 ASSERT(*output_length > MINIMUM_OUTPUT_LENGTH); |
| 5719 // We expect the first character to be the opening of an array. |
| 5720 ASSERT(output[0] == '['); |
| 5721 // We expect the last character to be the closing of an array. |
| 5722 ASSERT(output[*output_length - 2] == ']'); |
| 5723 if (events_will_follow) { |
| 5724 // Replace array closing character (']') with ','. |
| 5725 output[*output_length - 2] = ','; |
| 5726 } else { |
| 5727 // Replace array closing character (']') with '\0'. |
| 5728 output[*output_length - 2] = '\0'; |
| 5729 } |
| 5730 // Skip the array opening character ('['). |
| 5731 *output_length -= 2; |
| 5732 return &output[1]; |
| 5733 } |
| 5734 |
| 5735 |
| 5736 static void StartStreamToConsumer(Dart_StreamConsumer consumer, |
| 5737 void* user_data, |
| 5738 const char* stream_name) { |
| 5739 // Start stream. |
| 5740 consumer(Dart_StreamConsumer_kStart, |
| 5741 stream_name, |
| 5742 NULL, |
| 5743 0, |
| 5744 user_data); |
| 5745 } |
| 5746 |
| 5747 |
| 5748 static void FinishStreamToConsumer(Dart_StreamConsumer consumer, |
| 5749 void* user_data, |
| 5750 const char* stream_name) { |
| 5751 // Finish stream. |
| 5752 consumer(Dart_StreamConsumer_kFinish, |
| 5753 stream_name, |
| 5754 NULL, |
| 5755 0, |
| 5756 user_data); |
| 5757 } |
| 5758 |
| 5759 |
| 5760 static void DataStreamToConsumer(Dart_StreamConsumer consumer, |
| 5761 void* user_data, |
| 5762 const char* output, |
| 5763 intptr_t output_length, |
| 5764 const char* stream_name) { |
5709 if (output == NULL) { | 5765 if (output == NULL) { |
5710 return; | 5766 return; |
5711 } | 5767 } |
5712 if (output_length <= MINIMUM_OUTPUT_LENGTH) { | |
5713 return; | |
5714 } | |
5715 // We expect the first character to be the opening of an array. | |
5716 ASSERT(output[0] == '['); | |
5717 // We expect the last character to be the closing of an array. | |
5718 ASSERT(output[output_length - 2] == ']'); | |
5719 // Start stream. | |
5720 const char* kStreamName = "timeline"; | |
5721 const intptr_t kDataSize = 64 * KB; | 5768 const intptr_t kDataSize = 64 * KB; |
5722 consumer(Dart_StreamConsumer_kStart, | 5769 intptr_t cursor = 0; |
5723 kStreamName, | 5770 intptr_t remaining = output_length; |
5724 NULL, | |
5725 0, | |
5726 user_data); | |
5727 | |
5728 // Stream out data. Skipping the array characters. | |
5729 // Replace array close with '\0'. | |
5730 output[output_length - 2] = '\0'; | |
5731 intptr_t cursor = 1; | |
5732 output_length -= 1; | |
5733 intptr_t remaining = output_length - 1; | |
5734 | |
5735 while (remaining >= kDataSize) { | 5771 while (remaining >= kDataSize) { |
5736 consumer(Dart_StreamConsumer_kData, | 5772 consumer(Dart_StreamConsumer_kData, |
5737 kStreamName, | 5773 stream_name, |
5738 reinterpret_cast<uint8_t*>(&output[cursor]), | 5774 reinterpret_cast<const uint8_t*>(&output[cursor]), |
5739 kDataSize, | 5775 kDataSize, |
5740 user_data); | 5776 user_data); |
5741 cursor += kDataSize; | 5777 cursor += kDataSize; |
5742 remaining -= kDataSize; | 5778 remaining -= kDataSize; |
5743 } | 5779 } |
5744 if (remaining > 0) { | 5780 if (remaining > 0) { |
5745 ASSERT(remaining < kDataSize); | 5781 ASSERT(remaining < kDataSize); |
5746 consumer(Dart_StreamConsumer_kData, | 5782 consumer(Dart_StreamConsumer_kData, |
5747 kStreamName, | 5783 stream_name, |
5748 reinterpret_cast<uint8_t*>(&output[cursor]), | 5784 reinterpret_cast<const uint8_t*>(&output[cursor]), |
5749 remaining, | 5785 remaining, |
5750 user_data); | 5786 user_data); |
5751 cursor += remaining; | 5787 cursor += remaining; |
5752 remaining -= remaining; | 5788 remaining -= remaining; |
5753 } | 5789 } |
5754 ASSERT(cursor == output_length); | 5790 ASSERT(cursor == output_length); |
5755 ASSERT(remaining == 0); | 5791 ASSERT(remaining == 0); |
5756 | |
5757 // Finish stream. | |
5758 consumer(Dart_StreamConsumer_kFinish, | |
5759 kStreamName, | |
5760 NULL, | |
5761 0, | |
5762 user_data); | |
5763 } | 5792 } |
5764 | 5793 |
5765 | 5794 |
| 5795 static bool StreamTraceEvents(Dart_StreamConsumer consumer, |
| 5796 void* user_data, |
| 5797 JSONStream* js, |
| 5798 const char* dart_events) { |
| 5799 ASSERT(js != NULL); |
| 5800 // Steal output from JSONStream. |
| 5801 char* output = NULL; |
| 5802 intptr_t output_length = 0; |
| 5803 js->Steal(const_cast<const char**>(&output), &output_length); |
| 5804 |
| 5805 const bool output_vm = output_length > MINIMUM_OUTPUT_LENGTH; |
| 5806 const bool output_dart = dart_events != NULL; |
| 5807 |
| 5808 if (!output_vm && !output_dart) { |
| 5809 // We stole the JSONStream's output buffer, free it. |
| 5810 free(output); |
| 5811 // Nothing will be emitted. |
| 5812 return false; |
| 5813 } |
| 5814 |
| 5815 // Start the stream. |
| 5816 StartStreamToConsumer(consumer, user_data, "timeline"); |
| 5817 |
| 5818 // Send events from the VM. |
| 5819 if (output_vm) { |
| 5820 // Add one for the '\0' character. |
| 5821 output_length++; |
| 5822 char* trimmed_output = TrimOutput(output, &output_length, output_dart); |
| 5823 DataStreamToConsumer(consumer, user_data, |
| 5824 trimmed_output, output_length, "timeline"); |
| 5825 } |
| 5826 // We stole the JSONStream's output buffer, free it. |
| 5827 free(output); |
| 5828 |
| 5829 // Send events from dart. |
| 5830 if (output_dart) { |
| 5831 const intptr_t dart_events_len = strlen(dart_events) + 1; // +1 for '\0'. |
| 5832 DataStreamToConsumer(consumer, user_data, |
| 5833 dart_events, dart_events_len, "timeline"); |
| 5834 } |
| 5835 |
| 5836 // Finish the stream. |
| 5837 FinishStreamToConsumer(consumer, user_data, "timeline"); |
| 5838 return true; |
| 5839 } |
| 5840 |
| 5841 |
5766 DART_EXPORT bool Dart_TimelineGetTrace(Dart_StreamConsumer consumer, | 5842 DART_EXPORT bool Dart_TimelineGetTrace(Dart_StreamConsumer consumer, |
5767 void* user_data) { | 5843 void* user_data) { |
5768 Isolate* isolate = Isolate::Current(); | 5844 Isolate* isolate = Isolate::Current(); |
5769 CHECK_ISOLATE(isolate); | 5845 CHECK_ISOLATE(isolate); |
5770 if (consumer == NULL) { | 5846 if (consumer == NULL) { |
5771 return false; | 5847 return false; |
5772 } | 5848 } |
5773 TimelineEventRecorder* timeline_recorder = Timeline::recorder(); | 5849 TimelineEventRecorder* timeline_recorder = Timeline::recorder(); |
5774 if (timeline_recorder == NULL) { | 5850 if (timeline_recorder == NULL) { |
5775 // Nothing has been recorded. | 5851 // Nothing has been recorded. |
5776 return false; | 5852 return false; |
5777 } | 5853 } |
| 5854 Thread* T = Thread::Current(); |
| 5855 StackZone zone(T); |
5778 // Reclaim all blocks cached by isolate. | 5856 // Reclaim all blocks cached by isolate. |
5779 Timeline::ReclaimIsolateBlocks(); | 5857 Timeline::ReclaimIsolateBlocks(); |
5780 JSONStream js; | 5858 JSONStream js; |
5781 IsolateTimelineEventFilter filter(isolate); | 5859 IsolateTimelineEventFilter filter(isolate); |
5782 timeline_recorder->PrintTraceEvent(&js, &filter); | 5860 timeline_recorder->PrintTraceEvent(&js, &filter); |
5783 | 5861 const char* dart_events = |
5784 // Copy output. | 5862 DartTimelineEventIterator::PrintTraceEvents(timeline_recorder, |
5785 char* output = NULL; | 5863 zone.GetZone(), |
5786 intptr_t output_length = 0; | 5864 isolate); |
5787 js.Steal(const_cast<const char**>(&output), &output_length); | 5865 return StreamTraceEvents(consumer, user_data, &js, dart_events); |
5788 if (output != NULL) { | |
5789 // Add one for the '\0' character. | |
5790 output_length++; | |
5791 StreamToConsumer(consumer, user_data, output, output_length); | |
5792 // We stole the JSONStream's output buffer, free it. | |
5793 free(output); | |
5794 return output_length > MINIMUM_OUTPUT_LENGTH; | |
5795 } | |
5796 return false; | |
5797 } | 5866 } |
5798 | 5867 |
5799 | 5868 |
5800 DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer, | 5869 DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer, |
5801 void* user_data) { | 5870 void* user_data) { |
5802 if (consumer == NULL) { | 5871 if (consumer == NULL) { |
5803 return false; | 5872 return false; |
5804 } | 5873 } |
5805 TimelineEventRecorder* timeline_recorder = Timeline::recorder(); | 5874 TimelineEventRecorder* timeline_recorder = Timeline::recorder(); |
5806 if (timeline_recorder == NULL) { | 5875 if (timeline_recorder == NULL) { |
5807 // Nothing has been recorded. | 5876 // Nothing has been recorded. |
5808 return false; | 5877 return false; |
5809 } | 5878 } |
5810 | 5879 Thread* T = Thread::Current(); |
| 5880 StackZone zone(T); |
5811 // Reclaim all blocks cached in the system. | 5881 // Reclaim all blocks cached in the system. |
5812 Timeline::ReclaimAllBlocks(); | 5882 Timeline::ReclaimAllBlocks(); |
5813 JSONStream js; | 5883 JSONStream js; |
5814 TimelineEventFilter filter; | 5884 TimelineEventFilter filter; |
5815 timeline_recorder->PrintTraceEvent(&js, &filter); | 5885 timeline_recorder->PrintTraceEvent(&js, &filter); |
5816 | 5886 const char* dart_events = |
5817 // Copy output. | 5887 DartTimelineEventIterator::PrintTraceEvents(timeline_recorder, |
5818 char* output = NULL; | 5888 zone.GetZone(), |
5819 intptr_t output_length = 0; | 5889 NULL); |
5820 js.Steal(const_cast<const char**>(&output), &output_length); | 5890 return StreamTraceEvents(consumer, user_data, &js, dart_events); |
5821 if (output != NULL) { | |
5822 // Add one for the '\0' character. | |
5823 output_length++; | |
5824 StreamToConsumer(consumer, user_data, output, output_length); | |
5825 // We stole the JSONStream's output buffer, free it. | |
5826 free(output); | |
5827 return output_length > MINIMUM_OUTPUT_LENGTH; | |
5828 } | |
5829 return false; | |
5830 } | 5891 } |
5831 | 5892 |
5832 | 5893 |
5833 DART_EXPORT Dart_Handle Dart_TimelineDuration(const char* label, | 5894 DART_EXPORT Dart_Handle Dart_TimelineDuration(const char* label, |
5834 int64_t start_micros, | 5895 int64_t start_micros, |
5835 int64_t end_micros) { | 5896 int64_t end_micros) { |
5836 Isolate* isolate = Isolate::Current(); | 5897 Isolate* isolate = Isolate::Current(); |
5837 CHECK_ISOLATE(isolate); | 5898 CHECK_ISOLATE(isolate); |
5838 if (label == NULL) { | 5899 if (label == NULL) { |
5839 RETURN_NULL_ERROR(label); | 5900 RETURN_NULL_ERROR(label); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5994 ApiReallocate); | 6055 ApiReallocate); |
5995 writer.WriteFullSnapshot(); | 6056 writer.WriteFullSnapshot(); |
5996 *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize(); | 6057 *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize(); |
5997 *isolate_snapshot_size = writer.IsolateSnapshotSize(); | 6058 *isolate_snapshot_size = writer.IsolateSnapshotSize(); |
5998 *instructions_snapshot_size = writer.InstructionsSnapshotSize(); | 6059 *instructions_snapshot_size = writer.InstructionsSnapshotSize(); |
5999 | 6060 |
6000 return Api::Success(); | 6061 return Api::Success(); |
6001 } | 6062 } |
6002 | 6063 |
6003 } // namespace dart | 6064 } // namespace dart |
OLD | NEW |