| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/native_entry.h" | 9 #include "vm/native_entry.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| 11 #include "vm/os.h" | 11 #include "vm/os.h" |
| 12 #include "vm/timeline.h" | 12 #include "vm/timeline.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 // Native implementations for the dart:developer library. | 16 // Native implementations for the dart:developer library. |
| 17 | 17 |
| 18 DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0) { | 18 DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0) { |
| 19 #ifndef PRODUCT | 19 #ifndef PRODUCT |
| 20 if (!FLAG_support_timeline) { | 20 if (!FLAG_support_timeline) { |
| 21 return Bool::False().raw(); | 21 return Bool::False().raw(); |
| 22 } | 22 } |
| 23 if (Timeline::GetDartStream()->enabled()) { | 23 if (Timeline::GetDartStream()->enabled()) { |
| 24 return Bool::True().raw(); | 24 return Bool::True().raw(); |
| 25 } | 25 } |
| 26 #endif // !PRODUCT | 26 #endif // !PRODUCT |
| 27 return Bool::False().raw(); | 27 return Bool::False().raw(); |
| 28 } | 28 } |
| 29 | 29 |
| 30 | |
| 31 DEFINE_NATIVE_ENTRY(Timeline_getIsolateNum, 0) { | 30 DEFINE_NATIVE_ENTRY(Timeline_getIsolateNum, 0) { |
| 32 return Integer::New(static_cast<int64_t>(isolate->main_port()), Heap::kOld); | 31 return Integer::New(static_cast<int64_t>(isolate->main_port()), Heap::kOld); |
| 33 } | 32 } |
| 34 | 33 |
| 35 | |
| 36 DEFINE_NATIVE_ENTRY(Timeline_getNextAsyncId, 0) { | 34 DEFINE_NATIVE_ENTRY(Timeline_getNextAsyncId, 0) { |
| 37 if (!FLAG_support_timeline) { | 35 if (!FLAG_support_timeline) { |
| 38 return Integer::New(0); | 36 return Integer::New(0); |
| 39 } | 37 } |
| 40 TimelineEventRecorder* recorder = Timeline::recorder(); | 38 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 41 if (recorder == NULL) { | 39 if (recorder == NULL) { |
| 42 return Integer::New(0); | 40 return Integer::New(0); |
| 43 } | 41 } |
| 44 return Integer::New(recorder->GetNextAsyncId()); | 42 return Integer::New(recorder->GetNextAsyncId()); |
| 45 } | 43 } |
| 46 | 44 |
| 47 | |
| 48 DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) { | 45 DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) { |
| 49 return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew); | 46 return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew); |
| 50 } | 47 } |
| 51 | 48 |
| 52 | |
| 53 DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0) { | 49 DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0) { |
| 54 return Integer::New(OS::GetCurrentThreadCPUMicros(), Heap::kNew); | 50 return Integer::New(OS::GetCurrentThreadCPUMicros(), Heap::kNew); |
| 55 } | 51 } |
| 56 | 52 |
| 57 | |
| 58 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) { | 53 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) { |
| 59 #ifndef PRODUCT | 54 #ifndef PRODUCT |
| 60 if (!FLAG_support_timeline) { | 55 if (!FLAG_support_timeline) { |
| 61 return Object::null(); | 56 return Object::null(); |
| 62 } | 57 } |
| 63 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0)); | 58 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0)); |
| 64 GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(1)); | 59 GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(1)); |
| 65 GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments->NativeArgAt(2)); | 60 GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments->NativeArgAt(2)); |
| 66 GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(3)); | 61 GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(3)); |
| 67 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(4)); | 62 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(4)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 82 OSThread* os_thread = thread->os_thread(); | 77 OSThread* os_thread = thread->os_thread(); |
| 83 ASSERT(os_thread != NULL); | 78 ASSERT(os_thread != NULL); |
| 84 int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id()); | 79 int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id()); |
| 85 // Convert phase to a C string and perform a sanity check. | 80 // Convert phase to a C string and perform a sanity check. |
| 86 const char* phase_string = phase.ToCString(); | 81 const char* phase_string = phase.ToCString(); |
| 87 ASSERT(phase_string != NULL); | 82 ASSERT(phase_string != NULL); |
| 88 ASSERT((phase_string[0] == 'n') || (phase_string[0] == 'b') || | 83 ASSERT((phase_string[0] == 'n') || (phase_string[0] == 'b') || |
| 89 (phase_string[0] == 'e')); | 84 (phase_string[0] == 'e')); |
| 90 ASSERT(phase_string[1] == '\0'); | 85 ASSERT(phase_string[1] == '\0'); |
| 91 char* json = OS::SCreate( | 86 char* json = OS::SCreate( |
| 92 zone, "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 | 87 zone, |
| 93 "," | 88 "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 |
| 94 "\"ts\":%" Pd64 ",\"ph\":\"%s\",\"id\":%" Pd64 ", \"args\":%s}", | 89 "," |
| 90 "\"ts\":%" Pd64 ",\"ph\":\"%s\",\"id\":%" Pd64 ", \"args\":%s}", |
| 95 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), | 91 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), |
| 96 phase_string, id.AsInt64Value(), args.ToCString()); | 92 phase_string, id.AsInt64Value(), args.ToCString()); |
| 97 | 93 |
| 98 switch (phase_string[0]) { | 94 switch (phase_string[0]) { |
| 99 case 'n': | 95 case 'n': |
| 100 event->AsyncInstant("", id.AsInt64Value(), start.AsInt64Value()); | 96 event->AsyncInstant("", id.AsInt64Value(), start.AsInt64Value()); |
| 101 break; | 97 break; |
| 102 case 'b': | 98 case 'b': |
| 103 event->AsyncBegin("", id.AsInt64Value(), start.AsInt64Value()); | 99 event->AsyncBegin("", id.AsInt64Value(), start.AsInt64Value()); |
| 104 break; | 100 break; |
| 105 case 'e': | 101 case 'e': |
| 106 event->AsyncEnd("", id.AsInt64Value(), start.AsInt64Value()); | 102 event->AsyncEnd("", id.AsInt64Value(), start.AsInt64Value()); |
| 107 break; | 103 break; |
| 108 default: | 104 default: |
| 109 UNREACHABLE(); | 105 UNREACHABLE(); |
| 110 } | 106 } |
| 111 | 107 |
| 112 // json was allocated in the zone and a copy will be stored in event. | 108 // json was allocated in the zone and a copy will be stored in event. |
| 113 event->CompleteWithPreSerializedJSON(json); | 109 event->CompleteWithPreSerializedJSON(json); |
| 114 #endif | 110 #endif |
| 115 return Object::null(); | 111 return Object::null(); |
| 116 } | 112 } |
| 117 | 113 |
| 118 | |
| 119 DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 5) { | 114 DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 5) { |
| 120 #ifndef PRODUCT | 115 #ifndef PRODUCT |
| 121 if (!FLAG_support_timeline) { | 116 if (!FLAG_support_timeline) { |
| 122 return Object::null(); | 117 return Object::null(); |
| 123 } | 118 } |
| 124 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0)); | 119 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0)); |
| 125 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1)); | 120 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1)); |
| 126 GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2)); | 121 GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2)); |
| 127 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(3)); | 122 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(3)); |
| 128 GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4)); | 123 GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 144 const int64_t duration_cpu = end_cpu - start_cpu.AsInt64Value(); | 139 const int64_t duration_cpu = end_cpu - start_cpu.AsInt64Value(); |
| 145 int64_t pid = OS::ProcessId(); | 140 int64_t pid = OS::ProcessId(); |
| 146 OSThread* os_thread = thread->os_thread(); | 141 OSThread* os_thread = thread->os_thread(); |
| 147 ASSERT(os_thread != NULL); | 142 ASSERT(os_thread != NULL); |
| 148 int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id()); | 143 int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id()); |
| 149 | 144 |
| 150 char* json = NULL; | 145 char* json = NULL; |
| 151 | 146 |
| 152 if ((start_cpu.AsInt64Value() != -1) && (end_cpu != -1)) { | 147 if ((start_cpu.AsInt64Value() != -1) && (end_cpu != -1)) { |
| 153 json = OS::SCreate( | 148 json = OS::SCreate( |
| 154 zone, "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 | 149 zone, |
| 155 "," | 150 "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 |
| 156 "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 | 151 "," |
| 157 "," | 152 "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 |
| 158 "\"tdur\":%" Pd64 ",\"args\":%s}", | 153 "," |
| 154 "\"tdur\":%" Pd64 ",\"args\":%s}", |
| 159 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), | 155 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), |
| 160 duration, duration_cpu, args.ToCString()); | 156 duration, duration_cpu, args.ToCString()); |
| 161 } else { | 157 } else { |
| 162 json = OS::SCreate( | 158 json = OS::SCreate( |
| 163 zone, "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 | 159 zone, |
| 164 "," | 160 "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 |
| 165 "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}", | 161 "," |
| 162 "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}", |
| 166 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), | 163 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), |
| 167 duration, args.ToCString()); | 164 duration, args.ToCString()); |
| 168 } | 165 } |
| 169 ASSERT(json != NULL); | 166 ASSERT(json != NULL); |
| 170 | 167 |
| 171 event->Duration("", start.AsInt64Value(), end, start_cpu.AsInt64Value(), | 168 event->Duration("", start.AsInt64Value(), end, start_cpu.AsInt64Value(), |
| 172 end_cpu); | 169 end_cpu); |
| 173 // json was allocated in the zone and a copy will be stored in event. | 170 // json was allocated in the zone and a copy will be stored in event. |
| 174 event->CompleteWithPreSerializedJSON(json); | 171 event->CompleteWithPreSerializedJSON(json); |
| 175 #endif | 172 #endif |
| 176 return Object::null(); | 173 return Object::null(); |
| 177 } | 174 } |
| 178 | 175 |
| 179 | |
| 180 DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 4) { | 176 DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 4) { |
| 181 #ifndef PRODUCT | 177 #ifndef PRODUCT |
| 182 if (!FLAG_support_timeline) { | 178 if (!FLAG_support_timeline) { |
| 183 return Object::null(); | 179 return Object::null(); |
| 184 } | 180 } |
| 185 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0)); | 181 GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0)); |
| 186 GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(1)); | 182 GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(1)); |
| 187 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2)); | 183 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2)); |
| 188 GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(3)); | 184 GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(3)); |
| 189 | 185 |
| 190 TimelineEventRecorder* recorder = Timeline::recorder(); | 186 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 191 if (recorder == NULL) { | 187 if (recorder == NULL) { |
| 192 return Object::null(); | 188 return Object::null(); |
| 193 } | 189 } |
| 194 | 190 |
| 195 TimelineEvent* event = Timeline::GetDartStream()->StartEvent(); | 191 TimelineEvent* event = Timeline::GetDartStream()->StartEvent(); |
| 196 if (event == NULL) { | 192 if (event == NULL) { |
| 197 // Stream was turned off. | 193 // Stream was turned off. |
| 198 return Object::null(); | 194 return Object::null(); |
| 199 } | 195 } |
| 200 | 196 |
| 201 int64_t pid = OS::ProcessId(); | 197 int64_t pid = OS::ProcessId(); |
| 202 OSThread* os_thread = thread->os_thread(); | 198 OSThread* os_thread = thread->os_thread(); |
| 203 ASSERT(os_thread != NULL); | 199 ASSERT(os_thread != NULL); |
| 204 int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id()); | 200 int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id()); |
| 205 | 201 |
| 206 char* json = OS::SCreate( | 202 char* json = OS::SCreate(zone, |
| 207 zone, "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 | 203 "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 |
| 208 "," | 204 ",\"pid\":%" Pd64 |
| 209 "\"ts\":%" Pd64 ",\"ph\":\"I\",\"args\":%s}", | 205 "," |
| 210 name.ToCString(), category.ToCString(), tid, pid, start.AsInt64Value(), | 206 "\"ts\":%" Pd64 ",\"ph\":\"I\",\"args\":%s}", |
| 211 args.ToCString()); | 207 name.ToCString(), category.ToCString(), tid, pid, |
| 208 start.AsInt64Value(), args.ToCString()); |
| 212 | 209 |
| 213 event->Instant("", start.AsInt64Value()); | 210 event->Instant("", start.AsInt64Value()); |
| 214 // json was allocated in the zone and a copy will be stored in event. | 211 // json was allocated in the zone and a copy will be stored in event. |
| 215 event->CompleteWithPreSerializedJSON(json); | 212 event->CompleteWithPreSerializedJSON(json); |
| 216 #endif | 213 #endif |
| 217 return Object::null(); | 214 return Object::null(); |
| 218 } | 215 } |
| 219 | 216 |
| 220 } // namespace dart | 217 } // namespace dart |
| OLD | NEW |