| 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 #include "vm/dart_api_impl.h" | 6 #include "vm/dart_api_impl.h" |
| 7 #include "vm/datastream.h" | 7 #include "vm/datastream.h" |
| 8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| 11 #include "vm/kernel_isolate.h" |
| 11 #include "vm/message.h" | 12 #include "vm/message.h" |
| 12 #include "vm/message_handler.h" | 13 #include "vm/message_handler.h" |
| 13 #include "vm/native_entry.h" | 14 #include "vm/native_entry.h" |
| 14 #include "vm/object.h" | 15 #include "vm/object.h" |
| 15 #include "vm/port.h" | 16 #include "vm/port.h" |
| 16 #include "vm/service_event.h" | 17 #include "vm/service_event.h" |
| 17 #include "vm/service_isolate.h" | 18 #include "vm/service_isolate.h" |
| 18 #include "vm/symbols.h" | 19 #include "vm/symbols.h" |
| 19 #include "vm/kernel_isolate.h" | |
| 20 | 20 |
| 21 namespace dart { | 21 namespace dart { |
| 22 | 22 |
| 23 DECLARE_FLAG(bool, trace_service); | 23 DECLARE_FLAG(bool, trace_service); |
| 24 DECLARE_FLAG(bool, show_kernel_isolate); | 24 DECLARE_FLAG(bool, show_kernel_isolate); |
| 25 | 25 |
| 26 static uint8_t* malloc_allocator(uint8_t* ptr, | 26 static uint8_t* malloc_allocator(uint8_t* ptr, |
| 27 intptr_t old_size, | 27 intptr_t old_size, |
| 28 intptr_t new_size) { | 28 intptr_t new_size) { |
| 29 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 29 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 30 return reinterpret_cast<uint8_t*>(new_ptr); | 30 return reinterpret_cast<uint8_t*>(new_ptr); |
| 31 } | 31 } |
| 32 | 32 |
| 33 static void malloc_deallocator(uint8_t* ptr) { | 33 static void malloc_deallocator(uint8_t* ptr) { |
| 34 free(reinterpret_cast<void*>(ptr)); | 34 free(reinterpret_cast<void*>(ptr)); |
| 35 } | 35 } |
| 36 | 36 |
| 37 | |
| 38 #ifndef PRODUCT | 37 #ifndef PRODUCT |
| 39 class RegisterRunningIsolatesVisitor : public IsolateVisitor { | 38 class RegisterRunningIsolatesVisitor : public IsolateVisitor { |
| 40 public: | 39 public: |
| 41 explicit RegisterRunningIsolatesVisitor(Thread* thread) | 40 explicit RegisterRunningIsolatesVisitor(Thread* thread) |
| 42 : IsolateVisitor(), | 41 : IsolateVisitor(), |
| 43 register_function_(Function::Handle(thread->zone())), | 42 register_function_(Function::Handle(thread->zone())), |
| 44 service_isolate_(thread->isolate()) { | 43 service_isolate_(thread->isolate()) { |
| 45 ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current())); | 44 ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current())); |
| 46 // Get library. | 45 // Get library. |
| 47 const String& library_url = Symbols::DartVMService(); | 46 const String& library_url = Symbols::DartVMService(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 uint8_t* data = NULL; | 110 uint8_t* data = NULL; |
| 112 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 111 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
| 113 writer.WriteMessage(message); | 112 writer.WriteMessage(message); |
| 114 | 113 |
| 115 // TODO(turnidge): Throw an exception when the return value is false? | 114 // TODO(turnidge): Throw an exception when the return value is false? |
| 116 bool result = PortMap::PostMessage( | 115 bool result = PortMap::PostMessage( |
| 117 new Message(sp.Id(), data, writer.BytesWritten(), Message::kOOBPriority)); | 116 new Message(sp.Id(), data, writer.BytesWritten(), Message::kOOBPriority)); |
| 118 return Bool::Get(result).raw(); | 117 return Bool::Get(result).raw(); |
| 119 } | 118 } |
| 120 | 119 |
| 121 | |
| 122 DEFINE_NATIVE_ENTRY(VMService_SendRootServiceMessage, 1) { | 120 DEFINE_NATIVE_ENTRY(VMService_SendRootServiceMessage, 1) { |
| 123 GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0)); | 121 GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0)); |
| 124 if (FLAG_support_service) { | 122 if (FLAG_support_service) { |
| 125 return Service::HandleRootMessage(message); | 123 return Service::HandleRootMessage(message); |
| 126 } | 124 } |
| 127 return Object::null(); | 125 return Object::null(); |
| 128 } | 126 } |
| 129 | 127 |
| 130 | |
| 131 DEFINE_NATIVE_ENTRY(VMService_SendObjectRootServiceMessage, 1) { | 128 DEFINE_NATIVE_ENTRY(VMService_SendObjectRootServiceMessage, 1) { |
| 132 GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0)); | 129 GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0)); |
| 133 if (FLAG_support_service) { | 130 if (FLAG_support_service) { |
| 134 return Service::HandleObjectRootMessage(message); | 131 return Service::HandleObjectRootMessage(message); |
| 135 } | 132 } |
| 136 return Object::null(); | 133 return Object::null(); |
| 137 } | 134 } |
| 138 | 135 |
| 139 | |
| 140 DEFINE_NATIVE_ENTRY(VMService_OnStart, 0) { | 136 DEFINE_NATIVE_ENTRY(VMService_OnStart, 0) { |
| 141 if (FLAG_trace_service) { | 137 if (FLAG_trace_service) { |
| 142 OS::Print("vm-service: Booting dart:vmservice library.\n"); | 138 OS::Print("vm-service: Booting dart:vmservice library.\n"); |
| 143 } | 139 } |
| 144 // Boot the dart:vmservice library. | 140 // Boot the dart:vmservice library. |
| 145 ServiceIsolate::BootVmServiceLibrary(); | 141 ServiceIsolate::BootVmServiceLibrary(); |
| 146 if (!FLAG_support_service) { | 142 if (!FLAG_support_service) { |
| 147 return Object::null(); | 143 return Object::null(); |
| 148 } | 144 } |
| 149 #ifndef PRODUCT | 145 #ifndef PRODUCT |
| 150 // Register running isolates with service. | 146 // Register running isolates with service. |
| 151 RegisterRunningIsolatesVisitor register_isolates(thread); | 147 RegisterRunningIsolatesVisitor register_isolates(thread); |
| 152 if (FLAG_trace_service) { | 148 if (FLAG_trace_service) { |
| 153 OS::Print("vm-service: Registering running isolates.\n"); | 149 OS::Print("vm-service: Registering running isolates.\n"); |
| 154 } | 150 } |
| 155 Isolate::VisitIsolates(®ister_isolates); | 151 Isolate::VisitIsolates(®ister_isolates); |
| 156 #endif | 152 #endif |
| 157 return Object::null(); | 153 return Object::null(); |
| 158 } | 154 } |
| 159 | 155 |
| 160 | |
| 161 DEFINE_NATIVE_ENTRY(VMService_OnExit, 0) { | 156 DEFINE_NATIVE_ENTRY(VMService_OnExit, 0) { |
| 162 if (FLAG_trace_service) { | 157 if (FLAG_trace_service) { |
| 163 OS::Print("vm-service: processed exit message.\n"); | 158 OS::Print("vm-service: processed exit message.\n"); |
| 164 MessageHandler* message_handler = isolate->message_handler(); | 159 MessageHandler* message_handler = isolate->message_handler(); |
| 165 OS::Print("vm-service: live ports = %" Pd "\n", | 160 OS::Print("vm-service: live ports = %" Pd "\n", |
| 166 message_handler->live_ports()); | 161 message_handler->live_ports()); |
| 167 } | 162 } |
| 168 return Object::null(); | 163 return Object::null(); |
| 169 } | 164 } |
| 170 | 165 |
| 171 | |
| 172 DEFINE_NATIVE_ENTRY(VMService_OnServerAddressChange, 1) { | 166 DEFINE_NATIVE_ENTRY(VMService_OnServerAddressChange, 1) { |
| 173 if (!FLAG_support_service) { | 167 if (!FLAG_support_service) { |
| 174 return Object::null(); | 168 return Object::null(); |
| 175 } | 169 } |
| 176 GET_NATIVE_ARGUMENT(String, address, arguments->NativeArgAt(0)); | 170 GET_NATIVE_ARGUMENT(String, address, arguments->NativeArgAt(0)); |
| 177 if (address.IsNull()) { | 171 if (address.IsNull()) { |
| 178 ServiceIsolate::SetServerAddress(NULL); | 172 ServiceIsolate::SetServerAddress(NULL); |
| 179 } else { | 173 } else { |
| 180 ServiceIsolate::SetServerAddress(address.ToCString()); | 174 ServiceIsolate::SetServerAddress(address.ToCString()); |
| 181 } | 175 } |
| 182 return Object::null(); | 176 return Object::null(); |
| 183 } | 177 } |
| 184 | 178 |
| 185 | |
| 186 DEFINE_NATIVE_ENTRY(VMService_ListenStream, 1) { | 179 DEFINE_NATIVE_ENTRY(VMService_ListenStream, 1) { |
| 187 GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0)); | 180 GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0)); |
| 188 bool result = false; | 181 bool result = false; |
| 189 if (FLAG_support_service) { | 182 if (FLAG_support_service) { |
| 190 result = Service::ListenStream(stream_id.ToCString()); | 183 result = Service::ListenStream(stream_id.ToCString()); |
| 191 } | 184 } |
| 192 return Bool::Get(result).raw(); | 185 return Bool::Get(result).raw(); |
| 193 } | 186 } |
| 194 | 187 |
| 195 | |
| 196 DEFINE_NATIVE_ENTRY(VMService_CancelStream, 1) { | 188 DEFINE_NATIVE_ENTRY(VMService_CancelStream, 1) { |
| 197 GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0)); | 189 GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0)); |
| 198 if (FLAG_support_service) { | 190 if (FLAG_support_service) { |
| 199 Service::CancelStream(stream_id.ToCString()); | 191 Service::CancelStream(stream_id.ToCString()); |
| 200 } | 192 } |
| 201 return Object::null(); | 193 return Object::null(); |
| 202 } | 194 } |
| 203 | 195 |
| 204 | |
| 205 DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) { | 196 DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) { |
| 206 if (!FLAG_support_service) { | 197 if (!FLAG_support_service) { |
| 207 return Object::null(); | 198 return Object::null(); |
| 208 } | 199 } |
| 209 return Service::RequestAssets(); | 200 return Service::RequestAssets(); |
| 210 } | 201 } |
| 211 | 202 |
| 212 | |
| 213 #ifndef PRODUCT | 203 #ifndef PRODUCT |
| 214 // TODO(25041): When reading, this class copies out the filenames and contents | 204 // TODO(25041): When reading, this class copies out the filenames and contents |
| 215 // into new buffers. It does this because the lifetime of |bytes| is uncertain. | 205 // into new buffers. It does this because the lifetime of |bytes| is uncertain. |
| 216 // If |bytes| is pinned in memory, then we could instead load up | 206 // If |bytes| is pinned in memory, then we could instead load up |
| 217 // |filenames_| and |contents_| with pointers into |bytes| without making | 207 // |filenames_| and |contents_| with pointers into |bytes| without making |
| 218 // copies. | 208 // copies. |
| 219 class TarArchive { | 209 class TarArchive { |
| 220 public: | 210 public: |
| 221 TarArchive(uint8_t* bytes, intptr_t bytes_length) | 211 TarArchive(uint8_t* bytes, intptr_t bytes_length) |
| 222 : rs_(bytes, bytes_length) {} | 212 : rs_(bytes, bytes_length) {} |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 } | 356 } |
| 367 | 357 |
| 368 ReadStream rs_; | 358 ReadStream rs_; |
| 369 GrowableArray<char*> filenames_; | 359 GrowableArray<char*> filenames_; |
| 370 GrowableArray<uint8_t*> contents_; | 360 GrowableArray<uint8_t*> contents_; |
| 371 GrowableArray<intptr_t> content_lengths_; | 361 GrowableArray<intptr_t> content_lengths_; |
| 372 | 362 |
| 373 DISALLOW_COPY_AND_ASSIGN(TarArchive); | 363 DISALLOW_COPY_AND_ASSIGN(TarArchive); |
| 374 }; | 364 }; |
| 375 | 365 |
| 376 | |
| 377 static void ContentsFinalizer(void* isolate_callback_data, | 366 static void ContentsFinalizer(void* isolate_callback_data, |
| 378 Dart_WeakPersistentHandle handle, | 367 Dart_WeakPersistentHandle handle, |
| 379 void* peer) { | 368 void* peer) { |
| 380 uint8_t* data = reinterpret_cast<uint8_t*>(peer); | 369 uint8_t* data = reinterpret_cast<uint8_t*>(peer); |
| 381 delete[] data; | 370 delete[] data; |
| 382 } | 371 } |
| 383 | 372 |
| 384 | |
| 385 static void FilenameFinalizer(void* peer) { | 373 static void FilenameFinalizer(void* peer) { |
| 386 char* filename = reinterpret_cast<char*>(peer); | 374 char* filename = reinterpret_cast<char*>(peer); |
| 387 delete[] filename; | 375 delete[] filename; |
| 388 } | 376 } |
| 389 | 377 |
| 390 | |
| 391 #endif | 378 #endif |
| 392 | 379 |
| 393 | |
| 394 DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) { | 380 DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) { |
| 395 #ifndef PRODUCT | 381 #ifndef PRODUCT |
| 396 if (!FLAG_support_service) { | 382 if (!FLAG_support_service) { |
| 397 return Object::null(); | 383 return Object::null(); |
| 398 } | 384 } |
| 399 GET_NON_NULL_NATIVE_ARGUMENT(TypedData, data, arguments->NativeArgAt(0)); | 385 GET_NON_NULL_NATIVE_ARGUMENT(TypedData, data, arguments->NativeArgAt(0)); |
| 400 TransitionVMToNative transition(thread); | 386 TransitionVMToNative transition(thread); |
| 401 Api::Scope scope(thread); | 387 Api::Scope scope(thread); |
| 402 | 388 |
| 403 Dart_Handle data_handle = Api::NewHandle(thread, data.raw()); | 389 Dart_Handle data_handle = Api::NewHandle(thread, data.raw()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 Dart_ListSetAt(result_list, idx, dart_filename); | 426 Dart_ListSetAt(result_list, idx, dart_filename); |
| 441 Dart_ListSetAt(result_list, (idx + 1), dart_contents); | 427 Dart_ListSetAt(result_list, (idx + 1), dart_contents); |
| 442 idx += 2; | 428 idx += 2; |
| 443 } | 429 } |
| 444 return Api::UnwrapArrayHandle(thread->zone(), result_list).raw(); | 430 return Api::UnwrapArrayHandle(thread->zone(), result_list).raw(); |
| 445 #else | 431 #else |
| 446 return Object::null(); | 432 return Object::null(); |
| 447 #endif | 433 #endif |
| 448 } | 434 } |
| 449 | 435 |
| 450 | |
| 451 DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 2) { | 436 DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 2) { |
| 452 #ifndef PRODUCT | 437 #ifndef PRODUCT |
| 453 if (!FLAG_support_service) { | 438 if (!FLAG_support_service) { |
| 454 return Object::null(); | 439 return Object::null(); |
| 455 } | 440 } |
| 456 GET_NON_NULL_NATIVE_ARGUMENT(Instance, result, arguments->NativeArgAt(0)); | 441 GET_NON_NULL_NATIVE_ARGUMENT(Instance, result, arguments->NativeArgAt(0)); |
| 457 GET_NON_NULL_NATIVE_ARGUMENT(String, token, arguments->NativeArgAt(1)); | 442 GET_NON_NULL_NATIVE_ARGUMENT(String, token, arguments->NativeArgAt(1)); |
| 458 | 443 |
| 459 if (result.IsSendPort()) { | 444 if (result.IsSendPort()) { |
| 460 Dart_Port id = SendPort::Cast(result).Id(); | 445 Dart_Port id = SendPort::Cast(result).Id(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 479 ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn); | 464 ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn); |
| 480 spawn_event.set_spawn_token(&token); | 465 spawn_event.set_spawn_token(&token); |
| 481 spawn_event.set_spawn_error(&String::Cast(result)); | 466 spawn_event.set_spawn_error(&String::Cast(result)); |
| 482 Service::HandleEvent(&spawn_event); | 467 Service::HandleEvent(&spawn_event); |
| 483 } | 468 } |
| 484 #endif // PRODUCT | 469 #endif // PRODUCT |
| 485 return Object::null(); | 470 return Object::null(); |
| 486 } | 471 } |
| 487 | 472 |
| 488 } // namespace dart | 473 } // namespace dart |
| OLD | NEW |