| 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 "vm/service.h" | 5 #include "vm/service.h" | 
| 6 | 6 | 
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" | 
| 8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" | 
| 9 #include "platform/globals.h" | 9 #include "platform/globals.h" | 
| 10 | 10 | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 41 #include "vm/version.h" | 41 #include "vm/version.h" | 
| 42 | 42 | 
| 43 namespace dart { | 43 namespace dart { | 
| 44 | 44 | 
| 45 #define Z (T->zone()) | 45 #define Z (T->zone()) | 
| 46 | 46 | 
| 47 | 47 | 
| 48 DECLARE_FLAG(bool, trace_service); | 48 DECLARE_FLAG(bool, trace_service); | 
| 49 DECLARE_FLAG(bool, trace_service_pause_events); | 49 DECLARE_FLAG(bool, trace_service_pause_events); | 
| 50 DECLARE_FLAG(bool, profile_vm); | 50 DECLARE_FLAG(bool, profile_vm); | 
| 51 DEFINE_FLAG(charp, vm_name, "vm", | 51 DEFINE_FLAG(charp, | 
|  | 52             vm_name, | 
|  | 53             "vm", | 
| 52             "The default name of this vm as reported by the VM service " | 54             "The default name of this vm as reported by the VM service " | 
| 53             "protocol"); | 55             "protocol"); | 
| 54 | 56 | 
| 55 DEFINE_FLAG(bool, warn_on_pause_with_no_debugger, false, | 57 DEFINE_FLAG(bool, | 
|  | 58             warn_on_pause_with_no_debugger, | 
|  | 59             false, | 
| 56             "Print a message when an isolate is paused but there is no " | 60             "Print a message when an isolate is paused but there is no " | 
| 57             "debugger attached."); | 61             "debugger attached."); | 
| 58 | 62 | 
| 59 #ifndef PRODUCT | 63 #ifndef PRODUCT | 
| 60 // The name of this of this vm as reported by the VM service protocol. | 64 // The name of this of this vm as reported by the VM service protocol. | 
| 61 static char* vm_name = NULL; | 65 static char* vm_name = NULL; | 
| 62 | 66 | 
| 63 | 67 | 
| 64 static const char* GetVMName() { | 68 static const char* GetVMName() { | 
| 65   if (vm_name == NULL) { | 69   if (vm_name == NULL) { | 
| 66     return FLAG_vm_name; | 70     return FLAG_vm_name; | 
| 67   } | 71   } | 
| 68   return vm_name; | 72   return vm_name; | 
| 69 } | 73 } | 
| 70 | 74 | 
| 71 | 75 | 
| 72 ServiceIdZone::ServiceIdZone() { | 76 ServiceIdZone::ServiceIdZone() {} | 
| 73 } |  | 
| 74 | 77 | 
| 75 | 78 | 
| 76 ServiceIdZone::~ServiceIdZone() { | 79 ServiceIdZone::~ServiceIdZone() {} | 
| 77 } |  | 
| 78 | 80 | 
| 79 | 81 | 
| 80 RingServiceIdZone::RingServiceIdZone() | 82 RingServiceIdZone::RingServiceIdZone() | 
| 81     : ring_(NULL), | 83     : ring_(NULL), policy_(ObjectIdRing::kAllocateId) {} | 
| 82       policy_(ObjectIdRing::kAllocateId) { |  | 
| 83 } |  | 
| 84 | 84 | 
| 85 | 85 | 
| 86 RingServiceIdZone::~RingServiceIdZone() { | 86 RingServiceIdZone::~RingServiceIdZone() {} | 
| 87 } |  | 
| 88 | 87 | 
| 89 | 88 | 
| 90 void RingServiceIdZone::Init( | 89 void RingServiceIdZone::Init(ObjectIdRing* ring, | 
| 91     ObjectIdRing* ring, ObjectIdRing::IdPolicy policy) { | 90                              ObjectIdRing::IdPolicy policy) { | 
| 92   ring_ = ring; | 91   ring_ = ring; | 
| 93   policy_ = policy; | 92   policy_ = policy; | 
| 94 } | 93 } | 
| 95 | 94 | 
| 96 | 95 | 
| 97 char* RingServiceIdZone::GetServiceId(const Object& obj) { | 96 char* RingServiceIdZone::GetServiceId(const Object& obj) { | 
| 98   ASSERT(ring_ != NULL); | 97   ASSERT(ring_ != NULL); | 
| 99   Thread* thread = Thread::Current(); | 98   Thread* thread = Thread::Current(); | 
| 100   Zone* zone = thread->zone(); | 99   Zone* zone = thread->zone(); | 
| 101   ASSERT(zone != NULL); | 100   ASSERT(zone != NULL); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 121 StreamInfo Service::isolate_stream("Isolate"); | 120 StreamInfo Service::isolate_stream("Isolate"); | 
| 122 StreamInfo Service::debug_stream("Debug"); | 121 StreamInfo Service::debug_stream("Debug"); | 
| 123 StreamInfo Service::gc_stream("GC"); | 122 StreamInfo Service::gc_stream("GC"); | 
| 124 StreamInfo Service::echo_stream("_Echo"); | 123 StreamInfo Service::echo_stream("_Echo"); | 
| 125 StreamInfo Service::graph_stream("_Graph"); | 124 StreamInfo Service::graph_stream("_Graph"); | 
| 126 StreamInfo Service::logging_stream("_Logging"); | 125 StreamInfo Service::logging_stream("_Logging"); | 
| 127 StreamInfo Service::extension_stream("Extension"); | 126 StreamInfo Service::extension_stream("Extension"); | 
| 128 StreamInfo Service::timeline_stream("Timeline"); | 127 StreamInfo Service::timeline_stream("Timeline"); | 
| 129 | 128 | 
| 130 static StreamInfo* streams_[] = { | 129 static StreamInfo* streams_[] = { | 
| 131   &Service::vm_stream, | 130     &Service::vm_stream,       &Service::isolate_stream, | 
| 132   &Service::isolate_stream, | 131     &Service::debug_stream,    &Service::gc_stream, | 
| 133   &Service::debug_stream, | 132     &Service::echo_stream,     &Service::graph_stream, | 
| 134   &Service::gc_stream, | 133     &Service::logging_stream,  &Service::extension_stream, | 
| 135   &Service::echo_stream, | 134     &Service::timeline_stream, | 
| 136   &Service::graph_stream, |  | 
| 137   &Service::logging_stream, |  | 
| 138   &Service::extension_stream, |  | 
| 139   &Service::timeline_stream, |  | 
| 140 }; | 135 }; | 
| 141 | 136 | 
| 142 | 137 | 
| 143 bool Service::ListenStream(const char* stream_id) { | 138 bool Service::ListenStream(const char* stream_id) { | 
| 144   if (FLAG_trace_service) { | 139   if (FLAG_trace_service) { | 
| 145     OS::Print("vm-service: starting stream '%s'\n", | 140     OS::Print("vm-service: starting stream '%s'\n", stream_id); | 
| 146               stream_id); |  | 
| 147   } | 141   } | 
| 148   intptr_t num_streams = sizeof(streams_) / | 142   intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]); | 
| 149                          sizeof(streams_[0]); |  | 
| 150   for (intptr_t i = 0; i < num_streams; i++) { | 143   for (intptr_t i = 0; i < num_streams; i++) { | 
| 151     if (strcmp(stream_id, streams_[i]->id()) == 0) { | 144     if (strcmp(stream_id, streams_[i]->id()) == 0) { | 
| 152       streams_[i]->set_enabled(true); | 145       streams_[i]->set_enabled(true); | 
| 153       return true; | 146       return true; | 
| 154     } | 147     } | 
| 155   } | 148   } | 
| 156   if (stream_listen_callback_) { | 149   if (stream_listen_callback_) { | 
| 157     Thread* T = Thread::Current(); | 150     Thread* T = Thread::Current(); | 
| 158     TransitionVMToNative transition(T); | 151     TransitionVMToNative transition(T); | 
| 159     return (*stream_listen_callback_)(stream_id); | 152     return (*stream_listen_callback_)(stream_id); | 
| 160   } | 153   } | 
| 161   return false; | 154   return false; | 
| 162 } | 155 } | 
| 163 | 156 | 
| 164 | 157 | 
| 165 void Service::CancelStream(const char* stream_id) { | 158 void Service::CancelStream(const char* stream_id) { | 
| 166   if (FLAG_trace_service) { | 159   if (FLAG_trace_service) { | 
| 167     OS::Print("vm-service: stopping stream '%s'\n", | 160     OS::Print("vm-service: stopping stream '%s'\n", stream_id); | 
| 168               stream_id); |  | 
| 169   } | 161   } | 
| 170   intptr_t num_streams = sizeof(streams_) / | 162   intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]); | 
| 171                          sizeof(streams_[0]); |  | 
| 172   for (intptr_t i = 0; i < num_streams; i++) { | 163   for (intptr_t i = 0; i < num_streams; i++) { | 
| 173     if (strcmp(stream_id, streams_[i]->id()) == 0) { | 164     if (strcmp(stream_id, streams_[i]->id()) == 0) { | 
| 174       streams_[i]->set_enabled(false); | 165       streams_[i]->set_enabled(false); | 
| 175       return; | 166       return; | 
| 176     } | 167     } | 
| 177   } | 168   } | 
| 178   if (stream_cancel_callback_) { | 169   if (stream_cancel_callback_) { | 
| 179     Thread* T = Thread::Current(); | 170     Thread* T = Thread::Current(); | 
| 180     TransitionVMToNative transition(T); | 171     TransitionVMToNative transition(T); | 
| 181     return (*stream_cancel_callback_)(stream_id); | 172     return (*stream_cancel_callback_)(stream_id); | 
| 182   } | 173   } | 
| 183 } | 174 } | 
| 184 | 175 | 
| 185 RawObject* Service::RequestAssets() { | 176 RawObject* Service::RequestAssets() { | 
| 186   Thread* T = Thread::Current(); | 177   Thread* T = Thread::Current(); | 
| 187   TransitionVMToNative transition(T); | 178   TransitionVMToNative transition(T); | 
| 188   Api::Scope api_scope(T); | 179   Api::Scope api_scope(T); | 
| 189   if (get_service_assets_callback_ == NULL) { | 180   if (get_service_assets_callback_ == NULL) { | 
| 190     return Object::null(); | 181     return Object::null(); | 
| 191   } | 182   } | 
| 192   Dart_Handle handle = get_service_assets_callback_(); | 183   Dart_Handle handle = get_service_assets_callback_(); | 
| 193   if (Dart_IsError(handle)) { | 184   if (Dart_IsError(handle)) { | 
| 194     Dart_PropagateError(handle); | 185     Dart_PropagateError(handle); | 
| 195   } | 186   } | 
| 196   const Object& object = Object::Handle(Api::UnwrapHandle(handle)); | 187   const Object& object = Object::Handle(Api::UnwrapHandle(handle)); | 
| 197   if (object.IsNull()) { | 188   if (object.IsNull()) { | 
| 198     return Object::null(); | 189     return Object::null(); | 
| 199   } | 190   } | 
| 200   if (!object.IsTypedData()) { | 191   if (!object.IsTypedData()) { | 
| 201     const String& error_message = | 192     const String& error_message = String::Handle( | 
| 202         String::Handle( | 193         String::New("An implementation of Dart_GetVMServiceAssetsArchive " | 
| 203             String::New("An implementation of Dart_GetVMServiceAssetsArchive " | 194                     "should return a Uint8Array or null.")); | 
| 204                         "should return a Uint8Array or null.")); |  | 
| 205     const Error& error = Error::Handle(ApiError::New(error_message)); | 195     const Error& error = Error::Handle(ApiError::New(error_message)); | 
| 206     Exceptions::PropagateError(error); | 196     Exceptions::PropagateError(error); | 
| 207     return Object::null(); | 197     return Object::null(); | 
| 208   } | 198   } | 
| 209   const TypedData& typed_data = TypedData::Cast(object); | 199   const TypedData& typed_data = TypedData::Cast(object); | 
| 210   if (typed_data.ElementSizeInBytes() != 1) { | 200   if (typed_data.ElementSizeInBytes() != 1) { | 
| 211     const String& error_message = | 201     const String& error_message = String::Handle( | 
| 212         String::Handle( | 202         String::New("An implementation of Dart_GetVMServiceAssetsArchive " | 
| 213             String::New("An implementation of Dart_GetVMServiceAssetsArchive " | 203                     "should return a Uint8Array or null.")); | 
| 214                         "should return a Uint8Array or null.")); |  | 
| 215     const Error& error = Error::Handle(ApiError::New(error_message)); | 204     const Error& error = Error::Handle(ApiError::New(error_message)); | 
| 216     Exceptions::PropagateError(error); | 205     Exceptions::PropagateError(error); | 
| 217     return Object::null(); | 206     return Object::null(); | 
| 218   } | 207   } | 
| 219   return Api::UnwrapHandle(handle); | 208   return Api::UnwrapHandle(handle); | 
| 220 } | 209 } | 
| 221 | 210 | 
| 222 | 211 | 
| 223 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 212 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 
| 224   void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 213   void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 
| 225   if (new_ptr == NULL) { | 214   if (new_ptr == NULL) { | 
| 226     OUT_OF_MEMORY(); | 215     OUT_OF_MEMORY(); | 
| 227   } | 216   } | 
| 228   return reinterpret_cast<uint8_t*>(new_ptr); | 217   return reinterpret_cast<uint8_t*>(new_ptr); | 
| 229 } | 218 } | 
| 230 | 219 | 
| 231 | 220 | 
| 232 static void PrintMissingParamError(JSONStream* js, | 221 static void PrintMissingParamError(JSONStream* js, const char* param) { | 
| 233                                    const char* param) { | 222   js->PrintError(kInvalidParams, "%s expects the '%s' parameter", js->method(), | 
| 234   js->PrintError(kInvalidParams, | 223                  param); | 
| 235                  "%s expects the '%s' parameter", js->method(), param); |  | 
| 236 } | 224 } | 
| 237 | 225 | 
| 238 | 226 | 
| 239 static void PrintInvalidParamError(JSONStream* js, | 227 static void PrintInvalidParamError(JSONStream* js, const char* param) { | 
| 240                                    const char* param) { | 228   js->PrintError(kInvalidParams, "%s: invalid '%s' parameter: %s", js->method(), | 
| 241   js->PrintError(kInvalidParams, | 229                  param, js->LookupParam(param)); | 
| 242                  "%s: invalid '%s' parameter: %s", |  | 
| 243                  js->method(), param, js->LookupParam(param)); |  | 
| 244 } | 230 } | 
| 245 | 231 | 
| 246 | 232 | 
| 247 static void PrintIllegalParamError(JSONStream* js, | 233 static void PrintIllegalParamError(JSONStream* js, const char* param) { | 
| 248                                    const char* param) { | 234   js->PrintError(kInvalidParams, "%s: illegal '%s' parameter: %s", js->method(), | 
| 249   js->PrintError(kInvalidParams, | 235                  param, js->LookupParam(param)); | 
| 250                  "%s: illegal '%s' parameter: %s", |  | 
| 251                  js->method(), param, js->LookupParam(param)); |  | 
| 252 } | 236 } | 
| 253 | 237 | 
| 254 | 238 | 
| 255 static void PrintUnrecognizedMethodError(JSONStream* js) { | 239 static void PrintUnrecognizedMethodError(JSONStream* js) { | 
| 256   js->PrintError(kMethodNotFound, NULL); | 240   js->PrintError(kMethodNotFound, NULL); | 
| 257 } | 241 } | 
| 258 | 242 | 
| 259 | 243 | 
| 260 static void PrintSuccess(JSONStream* js) { | 244 static void PrintSuccess(JSONStream* js) { | 
| 261   JSONObject jsobj(js); | 245   JSONObject jsobj(js); | 
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 409   ClassTable* class_table = isolate->class_table(); | 393   ClassTable* class_table = isolate->class_table(); | 
| 410   ASSERT(class_table != NULL); | 394   ASSERT(class_table != NULL); | 
| 411   return class_table->At(cid); | 395   return class_table->At(cid); | 
| 412 } | 396 } | 
| 413 | 397 | 
| 414 | 398 | 
| 415 // TODO(johnmccutchan): Split into separate file and write unit tests. | 399 // TODO(johnmccutchan): Split into separate file and write unit tests. | 
| 416 class MethodParameter { | 400 class MethodParameter { | 
| 417  public: | 401  public: | 
| 418   MethodParameter(const char* name, bool required) | 402   MethodParameter(const char* name, bool required) | 
| 419       : name_(name), required_(required) { | 403       : name_(name), required_(required) {} | 
| 420   } |  | 
| 421 | 404 | 
| 422   virtual ~MethodParameter() { } | 405   virtual ~MethodParameter() {} | 
| 423 | 406 | 
| 424   virtual bool Validate(const char* value) const { | 407   virtual bool Validate(const char* value) const { return true; } | 
| 425     return true; |  | 
| 426   } |  | 
| 427 | 408 | 
| 428   virtual bool ValidateObject(const Object& value) const { | 409   virtual bool ValidateObject(const Object& value) const { return true; } | 
| 429     return true; |  | 
| 430   } |  | 
| 431 | 410 | 
| 432   const char* name() const { | 411   const char* name() const { return name_; } | 
| 433     return name_; |  | 
| 434   } |  | 
| 435 | 412 | 
| 436   bool required() const { | 413   bool required() const { return required_; } | 
| 437     return required_; |  | 
| 438   } |  | 
| 439 | 414 | 
| 440   virtual void PrintError(const char* name, | 415   virtual void PrintError(const char* name, | 
| 441                           const char* value, | 416                           const char* value, | 
| 442                           JSONStream* js) const { | 417                           JSONStream* js) const { | 
| 443     PrintInvalidParamError(js, name); | 418     PrintInvalidParamError(js, name); | 
| 444   } | 419   } | 
| 445 | 420 | 
| 446   virtual void PrintErrorObject(const char* name, | 421   virtual void PrintErrorObject(const char* name, | 
| 447                                 const Object& value, | 422                                 const Object& value, | 
| 448                                 JSONStream* js) const { | 423                                 JSONStream* js) const { | 
| 449     PrintInvalidParamError(js, name); | 424     PrintInvalidParamError(js, name); | 
| 450   } | 425   } | 
| 451 | 426 | 
| 452  private: | 427  private: | 
| 453   const char* name_; | 428   const char* name_; | 
| 454   bool required_; | 429   bool required_; | 
| 455 }; | 430 }; | 
| 456 | 431 | 
| 457 | 432 | 
| 458 class DartStringParameter : public MethodParameter { | 433 class DartStringParameter : public MethodParameter { | 
| 459  public: | 434  public: | 
| 460   DartStringParameter(const char* name, bool required) | 435   DartStringParameter(const char* name, bool required) | 
| 461       : MethodParameter(name, required) { | 436       : MethodParameter(name, required) {} | 
| 462   } |  | 
| 463 | 437 | 
| 464   virtual bool ValidateObject(const Object& value) const { | 438   virtual bool ValidateObject(const Object& value) const { | 
| 465     return value.IsString(); | 439     return value.IsString(); | 
| 466   } | 440   } | 
| 467 }; | 441 }; | 
| 468 | 442 | 
| 469 | 443 | 
| 470 class DartListParameter : public MethodParameter { | 444 class DartListParameter : public MethodParameter { | 
| 471  public: | 445  public: | 
| 472   DartListParameter(const char* name, bool required) | 446   DartListParameter(const char* name, bool required) | 
| 473       : MethodParameter(name, required) { | 447       : MethodParameter(name, required) {} | 
| 474   } |  | 
| 475 | 448 | 
| 476   virtual bool ValidateObject(const Object& value) const { | 449   virtual bool ValidateObject(const Object& value) const { | 
| 477     return value.IsArray() || value.IsGrowableObjectArray(); | 450     return value.IsArray() || value.IsGrowableObjectArray(); | 
| 478   } | 451   } | 
| 479 }; | 452 }; | 
| 480 | 453 | 
| 481 | 454 | 
| 482 class NoSuchParameter : public MethodParameter { | 455 class NoSuchParameter : public MethodParameter { | 
| 483  public: | 456  public: | 
| 484   explicit NoSuchParameter(const char* name) | 457   explicit NoSuchParameter(const char* name) : MethodParameter(name, false) {} | 
| 485     : MethodParameter(name, false) { |  | 
| 486   } |  | 
| 487 | 458 | 
| 488   virtual bool Validate(const char* value) const { | 459   virtual bool Validate(const char* value) const { return (value == NULL); } | 
| 489     return (value == NULL); |  | 
| 490   } |  | 
| 491 | 460 | 
| 492   virtual bool ValidateObject(const Object& value) const { | 461   virtual bool ValidateObject(const Object& value) const { | 
| 493     return value.IsNull(); | 462     return value.IsNull(); | 
| 494   } | 463   } | 
| 495 }; | 464 }; | 
| 496 | 465 | 
| 497 | 466 | 
| 498 class BoolParameter : public MethodParameter { | 467 class BoolParameter : public MethodParameter { | 
| 499  public: | 468  public: | 
| 500   BoolParameter(const char* name, bool required) | 469   BoolParameter(const char* name, bool required) | 
| 501       : MethodParameter(name, required) { | 470       : MethodParameter(name, required) {} | 
| 502   } |  | 
| 503 | 471 | 
| 504   virtual bool Validate(const char* value) const { | 472   virtual bool Validate(const char* value) const { | 
| 505     if (value == NULL) { | 473     if (value == NULL) { | 
| 506       return false; | 474       return false; | 
| 507     } | 475     } | 
| 508     return (strcmp("true", value) == 0) || (strcmp("false", value) == 0); | 476     return (strcmp("true", value) == 0) || (strcmp("false", value) == 0); | 
| 509   } | 477   } | 
| 510 | 478 | 
| 511   static bool Parse(const char* value, bool default_value = false) { | 479   static bool Parse(const char* value, bool default_value = false) { | 
| 512     if (value == NULL) { | 480     if (value == NULL) { | 
| 513       return default_value; | 481       return default_value; | 
| 514     } | 482     } | 
| 515     return strcmp("true", value) == 0; | 483     return strcmp("true", value) == 0; | 
| 516   } | 484   } | 
| 517 }; | 485 }; | 
| 518 | 486 | 
| 519 | 487 | 
| 520 class UIntParameter : public MethodParameter { | 488 class UIntParameter : public MethodParameter { | 
| 521  public: | 489  public: | 
| 522   UIntParameter(const char* name, bool required) | 490   UIntParameter(const char* name, bool required) | 
| 523       : MethodParameter(name, required) { | 491       : MethodParameter(name, required) {} | 
| 524   } |  | 
| 525 | 492 | 
| 526   virtual bool Validate(const char* value) const { | 493   virtual bool Validate(const char* value) const { | 
| 527     if (value == NULL) { | 494     if (value == NULL) { | 
| 528       return false; | 495       return false; | 
| 529     } | 496     } | 
| 530     for (const char* cp = value; *cp != '\0'; cp++) { | 497     for (const char* cp = value; *cp != '\0'; cp++) { | 
| 531       if (*cp < '0' || *cp > '9') { | 498       if (*cp < '0' || *cp > '9') { | 
| 532         return false; | 499         return false; | 
| 533       } | 500       } | 
| 534     } | 501     } | 
| 535     return true; | 502     return true; | 
| 536   } | 503   } | 
| 537 | 504 | 
| 538   static intptr_t Parse(const char* value) { | 505   static intptr_t Parse(const char* value) { | 
| 539     if (value == NULL) { | 506     if (value == NULL) { | 
| 540       return -1; | 507       return -1; | 
| 541     } | 508     } | 
| 542     char* end_ptr = NULL; | 509     char* end_ptr = NULL; | 
| 543     uintptr_t result = strtoul(value, &end_ptr, 10); | 510     uintptr_t result = strtoul(value, &end_ptr, 10); | 
| 544     ASSERT(*end_ptr == '\0');  // Parsed full string | 511     ASSERT(*end_ptr == '\0');  // Parsed full string | 
| 545     return result; | 512     return result; | 
| 546   } | 513   } | 
| 547 }; | 514 }; | 
| 548 | 515 | 
| 549 | 516 | 
| 550 class Int64Parameter : public MethodParameter { | 517 class Int64Parameter : public MethodParameter { | 
| 551  public: | 518  public: | 
| 552   Int64Parameter(const char* name, bool required) | 519   Int64Parameter(const char* name, bool required) | 
| 553       : MethodParameter(name, required) { | 520       : MethodParameter(name, required) {} | 
| 554   } |  | 
| 555 | 521 | 
| 556   virtual bool Validate(const char* value) const { | 522   virtual bool Validate(const char* value) const { | 
| 557     if (value == NULL) { | 523     if (value == NULL) { | 
| 558       return false; | 524       return false; | 
| 559     } | 525     } | 
| 560     for (const char* cp = value; *cp != '\0'; cp++) { | 526     for (const char* cp = value; *cp != '\0'; cp++) { | 
| 561       if ((*cp < '0' || *cp > '9') && (*cp != '-')) { | 527       if ((*cp < '0' || *cp > '9') && (*cp != '-')) { | 
| 562         return false; | 528         return false; | 
| 563       } | 529       } | 
| 564     } | 530     } | 
| 565     return true; | 531     return true; | 
| 566   } | 532   } | 
| 567 | 533 | 
| 568   static int64_t Parse(const char* value, int64_t default_value = -1) { | 534   static int64_t Parse(const char* value, int64_t default_value = -1) { | 
| 569     if ((value == NULL) || (*value == '\0')) { | 535     if ((value == NULL) || (*value == '\0')) { | 
| 570       return default_value; | 536       return default_value; | 
| 571     } | 537     } | 
| 572     char* end_ptr = NULL; | 538     char* end_ptr = NULL; | 
| 573     int64_t result = strtoll(value, &end_ptr, 10); | 539     int64_t result = strtoll(value, &end_ptr, 10); | 
| 574     ASSERT(*end_ptr == '\0');  // Parsed full string | 540     ASSERT(*end_ptr == '\0');  // Parsed full string | 
| 575     return result; | 541     return result; | 
| 576   } | 542   } | 
| 577 }; | 543 }; | 
| 578 | 544 | 
| 579 | 545 | 
| 580 class IdParameter : public MethodParameter { | 546 class IdParameter : public MethodParameter { | 
| 581  public: | 547  public: | 
| 582   IdParameter(const char* name, bool required) | 548   IdParameter(const char* name, bool required) | 
| 583       : MethodParameter(name, required) { | 549       : MethodParameter(name, required) {} | 
| 584   } |  | 
| 585 | 550 | 
| 586   virtual bool Validate(const char* value) const { | 551   virtual bool Validate(const char* value) const { return (value != NULL); } | 
| 587     return (value != NULL); |  | 
| 588   } |  | 
| 589 }; | 552 }; | 
| 590 | 553 | 
| 591 | 554 | 
| 592 class RunnableIsolateParameter : public MethodParameter { | 555 class RunnableIsolateParameter : public MethodParameter { | 
| 593  public: | 556  public: | 
| 594   explicit RunnableIsolateParameter(const char* name) | 557   explicit RunnableIsolateParameter(const char* name) | 
| 595       : MethodParameter(name, true) { | 558       : MethodParameter(name, true) {} | 
| 596   } |  | 
| 597 | 559 | 
| 598   virtual bool Validate(const char* value) const { | 560   virtual bool Validate(const char* value) const { | 
| 599     Isolate* isolate = Isolate::Current(); | 561     Isolate* isolate = Isolate::Current(); | 
| 600     return (value != NULL) && (isolate != NULL) && (isolate->is_runnable()); | 562     return (value != NULL) && (isolate != NULL) && (isolate->is_runnable()); | 
| 601   } | 563   } | 
| 602 | 564 | 
| 603   virtual void PrintError(const char* name, | 565   virtual void PrintError(const char* name, | 
| 604                           const char* value, | 566                           const char* value, | 
| 605                           JSONStream* js) const { | 567                           JSONStream* js) const { | 
| 606     js->PrintError(kIsolateMustBeRunnable, | 568     js->PrintError(kIsolateMustBeRunnable, | 
| 607                    "Isolate must be runnable before this request is made."); | 569                    "Isolate must be runnable before this request is made."); | 
| 608   } | 570   } | 
| 609 }; | 571 }; | 
| 610 | 572 | 
| 611 | 573 | 
| 612 #define ISOLATE_PARAMETER new IdParameter("isolateId", true) | 574 #define ISOLATE_PARAMETER new IdParameter("isolateId", true) | 
| 613 #define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId") | 575 #define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId") | 
| 614 #define RUNNABLE_ISOLATE_PARAMETER new RunnableIsolateParameter("isolateId") | 576 #define RUNNABLE_ISOLATE_PARAMETER new RunnableIsolateParameter("isolateId") | 
| 615 | 577 | 
| 616 class EnumParameter : public MethodParameter { | 578 class EnumParameter : public MethodParameter { | 
| 617  public: | 579  public: | 
| 618   EnumParameter(const char* name, bool required, const char* const* enums) | 580   EnumParameter(const char* name, bool required, const char* const* enums) | 
| 619       : MethodParameter(name, required), | 581       : MethodParameter(name, required), enums_(enums) {} | 
| 620         enums_(enums) { |  | 
| 621   } |  | 
| 622 | 582 | 
| 623   virtual bool Validate(const char* value) const { | 583   virtual bool Validate(const char* value) const { | 
| 624     if (value == NULL) { | 584     if (value == NULL) { | 
| 625       return true; | 585       return true; | 
| 626     } | 586     } | 
| 627     for (intptr_t i = 0; enums_[i] != NULL; i++) { | 587     for (intptr_t i = 0; enums_[i] != NULL; i++) { | 
| 628       if (strcmp(value, enums_[i]) == 0) { | 588       if (strcmp(value, enums_[i]) == 0) { | 
| 629         return true; | 589         return true; | 
| 630       } | 590       } | 
| 631     } | 591     } | 
| 632     return false; | 592     return false; | 
| 633   } | 593   } | 
| 634 | 594 | 
| 635  private: | 595  private: | 
| 636   const char* const* enums_; | 596   const char* const* enums_; | 
| 637 }; | 597 }; | 
| 638 | 598 | 
| 639 | 599 | 
| 640 // If the key is not found, this function returns the last element in the | 600 // If the key is not found, this function returns the last element in the | 
| 641 // values array. This can be used to encode the default value. | 601 // values array. This can be used to encode the default value. | 
| 642 template<typename T> | 602 template <typename T> | 
| 643 T EnumMapper(const char* value, const char* const* enums, T* values) { | 603 T EnumMapper(const char* value, const char* const* enums, T* values) { | 
| 644   ASSERT(value != NULL); | 604   ASSERT(value != NULL); | 
| 645   intptr_t i = 0; | 605   intptr_t i = 0; | 
| 646   for (i = 0; enums[i] != NULL; i++) { | 606   for (i = 0; enums[i] != NULL; i++) { | 
| 647     if (strcmp(value, enums[i]) == 0) { | 607     if (strcmp(value, enums[i]) == 0) { | 
| 648       return values[i]; | 608       return values[i]; | 
| 649     } | 609     } | 
| 650   } | 610   } | 
| 651   // Default value. | 611   // Default value. | 
| 652   return values[i]; | 612   return values[i]; | 
| 653 } | 613 } | 
| 654 | 614 | 
| 655 | 615 | 
| 656 class EnumListParameter : public MethodParameter { | 616 class EnumListParameter : public MethodParameter { | 
| 657  public: | 617  public: | 
| 658   EnumListParameter(const char* name, bool required, const char* const* enums) | 618   EnumListParameter(const char* name, bool required, const char* const* enums) | 
| 659       : MethodParameter(name, required), | 619       : MethodParameter(name, required), enums_(enums) {} | 
| 660         enums_(enums) { |  | 
| 661   } |  | 
| 662 | 620 | 
| 663   virtual bool Validate(const char* value) const { | 621   virtual bool Validate(const char* value) const { | 
| 664     return ElementCount(value) >= 0; | 622     return ElementCount(value) >= 0; | 
| 665   } | 623   } | 
| 666 | 624 | 
| 667   const char** Parse(Zone* zone, const char* value_in) const { | 625   const char** Parse(Zone* zone, const char* value_in) const { | 
| 668     const char* kJsonChars = " \t\r\n[,]"; | 626     const char* kJsonChars = " \t\r\n[,]"; | 
| 669 | 627 | 
| 670     // Make a writeable copy of the value. | 628     // Make a writeable copy of the value. | 
| 671     char* value = zone->MakeCopyOfString(value_in); | 629     char* value = zone->MakeCopyOfString(value_in); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 688 | 646 | 
| 689       // Advance.  +1 for null terminator. | 647       // Advance.  +1 for null terminator. | 
| 690       value += (len + 1); | 648       value += (len + 1); | 
| 691     } | 649     } | 
| 692     return const_cast<const char**>(elements); | 650     return const_cast<const char**>(elements); | 
| 693   } | 651   } | 
| 694 | 652 | 
| 695  private: | 653  private: | 
| 696   // For now observatory enums are ascii letters plus underscore. | 654   // For now observatory enums are ascii letters plus underscore. | 
| 697   static bool IsEnumChar(char c) { | 655   static bool IsEnumChar(char c) { | 
| 698     return (((c >= 'a') && (c <= 'z')) || | 656     return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || | 
| 699             ((c >= 'A') && (c <= 'Z')) || |  | 
| 700             (c == '_')); | 657             (c == '_')); | 
| 701   } | 658   } | 
| 702 | 659 | 
| 703   // Returns number of elements in the list.  -1 on parse error. | 660   // Returns number of elements in the list.  -1 on parse error. | 
| 704   intptr_t ElementCount(const char* value) const { | 661   intptr_t ElementCount(const char* value) const { | 
| 705     const char* kJsonWhitespaceChars = " \t\r\n"; | 662     const char* kJsonWhitespaceChars = " \t\r\n"; | 
| 706     if (value == NULL) { | 663     if (value == NULL) { | 
| 707       return -1; | 664       return -1; | 
| 708     } | 665     } | 
| 709     const char* cp = value; | 666     const char* cp = value; | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 770   const char* const* enums_; | 727   const char* const* enums_; | 
| 771 }; | 728 }; | 
| 772 | 729 | 
| 773 | 730 | 
| 774 typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js); | 731 typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js); | 
| 775 | 732 | 
| 776 | 733 | 
| 777 struct ServiceMethodDescriptor { | 734 struct ServiceMethodDescriptor { | 
| 778   const char* name; | 735   const char* name; | 
| 779   const ServiceMethodEntry entry; | 736   const ServiceMethodEntry entry; | 
| 780   const MethodParameter* const * parameters; | 737   const MethodParameter* const* parameters; | 
| 781 }; | 738 }; | 
| 782 | 739 | 
| 783 | 740 | 
| 784 // TODO(johnmccutchan): Do we reject unexpected parameters? | 741 // TODO(johnmccutchan): Do we reject unexpected parameters? | 
| 785 static bool ValidateParameters(const MethodParameter* const* parameters, | 742 static bool ValidateParameters(const MethodParameter* const* parameters, | 
| 786                               JSONStream* js) { | 743                                JSONStream* js) { | 
| 787   if (parameters == NULL) { | 744   if (parameters == NULL) { | 
| 788     return true; | 745     return true; | 
| 789   } | 746   } | 
| 790   if (js->NumObjectParameters() > 0) { | 747   if (js->NumObjectParameters() > 0) { | 
| 791     Object& value = Object::Handle(); | 748     Object& value = Object::Handle(); | 
| 792     for (intptr_t i = 0; parameters[i] != NULL; i++) { | 749     for (intptr_t i = 0; parameters[i] != NULL; i++) { | 
| 793       const MethodParameter* parameter = parameters[i]; | 750       const MethodParameter* parameter = parameters[i]; | 
| 794       const char* name = parameter->name(); | 751       const char* name = parameter->name(); | 
| 795       const bool required = parameter->required(); | 752       const bool required = parameter->required(); | 
| 796       value = js->LookupObjectParam(name); | 753       value = js->LookupObjectParam(name); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 828 void Service::PostError(const String& method_name, | 785 void Service::PostError(const String& method_name, | 
| 829                         const Array& parameter_keys, | 786                         const Array& parameter_keys, | 
| 830                         const Array& parameter_values, | 787                         const Array& parameter_values, | 
| 831                         const Instance& reply_port, | 788                         const Instance& reply_port, | 
| 832                         const Instance& id, | 789                         const Instance& id, | 
| 833                         const Error& error) { | 790                         const Error& error) { | 
| 834   Thread* T = Thread::Current(); | 791   Thread* T = Thread::Current(); | 
| 835   StackZone zone(T); | 792   StackZone zone(T); | 
| 836   HANDLESCOPE(T); | 793   HANDLESCOPE(T); | 
| 837   JSONStream js; | 794   JSONStream js; | 
| 838   js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), | 795   js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), id, method_name, | 
| 839            id, method_name, parameter_keys, parameter_values); | 796            parameter_keys, parameter_values); | 
| 840   js.PrintError(kExtensionError, | 797   js.PrintError(kExtensionError, "Error in extension `%s`: %s", js.method(), | 
| 841                 "Error in extension `%s`: %s", | 798                 error.ToErrorCString()); | 
| 842                 js.method(), error.ToErrorCString()); |  | 
| 843   js.PostReply(); | 799   js.PostReply(); | 
| 844 } | 800 } | 
| 845 | 801 | 
| 846 | 802 | 
| 847 void Service::InvokeMethod(Isolate* I, | 803 void Service::InvokeMethod(Isolate* I, | 
| 848                            const Array& msg, | 804                            const Array& msg, | 
| 849                            bool parameters_are_dart_objects) { | 805                            bool parameters_are_dart_objects) { | 
| 850   Thread* T = Thread::Current(); | 806   Thread* T = Thread::Current(); | 
| 851   ASSERT(I == T->isolate()); | 807   ASSERT(I == T->isolate()); | 
| 852   ASSERT(I != NULL); | 808   ASSERT(I != NULL); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 873     ASSERT(seq.IsNull() || seq.IsString() || seq.IsNumber()); | 829     ASSERT(seq.IsNull() || seq.IsString() || seq.IsNumber()); | 
| 874     ASSERT(!param_keys.IsNull()); | 830     ASSERT(!param_keys.IsNull()); | 
| 875     ASSERT(!param_values.IsNull()); | 831     ASSERT(!param_values.IsNull()); | 
| 876     ASSERT(param_keys.Length() == param_values.Length()); | 832     ASSERT(param_keys.Length() == param_values.Length()); | 
| 877 | 833 | 
| 878     if (!reply_port.IsSendPort()) { | 834     if (!reply_port.IsSendPort()) { | 
| 879       FATAL("SendPort expected."); | 835       FATAL("SendPort expected."); | 
| 880     } | 836     } | 
| 881 | 837 | 
| 882     JSONStream js; | 838     JSONStream js; | 
| 883     js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), | 839     js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), seq, method_name, | 
| 884              seq, | 840              param_keys, param_values, parameters_are_dart_objects); | 
| 885              method_name, |  | 
| 886              param_keys, |  | 
| 887              param_values, |  | 
| 888              parameters_are_dart_objects); |  | 
| 889 | 841 | 
| 890     // RPC came in with a custom service id zone. | 842     // RPC came in with a custom service id zone. | 
| 891     const char* id_zone_param = js.LookupParam("_idZone"); | 843     const char* id_zone_param = js.LookupParam("_idZone"); | 
| 892 | 844 | 
| 893     if (id_zone_param != NULL) { | 845     if (id_zone_param != NULL) { | 
| 894       // Override id zone. | 846       // Override id zone. | 
| 895       if (strcmp("default", id_zone_param) == 0) { | 847       if (strcmp("default", id_zone_param) == 0) { | 
| 896         // Ring with eager id allocation. This is the default ring and default | 848         // Ring with eager id allocation. This is the default ring and default | 
| 897         // policy. | 849         // policy. | 
| 898         // Nothing to do. | 850         // Nothing to do. | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 931     EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(c_method_name); | 883     EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(c_method_name); | 
| 932     if (handler == NULL) { | 884     if (handler == NULL) { | 
| 933       handler = FindRootEmbedderHandler(c_method_name); | 885       handler = FindRootEmbedderHandler(c_method_name); | 
| 934     } | 886     } | 
| 935 | 887 | 
| 936     if (handler != NULL) { | 888     if (handler != NULL) { | 
| 937       EmbedderHandleMessage(handler, &js); | 889       EmbedderHandleMessage(handler, &js); | 
| 938       return; | 890       return; | 
| 939     } | 891     } | 
| 940 | 892 | 
| 941     const Instance& extension_handler = Instance::Handle(Z, | 893     const Instance& extension_handler = | 
| 942         I->LookupServiceExtensionHandler(method_name)); | 894         Instance::Handle(Z, I->LookupServiceExtensionHandler(method_name)); | 
| 943     if (!extension_handler.IsNull()) { | 895     if (!extension_handler.IsNull()) { | 
| 944       ScheduleExtensionHandler(extension_handler, | 896       ScheduleExtensionHandler(extension_handler, method_name, param_keys, | 
| 945                                method_name, | 897                                param_values, reply_port, seq); | 
| 946                                param_keys, |  | 
| 947                                param_values, |  | 
| 948                                reply_port, |  | 
| 949                                seq); |  | 
| 950       // Schedule was successful. Extension code will post a reply | 898       // Schedule was successful. Extension code will post a reply | 
| 951       // asynchronously. | 899       // asynchronously. | 
| 952       return; | 900       return; | 
| 953     } | 901     } | 
| 954 | 902 | 
| 955     PrintUnrecognizedMethodError(&js); | 903     PrintUnrecognizedMethodError(&js); | 
| 956     js.PostReply(); | 904     js.PostReply(); | 
| 957     return; | 905     return; | 
| 958   } | 906   } | 
| 959 } | 907 } | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 988 void Service::SendEvent(const char* stream_id, | 936 void Service::SendEvent(const char* stream_id, | 
| 989                         const char* event_type, | 937                         const char* event_type, | 
| 990                         uint8_t* bytes, | 938                         uint8_t* bytes, | 
| 991                         intptr_t bytes_length) { | 939                         intptr_t bytes_length) { | 
| 992   Thread* thread = Thread::Current(); | 940   Thread* thread = Thread::Current(); | 
| 993   Isolate* isolate = thread->isolate(); | 941   Isolate* isolate = thread->isolate(); | 
| 994   ASSERT(isolate != NULL); | 942   ASSERT(isolate != NULL); | 
| 995   ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate)); | 943   ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate)); | 
| 996 | 944 | 
| 997   if (FLAG_trace_service) { | 945   if (FLAG_trace_service) { | 
| 998     OS::Print("vm-service: Pushing ServiceEvent(isolate='%s', kind='%s'," | 946     OS::Print( | 
| 999               " len=%" Pd ") to stream %s\n", | 947         "vm-service: Pushing ServiceEvent(isolate='%s', kind='%s'," | 
| 1000               isolate->name(), event_type, bytes_length, stream_id); | 948         " len=%" Pd ") to stream %s\n", | 
|  | 949         isolate->name(), event_type, bytes_length, stream_id); | 
| 1001   } | 950   } | 
| 1002 | 951 | 
| 1003   bool result; | 952   bool result; | 
| 1004   { | 953   { | 
| 1005     TransitionVMToNative transition(thread); | 954     TransitionVMToNative transition(thread); | 
| 1006     Dart_CObject cbytes; | 955     Dart_CObject cbytes; | 
| 1007     cbytes.type = Dart_CObject_kExternalTypedData; | 956     cbytes.type = Dart_CObject_kExternalTypedData; | 
| 1008     cbytes.value.as_external_typed_data.type = Dart_TypedData_kUint8; | 957     cbytes.value.as_external_typed_data.type = Dart_TypedData_kUint8; | 
| 1009     cbytes.value.as_external_typed_data.length = bytes_length; | 958     cbytes.value.as_external_typed_data.length = bytes_length; | 
| 1010     cbytes.value.as_external_typed_data.data = bytes; | 959     cbytes.value.as_external_typed_data.data = bytes; | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1059   memmove(&message[offset], data, data_size); | 1008   memmove(&message[offset], data, data_size); | 
| 1060   offset += data_size; | 1009   offset += data_size; | 
| 1061 | 1010 | 
| 1062   ASSERT(offset == total_bytes); | 1011   ASSERT(offset == total_bytes); | 
| 1063   SendEvent(stream_id, event_type, message, total_bytes); | 1012   SendEvent(stream_id, event_type, message, total_bytes); | 
| 1064 } | 1013 } | 
| 1065 | 1014 | 
| 1066 | 1015 | 
| 1067 static void ReportPauseOnConsole(ServiceEvent* event) { | 1016 static void ReportPauseOnConsole(ServiceEvent* event) { | 
| 1068   const char* name = event->isolate()->debugger_name(); | 1017   const char* name = event->isolate()->debugger_name(); | 
| 1069   switch (event->kind())  { | 1018   switch (event->kind()) { | 
| 1070     case ServiceEvent::kPauseStart: | 1019     case ServiceEvent::kPauseStart: | 
| 1071       OS::PrintErr( | 1020       OS::PrintErr( | 
| 1072           "vm-service: isolate '%s' has no debugger attached and is paused at " | 1021           "vm-service: isolate '%s' has no debugger attached and is paused at " | 
| 1073           "start.", name); | 1022           "start.", | 
|  | 1023           name); | 
| 1074       break; | 1024       break; | 
| 1075     case ServiceEvent::kPauseExit: | 1025     case ServiceEvent::kPauseExit: | 
| 1076       OS::PrintErr( | 1026       OS::PrintErr( | 
| 1077           "vm-service: isolate '%s' has no debugger attached and is paused at " | 1027           "vm-service: isolate '%s' has no debugger attached and is paused at " | 
| 1078           "exit.", name); | 1028           "exit.", | 
|  | 1029           name); | 
| 1079       break; | 1030       break; | 
| 1080     case ServiceEvent::kPauseException: | 1031     case ServiceEvent::kPauseException: | 
| 1081       OS::PrintErr( | 1032       OS::PrintErr( | 
| 1082           "vm-service: isolate '%s' has no debugger attached and is paused due " | 1033           "vm-service: isolate '%s' has no debugger attached and is paused due " | 
| 1083           "to exception.", name); | 1034           "to exception.", | 
|  | 1035           name); | 
| 1084       break; | 1036       break; | 
| 1085     case ServiceEvent::kPauseInterrupted: | 1037     case ServiceEvent::kPauseInterrupted: | 
| 1086       OS::PrintErr( | 1038       OS::PrintErr( | 
| 1087           "vm-service: isolate '%s' has no debugger attached and is paused due " | 1039           "vm-service: isolate '%s' has no debugger attached and is paused due " | 
| 1088           "to interrupt.", name); | 1040           "to interrupt.", | 
|  | 1041           name); | 
| 1089       break; | 1042       break; | 
| 1090     case ServiceEvent::kPauseBreakpoint: | 1043     case ServiceEvent::kPauseBreakpoint: | 
| 1091       OS::PrintErr( | 1044       OS::PrintErr( | 
| 1092           "vm-service: isolate '%s' has no debugger attached and is paused.", | 1045           "vm-service: isolate '%s' has no debugger attached and is paused.", | 
| 1093           name); | 1046           name); | 
| 1094       break; | 1047       break; | 
| 1095     case ServiceEvent::kPausePostRequest: | 1048     case ServiceEvent::kPausePostRequest: | 
| 1096       OS::PrintErr( | 1049       OS::PrintErr( | 
| 1097           "vm-service: isolate '%s' has no debugger attached and is paused " | 1050           "vm-service: isolate '%s' has no debugger attached and is paused " | 
| 1098           "post reload.", name); | 1051           "post reload.", | 
|  | 1052           name); | 
| 1099       break; | 1053       break; | 
| 1100     default: | 1054     default: | 
| 1101       UNREACHABLE(); | 1055       UNREACHABLE(); | 
| 1102       break; | 1056       break; | 
| 1103   } | 1057   } | 
| 1104   if (!ServiceIsolate::IsRunning()) { | 1058   if (!ServiceIsolate::IsRunning()) { | 
| 1105     OS::PrintErr("  Start the vm-service to debug.\n"); | 1059     OS::PrintErr("  Start the vm-service to debug.\n"); | 
| 1106   } else if (ServiceIsolate::server_address() == NULL) { | 1060   } else if (ServiceIsolate::server_address() == NULL) { | 
| 1107     OS::PrintErr("  Connect to Observatory to debug.\n"); | 1061     OS::PrintErr("  Connect to Observatory to debug.\n"); | 
| 1108   } else { | 1062   } else { | 
| 1109     OS::PrintErr("  Connect to Observatory at %s to debug.\n", | 1063     OS::PrintErr("  Connect to Observatory at %s to debug.\n", | 
| 1110                  ServiceIsolate::server_address()); | 1064                  ServiceIsolate::server_address()); | 
| 1111   } | 1065   } | 
| 1112   const Error& err = Error::Handle(Thread::Current()->sticky_error()); | 1066   const Error& err = Error::Handle(Thread::Current()->sticky_error()); | 
| 1113   if (!err.IsNull()) { | 1067   if (!err.IsNull()) { | 
| 1114     OS::PrintErr("%s\n", err.ToErrorCString()); | 1068     OS::PrintErr("%s\n", err.ToErrorCString()); | 
| 1115   } | 1069   } | 
| 1116 } | 1070 } | 
| 1117 | 1071 | 
| 1118 | 1072 | 
| 1119 void Service::HandleEvent(ServiceEvent* event) { | 1073 void Service::HandleEvent(ServiceEvent* event) { | 
| 1120   if (event->stream_info() != NULL && | 1074   if (event->stream_info() != NULL && !event->stream_info()->enabled()) { | 
| 1121       !event->stream_info()->enabled()) { | 1075     if (FLAG_warn_on_pause_with_no_debugger && event->IsPause()) { | 
| 1122     if (FLAG_warn_on_pause_with_no_debugger && |  | 
| 1123         event->IsPause()) { |  | 
| 1124       // If we are about to pause a running program which has no | 1076       // If we are about to pause a running program which has no | 
| 1125       // debugger connected, tell the user about it. | 1077       // debugger connected, tell the user about it. | 
| 1126       ReportPauseOnConsole(event); | 1078       ReportPauseOnConsole(event); | 
| 1127     } | 1079     } | 
| 1128     // Ignore events when no one is listening to the event stream. | 1080     // Ignore events when no one is listening to the event stream. | 
| 1129     return; | 1081     return; | 
| 1130   } | 1082   } | 
| 1131   if (!ServiceIsolate::IsRunning()) { | 1083   if (!ServiceIsolate::IsRunning()) { | 
| 1132     return; | 1084     return; | 
| 1133   } | 1085   } | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1173   Dart_CObject json_cobj; | 1125   Dart_CObject json_cobj; | 
| 1174   json_cobj.type = Dart_CObject_kString; | 1126   json_cobj.type = Dart_CObject_kString; | 
| 1175   json_cobj.value.as_string = const_cast<char*>(event->ToCString()); | 1127   json_cobj.value.as_string = const_cast<char*>(event->ToCString()); | 
| 1176   list_values[1] = &json_cobj; | 1128   list_values[1] = &json_cobj; | 
| 1177 | 1129 | 
| 1178   if (FLAG_trace_service) { | 1130   if (FLAG_trace_service) { | 
| 1179     const char* isolate_name = "<no current isolate>"; | 1131     const char* isolate_name = "<no current isolate>"; | 
| 1180     if (isolate != NULL) { | 1132     if (isolate != NULL) { | 
| 1181       isolate_name = isolate->name(); | 1133       isolate_name = isolate->name(); | 
| 1182     } | 1134     } | 
| 1183     OS::Print("vm-service: Pushing ServiceEvent(isolate='%s', kind='%s') " | 1135     OS::Print( | 
| 1184               "to stream %s\n", | 1136         "vm-service: Pushing ServiceEvent(isolate='%s', kind='%s') " | 
| 1185               isolate_name, kind, stream_id); | 1137         "to stream %s\n", | 
|  | 1138         isolate_name, kind, stream_id); | 
| 1186   } | 1139   } | 
| 1187 | 1140 | 
| 1188   Dart_PostCObject(ServiceIsolate::Port(), &list_cobj); | 1141   Dart_PostCObject(ServiceIsolate::Port(), &list_cobj); | 
| 1189 } | 1142 } | 
| 1190 | 1143 | 
| 1191 | 1144 | 
| 1192 class EmbedderServiceHandler { | 1145 class EmbedderServiceHandler { | 
| 1193  public: | 1146  public: | 
| 1194   explicit EmbedderServiceHandler(const char* name) : name_(NULL), | 1147   explicit EmbedderServiceHandler(const char* name) | 
| 1195                                                       callback_(NULL), | 1148       : name_(NULL), callback_(NULL), user_data_(NULL), next_(NULL) { | 
| 1196                                                       user_data_(NULL), |  | 
| 1197                                                       next_(NULL) { |  | 
| 1198     ASSERT(name != NULL); | 1149     ASSERT(name != NULL); | 
| 1199     name_ = strdup(name); | 1150     name_ = strdup(name); | 
| 1200   } | 1151   } | 
| 1201 | 1152 | 
| 1202   ~EmbedderServiceHandler() { | 1153   ~EmbedderServiceHandler() { free(name_); } | 
| 1203     free(name_); |  | 
| 1204   } |  | 
| 1205 | 1154 | 
| 1206   const char* name() const { return name_; } | 1155   const char* name() const { return name_; } | 
| 1207 | 1156 | 
| 1208   Dart_ServiceRequestCallback callback() const { return callback_; } | 1157   Dart_ServiceRequestCallback callback() const { return callback_; } | 
| 1209   void set_callback(Dart_ServiceRequestCallback callback) { | 1158   void set_callback(Dart_ServiceRequestCallback callback) { | 
| 1210     callback_ = callback; | 1159     callback_ = callback; | 
| 1211   } | 1160   } | 
| 1212 | 1161 | 
| 1213   void* user_data() const { return user_data_; } | 1162   void* user_data() const { return user_data_; } | 
| 1214   void set_user_data(void* user_data) { | 1163   void set_user_data(void* user_data) { user_data_ = user_data; } | 
| 1215     user_data_ = user_data; |  | 
| 1216   } |  | 
| 1217 | 1164 | 
| 1218   EmbedderServiceHandler* next() const { return next_; } | 1165   EmbedderServiceHandler* next() const { return next_; } | 
| 1219   void set_next(EmbedderServiceHandler* next) { | 1166   void set_next(EmbedderServiceHandler* next) { next_ = next; } | 
| 1220     next_ = next; |  | 
| 1221   } |  | 
| 1222 | 1167 | 
| 1223  private: | 1168  private: | 
| 1224   char* name_; | 1169   char* name_; | 
| 1225   Dart_ServiceRequestCallback callback_; | 1170   Dart_ServiceRequestCallback callback_; | 
| 1226   void* user_data_; | 1171   void* user_data_; | 
| 1227   EmbedderServiceHandler* next_; | 1172   EmbedderServiceHandler* next_; | 
| 1228 }; | 1173 }; | 
| 1229 | 1174 | 
| 1230 | 1175 | 
| 1231 void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler, | 1176 void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler, | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1268   handler = new EmbedderServiceHandler(name); | 1213   handler = new EmbedderServiceHandler(name); | 
| 1269   handler->set_callback(callback); | 1214   handler->set_callback(callback); | 
| 1270   handler->set_user_data(user_data); | 1215   handler->set_user_data(user_data); | 
| 1271 | 1216 | 
| 1272   // Insert into isolate_service_handler_head_ list. | 1217   // Insert into isolate_service_handler_head_ list. | 
| 1273   handler->set_next(isolate_service_handler_head_); | 1218   handler->set_next(isolate_service_handler_head_); | 
| 1274   isolate_service_handler_head_ = handler; | 1219   isolate_service_handler_head_ = handler; | 
| 1275 } | 1220 } | 
| 1276 | 1221 | 
| 1277 | 1222 | 
| 1278 EmbedderServiceHandler* Service::FindIsolateEmbedderHandler( | 1223 EmbedderServiceHandler* Service::FindIsolateEmbedderHandler(const char* name) { | 
| 1279     const char* name) { |  | 
| 1280   EmbedderServiceHandler* current = isolate_service_handler_head_; | 1224   EmbedderServiceHandler* current = isolate_service_handler_head_; | 
| 1281   while (current != NULL) { | 1225   while (current != NULL) { | 
| 1282     if (strcmp(name, current->name()) == 0) { | 1226     if (strcmp(name, current->name()) == 0) { | 
| 1283       return current; | 1227       return current; | 
| 1284     } | 1228     } | 
| 1285     current = current->next(); | 1229     current = current->next(); | 
| 1286   } | 1230   } | 
| 1287   return NULL; | 1231   return NULL; | 
| 1288 } | 1232 } | 
| 1289 | 1233 | 
| 1290 | 1234 | 
| 1291 void Service::RegisterRootEmbedderCallback( | 1235 void Service::RegisterRootEmbedderCallback(const char* name, | 
| 1292     const char* name, | 1236                                            Dart_ServiceRequestCallback callback, | 
| 1293     Dart_ServiceRequestCallback callback, | 1237                                            void* user_data) { | 
| 1294     void* user_data) { |  | 
| 1295   if (name == NULL) { | 1238   if (name == NULL) { | 
| 1296     return; | 1239     return; | 
| 1297   } | 1240   } | 
| 1298   EmbedderServiceHandler* handler = FindRootEmbedderHandler(name); | 1241   EmbedderServiceHandler* handler = FindRootEmbedderHandler(name); | 
| 1299   if (handler != NULL) { | 1242   if (handler != NULL) { | 
| 1300     // Update existing handler entry. | 1243     // Update existing handler entry. | 
| 1301     handler->set_callback(callback); | 1244     handler->set_callback(callback); | 
| 1302     handler->set_user_data(user_data); | 1245     handler->set_user_data(user_data); | 
| 1303     return; | 1246     return; | 
| 1304   } | 1247   } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 1320   stream_cancel_callback_ = cancel_callback; | 1263   stream_cancel_callback_ = cancel_callback; | 
| 1321 } | 1264 } | 
| 1322 | 1265 | 
| 1323 | 1266 | 
| 1324 void Service::SetGetServiceAssetsCallback( | 1267 void Service::SetGetServiceAssetsCallback( | 
| 1325     Dart_GetVMServiceAssetsArchive get_service_assets) { | 1268     Dart_GetVMServiceAssetsArchive get_service_assets) { | 
| 1326   get_service_assets_callback_ = get_service_assets; | 1269   get_service_assets_callback_ = get_service_assets; | 
| 1327 } | 1270 } | 
| 1328 | 1271 | 
| 1329 | 1272 | 
| 1330 EmbedderServiceHandler* Service::FindRootEmbedderHandler( | 1273 EmbedderServiceHandler* Service::FindRootEmbedderHandler(const char* name) { | 
| 1331     const char* name) { |  | 
| 1332   EmbedderServiceHandler* current = root_service_handler_head_; | 1274   EmbedderServiceHandler* current = root_service_handler_head_; | 
| 1333   while (current != NULL) { | 1275   while (current != NULL) { | 
| 1334     if (strcmp(name, current->name()) == 0) { | 1276     if (strcmp(name, current->name()) == 0) { | 
| 1335       return current; | 1277       return current; | 
| 1336     } | 1278     } | 
| 1337     current = current->next(); | 1279     current = current->next(); | 
| 1338   } | 1280   } | 
| 1339   return NULL; | 1281   return NULL; | 
| 1340 } | 1282 } | 
| 1341 | 1283 | 
| 1342 | 1284 | 
| 1343 void Service::ScheduleExtensionHandler(const Instance& handler, | 1285 void Service::ScheduleExtensionHandler(const Instance& handler, | 
| 1344                                        const String& method_name, | 1286                                        const String& method_name, | 
| 1345                                        const Array& parameter_keys, | 1287                                        const Array& parameter_keys, | 
| 1346                                        const Array& parameter_values, | 1288                                        const Array& parameter_values, | 
| 1347                                        const Instance& reply_port, | 1289                                        const Instance& reply_port, | 
| 1348                                        const Instance& id) { | 1290                                        const Instance& id) { | 
| 1349   ASSERT(!handler.IsNull()); | 1291   ASSERT(!handler.IsNull()); | 
| 1350   ASSERT(!method_name.IsNull()); | 1292   ASSERT(!method_name.IsNull()); | 
| 1351   ASSERT(!parameter_keys.IsNull()); | 1293   ASSERT(!parameter_keys.IsNull()); | 
| 1352   ASSERT(!parameter_values.IsNull()); | 1294   ASSERT(!parameter_values.IsNull()); | 
| 1353   ASSERT(!reply_port.IsNull()); | 1295   ASSERT(!reply_port.IsNull()); | 
| 1354   Isolate* isolate = Isolate::Current(); | 1296   Isolate* isolate = Isolate::Current(); | 
| 1355   ASSERT(isolate != NULL); | 1297   ASSERT(isolate != NULL); | 
| 1356   isolate->AppendServiceExtensionCall(handler, | 1298   isolate->AppendServiceExtensionCall(handler, method_name, parameter_keys, | 
| 1357                                       method_name, | 1299                                       parameter_values, reply_port, id); | 
| 1358                                       parameter_keys, |  | 
| 1359                                       parameter_values, |  | 
| 1360                                       reply_port, |  | 
| 1361                                       id); |  | 
| 1362 } | 1300 } | 
| 1363 | 1301 | 
| 1364 | 1302 | 
| 1365 static const MethodParameter* get_isolate_params[] = { | 1303 static const MethodParameter* get_isolate_params[] = { | 
| 1366   ISOLATE_PARAMETER, | 1304     ISOLATE_PARAMETER, NULL, | 
| 1367   NULL, |  | 
| 1368 }; | 1305 }; | 
| 1369 | 1306 | 
| 1370 | 1307 | 
| 1371 static bool GetIsolate(Thread* thread, JSONStream* js) { | 1308 static bool GetIsolate(Thread* thread, JSONStream* js) { | 
| 1372   thread->isolate()->PrintJSON(js, false); | 1309   thread->isolate()->PrintJSON(js, false); | 
| 1373   return true; | 1310   return true; | 
| 1374 } | 1311 } | 
| 1375 | 1312 | 
| 1376 | 1313 | 
| 1377 static const MethodParameter* get_stack_params[] = { | 1314 static const MethodParameter* get_stack_params[] = { | 
| 1378   RUNNABLE_ISOLATE_PARAMETER, | 1315     RUNNABLE_ISOLATE_PARAMETER, new BoolParameter("_full", false), NULL, | 
| 1379   new BoolParameter("_full", false), |  | 
| 1380   NULL, |  | 
| 1381 }; | 1316 }; | 
| 1382 | 1317 | 
| 1383 | 1318 | 
| 1384 static bool GetStack(Thread* thread, JSONStream* js) { | 1319 static bool GetStack(Thread* thread, JSONStream* js) { | 
| 1385   Isolate* isolate = thread->isolate(); | 1320   Isolate* isolate = thread->isolate(); | 
| 1386   if (isolate->debugger() == NULL) { | 1321   if (isolate->debugger() == NULL) { | 
| 1387     js->PrintError(kFeatureDisabled, | 1322     js->PrintError(kFeatureDisabled, | 
| 1388                    "Cannot get stack when debugger disabled."); | 1323                    "Cannot get stack when debugger disabled."); | 
| 1389     return true; | 1324     return true; | 
| 1390   } | 1325   } | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1440         event.AddProperty("kind", "_Echo"); | 1375         event.AddProperty("kind", "_Echo"); | 
| 1441         event.AddProperty("isolate", isolate); | 1376         event.AddProperty("isolate", isolate); | 
| 1442         if (text != NULL) { | 1377         if (text != NULL) { | 
| 1443           event.AddProperty("text", text); | 1378           event.AddProperty("text", text); | 
| 1444         } | 1379         } | 
| 1445         event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); | 1380         event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); | 
| 1446       } | 1381       } | 
| 1447     } | 1382     } | 
| 1448   } | 1383   } | 
| 1449   uint8_t data[] = {0, 128, 255}; | 1384   uint8_t data[] = {0, 128, 255}; | 
| 1450   SendEventWithData(echo_stream.id(), "_Echo", | 1385   SendEventWithData(echo_stream.id(), "_Echo", js.buffer()->buf(), | 
| 1451                     js.buffer()->buf(), js.buffer()->length(), | 1386                     js.buffer()->length(), data, sizeof(data)); | 
| 1452                     data, sizeof(data)); |  | 
| 1453 } | 1387 } | 
| 1454 | 1388 | 
| 1455 | 1389 | 
| 1456 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) { | 1390 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) { | 
| 1457   if (Service::echo_stream.enabled()) { | 1391   if (Service::echo_stream.enabled()) { | 
| 1458     Service::SendEchoEvent(thread->isolate(), js->LookupParam("text")); | 1392     Service::SendEchoEvent(thread->isolate(), js->LookupParam("text")); | 
| 1459   } | 1393   } | 
| 1460   JSONObject jsobj(js); | 1394   JSONObject jsobj(js); | 
| 1461   return HandleCommonEcho(&jsobj, js); | 1395   return HandleCommonEcho(&jsobj, js); | 
| 1462 } | 1396 } | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1510 } | 1444 } | 
| 1511 | 1445 | 
| 1512 | 1446 | 
| 1513 static RawObject* LookupObjectId(Thread* thread, | 1447 static RawObject* LookupObjectId(Thread* thread, | 
| 1514                                  const char* arg, | 1448                                  const char* arg, | 
| 1515                                  ObjectIdRing::LookupResult* kind) { | 1449                                  ObjectIdRing::LookupResult* kind) { | 
| 1516   *kind = ObjectIdRing::kValid; | 1450   *kind = ObjectIdRing::kValid; | 
| 1517   if (strncmp(arg, "int-", 4) == 0) { | 1451   if (strncmp(arg, "int-", 4) == 0) { | 
| 1518     arg += 4; | 1452     arg += 4; | 
| 1519     int64_t value = 0; | 1453     int64_t value = 0; | 
| 1520     if (!OS::StringToInt64(arg, &value) || | 1454     if (!OS::StringToInt64(arg, &value) || !Smi::IsValid(value)) { | 
| 1521         !Smi::IsValid(value)) { |  | 
| 1522       *kind = ObjectIdRing::kInvalid; | 1455       *kind = ObjectIdRing::kInvalid; | 
| 1523       return Object::null(); | 1456       return Object::null(); | 
| 1524     } | 1457     } | 
| 1525     const Integer& obj = Integer::Handle(thread->zone(), | 1458     const Integer& obj = | 
| 1526         Smi::New(static_cast<intptr_t>(value))); | 1459         Integer::Handle(thread->zone(), Smi::New(static_cast<intptr_t>(value))); | 
| 1527     return obj.raw(); | 1460     return obj.raw(); | 
| 1528   } else if (strcmp(arg, "bool-true") == 0) { | 1461   } else if (strcmp(arg, "bool-true") == 0) { | 
| 1529     return Bool::True().raw(); | 1462     return Bool::True().raw(); | 
| 1530   } else if (strcmp(arg, "bool-false") == 0) { | 1463   } else if (strcmp(arg, "bool-false") == 0) { | 
| 1531     return Bool::False().raw(); | 1464     return Bool::False().raw(); | 
| 1532   } else if (strcmp(arg, "null") == 0) { | 1465   } else if (strcmp(arg, "null") == 0) { | 
| 1533     return Object::null(); | 1466     return Object::null(); | 
| 1534   } | 1467   } | 
| 1535 | 1468 | 
| 1536   ObjectIdRing* ring = thread->isolate()->object_id_ring(); | 1469   ObjectIdRing* ring = thread->isolate()->object_id_ring(); | 
| 1537   ASSERT(ring != NULL); | 1470   ASSERT(ring != NULL); | 
| 1538   intptr_t id = -1; | 1471   intptr_t id = -1; | 
| 1539   if (!GetIntegerId(arg, &id)) { | 1472   if (!GetIntegerId(arg, &id)) { | 
| 1540     *kind = ObjectIdRing::kInvalid; | 1473     *kind = ObjectIdRing::kInvalid; | 
| 1541     return Object::null(); | 1474     return Object::null(); | 
| 1542   } | 1475   } | 
| 1543   return ring->GetObjectForId(id, kind); | 1476   return ring->GetObjectForId(id, kind); | 
| 1544 } | 1477 } | 
| 1545 | 1478 | 
| 1546 | 1479 | 
| 1547 static RawObject* LookupHeapObjectLibraries(Isolate* isolate, | 1480 static RawObject* LookupHeapObjectLibraries(Isolate* isolate, | 
| 1548                                             char** parts, int num_parts) { | 1481                                             char** parts, | 
|  | 1482                                             int num_parts) { | 
| 1549   // Library ids look like "libraries/35" | 1483   // Library ids look like "libraries/35" | 
| 1550   if (num_parts < 2) { | 1484   if (num_parts < 2) { | 
| 1551     return Object::sentinel().raw(); | 1485     return Object::sentinel().raw(); | 
| 1552   } | 1486   } | 
| 1553   const GrowableObjectArray& libs = | 1487   const GrowableObjectArray& libs = | 
| 1554       GrowableObjectArray::Handle(isolate->object_store()->libraries()); | 1488       GrowableObjectArray::Handle(isolate->object_store()->libraries()); | 
| 1555   ASSERT(!libs.IsNull()); | 1489   ASSERT(!libs.IsNull()); | 
| 1556   intptr_t id = 0; | 1490   intptr_t id = 0; | 
| 1557   if (!GetIntegerId(parts[1], &id)) { | 1491   if (!GetIntegerId(parts[1], &id)) { | 
| 1558     return Object::sentinel().raw(); | 1492     return Object::sentinel().raw(); | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1596         return script.raw(); | 1530         return script.raw(); | 
| 1597       } | 1531       } | 
| 1598     } | 1532     } | 
| 1599   } | 1533   } | 
| 1600 | 1534 | 
| 1601   // Not found. | 1535   // Not found. | 
| 1602   return Object::sentinel().raw(); | 1536   return Object::sentinel().raw(); | 
| 1603 } | 1537 } | 
| 1604 | 1538 | 
| 1605 static RawObject* LookupHeapObjectClasses(Thread* thread, | 1539 static RawObject* LookupHeapObjectClasses(Thread* thread, | 
| 1606                                           char** parts, int num_parts) { | 1540                                           char** parts, | 
|  | 1541                                           int num_parts) { | 
| 1607   // Class ids look like: "classes/17" | 1542   // Class ids look like: "classes/17" | 
| 1608   if (num_parts < 2) { | 1543   if (num_parts < 2) { | 
| 1609     return Object::sentinel().raw(); | 1544     return Object::sentinel().raw(); | 
| 1610   } | 1545   } | 
| 1611   Isolate* isolate = thread->isolate(); | 1546   Isolate* isolate = thread->isolate(); | 
| 1612   Zone* zone = thread->zone(); | 1547   Zone* zone = thread->zone(); | 
| 1613   ClassTable* table = isolate->class_table(); | 1548   ClassTable* table = isolate->class_table(); | 
| 1614   intptr_t id; | 1549   intptr_t id; | 
| 1615   if (!GetIntegerId(parts[1], &id) || | 1550   if (!GetIntegerId(parts[1], &id) || !table->IsValidIndex(id)) { | 
| 1616       !table->IsValidIndex(id)) { |  | 
| 1617     return Object::sentinel().raw(); | 1551     return Object::sentinel().raw(); | 
| 1618   } | 1552   } | 
| 1619   Class& cls = Class::Handle(zone, table->At(id)); | 1553   Class& cls = Class::Handle(zone, table->At(id)); | 
| 1620   if (num_parts == 2) { | 1554   if (num_parts == 2) { | 
| 1621     return cls.raw(); | 1555     return cls.raw(); | 
| 1622   } | 1556   } | 
| 1623   if (strcmp(parts[2], "closures") == 0) { | 1557   if (strcmp(parts[2], "closures") == 0) { | 
| 1624     // Closure ids look like: "classes/17/closures/11" | 1558     // Closure ids look like: "classes/17/closures/11" | 
| 1625     if (num_parts != 4) { | 1559     if (num_parts != 4) { | 
| 1626       return Object::sentinel().raw(); | 1560       return Object::sentinel().raw(); | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1719       return type.raw(); | 1653       return type.raw(); | 
| 1720     } | 1654     } | 
| 1721   } | 1655   } | 
| 1722 | 1656 | 
| 1723   // Not found. | 1657   // Not found. | 
| 1724   return Object::sentinel().raw(); | 1658   return Object::sentinel().raw(); | 
| 1725 } | 1659 } | 
| 1726 | 1660 | 
| 1727 | 1661 | 
| 1728 static RawObject* LookupHeapObjectTypeArguments(Thread* thread, | 1662 static RawObject* LookupHeapObjectTypeArguments(Thread* thread, | 
| 1729                                                 char** parts, int num_parts) { | 1663                                                 char** parts, | 
|  | 1664                                                 int num_parts) { | 
| 1730   Isolate* isolate = thread->isolate(); | 1665   Isolate* isolate = thread->isolate(); | 
| 1731   // TypeArguments ids look like: "typearguments/17" | 1666   // TypeArguments ids look like: "typearguments/17" | 
| 1732   if (num_parts < 2) { | 1667   if (num_parts < 2) { | 
| 1733     return Object::sentinel().raw(); | 1668     return Object::sentinel().raw(); | 
| 1734   } | 1669   } | 
| 1735   intptr_t id; | 1670   intptr_t id; | 
| 1736   if (!GetIntegerId(parts[1], &id)) { | 1671   if (!GetIntegerId(parts[1], &id)) { | 
| 1737     return Object::sentinel().raw(); | 1672     return Object::sentinel().raw(); | 
| 1738   } | 1673   } | 
| 1739   ObjectStore* object_store = isolate->object_store(); | 1674   ObjectStore* object_store = isolate->object_store(); | 
| 1740   const Array& table = Array::Handle(thread->zone(), | 1675   const Array& table = | 
| 1741                                      object_store->canonical_type_arguments()); | 1676       Array::Handle(thread->zone(), object_store->canonical_type_arguments()); | 
| 1742   ASSERT(table.Length() > 0); | 1677   ASSERT(table.Length() > 0); | 
| 1743   const intptr_t table_size = table.Length() - 1; | 1678   const intptr_t table_size = table.Length() - 1; | 
| 1744   if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) { | 1679   if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) { | 
| 1745     return Object::sentinel().raw(); | 1680     return Object::sentinel().raw(); | 
| 1746   } | 1681   } | 
| 1747   return table.At(id); | 1682   return table.At(id); | 
| 1748 } | 1683 } | 
| 1749 | 1684 | 
| 1750 | 1685 | 
| 1751 static RawObject* LookupHeapObjectCode(Isolate* isolate, | 1686 static RawObject* LookupHeapObjectCode(Isolate* isolate, | 
| 1752                                        char** parts, int num_parts) { | 1687                                        char** parts, | 
|  | 1688                                        int num_parts) { | 
| 1753   if (num_parts != 2) { | 1689   if (num_parts != 2) { | 
| 1754     return Object::sentinel().raw(); | 1690     return Object::sentinel().raw(); | 
| 1755   } | 1691   } | 
| 1756   uword pc; | 1692   uword pc; | 
| 1757   static const char* const kCollectedPrefix = "collected-"; | 1693   static const char* const kCollectedPrefix = "collected-"; | 
| 1758   static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); | 1694   static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); | 
| 1759   static const char* const kNativePrefix = "native-"; | 1695   static const char* const kNativePrefix = "native-"; | 
| 1760   static const intptr_t kNativePrefixLen = strlen(kNativePrefix); | 1696   static const intptr_t kNativePrefixLen = strlen(kNativePrefix); | 
| 1761   static const char* const kReusedPrefix = "reused-"; | 1697   static const char* const kReusedPrefix = "reused-"; | 
| 1762   static const intptr_t kReusedPrefixLen = strlen(kReusedPrefix); | 1698   static const intptr_t kReusedPrefixLen = strlen(kReusedPrefix); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 1790   if (!code.IsNull()) { | 1726   if (!code.IsNull()) { | 
| 1791     return code.raw(); | 1727     return code.raw(); | 
| 1792   } | 1728   } | 
| 1793 | 1729 | 
| 1794   // Not found. | 1730   // Not found. | 
| 1795   return Object::sentinel().raw(); | 1731   return Object::sentinel().raw(); | 
| 1796 } | 1732 } | 
| 1797 | 1733 | 
| 1798 | 1734 | 
| 1799 static RawObject* LookupHeapObjectMessage(Thread* thread, | 1735 static RawObject* LookupHeapObjectMessage(Thread* thread, | 
| 1800                                           char** parts, int num_parts) { | 1736                                           char** parts, | 
|  | 1737                                           int num_parts) { | 
| 1801   if (num_parts != 2) { | 1738   if (num_parts != 2) { | 
| 1802     return Object::sentinel().raw(); | 1739     return Object::sentinel().raw(); | 
| 1803   } | 1740   } | 
| 1804   uword message_id = 0; | 1741   uword message_id = 0; | 
| 1805   if (!GetUnsignedIntegerId(parts[1], &message_id, 16)) { | 1742   if (!GetUnsignedIntegerId(parts[1], &message_id, 16)) { | 
| 1806     return Object::sentinel().raw(); | 1743     return Object::sentinel().raw(); | 
| 1807   } | 1744   } | 
| 1808   MessageHandler::AcquiredQueues aq(thread->isolate()->message_handler()); | 1745   MessageHandler::AcquiredQueues aq(thread->isolate()->message_handler()); | 
| 1809   Message* message = aq.queue()->FindMessageById(message_id); | 1746   Message* message = aq.queue()->FindMessageById(message_id); | 
| 1810   if (message == NULL) { | 1747   if (message == NULL) { | 
| 1811     // The user may try to load an expired message. | 1748     // The user may try to load an expired message. | 
| 1812     return Object::sentinel().raw(); | 1749     return Object::sentinel().raw(); | 
| 1813   } | 1750   } | 
| 1814   if (message->len() > 0) { | 1751   if (message->len() > 0) { | 
| 1815     MessageSnapshotReader reader(message->data(), | 1752     MessageSnapshotReader reader(message->data(), message->len(), thread); | 
| 1816                                  message->len(), |  | 
| 1817                                  thread); |  | 
| 1818     return reader.ReadObject(); | 1753     return reader.ReadObject(); | 
| 1819   } else { | 1754   } else { | 
| 1820     return message->raw_obj(); | 1755     return message->raw_obj(); | 
| 1821   } | 1756   } | 
| 1822 } | 1757 } | 
| 1823 | 1758 | 
| 1824 | 1759 | 
| 1825 static RawObject* LookupHeapObject(Thread* thread, | 1760 static RawObject* LookupHeapObject(Thread* thread, | 
| 1826                                    const char* id_original, | 1761                                    const char* id_original, | 
| 1827                                    ObjectIdRing::LookupResult* result) { | 1762                                    ObjectIdRing::LookupResult* result) { | 
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1959     Field& field = Field::Handle(); | 1894     Field& field = Field::Handle(); | 
| 1960     Array& parent_field_map = Array::Handle(); | 1895     Array& parent_field_map = Array::Handle(); | 
| 1961     limit = Utils::Minimum(limit, length); | 1896     limit = Utils::Minimum(limit, length); | 
| 1962     for (intptr_t i = 0; i < limit; ++i) { | 1897     for (intptr_t i = 0; i < limit; ++i) { | 
| 1963       JSONObject jselement(&elements); | 1898       JSONObject jselement(&elements); | 
| 1964       source = path.At(i * 2); | 1899       source = path.At(i * 2); | 
| 1965       slot_offset ^= path.At((i * 2) + 1); | 1900       slot_offset ^= path.At((i * 2) + 1); | 
| 1966 | 1901 | 
| 1967       jselement.AddProperty("source", source); | 1902       jselement.AddProperty("source", source); | 
| 1968       if (source.IsArray()) { | 1903       if (source.IsArray()) { | 
| 1969         intptr_t element_index = slot_offset.Value() - | 1904         intptr_t element_index = | 
| 1970             (Array::element_offset(0) >> kWordSizeLog2); | 1905             slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2); | 
| 1971         jselement.AddProperty("parentListIndex", element_index); | 1906         jselement.AddProperty("parentListIndex", element_index); | 
| 1972       } else if (source.IsInstance()) { | 1907       } else if (source.IsInstance()) { | 
| 1973         source_class ^= source.clazz(); | 1908         source_class ^= source.clazz(); | 
| 1974         parent_field_map = source_class.OffsetToFieldMap(); | 1909         parent_field_map = source_class.OffsetToFieldMap(); | 
| 1975         intptr_t offset = slot_offset.Value(); | 1910         intptr_t offset = slot_offset.Value(); | 
| 1976         if (offset > 0 && offset < parent_field_map.Length()) { | 1911         if (offset > 0 && offset < parent_field_map.Length()) { | 
| 1977           field ^= parent_field_map.At(offset); | 1912           field ^= parent_field_map.At(offset); | 
| 1978           jselement.AddProperty("parentField", field); | 1913           jselement.AddProperty("parentField", field); | 
| 1979         } | 1914         } | 
| 1980       } else { | 1915       } else { | 
| 1981         intptr_t element_index = slot_offset.Value(); | 1916         intptr_t element_index = slot_offset.Value(); | 
| 1982         jselement.AddProperty("_parentWordOffset", element_index); | 1917         jselement.AddProperty("_parentWordOffset", element_index); | 
| 1983       } | 1918       } | 
| 1984     } | 1919     } | 
| 1985   } | 1920   } | 
| 1986 | 1921 | 
| 1987   // We nil out the array after generating the response to prevent | 1922   // We nil out the array after generating the response to prevent | 
| 1988   // reporting suprious references when repeatedly looking for the | 1923   // reporting suprious references when repeatedly looking for the | 
| 1989   // references to an object. | 1924   // references to an object. | 
| 1990   for (intptr_t i = 0; i < path.Length(); i++) { | 1925   for (intptr_t i = 0; i < path.Length(); i++) { | 
| 1991     path.SetAt(i, Object::null_object()); | 1926     path.SetAt(i, Object::null_object()); | 
| 1992   } | 1927   } | 
| 1993 | 1928 | 
| 1994   return true; | 1929   return true; | 
| 1995 } | 1930 } | 
| 1996 | 1931 | 
| 1997 | 1932 | 
| 1998 static const MethodParameter* get_inbound_references_params[] = { | 1933 static const MethodParameter* get_inbound_references_params[] = { | 
| 1999   RUNNABLE_ISOLATE_PARAMETER, | 1934     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2000   NULL, |  | 
| 2001 }; | 1935 }; | 
| 2002 | 1936 | 
| 2003 | 1937 | 
| 2004 static bool GetInboundReferences(Thread* thread, JSONStream* js) { | 1938 static bool GetInboundReferences(Thread* thread, JSONStream* js) { | 
| 2005   const char* target_id = js->LookupParam("targetId"); | 1939   const char* target_id = js->LookupParam("targetId"); | 
| 2006   if (target_id == NULL) { | 1940   if (target_id == NULL) { | 
| 2007     PrintMissingParamError(js, "targetId"); | 1941     PrintMissingParamError(js, "targetId"); | 
| 2008     return true; | 1942     return true; | 
| 2009   } | 1943   } | 
| 2010   const char* limit_cstr = js->LookupParam("limit"); | 1944   const char* limit_cstr = js->LookupParam("limit"); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2060   for (intptr_t i = 0; i < limit; ++i) { | 1994   for (intptr_t i = 0; i < limit; ++i) { | 
| 2061     JSONObject jselement(&elements); | 1995     JSONObject jselement(&elements); | 
| 2062     element = path.At(i * 2); | 1996     element = path.At(i * 2); | 
| 2063     jselement.AddProperty("value", element); | 1997     jselement.AddProperty("value", element); | 
| 2064     // Interpret the word offset from parent as list index, map key | 1998     // Interpret the word offset from parent as list index, map key | 
| 2065     // or instance field. | 1999     // or instance field. | 
| 2066     if (i > 0) { | 2000     if (i > 0) { | 
| 2067       slot_offset ^= path.At((i * 2) - 1); | 2001       slot_offset ^= path.At((i * 2) - 1); | 
| 2068       jselement.AddProperty("offset", slot_offset.Value()); | 2002       jselement.AddProperty("offset", slot_offset.Value()); | 
| 2069       if (element.IsArray() || element.IsGrowableObjectArray()) { | 2003       if (element.IsArray() || element.IsGrowableObjectArray()) { | 
| 2070         intptr_t element_index = slot_offset.Value() - | 2004         intptr_t element_index = | 
| 2071             (Array::element_offset(0) >> kWordSizeLog2); | 2005             slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2); | 
| 2072         jselement.AddProperty("parentListIndex", element_index); | 2006         jselement.AddProperty("parentListIndex", element_index); | 
| 2073       } else if (element.IsLinkedHashMap()) { | 2007       } else if (element.IsLinkedHashMap()) { | 
| 2074         map = static_cast<RawLinkedHashMap*>(path.At(i * 2)); | 2008         map = static_cast<RawLinkedHashMap*>(path.At(i * 2)); | 
| 2075         map_data = map.data(); | 2009         map_data = map.data(); | 
| 2076         intptr_t element_index = slot_offset.Value() - | 2010         intptr_t element_index = | 
| 2077             (Array::element_offset(0) >> kWordSizeLog2); | 2011             slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2); | 
| 2078         LinkedHashMap::Iterator iterator(map); | 2012         LinkedHashMap::Iterator iterator(map); | 
| 2079         while (iterator.MoveNext()) { | 2013         while (iterator.MoveNext()) { | 
| 2080           if (iterator.CurrentKey() == map_data.At(element_index) || | 2014           if (iterator.CurrentKey() == map_data.At(element_index) || | 
| 2081               iterator.CurrentValue() == map_data.At(element_index)) { | 2015               iterator.CurrentValue() == map_data.At(element_index)) { | 
| 2082             element = iterator.CurrentKey(); | 2016             element = iterator.CurrentKey(); | 
| 2083             jselement.AddProperty("parentMapKey", element); | 2017             jselement.AddProperty("parentMapKey", element); | 
| 2084             break; | 2018             break; | 
| 2085           } | 2019           } | 
| 2086         } | 2020         } | 
| 2087       } else if (element.IsInstance()) { | 2021       } else if (element.IsInstance()) { | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 2104   // after looking for a retaining path. | 2038   // after looking for a retaining path. | 
| 2105   for (intptr_t i = 0; i < path.Length(); i++) { | 2039   for (intptr_t i = 0; i < path.Length(); i++) { | 
| 2106     path.SetAt(i, Object::null_object()); | 2040     path.SetAt(i, Object::null_object()); | 
| 2107   } | 2041   } | 
| 2108 | 2042 | 
| 2109   return true; | 2043   return true; | 
| 2110 } | 2044 } | 
| 2111 | 2045 | 
| 2112 | 2046 | 
| 2113 static const MethodParameter* get_retaining_path_params[] = { | 2047 static const MethodParameter* get_retaining_path_params[] = { | 
| 2114   RUNNABLE_ISOLATE_PARAMETER, | 2048     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2115   NULL, |  | 
| 2116 }; | 2049 }; | 
| 2117 | 2050 | 
| 2118 | 2051 | 
| 2119 static bool GetRetainingPath(Thread* thread, JSONStream* js) { | 2052 static bool GetRetainingPath(Thread* thread, JSONStream* js) { | 
| 2120   const char* target_id = js->LookupParam("targetId"); | 2053   const char* target_id = js->LookupParam("targetId"); | 
| 2121   if (target_id == NULL) { | 2054   if (target_id == NULL) { | 
| 2122     PrintMissingParamError(js, "targetId"); | 2055     PrintMissingParamError(js, "targetId"); | 
| 2123     return true; | 2056     return true; | 
| 2124   } | 2057   } | 
| 2125   const char* limit_cstr = js->LookupParam("limit"); | 2058   const char* limit_cstr = js->LookupParam("limit"); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 2147     } else { | 2080     } else { | 
| 2148       PrintInvalidParamError(js, "targetId"); | 2081       PrintInvalidParamError(js, "targetId"); | 
| 2149     } | 2082     } | 
| 2150     return true; | 2083     return true; | 
| 2151   } | 2084   } | 
| 2152   return PrintRetainingPath(thread, &obj, limit, js); | 2085   return PrintRetainingPath(thread, &obj, limit, js); | 
| 2153 } | 2086 } | 
| 2154 | 2087 | 
| 2155 | 2088 | 
| 2156 static const MethodParameter* get_retained_size_params[] = { | 2089 static const MethodParameter* get_retained_size_params[] = { | 
| 2157   RUNNABLE_ISOLATE_PARAMETER, | 2090     RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL, | 
| 2158   new IdParameter("targetId", true), |  | 
| 2159   NULL, |  | 
| 2160 }; | 2091 }; | 
| 2161 | 2092 | 
| 2162 | 2093 | 
| 2163 static bool GetRetainedSize(Thread* thread, JSONStream* js) { | 2094 static bool GetRetainedSize(Thread* thread, JSONStream* js) { | 
| 2164   const char* target_id = js->LookupParam("targetId"); | 2095   const char* target_id = js->LookupParam("targetId"); | 
| 2165   ASSERT(target_id != NULL); | 2096   ASSERT(target_id != NULL); | 
| 2166   ObjectIdRing::LookupResult lookup_result; | 2097   ObjectIdRing::LookupResult lookup_result; | 
| 2167   Object& obj = Object::Handle(LookupHeapObject(thread, target_id, | 2098   Object& obj = | 
| 2168                                                 &lookup_result)); | 2099       Object::Handle(LookupHeapObject(thread, target_id, &lookup_result)); | 
| 2169   if (obj.raw() == Object::sentinel().raw()) { | 2100   if (obj.raw() == Object::sentinel().raw()) { | 
| 2170     if (lookup_result == ObjectIdRing::kCollected) { | 2101     if (lookup_result == ObjectIdRing::kCollected) { | 
| 2171       PrintSentinel(js, kCollectedSentinel); | 2102       PrintSentinel(js, kCollectedSentinel); | 
| 2172     } else if (lookup_result == ObjectIdRing::kExpired) { | 2103     } else if (lookup_result == ObjectIdRing::kExpired) { | 
| 2173       PrintSentinel(js, kExpiredSentinel); | 2104       PrintSentinel(js, kExpiredSentinel); | 
| 2174     } else { | 2105     } else { | 
| 2175       PrintInvalidParamError(js, "targetId"); | 2106       PrintInvalidParamError(js, "targetId"); | 
| 2176     } | 2107     } | 
| 2177     return true; | 2108     return true; | 
| 2178   } | 2109   } | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 2189 | 2120 | 
| 2190   ObjectGraph graph(thread); | 2121   ObjectGraph graph(thread); | 
| 2191   intptr_t retained_size = graph.SizeRetainedByInstance(obj); | 2122   intptr_t retained_size = graph.SizeRetainedByInstance(obj); | 
| 2192   const Object& result = Object::Handle(Integer::New(retained_size)); | 2123   const Object& result = Object::Handle(Integer::New(retained_size)); | 
| 2193   result.PrintJSON(js, true); | 2124   result.PrintJSON(js, true); | 
| 2194   return true; | 2125   return true; | 
| 2195 } | 2126 } | 
| 2196 | 2127 | 
| 2197 | 2128 | 
| 2198 static const MethodParameter* get_reachable_size_params[] = { | 2129 static const MethodParameter* get_reachable_size_params[] = { | 
| 2199   RUNNABLE_ISOLATE_PARAMETER, | 2130     RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL, | 
| 2200   new IdParameter("targetId", true), |  | 
| 2201   NULL, |  | 
| 2202 }; | 2131 }; | 
| 2203 | 2132 | 
| 2204 | 2133 | 
| 2205 static bool GetReachableSize(Thread* thread, JSONStream* js) { | 2134 static bool GetReachableSize(Thread* thread, JSONStream* js) { | 
| 2206   const char* target_id = js->LookupParam("targetId"); | 2135   const char* target_id = js->LookupParam("targetId"); | 
| 2207   ASSERT(target_id != NULL); | 2136   ASSERT(target_id != NULL); | 
| 2208   ObjectIdRing::LookupResult lookup_result; | 2137   ObjectIdRing::LookupResult lookup_result; | 
| 2209   Object& obj = Object::Handle(LookupHeapObject(thread, target_id, | 2138   Object& obj = | 
| 2210                                                 &lookup_result)); | 2139       Object::Handle(LookupHeapObject(thread, target_id, &lookup_result)); | 
| 2211   if (obj.raw() == Object::sentinel().raw()) { | 2140   if (obj.raw() == Object::sentinel().raw()) { | 
| 2212     if (lookup_result == ObjectIdRing::kCollected) { | 2141     if (lookup_result == ObjectIdRing::kCollected) { | 
| 2213       PrintSentinel(js, kCollectedSentinel); | 2142       PrintSentinel(js, kCollectedSentinel); | 
| 2214     } else if (lookup_result == ObjectIdRing::kExpired) { | 2143     } else if (lookup_result == ObjectIdRing::kExpired) { | 
| 2215       PrintSentinel(js, kExpiredSentinel); | 2144       PrintSentinel(js, kExpiredSentinel); | 
| 2216     } else { | 2145     } else { | 
| 2217       PrintInvalidParamError(js, "targetId"); | 2146       PrintInvalidParamError(js, "targetId"); | 
| 2218     } | 2147     } | 
| 2219     return true; | 2148     return true; | 
| 2220   } | 2149   } | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 2231 | 2160 | 
| 2232   ObjectGraph graph(thread); | 2161   ObjectGraph graph(thread); | 
| 2233   intptr_t retained_size = graph.SizeReachableByInstance(obj); | 2162   intptr_t retained_size = graph.SizeReachableByInstance(obj); | 
| 2234   const Object& result = Object::Handle(Integer::New(retained_size)); | 2163   const Object& result = Object::Handle(Integer::New(retained_size)); | 
| 2235   result.PrintJSON(js, true); | 2164   result.PrintJSON(js, true); | 
| 2236   return true; | 2165   return true; | 
| 2237 } | 2166 } | 
| 2238 | 2167 | 
| 2239 | 2168 | 
| 2240 static const MethodParameter* evaluate_params[] = { | 2169 static const MethodParameter* evaluate_params[] = { | 
| 2241   RUNNABLE_ISOLATE_PARAMETER, | 2170     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2242   NULL, |  | 
| 2243 }; | 2171 }; | 
| 2244 | 2172 | 
| 2245 | 2173 | 
| 2246 static bool Evaluate(Thread* thread, JSONStream* js) { | 2174 static bool Evaluate(Thread* thread, JSONStream* js) { | 
| 2247   if (!thread->isolate()->compilation_allowed()) { | 2175   if (!thread->isolate()->compilation_allowed()) { | 
| 2248     js->PrintError(kFeatureDisabled, | 2176     js->PrintError(kFeatureDisabled, | 
| 2249                    "Cannot evaluate when running a precompiled program."); | 2177                    "Cannot evaluate when running a precompiled program."); | 
| 2250     return true; | 2178     return true; | 
| 2251   } | 2179   } | 
| 2252   const char* target_id = js->LookupParam("targetId"); | 2180   const char* target_id = js->LookupParam("targetId"); | 
| 2253   if (target_id == NULL) { | 2181   if (target_id == NULL) { | 
| 2254     PrintMissingParamError(js, "targetId"); | 2182     PrintMissingParamError(js, "targetId"); | 
| 2255     return true; | 2183     return true; | 
| 2256   } | 2184   } | 
| 2257   const char* expr = js->LookupParam("expression"); | 2185   const char* expr = js->LookupParam("expression"); | 
| 2258   if (expr == NULL) { | 2186   if (expr == NULL) { | 
| 2259     PrintMissingParamError(js, "expression"); | 2187     PrintMissingParamError(js, "expression"); | 
| 2260     return true; | 2188     return true; | 
| 2261   } | 2189   } | 
| 2262   Zone* zone = thread->zone(); | 2190   Zone* zone = thread->zone(); | 
| 2263   const String& expr_str = String::Handle(zone, String::New(expr)); | 2191   const String& expr_str = String::Handle(zone, String::New(expr)); | 
| 2264   ObjectIdRing::LookupResult lookup_result; | 2192   ObjectIdRing::LookupResult lookup_result; | 
| 2265   Object& obj = Object::Handle(zone, LookupHeapObject(thread, target_id, | 2193   Object& obj = | 
| 2266                                                       &lookup_result)); | 2194       Object::Handle(zone, LookupHeapObject(thread, target_id, &lookup_result)); | 
| 2267   if (obj.raw() == Object::sentinel().raw()) { | 2195   if (obj.raw() == Object::sentinel().raw()) { | 
| 2268     if (lookup_result == ObjectIdRing::kCollected) { | 2196     if (lookup_result == ObjectIdRing::kCollected) { | 
| 2269       PrintSentinel(js, kCollectedSentinel); | 2197       PrintSentinel(js, kCollectedSentinel); | 
| 2270     } else if (lookup_result == ObjectIdRing::kExpired) { | 2198     } else if (lookup_result == ObjectIdRing::kExpired) { | 
| 2271       PrintSentinel(js, kExpiredSentinel); | 2199       PrintSentinel(js, kExpiredSentinel); | 
| 2272     } else { | 2200     } else { | 
| 2273       PrintInvalidParamError(js, "targetId"); | 2201       PrintInvalidParamError(js, "targetId"); | 
| 2274     } | 2202     } | 
| 2275     return true; | 2203     return true; | 
| 2276   } | 2204   } | 
| 2277   if (obj.IsLibrary()) { | 2205   if (obj.IsLibrary()) { | 
| 2278     const Library& lib = Library::Cast(obj); | 2206     const Library& lib = Library::Cast(obj); | 
| 2279     const Object& result = Object::Handle(zone, | 2207     const Object& result = Object::Handle( | 
|  | 2208         zone, | 
| 2280         lib.Evaluate(expr_str, Array::empty_array(), Array::empty_array())); | 2209         lib.Evaluate(expr_str, Array::empty_array(), Array::empty_array())); | 
| 2281     result.PrintJSON(js, true); | 2210     result.PrintJSON(js, true); | 
| 2282     return true; | 2211     return true; | 
| 2283   } | 2212   } | 
| 2284   if (obj.IsClass()) { | 2213   if (obj.IsClass()) { | 
| 2285     const Class& cls = Class::Cast(obj); | 2214     const Class& cls = Class::Cast(obj); | 
| 2286     const Object& result = Object::Handle(zone, | 2215     const Object& result = Object::Handle( | 
|  | 2216         zone, | 
| 2287         cls.Evaluate(expr_str, Array::empty_array(), Array::empty_array())); | 2217         cls.Evaluate(expr_str, Array::empty_array(), Array::empty_array())); | 
| 2288     result.PrintJSON(js, true); | 2218     result.PrintJSON(js, true); | 
| 2289     return true; | 2219     return true; | 
| 2290   } | 2220   } | 
| 2291   if ((obj.IsInstance() || obj.IsNull()) && | 2221   if ((obj.IsInstance() || obj.IsNull()) && !ContainsNonInstance(obj)) { | 
| 2292       !ContainsNonInstance(obj)) { |  | 
| 2293     // We don't use Instance::Cast here because it doesn't allow null. | 2222     // We don't use Instance::Cast here because it doesn't allow null. | 
| 2294     Instance& instance = Instance::Handle(zone); | 2223     Instance& instance = Instance::Handle(zone); | 
| 2295     instance ^= obj.raw(); | 2224     instance ^= obj.raw(); | 
| 2296     const Class& receiver_cls = Class::Handle(zone, instance.clazz()); | 2225     const Class& receiver_cls = Class::Handle(zone, instance.clazz()); | 
| 2297     const Object& result = | 2226     const Object& result = Object::Handle( | 
| 2298         Object::Handle(zone, instance.Evaluate(receiver_cls, | 2227         zone, instance.Evaluate(receiver_cls, expr_str, Array::empty_array(), | 
| 2299                                                expr_str, | 2228                                 Array::empty_array())); | 
| 2300                                                Array::empty_array(), |  | 
| 2301                                                Array::empty_array())); |  | 
| 2302     result.PrintJSON(js, true); | 2229     result.PrintJSON(js, true); | 
| 2303     return true; | 2230     return true; | 
| 2304   } | 2231   } | 
| 2305   js->PrintError(kInvalidParams, | 2232   js->PrintError(kInvalidParams, | 
| 2306                  "%s: invalid 'targetId' parameter: " | 2233                  "%s: invalid 'targetId' parameter: " | 
| 2307                  "Cannot evaluate against a VM-internal object", js->method()); | 2234                  "Cannot evaluate against a VM-internal object", | 
|  | 2235                  js->method()); | 
| 2308   return true; | 2236   return true; | 
| 2309 } | 2237 } | 
| 2310 | 2238 | 
| 2311 | 2239 | 
| 2312 static const MethodParameter* evaluate_in_frame_params[] = { | 2240 static const MethodParameter* evaluate_in_frame_params[] = { | 
| 2313   RUNNABLE_ISOLATE_PARAMETER, | 2241     RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("frameIndex", true), | 
| 2314   new UIntParameter("frameIndex", true), | 2242     new MethodParameter("expression", true), NULL, | 
| 2315   new MethodParameter("expression", true), |  | 
| 2316   NULL, |  | 
| 2317 }; | 2243 }; | 
| 2318 | 2244 | 
| 2319 | 2245 | 
| 2320 static bool EvaluateInFrame(Thread* thread, JSONStream* js) { | 2246 static bool EvaluateInFrame(Thread* thread, JSONStream* js) { | 
| 2321   Isolate* isolate = thread->isolate(); | 2247   Isolate* isolate = thread->isolate(); | 
| 2322   if (!isolate->compilation_allowed()) { | 2248   if (!isolate->compilation_allowed()) { | 
| 2323     js->PrintError(kFeatureDisabled, | 2249     js->PrintError(kFeatureDisabled, | 
| 2324                    "Cannot evaluate when running a precompiled program."); | 2250                    "Cannot evaluate when running a precompiled program."); | 
| 2325     return true; | 2251     return true; | 
| 2326   } | 2252   } | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2368   intptr_t count() const { return count_; } | 2294   intptr_t count() const { return count_; } | 
| 2369 | 2295 | 
| 2370  private: | 2296  private: | 
| 2371   const Class& cls_; | 2297   const Class& cls_; | 
| 2372   const Array& storage_; | 2298   const Array& storage_; | 
| 2373   intptr_t count_; | 2299   intptr_t count_; | 
| 2374 }; | 2300 }; | 
| 2375 | 2301 | 
| 2376 | 2302 | 
| 2377 static const MethodParameter* get_instances_params[] = { | 2303 static const MethodParameter* get_instances_params[] = { | 
| 2378   RUNNABLE_ISOLATE_PARAMETER, | 2304     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2379   NULL, |  | 
| 2380 }; | 2305 }; | 
| 2381 | 2306 | 
| 2382 | 2307 | 
| 2383 static bool GetInstances(Thread* thread, JSONStream* js) { | 2308 static bool GetInstances(Thread* thread, JSONStream* js) { | 
| 2384   const char* target_id = js->LookupParam("classId"); | 2309   const char* target_id = js->LookupParam("classId"); | 
| 2385   if (target_id == NULL) { | 2310   if (target_id == NULL) { | 
| 2386     PrintMissingParamError(js, "classId"); | 2311     PrintMissingParamError(js, "classId"); | 
| 2387     return true; | 2312     return true; | 
| 2388   } | 2313   } | 
| 2389   const char* limit_cstr = js->LookupParam("limit"); | 2314   const char* limit_cstr = js->LookupParam("limit"); | 
| 2390   if (limit_cstr == NULL) { | 2315   if (limit_cstr == NULL) { | 
| 2391     PrintMissingParamError(js, "limit"); | 2316     PrintMissingParamError(js, "limit"); | 
| 2392     return true; | 2317     return true; | 
| 2393   } | 2318   } | 
| 2394   intptr_t limit; | 2319   intptr_t limit; | 
| 2395   if (!GetIntegerId(limit_cstr, &limit)) { | 2320   if (!GetIntegerId(limit_cstr, &limit)) { | 
| 2396     PrintInvalidParamError(js, "limit"); | 2321     PrintInvalidParamError(js, "limit"); | 
| 2397     return true; | 2322     return true; | 
| 2398   } | 2323   } | 
| 2399   const Object& obj = | 2324   const Object& obj = Object::Handle(LookupHeapObject(thread, target_id, NULL)); | 
| 2400       Object::Handle(LookupHeapObject(thread, target_id, NULL)); | 2325   if (obj.raw() == Object::sentinel().raw() || !obj.IsClass()) { | 
| 2401   if (obj.raw() == Object::sentinel().raw() || |  | 
| 2402       !obj.IsClass()) { |  | 
| 2403     PrintInvalidParamError(js, "classId"); | 2326     PrintInvalidParamError(js, "classId"); | 
| 2404     return true; | 2327     return true; | 
| 2405   } | 2328   } | 
| 2406   const Class& cls = Class::Cast(obj); | 2329   const Class& cls = Class::Cast(obj); | 
| 2407   Array& storage = Array::Handle(Array::New(limit)); | 2330   Array& storage = Array::Handle(Array::New(limit)); | 
| 2408   GetInstancesVisitor visitor(cls, storage); | 2331   GetInstancesVisitor visitor(cls, storage); | 
| 2409   ObjectGraph graph(thread); | 2332   ObjectGraph graph(thread); | 
| 2410   graph.IterateObjects(&visitor); | 2333   graph.IterateObjects(&visitor); | 
| 2411   intptr_t count = visitor.count(); | 2334   intptr_t count = visitor.count(); | 
| 2412   JSONObject jsobj(js); | 2335   JSONObject jsobj(js); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 2425   // after looking at allInstances. | 2348   // after looking at allInstances. | 
| 2426   for (intptr_t i = 0; i < storage.Length(); i++) { | 2349   for (intptr_t i = 0; i < storage.Length(); i++) { | 
| 2427     storage.SetAt(i, Object::null_object()); | 2350     storage.SetAt(i, Object::null_object()); | 
| 2428   } | 2351   } | 
| 2429 | 2352 | 
| 2430   return true; | 2353   return true; | 
| 2431 } | 2354 } | 
| 2432 | 2355 | 
| 2433 | 2356 | 
| 2434 static const char* const report_enum_names[] = { | 2357 static const char* const report_enum_names[] = { | 
| 2435   SourceReport::kCallSitesStr, | 2358     SourceReport::kCallSitesStr, | 
| 2436   SourceReport::kCoverageStr, | 2359     SourceReport::kCoverageStr, | 
| 2437   SourceReport::kPossibleBreakpointsStr, | 2360     SourceReport::kPossibleBreakpointsStr, | 
| 2438   SourceReport::kProfileStr, | 2361     SourceReport::kProfileStr, | 
| 2439   NULL, | 2362     NULL, | 
| 2440 }; | 2363 }; | 
| 2441 | 2364 | 
| 2442 | 2365 | 
| 2443 static const MethodParameter* get_source_report_params[] = { | 2366 static const MethodParameter* get_source_report_params[] = { | 
| 2444   RUNNABLE_ISOLATE_PARAMETER, | 2367     RUNNABLE_ISOLATE_PARAMETER, | 
| 2445   new EnumListParameter("reports", true, report_enum_names), | 2368     new EnumListParameter("reports", true, report_enum_names), | 
| 2446   new IdParameter("scriptId", false), | 2369     new IdParameter("scriptId", false), | 
| 2447   new UIntParameter("tokenPos", false), | 2370     new UIntParameter("tokenPos", false), | 
| 2448   new UIntParameter("endTokenPos", false), | 2371     new UIntParameter("endTokenPos", false), | 
| 2449   new BoolParameter("forceCompile", false), | 2372     new BoolParameter("forceCompile", false), | 
| 2450   NULL, | 2373     NULL, | 
| 2451 }; | 2374 }; | 
| 2452 | 2375 | 
| 2453 | 2376 | 
| 2454 static bool GetSourceReport(Thread* thread, JSONStream* js) { | 2377 static bool GetSourceReport(Thread* thread, JSONStream* js) { | 
| 2455   if (!thread->isolate()->compilation_allowed()) { | 2378   if (!thread->isolate()->compilation_allowed()) { | 
| 2456     js->PrintError(kFeatureDisabled, | 2379     js->PrintError( | 
|  | 2380         kFeatureDisabled, | 
| 2457         "Cannot get source report when running a precompiled program."); | 2381         "Cannot get source report when running a precompiled program."); | 
| 2458     return true; | 2382     return true; | 
| 2459   } | 2383   } | 
| 2460   const char* reports_str = js->LookupParam("reports"); | 2384   const char* reports_str = js->LookupParam("reports"); | 
| 2461   const EnumListParameter* reports_parameter = | 2385   const EnumListParameter* reports_parameter = | 
| 2462       static_cast<const EnumListParameter*>(get_source_report_params[1]); | 2386       static_cast<const EnumListParameter*>(get_source_report_params[1]); | 
| 2463   const char** reports = reports_parameter->Parse(thread->zone(), reports_str); | 2387   const char** reports = reports_parameter->Parse(thread->zone(), reports_str); | 
| 2464   intptr_t report_set = 0; | 2388   intptr_t report_set = 0; | 
| 2465   while (*reports != NULL) { | 2389   while (*reports != NULL) { | 
| 2466     if (strcmp(*reports, SourceReport::kCallSitesStr) == 0) { | 2390     if (strcmp(*reports, SourceReport::kCallSitesStr) == 0) { | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2504     } | 2428     } | 
| 2505     if (js->HasParam("endTokenPos")) { | 2429     if (js->HasParam("endTokenPos")) { | 
| 2506       js->PrintError( | 2430       js->PrintError( | 
| 2507           kInvalidParams, | 2431           kInvalidParams, | 
| 2508           "%s: the 'endTokenPos' parameter requires the 'scriptId' parameter", | 2432           "%s: the 'endTokenPos' parameter requires the 'scriptId' parameter", | 
| 2509           js->method()); | 2433           js->method()); | 
| 2510       return true; | 2434       return true; | 
| 2511     } | 2435     } | 
| 2512   } | 2436   } | 
| 2513   SourceReport report(report_set, compile_mode); | 2437   SourceReport report(report_set, compile_mode); | 
| 2514   report.PrintJSON(js, | 2438   report.PrintJSON(js, script, TokenPosition(start_pos), | 
| 2515                    script, |  | 
| 2516                    TokenPosition(start_pos), |  | 
| 2517                    TokenPosition(end_pos)); | 2439                    TokenPosition(end_pos)); | 
| 2518   return true; | 2440   return true; | 
| 2519 } | 2441 } | 
| 2520 | 2442 | 
| 2521 | 2443 | 
| 2522 static const MethodParameter* reload_sources_params[] = { | 2444 static const MethodParameter* reload_sources_params[] = { | 
| 2523   RUNNABLE_ISOLATE_PARAMETER, | 2445     RUNNABLE_ISOLATE_PARAMETER, new BoolParameter("force", false), | 
| 2524   new BoolParameter("force", false), | 2446     new BoolParameter("pause", false), NULL, | 
| 2525   new BoolParameter("pause", false), |  | 
| 2526   NULL, |  | 
| 2527 }; | 2447 }; | 
| 2528 | 2448 | 
| 2529 | 2449 | 
| 2530 static bool ReloadSources(Thread* thread, JSONStream* js) { | 2450 static bool ReloadSources(Thread* thread, JSONStream* js) { | 
| 2531   Isolate* isolate = thread->isolate(); | 2451   Isolate* isolate = thread->isolate(); | 
| 2532   if (!isolate->compilation_allowed()) { | 2452   if (!isolate->compilation_allowed()) { | 
| 2533     js->PrintError(kFeatureDisabled, | 2453     js->PrintError(kFeatureDisabled, | 
| 2534         "Cannot reload source when running a precompiled program."); | 2454                    "Cannot reload source when running a precompiled program."); | 
| 2535     return true; | 2455     return true; | 
| 2536   } | 2456   } | 
| 2537   if (Dart::snapshot_kind() == Snapshot::kAppWithJIT) { | 2457   if (Dart::snapshot_kind() == Snapshot::kAppWithJIT) { | 
| 2538     js->PrintError(kFeatureDisabled, | 2458     js->PrintError(kFeatureDisabled, | 
| 2539         "Cannot reload source when running an app snapshot."); | 2459                    "Cannot reload source when running an app snapshot."); | 
| 2540     return true; | 2460     return true; | 
| 2541   } | 2461   } | 
| 2542   Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | 2462   Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | 
| 2543   if (handler == NULL) { | 2463   if (handler == NULL) { | 
| 2544     js->PrintError(kFeatureDisabled, | 2464     js->PrintError(kFeatureDisabled, | 
| 2545                    "A library tag handler must be installed."); | 2465                    "A library tag handler must be installed."); | 
| 2546     return true; | 2466     return true; | 
| 2547   } | 2467   } | 
| 2548   if ((isolate->sticky_error() != Error::null()) || | 2468   if ((isolate->sticky_error() != Error::null()) || | 
| 2549       (Thread::Current()->sticky_error() != Error::null())) { | 2469       (Thread::Current()->sticky_error() != Error::null())) { | 
| 2550     js->PrintError(kIsolateReloadBarred, | 2470     js->PrintError(kIsolateReloadBarred, | 
| 2551                    "This isolate cannot reload sources anymore because there " | 2471                    "This isolate cannot reload sources anymore because there " | 
| 2552                    "was an unhandled exception error. Restart the isolate."); | 2472                    "was an unhandled exception error. Restart the isolate."); | 
| 2553     return true; | 2473     return true; | 
| 2554   } | 2474   } | 
| 2555   if (isolate->IsReloading()) { | 2475   if (isolate->IsReloading()) { | 
| 2556     js->PrintError(kIsolateIsReloading, | 2476     js->PrintError(kIsolateIsReloading, "This isolate is being reloaded."); | 
| 2557                    "This isolate is being reloaded."); |  | 
| 2558     return true; | 2477     return true; | 
| 2559   } | 2478   } | 
| 2560   if (!isolate->CanReload()) { | 2479   if (!isolate->CanReload()) { | 
| 2561     js->PrintError(kFeatureDisabled, | 2480     js->PrintError(kFeatureDisabled, | 
| 2562                    "This isolate cannot reload sources right now."); | 2481                    "This isolate cannot reload sources right now."); | 
| 2563     return true; | 2482     return true; | 
| 2564   } | 2483   } | 
| 2565   const bool force_reload = | 2484   const bool force_reload = | 
| 2566       BoolParameter::Parse(js->LookupParam("force"), false); | 2485       BoolParameter::Parse(js->LookupParam("force"), false); | 
| 2567 | 2486 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 2588       isolate->PausePostRequest(); | 2507       isolate->PausePostRequest(); | 
| 2589     } | 2508     } | 
| 2590   } | 2509   } | 
| 2591 } | 2510 } | 
| 2592 | 2511 | 
| 2593 | 2512 | 
| 2594 static bool AddBreakpointCommon(Thread* thread, | 2513 static bool AddBreakpointCommon(Thread* thread, | 
| 2595                                 JSONStream* js, | 2514                                 JSONStream* js, | 
| 2596                                 const String& script_uri) { | 2515                                 const String& script_uri) { | 
| 2597   if (!thread->isolate()->compilation_allowed()) { | 2516   if (!thread->isolate()->compilation_allowed()) { | 
| 2598     js->PrintError(kFeatureDisabled, | 2517     js->PrintError( | 
|  | 2518         kFeatureDisabled, | 
| 2599         "Cannot use breakpoints when running a precompiled program."); | 2519         "Cannot use breakpoints when running a precompiled program."); | 
| 2600     return true; | 2520     return true; | 
| 2601   } | 2521   } | 
| 2602   const char* line_param = js->LookupParam("line"); | 2522   const char* line_param = js->LookupParam("line"); | 
| 2603   intptr_t line = UIntParameter::Parse(line_param); | 2523   intptr_t line = UIntParameter::Parse(line_param); | 
| 2604   const char* col_param = js->LookupParam("column"); | 2524   const char* col_param = js->LookupParam("column"); | 
| 2605   intptr_t col = -1; | 2525   intptr_t col = -1; | 
| 2606   if (col_param != NULL) { | 2526   if (col_param != NULL) { | 
| 2607     col = UIntParameter::Parse(col_param); | 2527     col = UIntParameter::Parse(col_param); | 
| 2608     if (col == 0) { | 2528     if (col == 0) { | 
| 2609       // Column number is 1-based. | 2529       // Column number is 1-based. | 
| 2610       PrintInvalidParamError(js, "column"); | 2530       PrintInvalidParamError(js, "column"); | 
| 2611       return true; | 2531       return true; | 
| 2612     } | 2532     } | 
| 2613   } | 2533   } | 
| 2614   ASSERT(!script_uri.IsNull()); | 2534   ASSERT(!script_uri.IsNull()); | 
| 2615   Breakpoint* bpt = NULL; | 2535   Breakpoint* bpt = NULL; | 
| 2616   bpt = thread->isolate()->debugger()-> | 2536   bpt = thread->isolate()->debugger()->SetBreakpointAtLineCol(script_uri, line, | 
| 2617       SetBreakpointAtLineCol(script_uri, line, col); | 2537                                                               col); | 
| 2618   if (bpt == NULL) { | 2538   if (bpt == NULL) { | 
| 2619     js->PrintError(kCannotAddBreakpoint, | 2539     js->PrintError(kCannotAddBreakpoint, | 
| 2620                    "%s: Cannot add breakpoint at line '%s'", | 2540                    "%s: Cannot add breakpoint at line '%s'", js->method(), | 
| 2621                    js->method(), line_param); | 2541                    line_param); | 
| 2622     return true; | 2542     return true; | 
| 2623   } | 2543   } | 
| 2624   bpt->PrintJSON(js); | 2544   bpt->PrintJSON(js); | 
| 2625   return true; | 2545   return true; | 
| 2626 } | 2546 } | 
| 2627 | 2547 | 
| 2628 | 2548 | 
| 2629 static const MethodParameter* add_breakpoint_params[] = { | 2549 static const MethodParameter* add_breakpoint_params[] = { | 
| 2630   RUNNABLE_ISOLATE_PARAMETER, | 2550     RUNNABLE_ISOLATE_PARAMETER, | 
| 2631   new IdParameter("scriptId", true), | 2551     new IdParameter("scriptId", true), | 
| 2632   new UIntParameter("line", true), | 2552     new UIntParameter("line", true), | 
| 2633   new UIntParameter("column", false), | 2553     new UIntParameter("column", false), | 
| 2634   NULL, | 2554     NULL, | 
| 2635 }; | 2555 }; | 
| 2636 | 2556 | 
| 2637 | 2557 | 
| 2638 static bool AddBreakpoint(Thread* thread, JSONStream* js) { | 2558 static bool AddBreakpoint(Thread* thread, JSONStream* js) { | 
| 2639   if (!thread->isolate()->compilation_allowed()) { | 2559   if (!thread->isolate()->compilation_allowed()) { | 
| 2640     js->PrintError(kFeatureDisabled, | 2560     js->PrintError( | 
|  | 2561         kFeatureDisabled, | 
| 2641         "Cannot use breakpoints when running a precompiled program."); | 2562         "Cannot use breakpoints when running a precompiled program."); | 
| 2642     return true; | 2563     return true; | 
| 2643   } | 2564   } | 
| 2644   const char* script_id_param = js->LookupParam("scriptId"); | 2565   const char* script_id_param = js->LookupParam("scriptId"); | 
| 2645   Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL)); | 2566   Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL)); | 
| 2646   if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) { | 2567   if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) { | 
| 2647     PrintInvalidParamError(js, "scriptId"); | 2568     PrintInvalidParamError(js, "scriptId"); | 
| 2648     return true; | 2569     return true; | 
| 2649   } | 2570   } | 
| 2650   const Script& script = Script::Cast(obj); | 2571   const Script& script = Script::Cast(obj); | 
| 2651   const String& script_uri = String::Handle(script.url()); | 2572   const String& script_uri = String::Handle(script.url()); | 
| 2652   ASSERT(!script_uri.IsNull()); | 2573   ASSERT(!script_uri.IsNull()); | 
| 2653   return AddBreakpointCommon(thread, js, script_uri); | 2574   return AddBreakpointCommon(thread, js, script_uri); | 
| 2654 } | 2575 } | 
| 2655 | 2576 | 
| 2656 | 2577 | 
| 2657 static const MethodParameter* add_breakpoint_with_script_uri_params[] = { | 2578 static const MethodParameter* add_breakpoint_with_script_uri_params[] = { | 
| 2658   RUNNABLE_ISOLATE_PARAMETER, | 2579     RUNNABLE_ISOLATE_PARAMETER, | 
| 2659   new IdParameter("scriptUri", true), | 2580     new IdParameter("scriptUri", true), | 
| 2660   new UIntParameter("line", true), | 2581     new UIntParameter("line", true), | 
| 2661   new UIntParameter("column", false), | 2582     new UIntParameter("column", false), | 
| 2662   NULL, | 2583     NULL, | 
| 2663 }; | 2584 }; | 
| 2664 | 2585 | 
| 2665 | 2586 | 
| 2666 static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) { | 2587 static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) { | 
| 2667   if (!thread->isolate()->compilation_allowed()) { | 2588   if (!thread->isolate()->compilation_allowed()) { | 
| 2668     js->PrintError(kFeatureDisabled, | 2589     js->PrintError( | 
|  | 2590         kFeatureDisabled, | 
| 2669         "Cannot use breakpoints when running a precompiled program."); | 2591         "Cannot use breakpoints when running a precompiled program."); | 
| 2670     return true; | 2592     return true; | 
| 2671   } | 2593   } | 
| 2672   const char* script_uri_param = js->LookupParam("scriptUri"); | 2594   const char* script_uri_param = js->LookupParam("scriptUri"); | 
| 2673   const String& script_uri = String::Handle(String::New(script_uri_param)); | 2595   const String& script_uri = String::Handle(String::New(script_uri_param)); | 
| 2674   return AddBreakpointCommon(thread, js, script_uri); | 2596   return AddBreakpointCommon(thread, js, script_uri); | 
| 2675 } | 2597 } | 
| 2676 | 2598 | 
| 2677 | 2599 | 
| 2678 static const MethodParameter* add_breakpoint_at_entry_params[] = { | 2600 static const MethodParameter* add_breakpoint_at_entry_params[] = { | 
| 2679   RUNNABLE_ISOLATE_PARAMETER, | 2601     RUNNABLE_ISOLATE_PARAMETER, new IdParameter("functionId", true), NULL, | 
| 2680   new IdParameter("functionId", true), |  | 
| 2681   NULL, |  | 
| 2682 }; | 2602 }; | 
| 2683 | 2603 | 
| 2684 | 2604 | 
| 2685 static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) { | 2605 static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) { | 
| 2686   if (!thread->isolate()->compilation_allowed()) { | 2606   if (!thread->isolate()->compilation_allowed()) { | 
| 2687     js->PrintError(kFeatureDisabled, | 2607     js->PrintError( | 
|  | 2608         kFeatureDisabled, | 
| 2688         "Cannot use breakpoints when running a precompiled program."); | 2609         "Cannot use breakpoints when running a precompiled program."); | 
| 2689     return true; | 2610     return true; | 
| 2690   } | 2611   } | 
| 2691   const char* function_id = js->LookupParam("functionId"); | 2612   const char* function_id = js->LookupParam("functionId"); | 
| 2692   Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL)); | 2613   Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL)); | 
| 2693   if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) { | 2614   if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) { | 
| 2694     PrintInvalidParamError(js, "functionId"); | 2615     PrintInvalidParamError(js, "functionId"); | 
| 2695     return true; | 2616     return true; | 
| 2696   } | 2617   } | 
| 2697   const Function& function = Function::Cast(obj); | 2618   const Function& function = Function::Cast(obj); | 
| 2698   Breakpoint* bpt = | 2619   Breakpoint* bpt = | 
| 2699       thread->isolate()->debugger()->SetBreakpointAtEntry(function, false); | 2620       thread->isolate()->debugger()->SetBreakpointAtEntry(function, false); | 
| 2700   if (bpt == NULL) { | 2621   if (bpt == NULL) { | 
| 2701     js->PrintError(kCannotAddBreakpoint, | 2622     js->PrintError(kCannotAddBreakpoint, | 
| 2702                    "%s: Cannot add breakpoint at function '%s'", | 2623                    "%s: Cannot add breakpoint at function '%s'", js->method(), | 
| 2703                    js->method(), function.ToCString()); | 2624                    function.ToCString()); | 
| 2704     return true; | 2625     return true; | 
| 2705   } | 2626   } | 
| 2706   bpt->PrintJSON(js); | 2627   bpt->PrintJSON(js); | 
| 2707   return true; | 2628   return true; | 
| 2708 } | 2629 } | 
| 2709 | 2630 | 
| 2710 | 2631 | 
| 2711 static const MethodParameter* add_breakpoint_at_activation_params[] = { | 2632 static const MethodParameter* add_breakpoint_at_activation_params[] = { | 
| 2712   RUNNABLE_ISOLATE_PARAMETER, | 2633     RUNNABLE_ISOLATE_PARAMETER, new IdParameter("objectId", true), NULL, | 
| 2713   new IdParameter("objectId", true), |  | 
| 2714   NULL, |  | 
| 2715 }; | 2634 }; | 
| 2716 | 2635 | 
| 2717 | 2636 | 
| 2718 static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) { | 2637 static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) { | 
| 2719   if (!thread->isolate()->compilation_allowed()) { | 2638   if (!thread->isolate()->compilation_allowed()) { | 
| 2720     js->PrintError(kFeatureDisabled, | 2639     js->PrintError( | 
|  | 2640         kFeatureDisabled, | 
| 2721         "Cannot use breakpoints when running a precompiled program."); | 2641         "Cannot use breakpoints when running a precompiled program."); | 
| 2722     return true; | 2642     return true; | 
| 2723   } | 2643   } | 
| 2724   const char* object_id = js->LookupParam("objectId"); | 2644   const char* object_id = js->LookupParam("objectId"); | 
| 2725   Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL)); | 2645   Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL)); | 
| 2726   if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) { | 2646   if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) { | 
| 2727     PrintInvalidParamError(js, "objectId"); | 2647     PrintInvalidParamError(js, "objectId"); | 
| 2728     return true; | 2648     return true; | 
| 2729   } | 2649   } | 
| 2730   const Instance& closure = Instance::Cast(obj); | 2650   const Instance& closure = Instance::Cast(obj); | 
| 2731   Breakpoint* bpt = | 2651   Breakpoint* bpt = | 
| 2732       thread->isolate()->debugger()->SetBreakpointAtActivation(closure, false); | 2652       thread->isolate()->debugger()->SetBreakpointAtActivation(closure, false); | 
| 2733   if (bpt == NULL) { | 2653   if (bpt == NULL) { | 
| 2734     js->PrintError(kCannotAddBreakpoint, | 2654     js->PrintError(kCannotAddBreakpoint, | 
| 2735                    "%s: Cannot add breakpoint at activation", | 2655                    "%s: Cannot add breakpoint at activation", js->method()); | 
| 2736                    js->method()); |  | 
| 2737     return true; | 2656     return true; | 
| 2738   } | 2657   } | 
| 2739   bpt->PrintJSON(js); | 2658   bpt->PrintJSON(js); | 
| 2740   return true; | 2659   return true; | 
| 2741 } | 2660 } | 
| 2742 | 2661 | 
| 2743 | 2662 | 
| 2744 static const MethodParameter* remove_breakpoint_params[] = { | 2663 static const MethodParameter* remove_breakpoint_params[] = { | 
| 2745   RUNNABLE_ISOLATE_PARAMETER, | 2664     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2746   NULL, |  | 
| 2747 }; | 2665 }; | 
| 2748 | 2666 | 
| 2749 | 2667 | 
| 2750 static bool RemoveBreakpoint(Thread* thread, JSONStream* js) { | 2668 static bool RemoveBreakpoint(Thread* thread, JSONStream* js) { | 
| 2751   if (!thread->isolate()->compilation_allowed()) { | 2669   if (!thread->isolate()->compilation_allowed()) { | 
| 2752     js->PrintError(kFeatureDisabled, | 2670     js->PrintError( | 
|  | 2671         kFeatureDisabled, | 
| 2753         "Cannot use breakpoints when running a precompiled program."); | 2672         "Cannot use breakpoints when running a precompiled program."); | 
| 2754     return true; | 2673     return true; | 
| 2755   } | 2674   } | 
| 2756   if (!js->HasParam("breakpointId")) { | 2675   if (!js->HasParam("breakpointId")) { | 
| 2757     PrintMissingParamError(js, "breakpointId"); | 2676     PrintMissingParamError(js, "breakpointId"); | 
| 2758     return true; | 2677     return true; | 
| 2759   } | 2678   } | 
| 2760   const char* bpt_id = js->LookupParam("breakpointId"); | 2679   const char* bpt_id = js->LookupParam("breakpointId"); | 
| 2761   ObjectIdRing::LookupResult lookup_result; | 2680   ObjectIdRing::LookupResult lookup_result; | 
| 2762   Isolate* isolate = thread->isolate(); | 2681   Isolate* isolate = thread->isolate(); | 
| 2763   Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result); | 2682   Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result); | 
| 2764   // TODO(turnidge): Should we return a different error for bpts whic | 2683   // TODO(turnidge): Should we return a different error for bpts whic | 
| 2765   // have been already removed? | 2684   // have been already removed? | 
| 2766   if (bpt == NULL) { | 2685   if (bpt == NULL) { | 
| 2767     PrintInvalidParamError(js, "breakpointId"); | 2686     PrintInvalidParamError(js, "breakpointId"); | 
| 2768     return true; | 2687     return true; | 
| 2769   } | 2688   } | 
| 2770   isolate->debugger()->RemoveBreakpoint(bpt->id()); | 2689   isolate->debugger()->RemoveBreakpoint(bpt->id()); | 
| 2771   PrintSuccess(js); | 2690   PrintSuccess(js); | 
| 2772   return true; | 2691   return true; | 
| 2773 } | 2692 } | 
| 2774 | 2693 | 
| 2775 | 2694 | 
| 2776 static RawClass* GetMetricsClass(Thread* thread) { | 2695 static RawClass* GetMetricsClass(Thread* thread) { | 
| 2777   Zone* zone = thread->zone(); | 2696   Zone* zone = thread->zone(); | 
| 2778   const Library& prof_lib = | 2697   const Library& prof_lib = Library::Handle(zone, Library::DeveloperLibrary()); | 
| 2779       Library::Handle(zone, Library::DeveloperLibrary()); |  | 
| 2780   ASSERT(!prof_lib.IsNull()); | 2698   ASSERT(!prof_lib.IsNull()); | 
| 2781   const String& metrics_cls_name = | 2699   const String& metrics_cls_name = String::Handle(zone, String::New("Metrics")); | 
| 2782       String::Handle(zone, String::New("Metrics")); |  | 
| 2783   ASSERT(!metrics_cls_name.IsNull()); | 2700   ASSERT(!metrics_cls_name.IsNull()); | 
| 2784   const Class& metrics_cls = | 2701   const Class& metrics_cls = | 
| 2785       Class::Handle(zone, prof_lib.LookupClass(metrics_cls_name)); | 2702       Class::Handle(zone, prof_lib.LookupClass(metrics_cls_name)); | 
| 2786   ASSERT(!metrics_cls.IsNull()); | 2703   ASSERT(!metrics_cls.IsNull()); | 
| 2787   return metrics_cls.raw(); | 2704   return metrics_cls.raw(); | 
| 2788 } | 2705 } | 
| 2789 | 2706 | 
| 2790 | 2707 | 
| 2791 |  | 
| 2792 static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) { | 2708 static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) { | 
| 2793   JSONObject obj(js); | 2709   JSONObject obj(js); | 
| 2794   obj.AddProperty("type", "MetricList"); | 2710   obj.AddProperty("type", "MetricList"); | 
| 2795   { | 2711   { | 
| 2796     JSONArray metrics(&obj, "metrics"); | 2712     JSONArray metrics(&obj, "metrics"); | 
| 2797     Metric* current = thread->isolate()->metrics_list_head(); | 2713     Metric* current = thread->isolate()->metrics_list_head(); | 
| 2798     while (current != NULL) { | 2714     while (current != NULL) { | 
| 2799       metrics.AddValue(current); | 2715       metrics.AddValue(current); | 
| 2800       current = current->next(); | 2716       current = current->next(); | 
| 2801     } | 2717     } | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 2815     } | 2731     } | 
| 2816     current = current->next(); | 2732     current = current->next(); | 
| 2817   } | 2733   } | 
| 2818   PrintInvalidParamError(js, "metricId"); | 2734   PrintInvalidParamError(js, "metricId"); | 
| 2819   return true; | 2735   return true; | 
| 2820 } | 2736 } | 
| 2821 | 2737 | 
| 2822 | 2738 | 
| 2823 static bool HandleDartMetricsList(Thread* thread, JSONStream* js) { | 2739 static bool HandleDartMetricsList(Thread* thread, JSONStream* js) { | 
| 2824   Zone* zone = thread->zone(); | 2740   Zone* zone = thread->zone(); | 
| 2825   const Class& metrics_cls = | 2741   const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(thread)); | 
| 2826       Class::Handle(zone, GetMetricsClass(thread)); |  | 
| 2827   const String& print_metrics_name = | 2742   const String& print_metrics_name = | 
| 2828       String::Handle(String::New("_printMetrics")); | 2743       String::Handle(String::New("_printMetrics")); | 
| 2829   ASSERT(!print_metrics_name.IsNull()); | 2744   ASSERT(!print_metrics_name.IsNull()); | 
| 2830   const Function& print_metrics = Function::Handle( | 2745   const Function& print_metrics = Function::Handle( | 
| 2831       zone, | 2746       zone, metrics_cls.LookupStaticFunctionAllowPrivate(print_metrics_name)); | 
| 2832       metrics_cls.LookupStaticFunctionAllowPrivate(print_metrics_name)); |  | 
| 2833   ASSERT(!print_metrics.IsNull()); | 2747   ASSERT(!print_metrics.IsNull()); | 
| 2834   const Array& args = Object::empty_array(); | 2748   const Array& args = Object::empty_array(); | 
| 2835   const Object& result = | 2749   const Object& result = | 
| 2836       Object::Handle(zone, DartEntry::InvokeFunction(print_metrics, args)); | 2750       Object::Handle(zone, DartEntry::InvokeFunction(print_metrics, args)); | 
| 2837   ASSERT(!result.IsNull()); | 2751   ASSERT(!result.IsNull()); | 
| 2838   ASSERT(result.IsString()); | 2752   ASSERT(result.IsString()); | 
| 2839   TextBuffer* buffer = js->buffer(); | 2753   TextBuffer* buffer = js->buffer(); | 
| 2840   buffer->AddString(String::Cast(result).ToCString()); | 2754   buffer->AddString(String::Cast(result).ToCString()); | 
| 2841   return true; | 2755   return true; | 
| 2842 } | 2756 } | 
| 2843 | 2757 | 
| 2844 | 2758 | 
| 2845 static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) { | 2759 static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) { | 
| 2846   Zone* zone = thread->zone(); | 2760   Zone* zone = thread->zone(); | 
| 2847   const Class& metrics_cls = | 2761   const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(thread)); | 
| 2848       Class::Handle(zone, GetMetricsClass(thread)); | 2762   const String& print_metric_name = String::Handle(String::New("_printMetric")); | 
| 2849   const String& print_metric_name = |  | 
| 2850       String::Handle(String::New("_printMetric")); |  | 
| 2851   ASSERT(!print_metric_name.IsNull()); | 2763   ASSERT(!print_metric_name.IsNull()); | 
| 2852   const Function& print_metric = Function::Handle( | 2764   const Function& print_metric = Function::Handle( | 
| 2853       zone, | 2765       zone, metrics_cls.LookupStaticFunctionAllowPrivate(print_metric_name)); | 
| 2854       metrics_cls.LookupStaticFunctionAllowPrivate(print_metric_name)); |  | 
| 2855   ASSERT(!print_metric.IsNull()); | 2766   ASSERT(!print_metric.IsNull()); | 
| 2856   const String& arg0 = String::Handle(String::New(id)); | 2767   const String& arg0 = String::Handle(String::New(id)); | 
| 2857   ASSERT(!arg0.IsNull()); | 2768   ASSERT(!arg0.IsNull()); | 
| 2858   const Array& args = Array::Handle(Array::New(1)); | 2769   const Array& args = Array::Handle(Array::New(1)); | 
| 2859   ASSERT(!args.IsNull()); | 2770   ASSERT(!args.IsNull()); | 
| 2860   args.SetAt(0, arg0); | 2771   args.SetAt(0, arg0); | 
| 2861   const Object& result = | 2772   const Object& result = | 
| 2862       Object::Handle(zone, DartEntry::InvokeFunction(print_metric, args)); | 2773       Object::Handle(zone, DartEntry::InvokeFunction(print_metric, args)); | 
| 2863   if (!result.IsNull()) { | 2774   if (!result.IsNull()) { | 
| 2864     ASSERT(result.IsString()); | 2775     ASSERT(result.IsString()); | 
| 2865     TextBuffer* buffer = js->buffer(); | 2776     TextBuffer* buffer = js->buffer(); | 
| 2866     buffer->AddString(String::Cast(result).ToCString()); | 2777     buffer->AddString(String::Cast(result).ToCString()); | 
| 2867     return true; | 2778     return true; | 
| 2868   } | 2779   } | 
| 2869   PrintInvalidParamError(js, "metricId"); | 2780   PrintInvalidParamError(js, "metricId"); | 
| 2870   return true; | 2781   return true; | 
| 2871 } | 2782 } | 
| 2872 | 2783 | 
| 2873 | 2784 | 
| 2874 static const MethodParameter* get_isolate_metric_list_params[] = { | 2785 static const MethodParameter* get_isolate_metric_list_params[] = { | 
| 2875   RUNNABLE_ISOLATE_PARAMETER, | 2786     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2876   NULL, |  | 
| 2877 }; | 2787 }; | 
| 2878 | 2788 | 
| 2879 | 2789 | 
| 2880 static bool GetIsolateMetricList(Thread* thread, JSONStream* js) { | 2790 static bool GetIsolateMetricList(Thread* thread, JSONStream* js) { | 
| 2881   bool native_metrics = false; | 2791   bool native_metrics = false; | 
| 2882   if (js->HasParam("type")) { | 2792   if (js->HasParam("type")) { | 
| 2883     if (js->ParamIs("type", "Native")) { | 2793     if (js->ParamIs("type", "Native")) { | 
| 2884       native_metrics = true; | 2794       native_metrics = true; | 
| 2885     } else if (js->ParamIs("type", "Dart")) { | 2795     } else if (js->ParamIs("type", "Dart")) { | 
| 2886       native_metrics = false; | 2796       native_metrics = false; | 
| 2887     } else { | 2797     } else { | 
| 2888       PrintInvalidParamError(js, "type"); | 2798       PrintInvalidParamError(js, "type"); | 
| 2889       return true; | 2799       return true; | 
| 2890     } | 2800     } | 
| 2891   } else { | 2801   } else { | 
| 2892     PrintMissingParamError(js, "type"); | 2802     PrintMissingParamError(js, "type"); | 
| 2893     return true; | 2803     return true; | 
| 2894   } | 2804   } | 
| 2895   if (native_metrics) { | 2805   if (native_metrics) { | 
| 2896     return HandleNativeMetricsList(thread, js); | 2806     return HandleNativeMetricsList(thread, js); | 
| 2897   } | 2807   } | 
| 2898   return HandleDartMetricsList(thread, js); | 2808   return HandleDartMetricsList(thread, js); | 
| 2899 } | 2809 } | 
| 2900 | 2810 | 
| 2901 | 2811 | 
| 2902 static const MethodParameter* get_isolate_metric_params[] = { | 2812 static const MethodParameter* get_isolate_metric_params[] = { | 
| 2903   RUNNABLE_ISOLATE_PARAMETER, | 2813     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 2904   NULL, |  | 
| 2905 }; | 2814 }; | 
| 2906 | 2815 | 
| 2907 | 2816 | 
| 2908 static bool GetIsolateMetric(Thread* thread, JSONStream* js) { | 2817 static bool GetIsolateMetric(Thread* thread, JSONStream* js) { | 
| 2909   const char* metric_id = js->LookupParam("metricId"); | 2818   const char* metric_id = js->LookupParam("metricId"); | 
| 2910   if (metric_id == NULL) { | 2819   if (metric_id == NULL) { | 
| 2911     PrintMissingParamError(js, "metricId"); | 2820     PrintMissingParamError(js, "metricId"); | 
| 2912     return true; | 2821     return true; | 
| 2913   } | 2822   } | 
| 2914   // Verify id begins with "metrics/". | 2823   // Verify id begins with "metrics/". | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2926   if (native_metric) { | 2835   if (native_metric) { | 
| 2927     const char* id = metric_id + kNativeMetricIdPrefixLen; | 2836     const char* id = metric_id + kNativeMetricIdPrefixLen; | 
| 2928     return HandleNativeMetric(thread, js, id); | 2837     return HandleNativeMetric(thread, js, id); | 
| 2929   } | 2838   } | 
| 2930   const char* id = metric_id + kMetricIdPrefixLen; | 2839   const char* id = metric_id + kMetricIdPrefixLen; | 
| 2931   return HandleDartMetric(thread, js, id); | 2840   return HandleDartMetric(thread, js, id); | 
| 2932 } | 2841 } | 
| 2933 | 2842 | 
| 2934 | 2843 | 
| 2935 static const MethodParameter* get_vm_metric_list_params[] = { | 2844 static const MethodParameter* get_vm_metric_list_params[] = { | 
| 2936   NO_ISOLATE_PARAMETER, | 2845     NO_ISOLATE_PARAMETER, NULL, | 
| 2937   NULL, |  | 
| 2938 }; | 2846 }; | 
| 2939 | 2847 | 
| 2940 | 2848 | 
| 2941 static bool GetVMMetricList(Thread* thread, JSONStream* js) { | 2849 static bool GetVMMetricList(Thread* thread, JSONStream* js) { | 
| 2942   return false; | 2850   return false; | 
| 2943 } | 2851 } | 
| 2944 | 2852 | 
| 2945 | 2853 | 
| 2946 static const MethodParameter* get_vm_metric_params[] = { | 2854 static const MethodParameter* get_vm_metric_params[] = { | 
| 2947   NO_ISOLATE_PARAMETER, | 2855     NO_ISOLATE_PARAMETER, NULL, | 
| 2948   NULL, |  | 
| 2949 }; | 2856 }; | 
| 2950 | 2857 | 
| 2951 | 2858 | 
| 2952 static bool GetVMMetric(Thread* thread, JSONStream* js) { | 2859 static bool GetVMMetric(Thread* thread, JSONStream* js) { | 
| 2953   const char* metric_id = js->LookupParam("metricId"); | 2860   const char* metric_id = js->LookupParam("metricId"); | 
| 2954   if (metric_id == NULL) { | 2861   if (metric_id == NULL) { | 
| 2955     PrintMissingParamError(js, "metricId"); | 2862     PrintMissingParamError(js, "metricId"); | 
| 2956   } | 2863   } | 
| 2957   return false; | 2864   return false; | 
| 2958 } | 2865 } | 
| 2959 | 2866 | 
| 2960 static const char* const timeline_streams_enum_names[] = { | 2867 static const char* const timeline_streams_enum_names[] = { | 
| 2961   "all", | 2868     "all", | 
| 2962 #define DEFINE_NAME(name, unused)                                              \ | 2869 #define DEFINE_NAME(name, unused) #name, | 
| 2963   #name, | 2870     TIMELINE_STREAM_LIST(DEFINE_NAME) | 
| 2964 TIMELINE_STREAM_LIST(DEFINE_NAME) |  | 
| 2965 #undef DEFINE_NAME | 2871 #undef DEFINE_NAME | 
| 2966   NULL | 2872         NULL}; | 
| 2967 }; |  | 
| 2968 | 2873 | 
| 2969 static const MethodParameter* set_vm_timeline_flags_params[] = { | 2874 static const MethodParameter* set_vm_timeline_flags_params[] = { | 
| 2970   NO_ISOLATE_PARAMETER, | 2875     NO_ISOLATE_PARAMETER, new EnumListParameter("recordedStreams", | 
| 2971   new EnumListParameter("recordedStreams", | 2876                                                 false, | 
| 2972                         false, | 2877                                                 timeline_streams_enum_names), | 
| 2973                         timeline_streams_enum_names), | 2878     NULL, | 
| 2974   NULL, |  | 
| 2975 }; | 2879 }; | 
| 2976 | 2880 | 
| 2977 | 2881 | 
| 2978 static bool HasStream(const char** recorded_streams, const char* stream) { | 2882 static bool HasStream(const char** recorded_streams, const char* stream) { | 
| 2979   while (*recorded_streams != NULL) { | 2883   while (*recorded_streams != NULL) { | 
| 2980     if ((strstr(*recorded_streams, "all") != NULL) || | 2884     if ((strstr(*recorded_streams, "all") != NULL) || | 
| 2981         (strstr(*recorded_streams, stream) != NULL)) { | 2885         (strstr(*recorded_streams, stream) != NULL)) { | 
| 2982       return true; | 2886       return true; | 
| 2983     } | 2887     } | 
| 2984     recorded_streams++; | 2888     recorded_streams++; | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 2998 | 2902 | 
| 2999   const EnumListParameter* recorded_streams_param = | 2903   const EnumListParameter* recorded_streams_param = | 
| 3000       static_cast<const EnumListParameter*>(set_vm_timeline_flags_params[1]); | 2904       static_cast<const EnumListParameter*>(set_vm_timeline_flags_params[1]); | 
| 3001 | 2905 | 
| 3002   const char* recorded_streams_str = js->LookupParam("recordedStreams"); | 2906   const char* recorded_streams_str = js->LookupParam("recordedStreams"); | 
| 3003   const char** recorded_streams = | 2907   const char** recorded_streams = | 
| 3004       recorded_streams_param->Parse(thread->zone(), recorded_streams_str); | 2908       recorded_streams_param->Parse(thread->zone(), recorded_streams_str); | 
| 3005 | 2909 | 
| 3006 #define SET_ENABLE_STREAM(name, unused)                                        \ | 2910 #define SET_ENABLE_STREAM(name, unused)                                        \ | 
| 3007   Timeline::SetStream##name##Enabled(HasStream(recorded_streams, #name)); | 2911   Timeline::SetStream##name##Enabled(HasStream(recorded_streams, #name)); | 
| 3008 TIMELINE_STREAM_LIST(SET_ENABLE_STREAM); | 2912   TIMELINE_STREAM_LIST(SET_ENABLE_STREAM); | 
| 3009 #undef SET_ENABLE_STREAM | 2913 #undef SET_ENABLE_STREAM | 
| 3010 | 2914 | 
| 3011   PrintSuccess(js); | 2915   PrintSuccess(js); | 
| 3012 | 2916 | 
| 3013   return true; | 2917   return true; | 
| 3014 } | 2918 } | 
| 3015 | 2919 | 
| 3016 | 2920 | 
| 3017 static const MethodParameter* get_vm_timeline_flags_params[] = { | 2921 static const MethodParameter* get_vm_timeline_flags_params[] = { | 
| 3018   NO_ISOLATE_PARAMETER, | 2922     NO_ISOLATE_PARAMETER, NULL, | 
| 3019   NULL, |  | 
| 3020 }; | 2923 }; | 
| 3021 | 2924 | 
| 3022 | 2925 | 
| 3023 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) { | 2926 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) { | 
| 3024   if (!FLAG_support_timeline) { | 2927   if (!FLAG_support_timeline) { | 
| 3025     JSONObject obj(js); | 2928     JSONObject obj(js); | 
| 3026     obj.AddProperty("type", "TimelineFlags"); | 2929     obj.AddProperty("type", "TimelineFlags"); | 
| 3027     return true; | 2930     return true; | 
| 3028   } | 2931   } | 
| 3029   Isolate* isolate = thread->isolate(); | 2932   Isolate* isolate = thread->isolate(); | 
| 3030   ASSERT(isolate != NULL); | 2933   ASSERT(isolate != NULL); | 
| 3031   StackZone zone(thread); | 2934   StackZone zone(thread); | 
| 3032   Timeline::PrintFlagsToJSON(js); | 2935   Timeline::PrintFlagsToJSON(js); | 
| 3033   return true; | 2936   return true; | 
| 3034 } | 2937 } | 
| 3035 | 2938 | 
| 3036 | 2939 | 
| 3037 static const MethodParameter* clear_vm_timeline_params[] = { | 2940 static const MethodParameter* clear_vm_timeline_params[] = { | 
| 3038   NO_ISOLATE_PARAMETER, | 2941     NO_ISOLATE_PARAMETER, NULL, | 
| 3039   NULL, |  | 
| 3040 }; | 2942 }; | 
| 3041 | 2943 | 
| 3042 | 2944 | 
| 3043 static bool ClearVMTimeline(Thread* thread, JSONStream* js) { | 2945 static bool ClearVMTimeline(Thread* thread, JSONStream* js) { | 
| 3044   Isolate* isolate = thread->isolate(); | 2946   Isolate* isolate = thread->isolate(); | 
| 3045   ASSERT(isolate != NULL); | 2947   ASSERT(isolate != NULL); | 
| 3046   StackZone zone(thread); | 2948   StackZone zone(thread); | 
| 3047 | 2949 | 
| 3048   Timeline::Clear(); | 2950   Timeline::Clear(); | 
| 3049 | 2951 | 
| 3050   PrintSuccess(js); | 2952   PrintSuccess(js); | 
| 3051 | 2953 | 
| 3052   return true; | 2954   return true; | 
| 3053 } | 2955 } | 
| 3054 | 2956 | 
| 3055 | 2957 | 
| 3056 static const MethodParameter* get_vm_timeline_params[] = { | 2958 static const MethodParameter* get_vm_timeline_params[] = { | 
| 3057   NO_ISOLATE_PARAMETER, | 2959     NO_ISOLATE_PARAMETER, new Int64Parameter("timeOriginMicros", false), | 
| 3058   new Int64Parameter("timeOriginMicros", false), | 2960     new Int64Parameter("timeExtentMicros", false), NULL, | 
| 3059   new Int64Parameter("timeExtentMicros", false), |  | 
| 3060   NULL, |  | 
| 3061 }; | 2961 }; | 
| 3062 | 2962 | 
| 3063 | 2963 | 
| 3064 static bool GetVMTimeline(Thread* thread, JSONStream* js) { | 2964 static bool GetVMTimeline(Thread* thread, JSONStream* js) { | 
| 3065   Isolate* isolate = thread->isolate(); | 2965   Isolate* isolate = thread->isolate(); | 
| 3066   ASSERT(isolate != NULL); | 2966   ASSERT(isolate != NULL); | 
| 3067   StackZone zone(thread); | 2967   StackZone zone(thread); | 
| 3068   Timeline::ReclaimCachedBlocksFromThreads(); | 2968   Timeline::ReclaimCachedBlocksFromThreads(); | 
| 3069   TimelineEventRecorder* timeline_recorder = Timeline::recorder(); | 2969   TimelineEventRecorder* timeline_recorder = Timeline::recorder(); | 
| 3070   // TODO(johnmccutchan): Return an error. | 2970   // TODO(johnmccutchan): Return an error. | 
| 3071   ASSERT(timeline_recorder != NULL); | 2971   ASSERT(timeline_recorder != NULL); | 
| 3072   int64_t time_origin_micros = | 2972   int64_t time_origin_micros = | 
| 3073       Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); | 2973       Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); | 
| 3074   int64_t time_extent_micros = | 2974   int64_t time_extent_micros = | 
| 3075       Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); | 2975       Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); | 
| 3076   TimelineEventFilter filter(time_origin_micros, time_extent_micros); | 2976   TimelineEventFilter filter(time_origin_micros, time_extent_micros); | 
| 3077   timeline_recorder->PrintJSON(js, &filter); | 2977   timeline_recorder->PrintJSON(js, &filter); | 
| 3078   return true; | 2978   return true; | 
| 3079 } | 2979 } | 
| 3080 | 2980 | 
| 3081 | 2981 | 
| 3082 static const MethodParameter* resume_params[] = { | 2982 static const MethodParameter* resume_params[] = { | 
| 3083   RUNNABLE_ISOLATE_PARAMETER, | 2983     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3084   NULL, |  | 
| 3085 }; | 2984 }; | 
| 3086 | 2985 | 
| 3087 | 2986 | 
| 3088 static bool Resume(Thread* thread, JSONStream* js) { | 2987 static bool Resume(Thread* thread, JSONStream* js) { | 
| 3089   const char* step_param = js->LookupParam("step"); | 2988   const char* step_param = js->LookupParam("step"); | 
| 3090   Isolate* isolate = thread->isolate(); | 2989   Isolate* isolate = thread->isolate(); | 
| 3091   if (isolate->message_handler()->is_paused_on_start()) { | 2990   if (isolate->message_handler()->is_paused_on_start()) { | 
| 3092     // If the user is issuing a 'Over' or an 'Out' step, that is the | 2991     // If the user is issuing a 'Over' or an 'Out' step, that is the | 
| 3093     // same as a regular resume request. | 2992     // same as a regular resume request. | 
| 3094     if ((step_param != NULL) && (strcmp(step_param, "Into") == 0)) { | 2993     if ((step_param != NULL) && (strcmp(step_param, "Into") == 0)) { | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3143     PrintSuccess(js); | 3042     PrintSuccess(js); | 
| 3144     return true; | 3043     return true; | 
| 3145   } | 3044   } | 
| 3146 | 3045 | 
| 3147   js->PrintError(kIsolateMustBePaused, NULL); | 3046   js->PrintError(kIsolateMustBePaused, NULL); | 
| 3148   return true; | 3047   return true; | 
| 3149 } | 3048 } | 
| 3150 | 3049 | 
| 3151 | 3050 | 
| 3152 static const MethodParameter* pause_params[] = { | 3051 static const MethodParameter* pause_params[] = { | 
| 3153   RUNNABLE_ISOLATE_PARAMETER, | 3052     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3154   NULL, |  | 
| 3155 }; | 3053 }; | 
| 3156 | 3054 | 
| 3157 | 3055 | 
| 3158 static bool Pause(Thread* thread, JSONStream* js) { | 3056 static bool Pause(Thread* thread, JSONStream* js) { | 
| 3159   // TODO(turnidge): This interrupt message could have been sent from | 3057   // TODO(turnidge): This interrupt message could have been sent from | 
| 3160   // the service isolate directly, but would require some special case | 3058   // the service isolate directly, but would require some special case | 
| 3161   // code.  That would prevent this isolate getting double-interrupted | 3059   // code.  That would prevent this isolate getting double-interrupted | 
| 3162   // with OOB messages. | 3060   // with OOB messages. | 
| 3163   Isolate* isolate = thread->isolate(); | 3061   Isolate* isolate = thread->isolate(); | 
| 3164   isolate->SendInternalLibMessage(Isolate::kInterruptMsg, | 3062   isolate->SendInternalLibMessage(Isolate::kInterruptMsg, | 
| 3165                                   isolate->pause_capability()); | 3063                                   isolate->pause_capability()); | 
| 3166   PrintSuccess(js); | 3064   PrintSuccess(js); | 
| 3167   return true; | 3065   return true; | 
| 3168 } | 3066 } | 
| 3169 | 3067 | 
| 3170 | 3068 | 
| 3171 static const MethodParameter* get_tag_profile_params[] = { | 3069 static const MethodParameter* get_tag_profile_params[] = { | 
| 3172   RUNNABLE_ISOLATE_PARAMETER, | 3070     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3173   NULL, |  | 
| 3174 }; | 3071 }; | 
| 3175 | 3072 | 
| 3176 | 3073 | 
| 3177 static bool GetTagProfile(Thread* thread, JSONStream* js) { | 3074 static bool GetTagProfile(Thread* thread, JSONStream* js) { | 
| 3178   JSONObject miniProfile(js); | 3075   JSONObject miniProfile(js); | 
| 3179   miniProfile.AddProperty("type", "TagProfile"); | 3076   miniProfile.AddProperty("type", "TagProfile"); | 
| 3180   thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile); | 3077   thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile); | 
| 3181   return true; | 3078   return true; | 
| 3182 } | 3079 } | 
| 3183 | 3080 | 
| 3184 | 3081 | 
| 3185 static const char* const tags_enum_names[] = { | 3082 static const char* const tags_enum_names[] = { | 
| 3186   "None", | 3083     "None", "UserVM", "UserOnly", "VMUser", "VMOnly", NULL, | 
| 3187   "UserVM", |  | 
| 3188   "UserOnly", |  | 
| 3189   "VMUser", |  | 
| 3190   "VMOnly", |  | 
| 3191   NULL, |  | 
| 3192 }; | 3084 }; | 
| 3193 | 3085 | 
| 3194 | 3086 | 
| 3195 static const Profile::TagOrder tags_enum_values[] = { | 3087 static const Profile::TagOrder tags_enum_values[] = { | 
| 3196   Profile::kNoTags, | 3088     Profile::kNoTags, Profile::kUserVM, Profile::kUser, | 
| 3197   Profile::kUserVM, | 3089     Profile::kVMUser, Profile::kVM, | 
| 3198   Profile::kUser, | 3090     Profile::kNoTags,  // Default value. | 
| 3199   Profile::kVMUser, |  | 
| 3200   Profile::kVM, |  | 
| 3201   Profile::kNoTags,  // Default value. |  | 
| 3202 }; | 3091 }; | 
| 3203 | 3092 | 
| 3204 | 3093 | 
| 3205 static const MethodParameter* get_cpu_profile_params[] = { | 3094 static const MethodParameter* get_cpu_profile_params[] = { | 
| 3206   RUNNABLE_ISOLATE_PARAMETER, | 3095     RUNNABLE_ISOLATE_PARAMETER, | 
| 3207   new EnumParameter("tags", true, tags_enum_names), | 3096     new EnumParameter("tags", true, tags_enum_names), | 
| 3208   new BoolParameter("_codeTransitionTags", false), | 3097     new BoolParameter("_codeTransitionTags", false), | 
| 3209   new Int64Parameter("timeOriginMicros", false), | 3098     new Int64Parameter("timeOriginMicros", false), | 
| 3210   new Int64Parameter("timeExtentMicros", false), | 3099     new Int64Parameter("timeExtentMicros", false), | 
| 3211   NULL, | 3100     NULL, | 
| 3212 }; | 3101 }; | 
| 3213 | 3102 | 
| 3214 | 3103 | 
| 3215 // TODO(johnmccutchan): Rename this to GetCpuSamples. | 3104 // TODO(johnmccutchan): Rename this to GetCpuSamples. | 
| 3216 static bool GetCpuProfile(Thread* thread, JSONStream* js) { | 3105 static bool GetCpuProfile(Thread* thread, JSONStream* js) { | 
| 3217   Profile::TagOrder tag_order = | 3106   Profile::TagOrder tag_order = | 
| 3218       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 3107       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 
| 3219   intptr_t extra_tags = 0; | 3108   intptr_t extra_tags = 0; | 
| 3220   if (BoolParameter::Parse(js->LookupParam("_codeTransitionTags"))) { | 3109   if (BoolParameter::Parse(js->LookupParam("_codeTransitionTags"))) { | 
| 3221     extra_tags |= ProfilerService::kCodeTransitionTagsBit; | 3110     extra_tags |= ProfilerService::kCodeTransitionTagsBit; | 
| 3222   } | 3111   } | 
| 3223   int64_t time_origin_micros = | 3112   int64_t time_origin_micros = | 
| 3224       Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); | 3113       Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); | 
| 3225   int64_t time_extent_micros = | 3114   int64_t time_extent_micros = | 
| 3226       Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); | 3115       Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); | 
| 3227   ProfilerService::PrintJSON(js, | 3116   ProfilerService::PrintJSON(js, tag_order, extra_tags, time_origin_micros, | 
| 3228                              tag_order, |  | 
| 3229                              extra_tags, |  | 
| 3230                              time_origin_micros, |  | 
| 3231                              time_extent_micros); | 3117                              time_extent_micros); | 
| 3232   return true; | 3118   return true; | 
| 3233 } | 3119 } | 
| 3234 | 3120 | 
| 3235 | 3121 | 
| 3236 static const MethodParameter* get_cpu_profile_timeline_params[] = { | 3122 static const MethodParameter* get_cpu_profile_timeline_params[] = { | 
| 3237   RUNNABLE_ISOLATE_PARAMETER, | 3123     RUNNABLE_ISOLATE_PARAMETER, | 
| 3238   new EnumParameter("tags", true, tags_enum_names), | 3124     new EnumParameter("tags", true, tags_enum_names), | 
| 3239   new Int64Parameter("timeOriginMicros", false), | 3125     new Int64Parameter("timeOriginMicros", false), | 
| 3240   new Int64Parameter("timeExtentMicros", false), | 3126     new Int64Parameter("timeExtentMicros", false), | 
| 3241   NULL, | 3127     NULL, | 
| 3242 }; | 3128 }; | 
| 3243 | 3129 | 
| 3244 | 3130 | 
| 3245 static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) { | 3131 static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) { | 
| 3246   Profile::TagOrder tag_order = | 3132   Profile::TagOrder tag_order = | 
| 3247       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 3133       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 
| 3248   int64_t time_origin_micros = | 3134   int64_t time_origin_micros = | 
| 3249       UIntParameter::Parse(js->LookupParam("timeOriginMicros")); | 3135       UIntParameter::Parse(js->LookupParam("timeOriginMicros")); | 
| 3250   int64_t time_extent_micros = | 3136   int64_t time_extent_micros = | 
| 3251       UIntParameter::Parse(js->LookupParam("timeExtentMicros")); | 3137       UIntParameter::Parse(js->LookupParam("timeExtentMicros")); | 
| 3252   ProfilerService::PrintTimelineJSON(js, | 3138   ProfilerService::PrintTimelineJSON(js, tag_order, time_origin_micros, | 
| 3253                                      tag_order, |  | 
| 3254                                      time_origin_micros, |  | 
| 3255                                      time_extent_micros); | 3139                                      time_extent_micros); | 
| 3256   return true; | 3140   return true; | 
| 3257 } | 3141 } | 
| 3258 | 3142 | 
| 3259 | 3143 | 
| 3260 static const MethodParameter* get_allocation_samples_params[] = { | 3144 static const MethodParameter* get_allocation_samples_params[] = { | 
| 3261   RUNNABLE_ISOLATE_PARAMETER, | 3145     RUNNABLE_ISOLATE_PARAMETER, | 
| 3262   new EnumParameter("tags", true, tags_enum_names), | 3146     new EnumParameter("tags", true, tags_enum_names), | 
| 3263   new IdParameter("classId", false), | 3147     new IdParameter("classId", false), | 
| 3264   new Int64Parameter("timeOriginMicros", false), | 3148     new Int64Parameter("timeOriginMicros", false), | 
| 3265   new Int64Parameter("timeExtentMicros", false), | 3149     new Int64Parameter("timeExtentMicros", false), | 
| 3266   NULL, | 3150     NULL, | 
| 3267 }; | 3151 }; | 
| 3268 | 3152 | 
| 3269 | 3153 | 
| 3270 static bool GetAllocationSamples(Thread* thread, JSONStream* js) { | 3154 static bool GetAllocationSamples(Thread* thread, JSONStream* js) { | 
| 3271   Profile::TagOrder tag_order = | 3155   Profile::TagOrder tag_order = | 
| 3272       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 3156       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 
| 3273   int64_t time_origin_micros = | 3157   int64_t time_origin_micros = | 
| 3274       Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); | 3158       Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); | 
| 3275   int64_t time_extent_micros = | 3159   int64_t time_extent_micros = | 
| 3276       Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); | 3160       Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); | 
| 3277   const char* class_id = js->LookupParam("classId"); | 3161   const char* class_id = js->LookupParam("classId"); | 
| 3278   intptr_t cid = -1; | 3162   intptr_t cid = -1; | 
| 3279   GetPrefixedIntegerId(class_id, "classes/", &cid); | 3163   GetPrefixedIntegerId(class_id, "classes/", &cid); | 
| 3280   Isolate* isolate = thread->isolate(); | 3164   Isolate* isolate = thread->isolate(); | 
| 3281   if (IsValidClassId(isolate, cid)) { | 3165   if (IsValidClassId(isolate, cid)) { | 
| 3282     const Class& cls = Class::Handle(GetClassForId(isolate, cid)); | 3166     const Class& cls = Class::Handle(GetClassForId(isolate, cid)); | 
| 3283     ProfilerService::PrintAllocationJSON(js, | 3167     ProfilerService::PrintAllocationJSON(js, tag_order, cls, time_origin_micros, | 
| 3284                                          tag_order, |  | 
| 3285                                          cls, |  | 
| 3286                                          time_origin_micros, |  | 
| 3287                                          time_extent_micros); | 3168                                          time_extent_micros); | 
| 3288   } else { | 3169   } else { | 
| 3289     PrintInvalidParamError(js, "classId"); | 3170     PrintInvalidParamError(js, "classId"); | 
| 3290   } | 3171   } | 
| 3291   return true; | 3172   return true; | 
| 3292 } | 3173 } | 
| 3293 | 3174 | 
| 3294 | 3175 | 
| 3295 static const MethodParameter* clear_cpu_profile_params[] = { | 3176 static const MethodParameter* clear_cpu_profile_params[] = { | 
| 3296   RUNNABLE_ISOLATE_PARAMETER, | 3177     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3297   NULL, |  | 
| 3298 }; | 3178 }; | 
| 3299 | 3179 | 
| 3300 | 3180 | 
| 3301 static bool ClearCpuProfile(Thread* thread, JSONStream* js) { | 3181 static bool ClearCpuProfile(Thread* thread, JSONStream* js) { | 
| 3302   ProfilerService::ClearSamples(); | 3182   ProfilerService::ClearSamples(); | 
| 3303   PrintSuccess(js); | 3183   PrintSuccess(js); | 
| 3304   return true; | 3184   return true; | 
| 3305 } | 3185 } | 
| 3306 | 3186 | 
| 3307 | 3187 | 
| 3308 static const MethodParameter* get_allocation_profile_params[] = { | 3188 static const MethodParameter* get_allocation_profile_params[] = { | 
| 3309   RUNNABLE_ISOLATE_PARAMETER, | 3189     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3310   NULL, |  | 
| 3311 }; | 3190 }; | 
| 3312 | 3191 | 
| 3313 | 3192 | 
| 3314 static bool GetAllocationProfile(Thread* thread, JSONStream* js) { | 3193 static bool GetAllocationProfile(Thread* thread, JSONStream* js) { | 
| 3315   bool should_reset_accumulator = false; | 3194   bool should_reset_accumulator = false; | 
| 3316   bool should_collect = false; | 3195   bool should_collect = false; | 
| 3317   if (js->HasParam("reset")) { | 3196   if (js->HasParam("reset")) { | 
| 3318     if (js->ParamIs("reset", "true")) { | 3197     if (js->ParamIs("reset", "true")) { | 
| 3319       should_reset_accumulator = true; | 3198       should_reset_accumulator = true; | 
| 3320     } else { | 3199     } else { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 3338   if (should_collect) { | 3217   if (should_collect) { | 
| 3339     isolate->UpdateLastAllocationProfileGCTimestamp(); | 3218     isolate->UpdateLastAllocationProfileGCTimestamp(); | 
| 3340     isolate->heap()->CollectAllGarbage(); | 3219     isolate->heap()->CollectAllGarbage(); | 
| 3341   } | 3220   } | 
| 3342   isolate->class_table()->AllocationProfilePrintJSON(js); | 3221   isolate->class_table()->AllocationProfilePrintJSON(js); | 
| 3343   return true; | 3222   return true; | 
| 3344 } | 3223 } | 
| 3345 | 3224 | 
| 3346 | 3225 | 
| 3347 static const MethodParameter* get_heap_map_params[] = { | 3226 static const MethodParameter* get_heap_map_params[] = { | 
| 3348   RUNNABLE_ISOLATE_PARAMETER, | 3227     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3349   NULL, |  | 
| 3350 }; | 3228 }; | 
| 3351 | 3229 | 
| 3352 | 3230 | 
| 3353 static bool GetHeapMap(Thread* thread, JSONStream* js) { | 3231 static bool GetHeapMap(Thread* thread, JSONStream* js) { | 
| 3354   Isolate* isolate = thread->isolate(); | 3232   Isolate* isolate = thread->isolate(); | 
| 3355   isolate->heap()->PrintHeapMapToJSONStream(isolate, js); | 3233   isolate->heap()->PrintHeapMapToJSONStream(isolate, js); | 
| 3356   return true; | 3234   return true; | 
| 3357 } | 3235 } | 
| 3358 | 3236 | 
| 3359 | 3237 | 
| 3360 static const MethodParameter* request_heap_snapshot_params[] = { | 3238 static const MethodParameter* request_heap_snapshot_params[] = { | 
| 3361   RUNNABLE_ISOLATE_PARAMETER, | 3239     RUNNABLE_ISOLATE_PARAMETER, | 
| 3362   new BoolParameter("collectGarbage", false /* not required */), | 3240     new BoolParameter("collectGarbage", false /* not required */), NULL, | 
| 3363   NULL, |  | 
| 3364 }; | 3241 }; | 
| 3365 | 3242 | 
| 3366 | 3243 | 
| 3367 static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) { | 3244 static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) { | 
| 3368   const bool collect_garbage = | 3245   const bool collect_garbage = | 
| 3369       BoolParameter::Parse(js->LookupParam("collectGarbage"), true); | 3246       BoolParameter::Parse(js->LookupParam("collectGarbage"), true); | 
| 3370   if (Service::graph_stream.enabled()) { | 3247   if (Service::graph_stream.enabled()) { | 
| 3371     Service::SendGraphEvent(thread, collect_garbage); | 3248     Service::SendGraphEvent(thread, collect_garbage); | 
| 3372   } | 3249   } | 
| 3373   // TODO(koda): Provide some id that ties this request to async response(s). | 3250   // TODO(koda): Provide some id that ties this request to async response(s). | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3406 | 3283 | 
| 3407           event.AddProperty("chunkIndex", i); | 3284           event.AddProperty("chunkIndex", i); | 
| 3408           event.AddProperty("chunkCount", num_chunks); | 3285           event.AddProperty("chunkCount", num_chunks); | 
| 3409           event.AddProperty("nodeCount", node_count); | 3286           event.AddProperty("nodeCount", node_count); | 
| 3410         } | 3287         } | 
| 3411       } | 3288       } | 
| 3412     } | 3289     } | 
| 3413 | 3290 | 
| 3414     uint8_t* chunk_start = buffer + (i * kChunkSize); | 3291     uint8_t* chunk_start = buffer + (i * kChunkSize); | 
| 3415     intptr_t chunk_size = (i + 1 == num_chunks) | 3292     intptr_t chunk_size = (i + 1 == num_chunks) | 
| 3416         ? stream.bytes_written() - (i * kChunkSize) | 3293                               ? stream.bytes_written() - (i * kChunkSize) | 
| 3417         : kChunkSize; | 3294                               : kChunkSize; | 
| 3418 | 3295 | 
| 3419     SendEventWithData(graph_stream.id(), "_Graph", | 3296     SendEventWithData(graph_stream.id(), "_Graph", js.buffer()->buf(), | 
| 3420                       js.buffer()->buf(), js.buffer()->length(), | 3297                       js.buffer()->length(), chunk_start, chunk_size); | 
| 3421                       chunk_start, chunk_size); |  | 
| 3422   } | 3298   } | 
| 3423 } | 3299 } | 
| 3424 | 3300 | 
| 3425 | 3301 | 
| 3426 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) { | 3302 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) { | 
| 3427   if (!Service::debug_stream.enabled()) { | 3303   if (!Service::debug_stream.enabled()) { | 
| 3428     return; | 3304     return; | 
| 3429   } | 3305   } | 
| 3430   ServiceEvent event(isolate, ServiceEvent::kInspect); | 3306   ServiceEvent event(isolate, ServiceEvent::kInspect); | 
| 3431   event.set_inspectee(&inspectee); | 3307   event.set_inspectee(&inspectee); | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3486   extension_event.event_kind = &event_kind; | 3362   extension_event.event_kind = &event_kind; | 
| 3487   extension_event.event_data = &event_data; | 3363   extension_event.event_data = &event_data; | 
| 3488   ServiceEvent event(isolate, ServiceEvent::kExtension); | 3364   ServiceEvent event(isolate, ServiceEvent::kExtension); | 
| 3489   event.set_extension_event(extension_event); | 3365   event.set_extension_event(extension_event); | 
| 3490   Service::HandleEvent(&event); | 3366   Service::HandleEvent(&event); | 
| 3491 } | 3367 } | 
| 3492 | 3368 | 
| 3493 | 3369 | 
| 3494 class ContainsAddressVisitor : public FindObjectVisitor { | 3370 class ContainsAddressVisitor : public FindObjectVisitor { | 
| 3495  public: | 3371  public: | 
| 3496   explicit ContainsAddressVisitor(uword addr) : addr_(addr) { } | 3372   explicit ContainsAddressVisitor(uword addr) : addr_(addr) {} | 
| 3497   virtual ~ContainsAddressVisitor() { } | 3373   virtual ~ContainsAddressVisitor() {} | 
| 3498 | 3374 | 
| 3499   virtual uword filter_addr() const { return addr_; } | 3375   virtual uword filter_addr() const { return addr_; } | 
| 3500 | 3376 | 
| 3501   virtual bool FindObject(RawObject* obj) const { | 3377   virtual bool FindObject(RawObject* obj) const { | 
| 3502     if (obj->IsPseudoObject()) { | 3378     if (obj->IsPseudoObject()) { | 
| 3503       return false; | 3379       return false; | 
| 3504     } | 3380     } | 
| 3505     uword obj_begin = RawObject::ToAddr(obj); | 3381     uword obj_begin = RawObject::ToAddr(obj); | 
| 3506     uword obj_end = obj_begin + obj->Size(); | 3382     uword obj_end = obj_begin + obj->Size(); | 
| 3507     return obj_begin <= addr_ && addr_ < obj_end; | 3383     return obj_begin <= addr_ && addr_ < obj_end; | 
| 3508   } | 3384   } | 
|  | 3385 | 
| 3509  private: | 3386  private: | 
| 3510   uword addr_; | 3387   uword addr_; | 
| 3511 }; | 3388 }; | 
| 3512 | 3389 | 
| 3513 | 3390 | 
| 3514 static const MethodParameter* get_object_by_address_params[] = { | 3391 static const MethodParameter* get_object_by_address_params[] = { | 
| 3515   RUNNABLE_ISOLATE_PARAMETER, | 3392     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3516   NULL, |  | 
| 3517 }; | 3393 }; | 
| 3518 | 3394 | 
| 3519 | 3395 | 
| 3520 static RawObject* GetObjectHelper(Thread* thread, uword addr) { | 3396 static RawObject* GetObjectHelper(Thread* thread, uword addr) { | 
| 3521   Object& object = Object::Handle(thread->zone()); | 3397   Object& object = Object::Handle(thread->zone()); | 
| 3522 | 3398 | 
| 3523   { | 3399   { | 
| 3524     NoSafepointScope no_safepoint; | 3400     NoSafepointScope no_safepoint; | 
| 3525     Isolate* isolate = thread->isolate(); | 3401     Isolate* isolate = thread->isolate(); | 
| 3526     ContainsAddressVisitor visitor(addr); | 3402     ContainsAddressVisitor visitor(addr); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 3548     return true; | 3424     return true; | 
| 3549   } | 3425   } | 
| 3550 | 3426 | 
| 3551   // Handle heap objects. | 3427   // Handle heap objects. | 
| 3552   uword addr = 0; | 3428   uword addr = 0; | 
| 3553   if (!GetUnsignedIntegerId(addr_str, &addr, 16)) { | 3429   if (!GetUnsignedIntegerId(addr_str, &addr, 16)) { | 
| 3554     PrintInvalidParamError(js, "address"); | 3430     PrintInvalidParamError(js, "address"); | 
| 3555     return true; | 3431     return true; | 
| 3556   } | 3432   } | 
| 3557   bool ref = js->HasParam("ref") && js->ParamIs("ref", "true"); | 3433   bool ref = js->HasParam("ref") && js->ParamIs("ref", "true"); | 
| 3558   const Object& obj = Object::Handle(thread->zone(), | 3434   const Object& obj = | 
| 3559       GetObjectHelper(thread, addr)); | 3435       Object::Handle(thread->zone(), GetObjectHelper(thread, addr)); | 
| 3560   if (obj.IsNull()) { | 3436   if (obj.IsNull()) { | 
| 3561     PrintSentinel(js, kFreeSentinel); | 3437     PrintSentinel(js, kFreeSentinel); | 
| 3562   } else { | 3438   } else { | 
| 3563     obj.PrintJSON(js, ref); | 3439     obj.PrintJSON(js, ref); | 
| 3564   } | 3440   } | 
| 3565   return true; | 3441   return true; | 
| 3566 } | 3442 } | 
| 3567 | 3443 | 
| 3568 | 3444 | 
| 3569 static const MethodParameter* get_persistent_handles_params[] = { | 3445 static const MethodParameter* get_persistent_handles_params[] = { | 
| 3570   ISOLATE_PARAMETER, | 3446     ISOLATE_PARAMETER, NULL, | 
| 3571   NULL, |  | 
| 3572 }; | 3447 }; | 
| 3573 | 3448 | 
| 3574 | 3449 | 
| 3575 template<typename T> | 3450 template <typename T> | 
| 3576 class PersistentHandleVisitor : public HandleVisitor { | 3451 class PersistentHandleVisitor : public HandleVisitor { | 
| 3577  public: | 3452  public: | 
| 3578   PersistentHandleVisitor(Thread* thread, JSONArray* handles) | 3453   PersistentHandleVisitor(Thread* thread, JSONArray* handles) | 
| 3579       : HandleVisitor(thread), | 3454       : HandleVisitor(thread), handles_(handles) { | 
| 3580         handles_(handles) { |  | 
| 3581     ASSERT(handles_ != NULL); | 3455     ASSERT(handles_ != NULL); | 
| 3582   } | 3456   } | 
| 3583 | 3457 | 
| 3584   void Append(PersistentHandle* persistent_handle) { | 3458   void Append(PersistentHandle* persistent_handle) { | 
| 3585     JSONObject obj(handles_); | 3459     JSONObject obj(handles_); | 
| 3586     obj.AddProperty("type", "_PersistentHandle"); | 3460     obj.AddProperty("type", "_PersistentHandle"); | 
| 3587     const Object& object = Object::Handle(persistent_handle->raw()); | 3461     const Object& object = Object::Handle(persistent_handle->raw()); | 
| 3588     obj.AddProperty("object", object); | 3462     obj.AddProperty("object", object); | 
| 3589   } | 3463   } | 
| 3590 | 3464 | 
| 3591   void Append(FinalizablePersistentHandle* weak_persistent_handle) { | 3465   void Append(FinalizablePersistentHandle* weak_persistent_handle) { | 
| 3592     if (!weak_persistent_handle->raw()->IsHeapObject()) { | 3466     if (!weak_persistent_handle->raw()->IsHeapObject()) { | 
| 3593       return;  // Free handle. | 3467       return;  // Free handle. | 
| 3594     } | 3468     } | 
| 3595 | 3469 | 
| 3596     JSONObject obj(handles_); | 3470     JSONObject obj(handles_); | 
| 3597     obj.AddProperty("type", "_WeakPersistentHandle"); | 3471     obj.AddProperty("type", "_WeakPersistentHandle"); | 
| 3598     const Object& object = | 3472     const Object& object = Object::Handle(weak_persistent_handle->raw()); | 
| 3599         Object::Handle(weak_persistent_handle->raw()); |  | 
| 3600     obj.AddProperty("object", object); | 3473     obj.AddProperty("object", object); | 
|  | 3474     obj.AddPropertyF("peer", "0x%" Px "", reinterpret_cast<uintptr_t>( | 
|  | 3475                                               weak_persistent_handle->peer())); | 
| 3601     obj.AddPropertyF( | 3476     obj.AddPropertyF( | 
| 3602         "peer", | 3477         "callbackAddress", "0x%" Px "", | 
| 3603         "0x%" Px "", |  | 
| 3604         reinterpret_cast<uintptr_t>(weak_persistent_handle->peer())); |  | 
| 3605     obj.AddPropertyF( |  | 
| 3606         "callbackAddress", |  | 
| 3607         "0x%" Px "", |  | 
| 3608         reinterpret_cast<uintptr_t>(weak_persistent_handle->callback())); | 3478         reinterpret_cast<uintptr_t>(weak_persistent_handle->callback())); | 
| 3609     // Attempt to include a native symbol name. | 3479     // Attempt to include a native symbol name. | 
| 3610     char* name = NativeSymbolResolver::LookupSymbolName( | 3480     char* name = NativeSymbolResolver::LookupSymbolName( | 
| 3611         reinterpret_cast<uintptr_t>(weak_persistent_handle->callback()), | 3481         reinterpret_cast<uintptr_t>(weak_persistent_handle->callback()), NULL); | 
| 3612         NULL); | 3482     obj.AddProperty("callbackSymbolName", (name == NULL) ? "" : name); | 
| 3613     obj.AddProperty("callbackSymbolName", |  | 
| 3614                     (name == NULL) ? "" : name); |  | 
| 3615     if (name != NULL) { | 3483     if (name != NULL) { | 
| 3616       NativeSymbolResolver::FreeSymbolName(name); | 3484       NativeSymbolResolver::FreeSymbolName(name); | 
| 3617     } | 3485     } | 
| 3618     obj.AddPropertyF("externalSize", | 3486     obj.AddPropertyF("externalSize", "%" Pd "", | 
| 3619                      "%" Pd "", |  | 
| 3620                      weak_persistent_handle->external_size()); | 3487                      weak_persistent_handle->external_size()); | 
| 3621   } | 3488   } | 
| 3622 | 3489 | 
| 3623  protected: | 3490  protected: | 
| 3624   virtual void VisitHandle(uword addr) { | 3491   virtual void VisitHandle(uword addr) { | 
| 3625     T* handle = reinterpret_cast<T*>(addr); | 3492     T* handle = reinterpret_cast<T*>(addr); | 
| 3626     Append(handle); | 3493     Append(handle); | 
| 3627   } | 3494   } | 
| 3628 | 3495 | 
| 3629   JSONArray* handles_; | 3496   JSONArray* handles_; | 
| 3630 }; | 3497 }; | 
| 3631 | 3498 | 
| 3632 | 3499 | 
| 3633 static bool GetPersistentHandles(Thread* thread, JSONStream* js) { | 3500 static bool GetPersistentHandles(Thread* thread, JSONStream* js) { | 
| 3634   Isolate* isolate = thread->isolate(); | 3501   Isolate* isolate = thread->isolate(); | 
| 3635   ASSERT(isolate != NULL); | 3502   ASSERT(isolate != NULL); | 
| 3636 | 3503 | 
| 3637   ApiState* api_state = isolate->api_state(); | 3504   ApiState* api_state = isolate->api_state(); | 
| 3638   ASSERT(api_state != NULL); | 3505   ASSERT(api_state != NULL); | 
| 3639 | 3506 | 
| 3640   { | 3507   { | 
| 3641     JSONObject obj(js); | 3508     JSONObject obj(js); | 
| 3642     obj.AddProperty("type", "_PersistentHandles"); | 3509     obj.AddProperty("type", "_PersistentHandles"); | 
| 3643     // Persistent handles. | 3510     // Persistent handles. | 
| 3644     { | 3511     { | 
| 3645       JSONArray persistent_handles(&obj, "persistentHandles"); | 3512       JSONArray persistent_handles(&obj, "persistentHandles"); | 
| 3646       PersistentHandles& handles = api_state->persistent_handles(); | 3513       PersistentHandles& handles = api_state->persistent_handles(); | 
| 3647       PersistentHandleVisitor<PersistentHandle> visitor( | 3514       PersistentHandleVisitor<PersistentHandle> visitor(thread, | 
| 3648           thread, &persistent_handles); | 3515                                                         &persistent_handles); | 
| 3649       handles.Visit(&visitor); | 3516       handles.Visit(&visitor); | 
| 3650     } | 3517     } | 
| 3651     // Weak persistent handles. | 3518     // Weak persistent handles. | 
| 3652     { | 3519     { | 
| 3653       JSONArray weak_persistent_handles(&obj, "weakPersistentHandles"); | 3520       JSONArray weak_persistent_handles(&obj, "weakPersistentHandles"); | 
| 3654       FinalizablePersistentHandles& handles = | 3521       FinalizablePersistentHandles& handles = | 
| 3655           api_state->weak_persistent_handles(); | 3522           api_state->weak_persistent_handles(); | 
| 3656       PersistentHandleVisitor<FinalizablePersistentHandle> visitor( | 3523       PersistentHandleVisitor<FinalizablePersistentHandle> visitor( | 
| 3657           thread, &weak_persistent_handles); | 3524           thread, &weak_persistent_handles); | 
| 3658       handles.VisitHandles(&visitor); | 3525       handles.VisitHandles(&visitor); | 
| 3659     } | 3526     } | 
| 3660   } | 3527   } | 
| 3661 | 3528 | 
| 3662   return true; | 3529   return true; | 
| 3663 } | 3530 } | 
| 3664 | 3531 | 
| 3665 | 3532 | 
| 3666 static const MethodParameter* get_ports_params[] = { | 3533 static const MethodParameter* get_ports_params[] = { | 
| 3667   RUNNABLE_ISOLATE_PARAMETER, | 3534     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3668   NULL, |  | 
| 3669 }; | 3535 }; | 
| 3670 | 3536 | 
| 3671 | 3537 | 
| 3672 static bool GetPorts(Thread* thread, JSONStream* js) { | 3538 static bool GetPorts(Thread* thread, JSONStream* js) { | 
| 3673   MessageHandler* message_handler = thread->isolate()->message_handler(); | 3539   MessageHandler* message_handler = thread->isolate()->message_handler(); | 
| 3674   PortMap::PrintPortsForMessageHandler(message_handler, js); | 3540   PortMap::PrintPortsForMessageHandler(message_handler, js); | 
| 3675   return true; | 3541   return true; | 
| 3676 } | 3542 } | 
| 3677 | 3543 | 
| 3678 | 3544 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 3690 | 3556 | 
| 3691 | 3557 | 
| 3692 static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) { | 3558 static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) { | 
| 3693   JSONObject jsobj(js); | 3559   JSONObject jsobj(js); | 
| 3694   jsobj.AddProperty("bart", "simpson"); | 3560   jsobj.AddProperty("bart", "simpson"); | 
| 3695   return true; | 3561   return true; | 
| 3696 } | 3562 } | 
| 3697 | 3563 | 
| 3698 | 3564 | 
| 3699 static const MethodParameter* get_object_params[] = { | 3565 static const MethodParameter* get_object_params[] = { | 
| 3700   RUNNABLE_ISOLATE_PARAMETER, | 3566     RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("offset", false), | 
| 3701   new UIntParameter("offset", false), | 3567     new UIntParameter("count", false), NULL, | 
| 3702   new UIntParameter("count", false), |  | 
| 3703   NULL, |  | 
| 3704 }; | 3568 }; | 
| 3705 | 3569 | 
| 3706 | 3570 | 
| 3707 static bool GetObject(Thread* thread, JSONStream* js) { | 3571 static bool GetObject(Thread* thread, JSONStream* js) { | 
| 3708   const char* id = js->LookupParam("objectId"); | 3572   const char* id = js->LookupParam("objectId"); | 
| 3709   if (id == NULL) { | 3573   if (id == NULL) { | 
| 3710     PrintMissingParamError(js, "objectId"); | 3574     PrintMissingParamError(js, "objectId"); | 
| 3711     return true; | 3575     return true; | 
| 3712   } | 3576   } | 
| 3713   if (js->HasParam("offset")) { | 3577   if (js->HasParam("offset")) { | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3752     PrintSentinel(js, kCollectedSentinel); | 3616     PrintSentinel(js, kCollectedSentinel); | 
| 3753     return true; | 3617     return true; | 
| 3754   } | 3618   } | 
| 3755 | 3619 | 
| 3756   PrintInvalidParamError(js, "objectId"); | 3620   PrintInvalidParamError(js, "objectId"); | 
| 3757   return true; | 3621   return true; | 
| 3758 } | 3622 } | 
| 3759 | 3623 | 
| 3760 | 3624 | 
| 3761 static const MethodParameter* get_object_store_params[] = { | 3625 static const MethodParameter* get_object_store_params[] = { | 
| 3762   RUNNABLE_ISOLATE_PARAMETER, | 3626     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3763   NULL, |  | 
| 3764 }; | 3627 }; | 
| 3765 | 3628 | 
| 3766 | 3629 | 
| 3767 static bool GetObjectStore(Thread* thread, JSONStream* js) { | 3630 static bool GetObjectStore(Thread* thread, JSONStream* js) { | 
| 3768   JSONObject jsobj(js); | 3631   JSONObject jsobj(js); | 
| 3769   thread->isolate()->object_store()->PrintToJSONObject(&jsobj); | 3632   thread->isolate()->object_store()->PrintToJSONObject(&jsobj); | 
| 3770   return true; | 3633   return true; | 
| 3771 } | 3634 } | 
| 3772 | 3635 | 
| 3773 | 3636 | 
| 3774 static const MethodParameter* get_class_list_params[] = { | 3637 static const MethodParameter* get_class_list_params[] = { | 
| 3775   RUNNABLE_ISOLATE_PARAMETER, | 3638     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3776   NULL, |  | 
| 3777 }; | 3639 }; | 
| 3778 | 3640 | 
| 3779 | 3641 | 
| 3780 static bool GetClassList(Thread* thread, JSONStream* js) { | 3642 static bool GetClassList(Thread* thread, JSONStream* js) { | 
| 3781   ClassTable* table = thread->isolate()->class_table(); | 3643   ClassTable* table = thread->isolate()->class_table(); | 
| 3782   JSONObject jsobj(js); | 3644   JSONObject jsobj(js); | 
| 3783   table->PrintToJSONObject(&jsobj); | 3645   table->PrintToJSONObject(&jsobj); | 
| 3784   return true; | 3646   return true; | 
| 3785 } | 3647 } | 
| 3786 | 3648 | 
| 3787 | 3649 | 
| 3788 static const MethodParameter* get_type_arguments_list_params[] = { | 3650 static const MethodParameter* get_type_arguments_list_params[] = { | 
| 3789   RUNNABLE_ISOLATE_PARAMETER, | 3651     RUNNABLE_ISOLATE_PARAMETER, NULL, | 
| 3790   NULL, |  | 
| 3791 }; | 3652 }; | 
| 3792 | 3653 | 
| 3793 | 3654 | 
| 3794 static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) { | 3655 static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) { | 
| 3795   bool only_with_instantiations = false; | 3656   bool only_with_instantiations = false; | 
| 3796   if (js->ParamIs("onlyWithInstantiations", "true")) { | 3657   if (js->ParamIs("onlyWithInstantiations", "true")) { | 
| 3797     only_with_instantiations = true; | 3658     only_with_instantiations = true; | 
| 3798   } | 3659   } | 
| 3799   Zone* zone = thread->zone(); | 3660   Zone* zone = thread->zone(); | 
| 3800   ObjectStore* object_store = thread->isolate()->object_store(); | 3661   ObjectStore* object_store = thread->isolate()->object_store(); | 
| 3801   CanonicalTypeArgumentsSet typeargs_table( | 3662   CanonicalTypeArgumentsSet typeargs_table( | 
| 3802       zone, object_store->canonical_type_arguments()); | 3663       zone, object_store->canonical_type_arguments()); | 
| 3803   const intptr_t table_size = typeargs_table.NumEntries(); | 3664   const intptr_t table_size = typeargs_table.NumEntries(); | 
| 3804   const intptr_t table_used = typeargs_table.NumOccupied(); | 3665   const intptr_t table_used = typeargs_table.NumOccupied(); | 
| 3805   const Array& typeargs_array = Array::Handle( | 3666   const Array& typeargs_array = | 
| 3806       zone, HashTables::ToArray(typeargs_table, false)); | 3667       Array::Handle(zone, HashTables::ToArray(typeargs_table, false)); | 
| 3807   ASSERT(typeargs_array.Length() == table_used); | 3668   ASSERT(typeargs_array.Length() == table_used); | 
| 3808   TypeArguments& typeargs = TypeArguments::Handle(zone); | 3669   TypeArguments& typeargs = TypeArguments::Handle(zone); | 
| 3809   JSONObject jsobj(js); | 3670   JSONObject jsobj(js); | 
| 3810   jsobj.AddProperty("type", "TypeArgumentsList"); | 3671   jsobj.AddProperty("type", "TypeArgumentsList"); | 
| 3811   jsobj.AddProperty("canonicalTypeArgumentsTableSize", table_size); | 3672   jsobj.AddProperty("canonicalTypeArgumentsTableSize", table_size); | 
| 3812   jsobj.AddProperty("canonicalTypeArgumentsTableUsed", table_used); | 3673   jsobj.AddProperty("canonicalTypeArgumentsTableUsed", table_used); | 
| 3813   JSONArray members(&jsobj, "typeArguments"); | 3674   JSONArray members(&jsobj, "typeArguments"); | 
| 3814   for (intptr_t i = 0; i < table_used; i++) { | 3675   for (intptr_t i = 0; i < table_used; i++) { | 
| 3815     typeargs ^= typeargs_array.At(i); | 3676     typeargs ^= typeargs_array.At(i); | 
| 3816     if (!typeargs.IsNull()) { | 3677     if (!typeargs.IsNull()) { | 
| 3817       if (!only_with_instantiations || typeargs.HasInstantiations()) { | 3678       if (!only_with_instantiations || typeargs.HasInstantiations()) { | 
| 3818         members.AddValue(typeargs); | 3679         members.AddValue(typeargs); | 
| 3819       } | 3680       } | 
| 3820     } | 3681     } | 
| 3821   } | 3682   } | 
| 3822   typeargs_table.Release(); | 3683   typeargs_table.Release(); | 
| 3823   return true; | 3684   return true; | 
| 3824 } | 3685 } | 
| 3825 | 3686 | 
| 3826 | 3687 | 
| 3827 static const MethodParameter* get_version_params[] = { | 3688 static const MethodParameter* get_version_params[] = { | 
| 3828   NO_ISOLATE_PARAMETER, | 3689     NO_ISOLATE_PARAMETER, NULL, | 
| 3829   NULL, |  | 
| 3830 }; | 3690 }; | 
| 3831 | 3691 | 
| 3832 | 3692 | 
| 3833 static bool GetVersion(Thread* thread, JSONStream* js) { | 3693 static bool GetVersion(Thread* thread, JSONStream* js) { | 
| 3834   JSONObject jsobj(js); | 3694   JSONObject jsobj(js); | 
| 3835   jsobj.AddProperty("type", "Version"); | 3695   jsobj.AddProperty("type", "Version"); | 
| 3836   jsobj.AddProperty("major", | 3696   jsobj.AddProperty("major", | 
| 3837                     static_cast<intptr_t>(SERVICE_PROTOCOL_MAJOR_VERSION)); | 3697                     static_cast<intptr_t>(SERVICE_PROTOCOL_MAJOR_VERSION)); | 
| 3838   jsobj.AddProperty("minor", | 3698   jsobj.AddProperty("minor", | 
| 3839                     static_cast<intptr_t>(SERVICE_PROTOCOL_MINOR_VERSION)); | 3699                     static_cast<intptr_t>(SERVICE_PROTOCOL_MINOR_VERSION)); | 
| 3840   jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0)); | 3700   jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0)); | 
| 3841   jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0)); | 3701   jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0)); | 
| 3842   return true; | 3702   return true; | 
| 3843 } | 3703 } | 
| 3844 | 3704 | 
| 3845 | 3705 | 
| 3846 class ServiceIsolateVisitor : public IsolateVisitor { | 3706 class ServiceIsolateVisitor : public IsolateVisitor { | 
| 3847  public: | 3707  public: | 
| 3848   explicit ServiceIsolateVisitor(JSONArray* jsarr) | 3708   explicit ServiceIsolateVisitor(JSONArray* jsarr) : jsarr_(jsarr) {} | 
| 3849       : jsarr_(jsarr) { |  | 
| 3850   } |  | 
| 3851 | 3709 | 
| 3852   virtual ~ServiceIsolateVisitor() {} | 3710   virtual ~ServiceIsolateVisitor() {} | 
| 3853 | 3711 | 
| 3854   void VisitIsolate(Isolate* isolate) { | 3712   void VisitIsolate(Isolate* isolate) { | 
| 3855     if ((isolate != Dart::vm_isolate()) && | 3713     if ((isolate != Dart::vm_isolate()) && | 
| 3856         !ServiceIsolate::IsServiceIsolateDescendant(isolate)) { | 3714         !ServiceIsolate::IsServiceIsolateDescendant(isolate)) { | 
| 3857       jsarr_->AddValue(isolate); | 3715       jsarr_->AddValue(isolate); | 
| 3858     } | 3716     } | 
| 3859   } | 3717   } | 
| 3860 | 3718 | 
| 3861  private: | 3719  private: | 
| 3862   JSONArray* jsarr_; | 3720   JSONArray* jsarr_; | 
| 3863 }; | 3721 }; | 
| 3864 | 3722 | 
| 3865 | 3723 | 
| 3866 static const MethodParameter* get_vm_params[] = { | 3724 static const MethodParameter* get_vm_params[] = { | 
| 3867   NO_ISOLATE_PARAMETER, | 3725     NO_ISOLATE_PARAMETER, NULL, | 
| 3868   NULL, |  | 
| 3869 }; | 3726 }; | 
| 3870 | 3727 | 
| 3871 | 3728 | 
| 3872 void Service::PrintJSONForVM(JSONStream* js, bool ref) { | 3729 void Service::PrintJSONForVM(JSONStream* js, bool ref) { | 
| 3873   JSONObject jsobj(js); | 3730   JSONObject jsobj(js); | 
| 3874   jsobj.AddProperty("type", (ref ? "@VM" : "VM")); | 3731   jsobj.AddProperty("type", (ref ? "@VM" : "VM")); | 
| 3875   jsobj.AddProperty("name", GetVMName()); | 3732   jsobj.AddProperty("name", GetVMName()); | 
| 3876   if (ref) { | 3733   if (ref) { | 
| 3877     return; | 3734     return; | 
| 3878   } | 3735   } | 
| 3879   Isolate* vm_isolate = Dart::vm_isolate(); | 3736   Isolate* vm_isolate = Dart::vm_isolate(); | 
| 3880   jsobj.AddProperty("architectureBits", static_cast<intptr_t>(kBitsPerWord)); | 3737   jsobj.AddProperty("architectureBits", static_cast<intptr_t>(kBitsPerWord)); | 
| 3881   jsobj.AddProperty("targetCPU", CPU::Id()); | 3738   jsobj.AddProperty("targetCPU", CPU::Id()); | 
| 3882   jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware()); | 3739   jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware()); | 
| 3883   jsobj.AddProperty("version", Version::String()); | 3740   jsobj.AddProperty("version", Version::String()); | 
| 3884   jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart"); | 3741   jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart"); | 
| 3885   jsobj.AddProperty64("pid", OS::ProcessId()); | 3742   jsobj.AddProperty64("pid", OS::ProcessId()); | 
| 3886   jsobj.AddProperty64("_maxRSS", OS::MaxRSS()); | 3743   jsobj.AddProperty64("_maxRSS", OS::MaxRSS()); | 
| 3887   int64_t start_time_millis = (vm_isolate->start_time() / | 3744   int64_t start_time_millis = | 
| 3888                                kMicrosecondsPerMillisecond); | 3745       (vm_isolate->start_time() / kMicrosecondsPerMillisecond); | 
| 3889   jsobj.AddPropertyTimeMillis("startTime", start_time_millis); | 3746   jsobj.AddPropertyTimeMillis("startTime", start_time_millis); | 
| 3890   // Construct the isolate list. | 3747   // Construct the isolate list. | 
| 3891   { | 3748   { | 
| 3892     JSONArray jsarr(&jsobj, "isolates"); | 3749     JSONArray jsarr(&jsobj, "isolates"); | 
| 3893     ServiceIsolateVisitor visitor(&jsarr); | 3750     ServiceIsolateVisitor visitor(&jsarr); | 
| 3894     Isolate::VisitIsolates(&visitor); | 3751     Isolate::VisitIsolates(&visitor); | 
| 3895   } | 3752   } | 
| 3896 } | 3753 } | 
| 3897 | 3754 | 
| 3898 | 3755 | 
| 3899 static bool GetVM(Thread* thread, JSONStream* js) { | 3756 static bool GetVM(Thread* thread, JSONStream* js) { | 
| 3900   Service::PrintJSONForVM(js, false); | 3757   Service::PrintJSONForVM(js, false); | 
| 3901   return true; | 3758   return true; | 
| 3902 } | 3759 } | 
| 3903 | 3760 | 
| 3904 | 3761 | 
| 3905 static const MethodParameter* restart_vm_params[] = { | 3762 static const MethodParameter* restart_vm_params[] = { | 
| 3906   NO_ISOLATE_PARAMETER, | 3763     NO_ISOLATE_PARAMETER, NULL, | 
| 3907   NULL, |  | 
| 3908 }; | 3764 }; | 
| 3909 | 3765 | 
| 3910 | 3766 | 
| 3911 static bool RestartVM(Thread* thread, JSONStream* js) { | 3767 static bool RestartVM(Thread* thread, JSONStream* js) { | 
| 3912   Isolate::KillAllIsolates(Isolate::kVMRestartMsg); | 3768   Isolate::KillAllIsolates(Isolate::kVMRestartMsg); | 
| 3913   PrintSuccess(js); | 3769   PrintSuccess(js); | 
| 3914   return true; | 3770   return true; | 
| 3915 } | 3771 } | 
| 3916 | 3772 | 
| 3917 | 3773 | 
| 3918 static const char* exception_pause_mode_names[] = { | 3774 static const char* exception_pause_mode_names[] = { | 
| 3919   "All", | 3775     "All", "None", "Unhandled", NULL, | 
| 3920   "None", |  | 
| 3921   "Unhandled", |  | 
| 3922   NULL, |  | 
| 3923 }; | 3776 }; | 
| 3924 | 3777 | 
| 3925 | 3778 | 
| 3926 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = { | 3779 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = { | 
| 3927   kPauseOnAllExceptions, | 3780     kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions, | 
| 3928   kNoPauseOnExceptions, | 3781     kInvalidExceptionPauseInfo, | 
| 3929   kPauseOnUnhandledExceptions, |  | 
| 3930   kInvalidExceptionPauseInfo, |  | 
| 3931 }; | 3782 }; | 
| 3932 | 3783 | 
| 3933 | 3784 | 
| 3934 static const MethodParameter* set_exception_pause_mode_params[] = { | 3785 static const MethodParameter* set_exception_pause_mode_params[] = { | 
| 3935   ISOLATE_PARAMETER, | 3786     ISOLATE_PARAMETER, | 
| 3936   new EnumParameter("mode", true, exception_pause_mode_names), | 3787     new EnumParameter("mode", true, exception_pause_mode_names), NULL, | 
| 3937   NULL, |  | 
| 3938 }; | 3788 }; | 
| 3939 | 3789 | 
| 3940 | 3790 | 
| 3941 static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) { | 3791 static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) { | 
| 3942   const char* mode = js->LookupParam("mode"); | 3792   const char* mode = js->LookupParam("mode"); | 
| 3943   if (mode == NULL) { | 3793   if (mode == NULL) { | 
| 3944     PrintMissingParamError(js, "mode"); | 3794     PrintMissingParamError(js, "mode"); | 
| 3945     return true; | 3795     return true; | 
| 3946   } | 3796   } | 
| 3947   Dart_ExceptionPauseInfo info = | 3797   Dart_ExceptionPauseInfo info = | 
| 3948       EnumMapper(mode, exception_pause_mode_names, exception_pause_mode_values); | 3798       EnumMapper(mode, exception_pause_mode_names, exception_pause_mode_values); | 
| 3949   if (info == kInvalidExceptionPauseInfo) { | 3799   if (info == kInvalidExceptionPauseInfo) { | 
| 3950     PrintInvalidParamError(js, "mode"); | 3800     PrintInvalidParamError(js, "mode"); | 
| 3951     return true; | 3801     return true; | 
| 3952   } | 3802   } | 
| 3953   Isolate* isolate = thread->isolate(); | 3803   Isolate* isolate = thread->isolate(); | 
| 3954   isolate->debugger()->SetExceptionPauseInfo(info); | 3804   isolate->debugger()->SetExceptionPauseInfo(info); | 
| 3955   if (Service::debug_stream.enabled()) { | 3805   if (Service::debug_stream.enabled()) { | 
| 3956     ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate); | 3806     ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate); | 
| 3957     Service::HandleEvent(&event); | 3807     Service::HandleEvent(&event); | 
| 3958   } | 3808   } | 
| 3959   PrintSuccess(js); | 3809   PrintSuccess(js); | 
| 3960   return true; | 3810   return true; | 
| 3961 } | 3811 } | 
| 3962 | 3812 | 
| 3963 | 3813 | 
| 3964 static const MethodParameter* get_flag_list_params[] = { | 3814 static const MethodParameter* get_flag_list_params[] = { | 
| 3965   NO_ISOLATE_PARAMETER, | 3815     NO_ISOLATE_PARAMETER, NULL, | 
| 3966   NULL, |  | 
| 3967 }; | 3816 }; | 
| 3968 | 3817 | 
| 3969 | 3818 | 
| 3970 static bool GetFlagList(Thread* thread, JSONStream* js) { | 3819 static bool GetFlagList(Thread* thread, JSONStream* js) { | 
| 3971   Flags::PrintJSON(js); | 3820   Flags::PrintJSON(js); | 
| 3972   return true; | 3821   return true; | 
| 3973 } | 3822 } | 
| 3974 | 3823 | 
| 3975 | 3824 | 
| 3976 static const MethodParameter* set_flags_params[] = { | 3825 static const MethodParameter* set_flags_params[] = { | 
| 3977   NO_ISOLATE_PARAMETER, | 3826     NO_ISOLATE_PARAMETER, NULL, | 
| 3978   NULL, |  | 
| 3979 }; | 3827 }; | 
| 3980 | 3828 | 
| 3981 | 3829 | 
| 3982 static bool SetFlag(Thread* thread, JSONStream* js) { | 3830 static bool SetFlag(Thread* thread, JSONStream* js) { | 
| 3983   const char* flag_name = js->LookupParam("name"); | 3831   const char* flag_name = js->LookupParam("name"); | 
| 3984   if (flag_name == NULL) { | 3832   if (flag_name == NULL) { | 
| 3985     PrintMissingParamError(js, "name"); | 3833     PrintMissingParamError(js, "name"); | 
| 3986     return true; | 3834     return true; | 
| 3987   } | 3835   } | 
| 3988   const char* flag_value = js->LookupParam("value"); | 3836   const char* flag_value = js->LookupParam("value"); | 
| 3989   if (flag_value == NULL) { | 3837   if (flag_value == NULL) { | 
| 3990     PrintMissingParamError(js, "value"); | 3838     PrintMissingParamError(js, "value"); | 
| 3991     return true; | 3839     return true; | 
| 3992   } | 3840   } | 
| 3993   const char* error = NULL; | 3841   const char* error = NULL; | 
| 3994   if (Flags::SetFlag(flag_name, flag_value, &error)) { | 3842   if (Flags::SetFlag(flag_name, flag_value, &error)) { | 
| 3995     PrintSuccess(js); | 3843     PrintSuccess(js); | 
| 3996     return true; | 3844     return true; | 
| 3997   } else { | 3845   } else { | 
| 3998     JSONObject jsobj(js); | 3846     JSONObject jsobj(js); | 
| 3999     jsobj.AddProperty("type", "Error"); | 3847     jsobj.AddProperty("type", "Error"); | 
| 4000     jsobj.AddProperty("message", error); | 3848     jsobj.AddProperty("message", error); | 
| 4001     return true; | 3849     return true; | 
| 4002   } | 3850   } | 
| 4003 } | 3851 } | 
| 4004 | 3852 | 
| 4005 | 3853 | 
| 4006 static const MethodParameter* set_library_debuggable_params[] = { | 3854 static const MethodParameter* set_library_debuggable_params[] = { | 
| 4007   RUNNABLE_ISOLATE_PARAMETER, | 3855     RUNNABLE_ISOLATE_PARAMETER, new IdParameter("libraryId", true), | 
| 4008   new IdParameter("libraryId", true), | 3856     new BoolParameter("isDebuggable", true), NULL, | 
| 4009   new BoolParameter("isDebuggable", true), |  | 
| 4010   NULL, |  | 
| 4011 }; | 3857 }; | 
| 4012 | 3858 | 
| 4013 | 3859 | 
| 4014 static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) { | 3860 static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) { | 
| 4015   const char* lib_id = js->LookupParam("libraryId"); | 3861   const char* lib_id = js->LookupParam("libraryId"); | 
| 4016   ObjectIdRing::LookupResult lookup_result; | 3862   ObjectIdRing::LookupResult lookup_result; | 
| 4017   Object& obj = Object::Handle(LookupHeapObject(thread, lib_id, | 3863   Object& obj = | 
| 4018                                                 &lookup_result)); | 3864       Object::Handle(LookupHeapObject(thread, lib_id, &lookup_result)); | 
| 4019   const bool is_debuggable = | 3865   const bool is_debuggable = | 
| 4020       BoolParameter::Parse(js->LookupParam("isDebuggable"), false); | 3866       BoolParameter::Parse(js->LookupParam("isDebuggable"), false); | 
| 4021   if (obj.IsLibrary()) { | 3867   if (obj.IsLibrary()) { | 
| 4022     const Library& lib = Library::Cast(obj); | 3868     const Library& lib = Library::Cast(obj); | 
| 4023     if (lib.is_dart_scheme()) { | 3869     if (lib.is_dart_scheme()) { | 
| 4024       const String& url = String::Handle(lib.url()); | 3870       const String& url = String::Handle(lib.url()); | 
| 4025       if (url.StartsWith(Symbols::DartSchemePrivate())) { | 3871       if (url.StartsWith(Symbols::DartSchemePrivate())) { | 
| 4026         PrintIllegalParamError(js, "libraryId"); | 3872         PrintIllegalParamError(js, "libraryId"); | 
| 4027         return true; | 3873         return true; | 
| 4028       } | 3874       } | 
| 4029     } | 3875     } | 
| 4030     lib.set_debuggable(is_debuggable); | 3876     lib.set_debuggable(is_debuggable); | 
| 4031     PrintSuccess(js); | 3877     PrintSuccess(js); | 
| 4032     return true; | 3878     return true; | 
| 4033   } | 3879   } | 
| 4034   PrintInvalidParamError(js, "libraryId"); | 3880   PrintInvalidParamError(js, "libraryId"); | 
| 4035   return true; | 3881   return true; | 
| 4036 } | 3882 } | 
| 4037 | 3883 | 
| 4038 | 3884 | 
| 4039 static const MethodParameter* set_name_params[] = { | 3885 static const MethodParameter* set_name_params[] = { | 
| 4040   ISOLATE_PARAMETER, | 3886     ISOLATE_PARAMETER, new MethodParameter("name", true), NULL, | 
| 4041   new MethodParameter("name", true), |  | 
| 4042   NULL, |  | 
| 4043 }; | 3887 }; | 
| 4044 | 3888 | 
| 4045 | 3889 | 
| 4046 static bool SetName(Thread* thread, JSONStream* js) { | 3890 static bool SetName(Thread* thread, JSONStream* js) { | 
| 4047   Isolate* isolate = thread->isolate(); | 3891   Isolate* isolate = thread->isolate(); | 
| 4048   isolate->set_debugger_name(js->LookupParam("name")); | 3892   isolate->set_debugger_name(js->LookupParam("name")); | 
| 4049   if (Service::isolate_stream.enabled()) { | 3893   if (Service::isolate_stream.enabled()) { | 
| 4050     ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); | 3894     ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); | 
| 4051     Service::HandleEvent(&event); | 3895     Service::HandleEvent(&event); | 
| 4052   } | 3896   } | 
| 4053   PrintSuccess(js); | 3897   PrintSuccess(js); | 
| 4054   return true; | 3898   return true; | 
| 4055 } | 3899 } | 
| 4056 | 3900 | 
| 4057 | 3901 | 
| 4058 static const MethodParameter* set_vm_name_params[] = { | 3902 static const MethodParameter* set_vm_name_params[] = { | 
| 4059   NO_ISOLATE_PARAMETER, | 3903     NO_ISOLATE_PARAMETER, new MethodParameter("name", true), NULL, | 
| 4060   new MethodParameter("name", true), |  | 
| 4061   NULL, |  | 
| 4062 }; | 3904 }; | 
| 4063 | 3905 | 
| 4064 | 3906 | 
| 4065 static bool SetVMName(Thread* thread, JSONStream* js) { | 3907 static bool SetVMName(Thread* thread, JSONStream* js) { | 
| 4066   const char* name_param = js->LookupParam("name"); | 3908   const char* name_param = js->LookupParam("name"); | 
| 4067   free(vm_name); | 3909   free(vm_name); | 
| 4068   vm_name = strdup(name_param); | 3910   vm_name = strdup(name_param); | 
| 4069   if (Service::vm_stream.enabled()) { | 3911   if (Service::vm_stream.enabled()) { | 
| 4070     ServiceEvent event(NULL, ServiceEvent::kVMUpdate); | 3912     ServiceEvent event(NULL, ServiceEvent::kVMUpdate); | 
| 4071     Service::HandleEvent(&event); | 3913     Service::HandleEvent(&event); | 
| 4072   } | 3914   } | 
| 4073   PrintSuccess(js); | 3915   PrintSuccess(js); | 
| 4074   return true; | 3916   return true; | 
| 4075 } | 3917 } | 
| 4076 | 3918 | 
| 4077 | 3919 | 
| 4078 static const MethodParameter* set_trace_class_allocation_params[] = { | 3920 static const MethodParameter* set_trace_class_allocation_params[] = { | 
| 4079   RUNNABLE_ISOLATE_PARAMETER, | 3921     RUNNABLE_ISOLATE_PARAMETER, new IdParameter("classId", true), | 
| 4080   new IdParameter("classId", true), | 3922     new BoolParameter("enable", true), NULL, | 
| 4081   new BoolParameter("enable", true), |  | 
| 4082   NULL, |  | 
| 4083 }; | 3923 }; | 
| 4084 | 3924 | 
| 4085 | 3925 | 
| 4086 static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) { | 3926 static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) { | 
| 4087   if (!thread->isolate()->compilation_allowed()) { | 3927   if (!thread->isolate()->compilation_allowed()) { | 
| 4088     js->PrintError(kFeatureDisabled, | 3928     js->PrintError( | 
|  | 3929         kFeatureDisabled, | 
| 4089         "Cannot trace allocation when running a precompiled program."); | 3930         "Cannot trace allocation when running a precompiled program."); | 
| 4090     return true; | 3931     return true; | 
| 4091   } | 3932   } | 
| 4092   const char* class_id = js->LookupParam("classId"); | 3933   const char* class_id = js->LookupParam("classId"); | 
| 4093   const bool enable = BoolParameter::Parse(js->LookupParam("enable")); | 3934   const bool enable = BoolParameter::Parse(js->LookupParam("enable")); | 
| 4094   intptr_t cid = -1; | 3935   intptr_t cid = -1; | 
| 4095   GetPrefixedIntegerId(class_id, "classes/", &cid); | 3936   GetPrefixedIntegerId(class_id, "classes/", &cid); | 
| 4096   Isolate* isolate = thread->isolate(); | 3937   Isolate* isolate = thread->isolate(); | 
| 4097   if (!IsValidClassId(isolate, cid)) { | 3938   if (!IsValidClassId(isolate, cid)) { | 
| 4098     PrintInvalidParamError(js, "classId"); | 3939     PrintInvalidParamError(js, "classId"); | 
| 4099     return true; | 3940     return true; | 
| 4100   } | 3941   } | 
| 4101   const Class& cls = Class::Handle(GetClassForId(isolate, cid)); | 3942   const Class& cls = Class::Handle(GetClassForId(isolate, cid)); | 
| 4102   ASSERT(!cls.IsNull()); | 3943   ASSERT(!cls.IsNull()); | 
| 4103   cls.SetTraceAllocation(enable); | 3944   cls.SetTraceAllocation(enable); | 
| 4104   PrintSuccess(js); | 3945   PrintSuccess(js); | 
| 4105   return true; | 3946   return true; | 
| 4106 } | 3947 } | 
| 4107 | 3948 | 
| 4108 | 3949 | 
|  | 3950 // clang-format off | 
| 4109 static const ServiceMethodDescriptor service_methods_[] = { | 3951 static const ServiceMethodDescriptor service_methods_[] = { | 
| 4110   { "_dumpIdZone", DumpIdZone, NULL }, | 3952   { "_dumpIdZone", DumpIdZone, NULL }, | 
| 4111   { "_echo", Echo, | 3953   { "_echo", Echo, | 
| 4112     NULL }, | 3954     NULL }, | 
| 4113   { "_respondWithMalformedJson", RespondWithMalformedJson, | 3955   { "_respondWithMalformedJson", RespondWithMalformedJson, | 
| 4114     NULL }, | 3956     NULL }, | 
| 4115   { "_respondWithMalformedObject", RespondWithMalformedObject, | 3957   { "_respondWithMalformedObject", RespondWithMalformedObject, | 
| 4116     NULL }, | 3958     NULL }, | 
| 4117   { "_triggerEchoEvent", TriggerEchoEvent, | 3959   { "_triggerEchoEvent", TriggerEchoEvent, | 
| 4118     NULL }, | 3960     NULL }, | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4214     set_library_debuggable_params }, | 4056     set_library_debuggable_params }, | 
| 4215   { "setName", SetName, | 4057   { "setName", SetName, | 
| 4216     set_name_params }, | 4058     set_name_params }, | 
| 4217   { "_setTraceClassAllocation", SetTraceClassAllocation, | 4059   { "_setTraceClassAllocation", SetTraceClassAllocation, | 
| 4218     set_trace_class_allocation_params }, | 4060     set_trace_class_allocation_params }, | 
| 4219   { "setVMName", SetVMName, | 4061   { "setVMName", SetVMName, | 
| 4220     set_vm_name_params }, | 4062     set_vm_name_params }, | 
| 4221   { "_setVMTimelineFlags", SetVMTimelineFlags, | 4063   { "_setVMTimelineFlags", SetVMTimelineFlags, | 
| 4222     set_vm_timeline_flags_params }, | 4064     set_vm_timeline_flags_params }, | 
| 4223 }; | 4065 }; | 
| 4224 | 4066 // clang-format on | 
| 4225 | 4067 | 
| 4226 const ServiceMethodDescriptor* FindMethod(const char* method_name) { | 4068 const ServiceMethodDescriptor* FindMethod(const char* method_name) { | 
| 4227   intptr_t num_methods = sizeof(service_methods_) / | 4069   intptr_t num_methods = sizeof(service_methods_) / sizeof(service_methods_[0]); | 
| 4228                          sizeof(service_methods_[0]); |  | 
| 4229   for (intptr_t i = 0; i < num_methods; i++) { | 4070   for (intptr_t i = 0; i < num_methods; i++) { | 
| 4230     const ServiceMethodDescriptor& method = service_methods_[i]; | 4071     const ServiceMethodDescriptor& method = service_methods_[i]; | 
| 4231     if (strcmp(method_name, method.name) == 0) { | 4072     if (strcmp(method_name, method.name) == 0) { | 
| 4232       return &method; | 4073       return &method; | 
| 4233     } | 4074     } | 
| 4234   } | 4075   } | 
| 4235   return NULL; | 4076   return NULL; | 
| 4236 } | 4077 } | 
| 4237 | 4078 | 
| 4238 #endif  // !PRODUCT | 4079 #endif  // !PRODUCT | 
| 4239 | 4080 | 
| 4240 }  // namespace dart | 4081 }  // namespace dart | 
| OLD | NEW | 
|---|