Chromium Code Reviews| Index: runtime/vm/dart_api_impl.cc |
| diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc |
| index 922c9f1d9264d14251820aec00517008e3e2829e..ba5375ad2cbd7b6d7837d64d3b90658f2554ae76 100644 |
| --- a/runtime/vm/dart_api_impl.cc |
| +++ b/runtime/vm/dart_api_impl.cc |
| @@ -5785,14 +5785,11 @@ DART_EXPORT void Dart_TimelineSetRecordedStreams(int64_t stream_mask) { |
| } |
| -DART_EXPORT bool Dart_TimelineGetTrace(const char** output, |
| - intptr_t* output_length) { |
| +DART_EXPORT bool Dart_TimelineGetTrace(Dart_StreamConsumer consumer, |
| + void* user_data) { |
| Isolate* isolate = Isolate::Current(); |
| CHECK_ISOLATE(isolate); |
| - if (output == NULL) { |
| - return false; |
| - } |
| - if (output_length == NULL) { |
| + if (consumer == NULL) { |
| return false; |
| } |
| TimelineEventRecorder* timeline_recorder = isolate->timeline_event_recorder(); |
| @@ -5804,8 +5801,57 @@ DART_EXPORT bool Dart_TimelineGetTrace(const char** output, |
| isolate->thread_registry()->SafepointThreads(); |
| JSONStream js; |
| timeline_recorder->PrintJSON(&js); |
| - js.Steal(output, output_length); |
| + // Resume execution of other threads. |
| isolate->thread_registry()->ResumeAllThreads(); |
| + |
| + // Copy output. |
| + char* output = NULL; |
| + intptr_t output_length = 0; |
| + js.Steal(const_cast<const char**>(&output), &output_length); |
| + if (output != NULL) { |
| + // Add one for the '\0' character. |
| + output_length++; |
| + } |
| + // Start stream. |
| + const char* kStreamName = "timeline"; |
| + const intptr_t kDataSize = 64 * KB; |
| + consumer(DART_STREAM_CONSUMER_STATE_START, |
| + kStreamName, |
| + NULL, |
| + 0, |
| + user_data); |
| + |
| + // Stream out data. |
| + intptr_t cursor = 0; |
| + intptr_t remaining = output_length - cursor; |
|
siva
2015/08/11 16:54:33
intptr_t remaining = output_length;
Cutch
2015/08/11 17:08:56
Done.
|
| + while (remaining >= kDataSize) { |
| + consumer(DART_STREAM_CONSUMER_STATE_DATA, |
| + kStreamName, |
| + reinterpret_cast<uint8_t*>(&output[cursor]), |
| + kDataSize, |
| + user_data); |
| + cursor += kDataSize; |
| + remaining -= kDataSize; |
| + } |
| + if (remaining > 0) { |
| + ASSERT(remaining < kDataSize); |
| + consumer(DART_STREAM_CONSUMER_STATE_DATA, |
| + kStreamName, |
| + reinterpret_cast<uint8_t*>(&output[cursor]), |
| + remaining, |
| + user_data); |
| + cursor += remaining; |
| + remaining -= remaining; |
| + } |
| + ASSERT(cursor == output_length); |
| + ASSERT(remaining == 0); |
| + |
| + // Finish stream. |
| + consumer(DART_STREAM_CONSUMER_STATE_FINISH, |
| + kStreamName, |
| + NULL, |
| + 0, |
| + user_data); |
|
siva
2015/08/11 16:54:33
Why does start and end have to have a NULL buffer
Cutch
2015/08/11 17:08:56
I find this API simpler to work with.
|
| return true; |
| } |