Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(887)

Side by Side Diff: runtime/vm/service.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/service.h ('k') | runtime/vm/service_event.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 28 matching lines...) Expand all
39 #include "vm/symbols.h" 39 #include "vm/symbols.h"
40 #include "vm/timeline.h" 40 #include "vm/timeline.h"
41 #include "vm/type_table.h" 41 #include "vm/type_table.h"
42 #include "vm/unicode.h" 42 #include "vm/unicode.h"
43 #include "vm/version.h" 43 #include "vm/version.h"
44 44
45 namespace dart { 45 namespace dart {
46 46
47 #define Z (T->zone()) 47 #define Z (T->zone())
48 48
49
50 DECLARE_FLAG(bool, trace_service); 49 DECLARE_FLAG(bool, trace_service);
51 DECLARE_FLAG(bool, trace_service_pause_events); 50 DECLARE_FLAG(bool, trace_service_pause_events);
52 DECLARE_FLAG(bool, profile_vm); 51 DECLARE_FLAG(bool, profile_vm);
53 DEFINE_FLAG(charp, 52 DEFINE_FLAG(charp,
54 vm_name, 53 vm_name,
55 "vm", 54 "vm",
56 "The default name of this vm as reported by the VM service " 55 "The default name of this vm as reported by the VM service "
57 "protocol"); 56 "protocol");
58 57
59 DEFINE_FLAG(bool, 58 DEFINE_FLAG(bool,
60 warn_on_pause_with_no_debugger, 59 warn_on_pause_with_no_debugger,
61 false, 60 false,
62 "Print a message when an isolate is paused but there is no " 61 "Print a message when an isolate is paused but there is no "
63 "debugger attached."); 62 "debugger attached.");
64 63
65 DECLARE_FLAG(bool, show_kernel_isolate); 64 DECLARE_FLAG(bool, show_kernel_isolate);
66 65
67 #ifndef PRODUCT 66 #ifndef PRODUCT
68 // The name of this of this vm as reported by the VM service protocol. 67 // The name of this of this vm as reported by the VM service protocol.
69 static char* vm_name = NULL; 68 static char* vm_name = NULL;
70 69
71
72 static const char* GetVMName() { 70 static const char* GetVMName() {
73 if (vm_name == NULL) { 71 if (vm_name == NULL) {
74 return FLAG_vm_name; 72 return FLAG_vm_name;
75 } 73 }
76 return vm_name; 74 return vm_name;
77 } 75 }
78 76
79
80 ServiceIdZone::ServiceIdZone() {} 77 ServiceIdZone::ServiceIdZone() {}
81 78
82
83 ServiceIdZone::~ServiceIdZone() {} 79 ServiceIdZone::~ServiceIdZone() {}
84 80
85
86 RingServiceIdZone::RingServiceIdZone() 81 RingServiceIdZone::RingServiceIdZone()
87 : ring_(NULL), policy_(ObjectIdRing::kAllocateId) {} 82 : ring_(NULL), policy_(ObjectIdRing::kAllocateId) {}
88 83
89
90 RingServiceIdZone::~RingServiceIdZone() {} 84 RingServiceIdZone::~RingServiceIdZone() {}
91 85
92
93 void RingServiceIdZone::Init(ObjectIdRing* ring, 86 void RingServiceIdZone::Init(ObjectIdRing* ring,
94 ObjectIdRing::IdPolicy policy) { 87 ObjectIdRing::IdPolicy policy) {
95 ring_ = ring; 88 ring_ = ring;
96 policy_ = policy; 89 policy_ = policy;
97 } 90 }
98 91
99
100 char* RingServiceIdZone::GetServiceId(const Object& obj) { 92 char* RingServiceIdZone::GetServiceId(const Object& obj) {
101 ASSERT(ring_ != NULL); 93 ASSERT(ring_ != NULL);
102 Thread* thread = Thread::Current(); 94 Thread* thread = Thread::Current();
103 Zone* zone = thread->zone(); 95 Zone* zone = thread->zone();
104 ASSERT(zone != NULL); 96 ASSERT(zone != NULL);
105 const intptr_t id = ring_->GetIdForObject(obj.raw(), policy_); 97 const intptr_t id = ring_->GetIdForObject(obj.raw(), policy_);
106 return zone->PrintToString("objects/%" Pd "", id); 98 return zone->PrintToString("objects/%" Pd "", id);
107 } 99 }
108 100
109
110 // TODO(johnmccutchan): Unify embedder service handler lists and their APIs. 101 // TODO(johnmccutchan): Unify embedder service handler lists and their APIs.
111 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; 102 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL;
112 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; 103 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
113 struct ServiceMethodDescriptor; 104 struct ServiceMethodDescriptor;
114 const ServiceMethodDescriptor* FindMethod(const char* method_name); 105 const ServiceMethodDescriptor* FindMethod(const char* method_name);
115 106
116
117 // Support for streams defined in embedders. 107 // Support for streams defined in embedders.
118 Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL; 108 Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL;
119 Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL; 109 Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL;
120 Dart_GetVMServiceAssetsArchive Service::get_service_assets_callback_ = NULL; 110 Dart_GetVMServiceAssetsArchive Service::get_service_assets_callback_ = NULL;
121 111
122 // These are the set of streams known to the core VM. 112 // These are the set of streams known to the core VM.
123 StreamInfo Service::vm_stream("VM"); 113 StreamInfo Service::vm_stream("VM");
124 StreamInfo Service::isolate_stream("Isolate"); 114 StreamInfo Service::isolate_stream("Isolate");
125 StreamInfo Service::debug_stream("Debug"); 115 StreamInfo Service::debug_stream("Debug");
126 StreamInfo Service::gc_stream("GC"); 116 StreamInfo Service::gc_stream("GC");
127 StreamInfo Service::echo_stream("_Echo"); 117 StreamInfo Service::echo_stream("_Echo");
128 StreamInfo Service::graph_stream("_Graph"); 118 StreamInfo Service::graph_stream("_Graph");
129 StreamInfo Service::logging_stream("_Logging"); 119 StreamInfo Service::logging_stream("_Logging");
130 StreamInfo Service::extension_stream("Extension"); 120 StreamInfo Service::extension_stream("Extension");
131 StreamInfo Service::timeline_stream("Timeline"); 121 StreamInfo Service::timeline_stream("Timeline");
132 StreamInfo Service::editor_stream("_Editor"); 122 StreamInfo Service::editor_stream("_Editor");
133 123
134 static StreamInfo* streams_[] = { 124 static StreamInfo* streams_[] = {
135 &Service::vm_stream, &Service::isolate_stream, 125 &Service::vm_stream, &Service::isolate_stream,
136 &Service::debug_stream, &Service::gc_stream, 126 &Service::debug_stream, &Service::gc_stream,
137 &Service::echo_stream, &Service::graph_stream, 127 &Service::echo_stream, &Service::graph_stream,
138 &Service::logging_stream, &Service::extension_stream, 128 &Service::logging_stream, &Service::extension_stream,
139 &Service::timeline_stream, &Service::editor_stream}; 129 &Service::timeline_stream, &Service::editor_stream};
140 130
141
142 bool Service::ListenStream(const char* stream_id) { 131 bool Service::ListenStream(const char* stream_id) {
143 if (FLAG_trace_service) { 132 if (FLAG_trace_service) {
144 OS::Print("vm-service: starting stream '%s'\n", stream_id); 133 OS::Print("vm-service: starting stream '%s'\n", stream_id);
145 } 134 }
146 intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]); 135 intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]);
147 for (intptr_t i = 0; i < num_streams; i++) { 136 for (intptr_t i = 0; i < num_streams; i++) {
148 if (strcmp(stream_id, streams_[i]->id()) == 0) { 137 if (strcmp(stream_id, streams_[i]->id()) == 0) {
149 streams_[i]->set_enabled(true); 138 streams_[i]->set_enabled(true);
150 return true; 139 return true;
151 } 140 }
152 } 141 }
153 if (stream_listen_callback_) { 142 if (stream_listen_callback_) {
154 Thread* T = Thread::Current(); 143 Thread* T = Thread::Current();
155 TransitionVMToNative transition(T); 144 TransitionVMToNative transition(T);
156 return (*stream_listen_callback_)(stream_id); 145 return (*stream_listen_callback_)(stream_id);
157 } 146 }
158 return false; 147 return false;
159 } 148 }
160 149
161
162 void Service::CancelStream(const char* stream_id) { 150 void Service::CancelStream(const char* stream_id) {
163 if (FLAG_trace_service) { 151 if (FLAG_trace_service) {
164 OS::Print("vm-service: stopping stream '%s'\n", stream_id); 152 OS::Print("vm-service: stopping stream '%s'\n", stream_id);
165 } 153 }
166 intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]); 154 intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]);
167 for (intptr_t i = 0; i < num_streams; i++) { 155 for (intptr_t i = 0; i < num_streams; i++) {
168 if (strcmp(stream_id, streams_[i]->id()) == 0) { 156 if (strcmp(stream_id, streams_[i]->id()) == 0) {
169 streams_[i]->set_enabled(false); 157 streams_[i]->set_enabled(false);
170 return; 158 return;
171 } 159 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 const String& error_message = String::Handle( 193 const String& error_message = String::Handle(
206 String::New("An implementation of Dart_GetVMServiceAssetsArchive " 194 String::New("An implementation of Dart_GetVMServiceAssetsArchive "
207 "should return a Uint8Array or null.")); 195 "should return a Uint8Array or null."));
208 const Error& error = Error::Handle(ApiError::New(error_message)); 196 const Error& error = Error::Handle(ApiError::New(error_message));
209 Exceptions::PropagateError(error); 197 Exceptions::PropagateError(error);
210 return Object::null(); 198 return Object::null();
211 } 199 }
212 return Api::UnwrapHandle(handle); 200 return Api::UnwrapHandle(handle);
213 } 201 }
214 202
215
216 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 203 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
217 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 204 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
218 if (new_ptr == NULL) { 205 if (new_ptr == NULL) {
219 OUT_OF_MEMORY(); 206 OUT_OF_MEMORY();
220 } 207 }
221 return reinterpret_cast<uint8_t*>(new_ptr); 208 return reinterpret_cast<uint8_t*>(new_ptr);
222 } 209 }
223 210
224
225 static void PrintMissingParamError(JSONStream* js, const char* param) { 211 static void PrintMissingParamError(JSONStream* js, const char* param) {
226 js->PrintError(kInvalidParams, "%s expects the '%s' parameter", js->method(), 212 js->PrintError(kInvalidParams, "%s expects the '%s' parameter", js->method(),
227 param); 213 param);
228 } 214 }
229 215
230
231 static void PrintInvalidParamError(JSONStream* js, const char* param) { 216 static void PrintInvalidParamError(JSONStream* js, const char* param) {
232 js->PrintError(kInvalidParams, "%s: invalid '%s' parameter: %s", js->method(), 217 js->PrintError(kInvalidParams, "%s: invalid '%s' parameter: %s", js->method(),
233 param, js->LookupParam(param)); 218 param, js->LookupParam(param));
234 } 219 }
235 220
236
237 static void PrintIllegalParamError(JSONStream* js, const char* param) { 221 static void PrintIllegalParamError(JSONStream* js, const char* param) {
238 js->PrintError(kInvalidParams, "%s: illegal '%s' parameter: %s", js->method(), 222 js->PrintError(kInvalidParams, "%s: illegal '%s' parameter: %s", js->method(),
239 param, js->LookupParam(param)); 223 param, js->LookupParam(param));
240 } 224 }
241 225
242
243 static void PrintUnrecognizedMethodError(JSONStream* js) { 226 static void PrintUnrecognizedMethodError(JSONStream* js) {
244 js->PrintError(kMethodNotFound, NULL); 227 js->PrintError(kMethodNotFound, NULL);
245 } 228 }
246 229
247
248 static void PrintSuccess(JSONStream* js) { 230 static void PrintSuccess(JSONStream* js) {
249 JSONObject jsobj(js); 231 JSONObject jsobj(js);
250 jsobj.AddProperty("type", "Success"); 232 jsobj.AddProperty("type", "Success");
251 } 233 }
252 234
253
254 static bool GetIntegerId(const char* s, intptr_t* id, int base = 10) { 235 static bool GetIntegerId(const char* s, intptr_t* id, int base = 10) {
255 if ((s == NULL) || (*s == '\0')) { 236 if ((s == NULL) || (*s == '\0')) {
256 // Empty string. 237 // Empty string.
257 return false; 238 return false;
258 } 239 }
259 if (id == NULL) { 240 if (id == NULL) {
260 // No id pointer. 241 // No id pointer.
261 return false; 242 return false;
262 } 243 }
263 intptr_t r = 0; 244 intptr_t r = 0;
264 char* end_ptr = NULL; 245 char* end_ptr = NULL;
265 r = strtol(s, &end_ptr, base); 246 r = strtol(s, &end_ptr, base);
266 if (end_ptr == s) { 247 if (end_ptr == s) {
267 // String was not advanced at all, cannot be valid. 248 // String was not advanced at all, cannot be valid.
268 return false; 249 return false;
269 } 250 }
270 *id = r; 251 *id = r;
271 return true; 252 return true;
272 } 253 }
273 254
274
275 static bool GetUnsignedIntegerId(const char* s, uintptr_t* id, int base = 10) { 255 static bool GetUnsignedIntegerId(const char* s, uintptr_t* id, int base = 10) {
276 if ((s == NULL) || (*s == '\0')) { 256 if ((s == NULL) || (*s == '\0')) {
277 // Empty string. 257 // Empty string.
278 return false; 258 return false;
279 } 259 }
280 if (id == NULL) { 260 if (id == NULL) {
281 // No id pointer. 261 // No id pointer.
282 return false; 262 return false;
283 } 263 }
284 uintptr_t r = 0; 264 uintptr_t r = 0;
285 char* end_ptr = NULL; 265 char* end_ptr = NULL;
286 r = strtoul(s, &end_ptr, base); 266 r = strtoul(s, &end_ptr, base);
287 if (end_ptr == s) { 267 if (end_ptr == s) {
288 // String was not advanced at all, cannot be valid. 268 // String was not advanced at all, cannot be valid.
289 return false; 269 return false;
290 } 270 }
291 *id = r; 271 *id = r;
292 return true; 272 return true;
293 } 273 }
294 274
295
296 static bool GetInteger64Id(const char* s, int64_t* id, int base = 10) { 275 static bool GetInteger64Id(const char* s, int64_t* id, int base = 10) {
297 if ((s == NULL) || (*s == '\0')) { 276 if ((s == NULL) || (*s == '\0')) {
298 // Empty string. 277 // Empty string.
299 return false; 278 return false;
300 } 279 }
301 if (id == NULL) { 280 if (id == NULL) {
302 // No id pointer. 281 // No id pointer.
303 return false; 282 return false;
304 } 283 }
305 int64_t r = 0; 284 int64_t r = 0;
306 char* end_ptr = NULL; 285 char* end_ptr = NULL;
307 r = strtoll(s, &end_ptr, base); 286 r = strtoll(s, &end_ptr, base);
308 if (end_ptr == s) { 287 if (end_ptr == s) {
309 // String was not advanced at all, cannot be valid. 288 // String was not advanced at all, cannot be valid.
310 return false; 289 return false;
311 } 290 }
312 *id = r; 291 *id = r;
313 return true; 292 return true;
314 } 293 }
315 294
316
317 // Scans the string until the '-' character. Returns pointer to string 295 // Scans the string until the '-' character. Returns pointer to string
318 // at '-' character. Returns NULL if not found. 296 // at '-' character. Returns NULL if not found.
319 static const char* ScanUntilDash(const char* s) { 297 static const char* ScanUntilDash(const char* s) {
320 if ((s == NULL) || (*s == '\0')) { 298 if ((s == NULL) || (*s == '\0')) {
321 // Empty string. 299 // Empty string.
322 return NULL; 300 return NULL;
323 } 301 }
324 while (*s != '\0') { 302 while (*s != '\0') {
325 if (*s == '-') { 303 if (*s == '-') {
326 return s; 304 return s;
327 } 305 }
328 s++; 306 s++;
329 } 307 }
330 return NULL; 308 return NULL;
331 } 309 }
332 310
333
334 static bool GetCodeId(const char* s, int64_t* timestamp, uword* address) { 311 static bool GetCodeId(const char* s, int64_t* timestamp, uword* address) {
335 if ((s == NULL) || (*s == '\0')) { 312 if ((s == NULL) || (*s == '\0')) {
336 // Empty string. 313 // Empty string.
337 return false; 314 return false;
338 } 315 }
339 if ((timestamp == NULL) || (address == NULL)) { 316 if ((timestamp == NULL) || (address == NULL)) {
340 // Bad arguments. 317 // Bad arguments.
341 return false; 318 return false;
342 } 319 }
343 // Extract the timestamp. 320 // Extract the timestamp.
344 if (!GetInteger64Id(s, timestamp, 16) || (*timestamp < 0)) { 321 if (!GetInteger64Id(s, timestamp, 16) || (*timestamp < 0)) {
345 return false; 322 return false;
346 } 323 }
347 s = ScanUntilDash(s); 324 s = ScanUntilDash(s);
348 if (s == NULL) { 325 if (s == NULL) {
349 return false; 326 return false;
350 } 327 }
351 // Skip the dash. 328 // Skip the dash.
352 s++; 329 s++;
353 // Extract the PC. 330 // Extract the PC.
354 if (!GetUnsignedIntegerId(s, address, 16)) { 331 if (!GetUnsignedIntegerId(s, address, 16)) {
355 return false; 332 return false;
356 } 333 }
357 return true; 334 return true;
358 } 335 }
359 336
360
361 // Verifies that |s| begins with |prefix| and then calls |GetIntegerId| on 337 // Verifies that |s| begins with |prefix| and then calls |GetIntegerId| on
362 // the remainder of |s|. 338 // the remainder of |s|.
363 static bool GetPrefixedIntegerId(const char* s, 339 static bool GetPrefixedIntegerId(const char* s,
364 const char* prefix, 340 const char* prefix,
365 intptr_t* service_id) { 341 intptr_t* service_id) {
366 if (s == NULL) { 342 if (s == NULL) {
367 return false; 343 return false;
368 } 344 }
369 ASSERT(prefix != NULL); 345 ASSERT(prefix != NULL);
370 const intptr_t kInputLen = strlen(s); 346 const intptr_t kInputLen = strlen(s);
371 const intptr_t kPrefixLen = strlen(prefix); 347 const intptr_t kPrefixLen = strlen(prefix);
372 ASSERT(kPrefixLen > 0); 348 ASSERT(kPrefixLen > 0);
373 if (kInputLen <= kPrefixLen) { 349 if (kInputLen <= kPrefixLen) {
374 return false; 350 return false;
375 } 351 }
376 if (strncmp(s, prefix, kPrefixLen) != 0) { 352 if (strncmp(s, prefix, kPrefixLen) != 0) {
377 return false; 353 return false;
378 } 354 }
379 // Prefix satisfied. Move forward. 355 // Prefix satisfied. Move forward.
380 s += kPrefixLen; 356 s += kPrefixLen;
381 // Attempt to read integer id. 357 // Attempt to read integer id.
382 return GetIntegerId(s, service_id); 358 return GetIntegerId(s, service_id);
383 } 359 }
384 360
385
386 static bool IsValidClassId(Isolate* isolate, intptr_t cid) { 361 static bool IsValidClassId(Isolate* isolate, intptr_t cid) {
387 ASSERT(isolate != NULL); 362 ASSERT(isolate != NULL);
388 ClassTable* class_table = isolate->class_table(); 363 ClassTable* class_table = isolate->class_table();
389 ASSERT(class_table != NULL); 364 ASSERT(class_table != NULL);
390 return class_table->IsValidIndex(cid) && class_table->HasValidClassAt(cid); 365 return class_table->IsValidIndex(cid) && class_table->HasValidClassAt(cid);
391 } 366 }
392 367
393
394 static RawClass* GetClassForId(Isolate* isolate, intptr_t cid) { 368 static RawClass* GetClassForId(Isolate* isolate, intptr_t cid) {
395 ASSERT(isolate == Isolate::Current()); 369 ASSERT(isolate == Isolate::Current());
396 ASSERT(isolate != NULL); 370 ASSERT(isolate != NULL);
397 ClassTable* class_table = isolate->class_table(); 371 ClassTable* class_table = isolate->class_table();
398 ASSERT(class_table != NULL); 372 ASSERT(class_table != NULL);
399 return class_table->At(cid); 373 return class_table->At(cid);
400 } 374 }
401 375
402
403 // TODO(johnmccutchan): Split into separate file and write unit tests. 376 // TODO(johnmccutchan): Split into separate file and write unit tests.
404 class MethodParameter { 377 class MethodParameter {
405 public: 378 public:
406 MethodParameter(const char* name, bool required) 379 MethodParameter(const char* name, bool required)
407 : name_(name), required_(required) {} 380 : name_(name), required_(required) {}
408 381
409 virtual ~MethodParameter() {} 382 virtual ~MethodParameter() {}
410 383
411 virtual bool Validate(const char* value) const { return true; } 384 virtual bool Validate(const char* value) const { return true; }
412 385
(...skipping 13 matching lines...) Expand all
426 const Object& value, 399 const Object& value,
427 JSONStream* js) const { 400 JSONStream* js) const {
428 PrintInvalidParamError(js, name); 401 PrintInvalidParamError(js, name);
429 } 402 }
430 403
431 private: 404 private:
432 const char* name_; 405 const char* name_;
433 bool required_; 406 bool required_;
434 }; 407 };
435 408
436
437 class DartStringParameter : public MethodParameter { 409 class DartStringParameter : public MethodParameter {
438 public: 410 public:
439 DartStringParameter(const char* name, bool required) 411 DartStringParameter(const char* name, bool required)
440 : MethodParameter(name, required) {} 412 : MethodParameter(name, required) {}
441 413
442 virtual bool ValidateObject(const Object& value) const { 414 virtual bool ValidateObject(const Object& value) const {
443 return value.IsString(); 415 return value.IsString();
444 } 416 }
445 }; 417 };
446 418
447
448 class DartListParameter : public MethodParameter { 419 class DartListParameter : public MethodParameter {
449 public: 420 public:
450 DartListParameter(const char* name, bool required) 421 DartListParameter(const char* name, bool required)
451 : MethodParameter(name, required) {} 422 : MethodParameter(name, required) {}
452 423
453 virtual bool ValidateObject(const Object& value) const { 424 virtual bool ValidateObject(const Object& value) const {
454 return value.IsArray() || value.IsGrowableObjectArray(); 425 return value.IsArray() || value.IsGrowableObjectArray();
455 } 426 }
456 }; 427 };
457 428
458
459 class NoSuchParameter : public MethodParameter { 429 class NoSuchParameter : public MethodParameter {
460 public: 430 public:
461 explicit NoSuchParameter(const char* name) : MethodParameter(name, false) {} 431 explicit NoSuchParameter(const char* name) : MethodParameter(name, false) {}
462 432
463 virtual bool Validate(const char* value) const { return (value == NULL); } 433 virtual bool Validate(const char* value) const { return (value == NULL); }
464 434
465 virtual bool ValidateObject(const Object& value) const { 435 virtual bool ValidateObject(const Object& value) const {
466 return value.IsNull(); 436 return value.IsNull();
467 } 437 }
468 }; 438 };
469 439
470
471 class BoolParameter : public MethodParameter { 440 class BoolParameter : public MethodParameter {
472 public: 441 public:
473 BoolParameter(const char* name, bool required) 442 BoolParameter(const char* name, bool required)
474 : MethodParameter(name, required) {} 443 : MethodParameter(name, required) {}
475 444
476 virtual bool Validate(const char* value) const { 445 virtual bool Validate(const char* value) const {
477 if (value == NULL) { 446 if (value == NULL) {
478 return false; 447 return false;
479 } 448 }
480 return (strcmp("true", value) == 0) || (strcmp("false", value) == 0); 449 return (strcmp("true", value) == 0) || (strcmp("false", value) == 0);
481 } 450 }
482 451
483 static bool Parse(const char* value, bool default_value = false) { 452 static bool Parse(const char* value, bool default_value = false) {
484 if (value == NULL) { 453 if (value == NULL) {
485 return default_value; 454 return default_value;
486 } 455 }
487 return strcmp("true", value) == 0; 456 return strcmp("true", value) == 0;
488 } 457 }
489 }; 458 };
490 459
491
492 class UIntParameter : public MethodParameter { 460 class UIntParameter : public MethodParameter {
493 public: 461 public:
494 UIntParameter(const char* name, bool required) 462 UIntParameter(const char* name, bool required)
495 : MethodParameter(name, required) {} 463 : MethodParameter(name, required) {}
496 464
497 virtual bool Validate(const char* value) const { 465 virtual bool Validate(const char* value) const {
498 if (value == NULL) { 466 if (value == NULL) {
499 return false; 467 return false;
500 } 468 }
501 for (const char* cp = value; *cp != '\0'; cp++) { 469 for (const char* cp = value; *cp != '\0'; cp++) {
502 if (*cp < '0' || *cp > '9') { 470 if (*cp < '0' || *cp > '9') {
503 return false; 471 return false;
504 } 472 }
505 } 473 }
506 return true; 474 return true;
507 } 475 }
508 476
509 static intptr_t Parse(const char* value) { 477 static intptr_t Parse(const char* value) {
510 if (value == NULL) { 478 if (value == NULL) {
511 return -1; 479 return -1;
512 } 480 }
513 char* end_ptr = NULL; 481 char* end_ptr = NULL;
514 uintptr_t result = strtoul(value, &end_ptr, 10); 482 uintptr_t result = strtoul(value, &end_ptr, 10);
515 ASSERT(*end_ptr == '\0'); // Parsed full string 483 ASSERT(*end_ptr == '\0'); // Parsed full string
516 return result; 484 return result;
517 } 485 }
518 }; 486 };
519 487
520
521 class Int64Parameter : public MethodParameter { 488 class Int64Parameter : public MethodParameter {
522 public: 489 public:
523 Int64Parameter(const char* name, bool required) 490 Int64Parameter(const char* name, bool required)
524 : MethodParameter(name, required) {} 491 : MethodParameter(name, required) {}
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') && (*cp != '-')) { 498 if ((*cp < '0' || *cp > '9') && (*cp != '-')) {
532 return false; 499 return false;
533 } 500 }
534 } 501 }
535 return true; 502 return true;
536 } 503 }
537 504
538 static int64_t Parse(const char* value, int64_t default_value = -1) { 505 static int64_t Parse(const char* value, int64_t default_value = -1) {
539 if ((value == NULL) || (*value == '\0')) { 506 if ((value == NULL) || (*value == '\0')) {
540 return default_value; 507 return default_value;
541 } 508 }
542 char* end_ptr = NULL; 509 char* end_ptr = NULL;
543 int64_t result = strtoll(value, &end_ptr, 10); 510 int64_t result = strtoll(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
550 class IdParameter : public MethodParameter { 516 class IdParameter : public MethodParameter {
551 public: 517 public:
552 IdParameter(const char* name, bool required) 518 IdParameter(const char* name, bool required)
553 : MethodParameter(name, required) {} 519 : MethodParameter(name, required) {}
554 520
555 virtual bool Validate(const char* value) const { return (value != NULL); } 521 virtual bool Validate(const char* value) const { return (value != NULL); }
556 }; 522 };
557 523
558
559 class StringParameter : public MethodParameter { 524 class StringParameter : public MethodParameter {
560 public: 525 public:
561 StringParameter(const char* name, bool required) 526 StringParameter(const char* name, bool required)
562 : MethodParameter(name, required) {} 527 : MethodParameter(name, required) {}
563 528
564 virtual bool Validate(const char* value) const { return (value != NULL); } 529 virtual bool Validate(const char* value) const { return (value != NULL); }
565 }; 530 };
566 531
567
568 class RunnableIsolateParameter : public MethodParameter { 532 class RunnableIsolateParameter : public MethodParameter {
569 public: 533 public:
570 explicit RunnableIsolateParameter(const char* name) 534 explicit RunnableIsolateParameter(const char* name)
571 : MethodParameter(name, true) {} 535 : MethodParameter(name, true) {}
572 536
573 virtual bool Validate(const char* value) const { 537 virtual bool Validate(const char* value) const {
574 Isolate* isolate = Isolate::Current(); 538 Isolate* isolate = Isolate::Current();
575 return (value != NULL) && (isolate != NULL) && (isolate->is_runnable()); 539 return (value != NULL) && (isolate != NULL) && (isolate->is_runnable());
576 } 540 }
577 541
578 virtual void PrintError(const char* name, 542 virtual void PrintError(const char* name,
579 const char* value, 543 const char* value,
580 JSONStream* js) const { 544 JSONStream* js) const {
581 js->PrintError(kIsolateMustBeRunnable, 545 js->PrintError(kIsolateMustBeRunnable,
582 "Isolate must be runnable before this request is made."); 546 "Isolate must be runnable before this request is made.");
583 } 547 }
584 }; 548 };
585 549
586
587 #define ISOLATE_PARAMETER new IdParameter("isolateId", true) 550 #define ISOLATE_PARAMETER new IdParameter("isolateId", true)
588 #define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId") 551 #define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId")
589 #define RUNNABLE_ISOLATE_PARAMETER new RunnableIsolateParameter("isolateId") 552 #define RUNNABLE_ISOLATE_PARAMETER new RunnableIsolateParameter("isolateId")
590 553
591 class EnumParameter : public MethodParameter { 554 class EnumParameter : public MethodParameter {
592 public: 555 public:
593 EnumParameter(const char* name, bool required, const char* const* enums) 556 EnumParameter(const char* name, bool required, const char* const* enums)
594 : MethodParameter(name, required), enums_(enums) {} 557 : MethodParameter(name, required), enums_(enums) {}
595 558
596 virtual bool Validate(const char* value) const { 559 virtual bool Validate(const char* value) const {
597 if (value == NULL) { 560 if (value == NULL) {
598 return true; 561 return true;
599 } 562 }
600 for (intptr_t i = 0; enums_[i] != NULL; i++) { 563 for (intptr_t i = 0; enums_[i] != NULL; i++) {
601 if (strcmp(value, enums_[i]) == 0) { 564 if (strcmp(value, enums_[i]) == 0) {
602 return true; 565 return true;
603 } 566 }
604 } 567 }
605 return false; 568 return false;
606 } 569 }
607 570
608 private: 571 private:
609 const char* const* enums_; 572 const char* const* enums_;
610 }; 573 };
611 574
612
613 // If the key is not found, this function returns the last element in the 575 // If the key is not found, this function returns the last element in the
614 // values array. This can be used to encode the default value. 576 // values array. This can be used to encode the default value.
615 template <typename T> 577 template <typename T>
616 T EnumMapper(const char* value, const char* const* enums, T* values) { 578 T EnumMapper(const char* value, const char* const* enums, T* values) {
617 ASSERT(value != NULL); 579 ASSERT(value != NULL);
618 intptr_t i = 0; 580 intptr_t i = 0;
619 for (i = 0; enums[i] != NULL; i++) { 581 for (i = 0; enums[i] != NULL; i++) {
620 if (strcmp(value, enums[i]) == 0) { 582 if (strcmp(value, enums[i]) == 0) {
621 return values[i]; 583 return values[i];
622 } 584 }
623 } 585 }
624 // Default value. 586 // Default value.
625 return values[i]; 587 return values[i];
626 } 588 }
627 589
628
629 class EnumListParameter : public MethodParameter { 590 class EnumListParameter : public MethodParameter {
630 public: 591 public:
631 EnumListParameter(const char* name, bool required, const char* const* enums) 592 EnumListParameter(const char* name, bool required, const char* const* enums)
632 : MethodParameter(name, required), enums_(enums) {} 593 : MethodParameter(name, required), enums_(enums) {}
633 594
634 virtual bool Validate(const char* value) const { 595 virtual bool Validate(const char* value) const {
635 return ElementCount(value) >= 0; 596 return ElementCount(value) >= 0;
636 } 597 }
637 598
638 const char** Parse(Zone* zone, const char* value_in) const { 599 const char** Parse(Zone* zone, const char* value_in) const {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 return -1; 694 return -1;
734 } 695 }
735 break; 696 break;
736 } 697 }
737 } 698 }
738 } 699 }
739 700
740 const char* const* enums_; 701 const char* const* enums_;
741 }; 702 };
742 703
743
744 typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js); 704 typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js);
745 705
746
747 struct ServiceMethodDescriptor { 706 struct ServiceMethodDescriptor {
748 const char* name; 707 const char* name;
749 const ServiceMethodEntry entry; 708 const ServiceMethodEntry entry;
750 const MethodParameter* const* parameters; 709 const MethodParameter* const* parameters;
751 }; 710 };
752 711
753
754 // TODO(johnmccutchan): Do we reject unexpected parameters? 712 // TODO(johnmccutchan): Do we reject unexpected parameters?
755 static bool ValidateParameters(const MethodParameter* const* parameters, 713 static bool ValidateParameters(const MethodParameter* const* parameters,
756 JSONStream* js) { 714 JSONStream* js) {
757 if (parameters == NULL) { 715 if (parameters == NULL) {
758 return true; 716 return true;
759 } 717 }
760 if (js->NumObjectParameters() > 0) { 718 if (js->NumObjectParameters() > 0) {
761 Object& value = Object::Handle(); 719 Object& value = Object::Handle();
762 for (intptr_t i = 0; parameters[i] != NULL; i++) { 720 for (intptr_t i = 0; parameters[i] != NULL; i++) {
763 const MethodParameter* parameter = parameters[i]; 721 const MethodParameter* parameter = parameters[i];
(...skipping 23 matching lines...) Expand all
787 } 745 }
788 if (has_parameter && !parameter->Validate(value)) { 746 if (has_parameter && !parameter->Validate(value)) {
789 parameter->PrintError(name, value, js); 747 parameter->PrintError(name, value, js);
790 return false; 748 return false;
791 } 749 }
792 } 750 }
793 } 751 }
794 return true; 752 return true;
795 } 753 }
796 754
797
798 void Service::PostError(const String& method_name, 755 void Service::PostError(const String& method_name,
799 const Array& parameter_keys, 756 const Array& parameter_keys,
800 const Array& parameter_values, 757 const Array& parameter_values,
801 const Instance& reply_port, 758 const Instance& reply_port,
802 const Instance& id, 759 const Instance& id,
803 const Error& error) { 760 const Error& error) {
804 Thread* T = Thread::Current(); 761 Thread* T = Thread::Current();
805 StackZone zone(T); 762 StackZone zone(T);
806 HANDLESCOPE(T); 763 HANDLESCOPE(T);
807 JSONStream js; 764 JSONStream js;
808 js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), id, method_name, 765 js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), id, method_name,
809 parameter_keys, parameter_values); 766 parameter_keys, parameter_values);
810 js.PrintError(kExtensionError, "Error in extension `%s`: %s", js.method(), 767 js.PrintError(kExtensionError, "Error in extension `%s`: %s", js.method(),
811 error.ToErrorCString()); 768 error.ToErrorCString());
812 js.PostReply(); 769 js.PostReply();
813 } 770 }
814 771
815
816 RawError* Service::InvokeMethod(Isolate* I, 772 RawError* Service::InvokeMethod(Isolate* I,
817 const Array& msg, 773 const Array& msg,
818 bool parameters_are_dart_objects) { 774 bool parameters_are_dart_objects) {
819 Thread* T = Thread::Current(); 775 Thread* T = Thread::Current();
820 ASSERT(I == T->isolate()); 776 ASSERT(I == T->isolate());
821 ASSERT(I != NULL); 777 ASSERT(I != NULL);
822 ASSERT(T->execution_state() == Thread::kThreadInVM); 778 ASSERT(T->execution_state() == Thread::kThreadInVM);
823 ASSERT(!msg.IsNull()); 779 ASSERT(!msg.IsNull());
824 ASSERT(msg.Length() == 6); 780 ASSERT(msg.Length() == 6);
825 781
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 // asynchronously. 873 // asynchronously.
918 return T->get_and_clear_sticky_error(); 874 return T->get_and_clear_sticky_error();
919 } 875 }
920 876
921 PrintUnrecognizedMethodError(&js); 877 PrintUnrecognizedMethodError(&js);
922 js.PostReply(); 878 js.PostReply();
923 return T->get_and_clear_sticky_error(); 879 return T->get_and_clear_sticky_error();
924 } 880 }
925 } 881 }
926 882
927
928 RawError* Service::HandleRootMessage(const Array& msg_instance) { 883 RawError* Service::HandleRootMessage(const Array& msg_instance) {
929 Isolate* isolate = Isolate::Current(); 884 Isolate* isolate = Isolate::Current();
930 return InvokeMethod(isolate, msg_instance); 885 return InvokeMethod(isolate, msg_instance);
931 } 886 }
932 887
933
934 RawError* Service::HandleObjectRootMessage(const Array& msg_instance) { 888 RawError* Service::HandleObjectRootMessage(const Array& msg_instance) {
935 Isolate* isolate = Isolate::Current(); 889 Isolate* isolate = Isolate::Current();
936 return InvokeMethod(isolate, msg_instance, true); 890 return InvokeMethod(isolate, msg_instance, true);
937 } 891 }
938 892
939
940 RawError* Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { 893 RawError* Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
941 ASSERT(isolate != NULL); 894 ASSERT(isolate != NULL);
942 const Error& error = Error::Handle(InvokeMethod(isolate, msg)); 895 const Error& error = Error::Handle(InvokeMethod(isolate, msg));
943 return MaybePause(isolate, error); 896 return MaybePause(isolate, error);
944 } 897 }
945 898
946
947 static void Finalizer(void* isolate_callback_data, 899 static void Finalizer(void* isolate_callback_data,
948 Dart_WeakPersistentHandle handle, 900 Dart_WeakPersistentHandle handle,
949 void* buffer) { 901 void* buffer) {
950 free(buffer); 902 free(buffer);
951 } 903 }
952 904
953
954 void Service::SendEvent(const char* stream_id, 905 void Service::SendEvent(const char* stream_id,
955 const char* event_type, 906 const char* event_type,
956 uint8_t* bytes, 907 uint8_t* bytes,
957 intptr_t bytes_length) { 908 intptr_t bytes_length) {
958 Thread* thread = Thread::Current(); 909 Thread* thread = Thread::Current();
959 Isolate* isolate = thread->isolate(); 910 Isolate* isolate = thread->isolate();
960 ASSERT(isolate != NULL); 911 ASSERT(isolate != NULL);
961 ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate)); 912 ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate));
962 913
963 if (FLAG_trace_service) { 914 if (FLAG_trace_service) {
(...skipping 26 matching lines...) Expand all
990 message.value.as_array.length = 2; 941 message.value.as_array.length = 2;
991 message.value.as_array.values = elements; 942 message.value.as_array.values = elements;
992 result = Dart_PostCObject(ServiceIsolate::Port(), &message); 943 result = Dart_PostCObject(ServiceIsolate::Port(), &message);
993 } 944 }
994 945
995 if (!result) { 946 if (!result) {
996 free(bytes); 947 free(bytes);
997 } 948 }
998 } 949 }
999 950
1000
1001 void Service::SendEventWithData(const char* stream_id, 951 void Service::SendEventWithData(const char* stream_id,
1002 const char* event_type, 952 const char* event_type,
1003 const char* metadata, 953 const char* metadata,
1004 intptr_t metadata_size, 954 intptr_t metadata_size,
1005 const uint8_t* data, 955 const uint8_t* data,
1006 intptr_t data_size) { 956 intptr_t data_size) {
1007 // Bitstream: [metadata size (big-endian 64 bit)] [metadata (UTF-8)] [data] 957 // Bitstream: [metadata size (big-endian 64 bit)] [metadata (UTF-8)] [data]
1008 const intptr_t total_bytes = sizeof(uint64_t) + metadata_size + data_size; 958 const intptr_t total_bytes = sizeof(uint64_t) + metadata_size + data_size;
1009 959
1010 uint8_t* message = static_cast<uint8_t*>(malloc(total_bytes)); 960 uint8_t* message = static_cast<uint8_t*>(malloc(total_bytes));
(...skipping 12 matching lines...) Expand all
1023 offset += metadata_size; 973 offset += metadata_size;
1024 974
1025 // Data. 975 // Data.
1026 memmove(&message[offset], data, data_size); 976 memmove(&message[offset], data, data_size);
1027 offset += data_size; 977 offset += data_size;
1028 978
1029 ASSERT(offset == total_bytes); 979 ASSERT(offset == total_bytes);
1030 SendEvent(stream_id, event_type, message, total_bytes); 980 SendEvent(stream_id, event_type, message, total_bytes);
1031 } 981 }
1032 982
1033
1034 static void ReportPauseOnConsole(ServiceEvent* event) { 983 static void ReportPauseOnConsole(ServiceEvent* event) {
1035 const char* name = event->isolate()->debugger_name(); 984 const char* name = event->isolate()->debugger_name();
1036 switch (event->kind()) { 985 switch (event->kind()) {
1037 case ServiceEvent::kPauseStart: 986 case ServiceEvent::kPauseStart:
1038 OS::PrintErr( 987 OS::PrintErr(
1039 "vm-service: isolate '%s' has no debugger attached and is paused at " 988 "vm-service: isolate '%s' has no debugger attached and is paused at "
1040 "start.", 989 "start.",
1041 name); 990 name);
1042 break; 991 break;
1043 case ServiceEvent::kPauseExit: 992 case ServiceEvent::kPauseExit:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 } else { 1029 } else {
1081 OS::PrintErr(" Connect to Observatory at %s to debug.\n", 1030 OS::PrintErr(" Connect to Observatory at %s to debug.\n",
1082 ServiceIsolate::server_address()); 1031 ServiceIsolate::server_address());
1083 } 1032 }
1084 const Error& err = Error::Handle(Thread::Current()->sticky_error()); 1033 const Error& err = Error::Handle(Thread::Current()->sticky_error());
1085 if (!err.IsNull()) { 1034 if (!err.IsNull()) {
1086 OS::PrintErr("%s\n", err.ToErrorCString()); 1035 OS::PrintErr("%s\n", err.ToErrorCString());
1087 } 1036 }
1088 } 1037 }
1089 1038
1090
1091 void Service::HandleEvent(ServiceEvent* event) { 1039 void Service::HandleEvent(ServiceEvent* event) {
1092 if (event->stream_info() != NULL && !event->stream_info()->enabled()) { 1040 if (event->stream_info() != NULL && !event->stream_info()->enabled()) {
1093 if (FLAG_warn_on_pause_with_no_debugger && event->IsPause()) { 1041 if (FLAG_warn_on_pause_with_no_debugger && event->IsPause()) {
1094 // If we are about to pause a running program which has no 1042 // If we are about to pause a running program which has no
1095 // debugger connected, tell the user about it. 1043 // debugger connected, tell the user about it.
1096 ReportPauseOnConsole(event); 1044 ReportPauseOnConsole(event);
1097 } 1045 }
1098 // Ignore events when no one is listening to the event stream. 1046 // Ignore events when no one is listening to the event stream.
1099 return; 1047 return;
1100 } 1048 }
1101 if (!ServiceIsolate::IsRunning()) { 1049 if (!ServiceIsolate::IsRunning()) {
1102 return; 1050 return;
1103 } 1051 }
1104 JSONStream js; 1052 JSONStream js;
1105 const char* stream_id = event->stream_id(); 1053 const char* stream_id = event->stream_id();
1106 ASSERT(stream_id != NULL); 1054 ASSERT(stream_id != NULL);
1107 { 1055 {
1108 JSONObject jsobj(&js); 1056 JSONObject jsobj(&js);
1109 jsobj.AddProperty("jsonrpc", "2.0"); 1057 jsobj.AddProperty("jsonrpc", "2.0");
1110 jsobj.AddProperty("method", "streamNotify"); 1058 jsobj.AddProperty("method", "streamNotify");
1111 JSONObject params(&jsobj, "params"); 1059 JSONObject params(&jsobj, "params");
1112 params.AddProperty("streamId", stream_id); 1060 params.AddProperty("streamId", stream_id);
1113 params.AddProperty("event", event); 1061 params.AddProperty("event", event);
1114 } 1062 }
1115 PostEvent(event->isolate(), stream_id, event->KindAsCString(), &js); 1063 PostEvent(event->isolate(), stream_id, event->KindAsCString(), &js);
1116 } 1064 }
1117 1065
1118
1119 void Service::PostEvent(Isolate* isolate, 1066 void Service::PostEvent(Isolate* isolate,
1120 const char* stream_id, 1067 const char* stream_id,
1121 const char* kind, 1068 const char* kind,
1122 JSONStream* event) { 1069 JSONStream* event) {
1123 ASSERT(stream_id != NULL); 1070 ASSERT(stream_id != NULL);
1124 ASSERT(kind != NULL); 1071 ASSERT(kind != NULL);
1125 ASSERT(event != NULL); 1072 ASSERT(event != NULL);
1126 1073
1127 // Message is of the format [<stream id>, <json string>]. 1074 // Message is of the format [<stream id>, <json string>].
1128 // 1075 //
(...skipping 23 matching lines...) Expand all
1152 } 1099 }
1153 OS::Print( 1100 OS::Print(
1154 "vm-service: Pushing ServiceEvent(isolate='%s', kind='%s') " 1101 "vm-service: Pushing ServiceEvent(isolate='%s', kind='%s') "
1155 "to stream %s\n", 1102 "to stream %s\n",
1156 isolate_name, kind, stream_id); 1103 isolate_name, kind, stream_id);
1157 } 1104 }
1158 1105
1159 Dart_PostCObject(ServiceIsolate::Port(), &list_cobj); 1106 Dart_PostCObject(ServiceIsolate::Port(), &list_cobj);
1160 } 1107 }
1161 1108
1162
1163 class EmbedderServiceHandler { 1109 class EmbedderServiceHandler {
1164 public: 1110 public:
1165 explicit EmbedderServiceHandler(const char* name) 1111 explicit EmbedderServiceHandler(const char* name)
1166 : name_(NULL), callback_(NULL), user_data_(NULL), next_(NULL) { 1112 : name_(NULL), callback_(NULL), user_data_(NULL), next_(NULL) {
1167 ASSERT(name != NULL); 1113 ASSERT(name != NULL);
1168 name_ = strdup(name); 1114 name_ = strdup(name);
1169 } 1115 }
1170 1116
1171 ~EmbedderServiceHandler() { free(name_); } 1117 ~EmbedderServiceHandler() { free(name_); }
1172 1118
(...skipping 10 matching lines...) Expand all
1183 EmbedderServiceHandler* next() const { return next_; } 1129 EmbedderServiceHandler* next() const { return next_; }
1184 void set_next(EmbedderServiceHandler* next) { next_ = next; } 1130 void set_next(EmbedderServiceHandler* next) { next_ = next; }
1185 1131
1186 private: 1132 private:
1187 char* name_; 1133 char* name_;
1188 Dart_ServiceRequestCallback callback_; 1134 Dart_ServiceRequestCallback callback_;
1189 void* user_data_; 1135 void* user_data_;
1190 EmbedderServiceHandler* next_; 1136 EmbedderServiceHandler* next_;
1191 }; 1137 };
1192 1138
1193
1194 void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler, 1139 void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler,
1195 JSONStream* js) { 1140 JSONStream* js) {
1196 ASSERT(handler != NULL); 1141 ASSERT(handler != NULL);
1197 Dart_ServiceRequestCallback callback = handler->callback(); 1142 Dart_ServiceRequestCallback callback = handler->callback();
1198 ASSERT(callback != NULL); 1143 ASSERT(callback != NULL);
1199 const char* response = NULL; 1144 const char* response = NULL;
1200 bool success; 1145 bool success;
1201 { 1146 {
1202 TransitionVMToNative transition(Thread::Current()); 1147 TransitionVMToNative transition(Thread::Current());
1203 success = callback(js->method(), js->param_keys(), js->param_values(), 1148 success = callback(js->method(), js->param_keys(), js->param_values(),
1204 js->num_params(), handler->user_data(), &response); 1149 js->num_params(), handler->user_data(), &response);
1205 } 1150 }
1206 ASSERT(response != NULL); 1151 ASSERT(response != NULL);
1207 if (!success) { 1152 if (!success) {
1208 js->SetupError(); 1153 js->SetupError();
1209 } 1154 }
1210 js->buffer()->AddString(response); 1155 js->buffer()->AddString(response);
1211 js->PostReply(); 1156 js->PostReply();
1212 free(const_cast<char*>(response)); 1157 free(const_cast<char*>(response));
1213 } 1158 }
1214 1159
1215
1216 void Service::RegisterIsolateEmbedderCallback( 1160 void Service::RegisterIsolateEmbedderCallback(
1217 const char* name, 1161 const char* name,
1218 Dart_ServiceRequestCallback callback, 1162 Dart_ServiceRequestCallback callback,
1219 void* user_data) { 1163 void* user_data) {
1220 if (name == NULL) { 1164 if (name == NULL) {
1221 return; 1165 return;
1222 } 1166 }
1223 EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(name); 1167 EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(name);
1224 if (handler != NULL) { 1168 if (handler != NULL) {
1225 // Update existing handler entry. 1169 // Update existing handler entry.
1226 handler->set_callback(callback); 1170 handler->set_callback(callback);
1227 handler->set_user_data(user_data); 1171 handler->set_user_data(user_data);
1228 return; 1172 return;
1229 } 1173 }
1230 // Create a new handler. 1174 // Create a new handler.
1231 handler = new EmbedderServiceHandler(name); 1175 handler = new EmbedderServiceHandler(name);
1232 handler->set_callback(callback); 1176 handler->set_callback(callback);
1233 handler->set_user_data(user_data); 1177 handler->set_user_data(user_data);
1234 1178
1235 // Insert into isolate_service_handler_head_ list. 1179 // Insert into isolate_service_handler_head_ list.
1236 handler->set_next(isolate_service_handler_head_); 1180 handler->set_next(isolate_service_handler_head_);
1237 isolate_service_handler_head_ = handler; 1181 isolate_service_handler_head_ = handler;
1238 } 1182 }
1239 1183
1240
1241 EmbedderServiceHandler* Service::FindIsolateEmbedderHandler(const char* name) { 1184 EmbedderServiceHandler* Service::FindIsolateEmbedderHandler(const char* name) {
1242 EmbedderServiceHandler* current = isolate_service_handler_head_; 1185 EmbedderServiceHandler* current = isolate_service_handler_head_;
1243 while (current != NULL) { 1186 while (current != NULL) {
1244 if (strcmp(name, current->name()) == 0) { 1187 if (strcmp(name, current->name()) == 0) {
1245 return current; 1188 return current;
1246 } 1189 }
1247 current = current->next(); 1190 current = current->next();
1248 } 1191 }
1249 return NULL; 1192 return NULL;
1250 } 1193 }
1251 1194
1252
1253 void Service::RegisterRootEmbedderCallback(const char* name, 1195 void Service::RegisterRootEmbedderCallback(const char* name,
1254 Dart_ServiceRequestCallback callback, 1196 Dart_ServiceRequestCallback callback,
1255 void* user_data) { 1197 void* user_data) {
1256 if (name == NULL) { 1198 if (name == NULL) {
1257 return; 1199 return;
1258 } 1200 }
1259 EmbedderServiceHandler* handler = FindRootEmbedderHandler(name); 1201 EmbedderServiceHandler* handler = FindRootEmbedderHandler(name);
1260 if (handler != NULL) { 1202 if (handler != NULL) {
1261 // Update existing handler entry. 1203 // Update existing handler entry.
1262 handler->set_callback(callback); 1204 handler->set_callback(callback);
1263 handler->set_user_data(user_data); 1205 handler->set_user_data(user_data);
1264 return; 1206 return;
1265 } 1207 }
1266 // Create a new handler. 1208 // Create a new handler.
1267 handler = new EmbedderServiceHandler(name); 1209 handler = new EmbedderServiceHandler(name);
1268 handler->set_callback(callback); 1210 handler->set_callback(callback);
1269 handler->set_user_data(user_data); 1211 handler->set_user_data(user_data);
1270 1212
1271 // Insert into root_service_handler_head_ list. 1213 // Insert into root_service_handler_head_ list.
1272 handler->set_next(root_service_handler_head_); 1214 handler->set_next(root_service_handler_head_);
1273 root_service_handler_head_ = handler; 1215 root_service_handler_head_ = handler;
1274 } 1216 }
1275 1217
1276
1277 void Service::SetEmbedderStreamCallbacks( 1218 void Service::SetEmbedderStreamCallbacks(
1278 Dart_ServiceStreamListenCallback listen_callback, 1219 Dart_ServiceStreamListenCallback listen_callback,
1279 Dart_ServiceStreamCancelCallback cancel_callback) { 1220 Dart_ServiceStreamCancelCallback cancel_callback) {
1280 stream_listen_callback_ = listen_callback; 1221 stream_listen_callback_ = listen_callback;
1281 stream_cancel_callback_ = cancel_callback; 1222 stream_cancel_callback_ = cancel_callback;
1282 } 1223 }
1283 1224
1284
1285 void Service::SetGetServiceAssetsCallback( 1225 void Service::SetGetServiceAssetsCallback(
1286 Dart_GetVMServiceAssetsArchive get_service_assets) { 1226 Dart_GetVMServiceAssetsArchive get_service_assets) {
1287 get_service_assets_callback_ = get_service_assets; 1227 get_service_assets_callback_ = get_service_assets;
1288 } 1228 }
1289 1229
1290
1291 EmbedderServiceHandler* Service::FindRootEmbedderHandler(const char* name) { 1230 EmbedderServiceHandler* Service::FindRootEmbedderHandler(const char* name) {
1292 EmbedderServiceHandler* current = root_service_handler_head_; 1231 EmbedderServiceHandler* current = root_service_handler_head_;
1293 while (current != NULL) { 1232 while (current != NULL) {
1294 if (strcmp(name, current->name()) == 0) { 1233 if (strcmp(name, current->name()) == 0) {
1295 return current; 1234 return current;
1296 } 1235 }
1297 current = current->next(); 1236 current = current->next();
1298 } 1237 }
1299 return NULL; 1238 return NULL;
1300 } 1239 }
1301 1240
1302
1303 void Service::ScheduleExtensionHandler(const Instance& handler, 1241 void Service::ScheduleExtensionHandler(const Instance& handler,
1304 const String& method_name, 1242 const String& method_name,
1305 const Array& parameter_keys, 1243 const Array& parameter_keys,
1306 const Array& parameter_values, 1244 const Array& parameter_values,
1307 const Instance& reply_port, 1245 const Instance& reply_port,
1308 const Instance& id) { 1246 const Instance& id) {
1309 ASSERT(!handler.IsNull()); 1247 ASSERT(!handler.IsNull());
1310 ASSERT(!method_name.IsNull()); 1248 ASSERT(!method_name.IsNull());
1311 ASSERT(!parameter_keys.IsNull()); 1249 ASSERT(!parameter_keys.IsNull());
1312 ASSERT(!parameter_values.IsNull()); 1250 ASSERT(!parameter_values.IsNull());
1313 ASSERT(!reply_port.IsNull()); 1251 ASSERT(!reply_port.IsNull());
1314 Isolate* isolate = Isolate::Current(); 1252 Isolate* isolate = Isolate::Current();
1315 ASSERT(isolate != NULL); 1253 ASSERT(isolate != NULL);
1316 isolate->AppendServiceExtensionCall(handler, method_name, parameter_keys, 1254 isolate->AppendServiceExtensionCall(handler, method_name, parameter_keys,
1317 parameter_values, reply_port, id); 1255 parameter_values, reply_port, id);
1318 } 1256 }
1319 1257
1320
1321 static const MethodParameter* get_isolate_params[] = { 1258 static const MethodParameter* get_isolate_params[] = {
1322 ISOLATE_PARAMETER, NULL, 1259 ISOLATE_PARAMETER, NULL,
1323 }; 1260 };
1324 1261
1325
1326 static bool GetIsolate(Thread* thread, JSONStream* js) { 1262 static bool GetIsolate(Thread* thread, JSONStream* js) {
1327 thread->isolate()->PrintJSON(js, false); 1263 thread->isolate()->PrintJSON(js, false);
1328 return true; 1264 return true;
1329 } 1265 }
1330 1266
1331
1332 static const MethodParameter* get_stack_params[] = { 1267 static const MethodParameter* get_stack_params[] = {
1333 RUNNABLE_ISOLATE_PARAMETER, new BoolParameter("_full", false), NULL, 1268 RUNNABLE_ISOLATE_PARAMETER, new BoolParameter("_full", false), NULL,
1334 }; 1269 };
1335 1270
1336
1337 static bool GetStack(Thread* thread, JSONStream* js) { 1271 static bool GetStack(Thread* thread, JSONStream* js) {
1338 Isolate* isolate = thread->isolate(); 1272 Isolate* isolate = thread->isolate();
1339 if (isolate->debugger() == NULL) { 1273 if (isolate->debugger() == NULL) {
1340 js->PrintError(kFeatureDisabled, 1274 js->PrintError(kFeatureDisabled,
1341 "Cannot get stack when debugger disabled."); 1275 "Cannot get stack when debugger disabled.");
1342 return true; 1276 return true;
1343 } 1277 }
1344 ASSERT(isolate->compilation_allowed()); 1278 ASSERT(isolate->compilation_allowed());
1345 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); 1279 DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
1346 DebuggerStackTrace* async_causal_stack = 1280 DebuggerStackTrace* async_causal_stack =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 } 1320 }
1387 1321
1388 { 1322 {
1389 MessageHandler::AcquiredQueues aq(isolate->message_handler()); 1323 MessageHandler::AcquiredQueues aq(isolate->message_handler());
1390 jsobj.AddProperty("messages", aq.queue()); 1324 jsobj.AddProperty("messages", aq.queue());
1391 } 1325 }
1392 1326
1393 return true; 1327 return true;
1394 } 1328 }
1395 1329
1396
1397 static bool HandleCommonEcho(JSONObject* jsobj, JSONStream* js) { 1330 static bool HandleCommonEcho(JSONObject* jsobj, JSONStream* js) {
1398 jsobj->AddProperty("type", "_EchoResponse"); 1331 jsobj->AddProperty("type", "_EchoResponse");
1399 if (js->HasParam("text")) { 1332 if (js->HasParam("text")) {
1400 jsobj->AddProperty("text", js->LookupParam("text")); 1333 jsobj->AddProperty("text", js->LookupParam("text"));
1401 } 1334 }
1402 return true; 1335 return true;
1403 } 1336 }
1404 1337
1405
1406 void Service::SendEchoEvent(Isolate* isolate, const char* text) { 1338 void Service::SendEchoEvent(Isolate* isolate, const char* text) {
1407 JSONStream js; 1339 JSONStream js;
1408 { 1340 {
1409 JSONObject jsobj(&js); 1341 JSONObject jsobj(&js);
1410 jsobj.AddProperty("jsonrpc", "2.0"); 1342 jsobj.AddProperty("jsonrpc", "2.0");
1411 jsobj.AddProperty("method", "streamNotify"); 1343 jsobj.AddProperty("method", "streamNotify");
1412 { 1344 {
1413 JSONObject params(&jsobj, "params"); 1345 JSONObject params(&jsobj, "params");
1414 params.AddProperty("streamId", echo_stream.id()); 1346 params.AddProperty("streamId", echo_stream.id());
1415 { 1347 {
1416 JSONObject event(&params, "event"); 1348 JSONObject event(&params, "event");
1417 event.AddProperty("type", "Event"); 1349 event.AddProperty("type", "Event");
1418 event.AddProperty("kind", "_Echo"); 1350 event.AddProperty("kind", "_Echo");
1419 event.AddProperty("isolate", isolate); 1351 event.AddProperty("isolate", isolate);
1420 if (text != NULL) { 1352 if (text != NULL) {
1421 event.AddProperty("text", text); 1353 event.AddProperty("text", text);
1422 } 1354 }
1423 event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); 1355 event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis());
1424 } 1356 }
1425 } 1357 }
1426 } 1358 }
1427 uint8_t data[] = {0, 128, 255}; 1359 uint8_t data[] = {0, 128, 255};
1428 SendEventWithData(echo_stream.id(), "_Echo", js.buffer()->buf(), 1360 SendEventWithData(echo_stream.id(), "_Echo", js.buffer()->buf(),
1429 js.buffer()->length(), data, sizeof(data)); 1361 js.buffer()->length(), data, sizeof(data));
1430 } 1362 }
1431 1363
1432
1433 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) { 1364 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) {
1434 if (Service::echo_stream.enabled()) { 1365 if (Service::echo_stream.enabled()) {
1435 Service::SendEchoEvent(thread->isolate(), js->LookupParam("text")); 1366 Service::SendEchoEvent(thread->isolate(), js->LookupParam("text"));
1436 } 1367 }
1437 JSONObject jsobj(js); 1368 JSONObject jsobj(js);
1438 return HandleCommonEcho(&jsobj, js); 1369 return HandleCommonEcho(&jsobj, js);
1439 } 1370 }
1440 1371
1441
1442 static bool DumpIdZone(Thread* thread, JSONStream* js) { 1372 static bool DumpIdZone(Thread* thread, JSONStream* js) {
1443 // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now, 1373 // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now,
1444 // always send the ObjectIdRing. 1374 // always send the ObjectIdRing.
1445 // 1375 //
1446 ObjectIdRing* ring = thread->isolate()->object_id_ring(); 1376 ObjectIdRing* ring = thread->isolate()->object_id_ring();
1447 ASSERT(ring != NULL); 1377 ASSERT(ring != NULL);
1448 // When printing the ObjectIdRing, force object id reuse policy. 1378 // When printing the ObjectIdRing, force object id reuse policy.
1449 RingServiceIdZone reuse_zone; 1379 RingServiceIdZone reuse_zone;
1450 reuse_zone.Init(ring, ObjectIdRing::kReuseId); 1380 reuse_zone.Init(ring, ObjectIdRing::kReuseId);
1451 js->set_id_zone(&reuse_zone); 1381 js->set_id_zone(&reuse_zone);
1452 ring->PrintJSON(js); 1382 ring->PrintJSON(js);
1453 return true; 1383 return true;
1454 } 1384 }
1455 1385
1456
1457 static bool Echo(Thread* thread, JSONStream* js) { 1386 static bool Echo(Thread* thread, JSONStream* js) {
1458 JSONObject jsobj(js); 1387 JSONObject jsobj(js);
1459 return HandleCommonEcho(&jsobj, js); 1388 return HandleCommonEcho(&jsobj, js);
1460 } 1389 }
1461 1390
1462
1463 static bool ContainsNonInstance(const Object& obj) { 1391 static bool ContainsNonInstance(const Object& obj) {
1464 if (obj.IsArray()) { 1392 if (obj.IsArray()) {
1465 const Array& array = Array::Cast(obj); 1393 const Array& array = Array::Cast(obj);
1466 Object& element = Object::Handle(); 1394 Object& element = Object::Handle();
1467 for (intptr_t i = 0; i < array.Length(); ++i) { 1395 for (intptr_t i = 0; i < array.Length(); ++i) {
1468 element = array.At(i); 1396 element = array.At(i);
1469 if (!(element.IsInstance() || element.IsNull())) { 1397 if (!(element.IsInstance() || element.IsNull())) {
1470 return true; 1398 return true;
1471 } 1399 }
1472 } 1400 }
1473 return false; 1401 return false;
1474 } else if (obj.IsGrowableObjectArray()) { 1402 } else if (obj.IsGrowableObjectArray()) {
1475 const GrowableObjectArray& array = GrowableObjectArray::Cast(obj); 1403 const GrowableObjectArray& array = GrowableObjectArray::Cast(obj);
1476 Object& element = Object::Handle(); 1404 Object& element = Object::Handle();
1477 for (intptr_t i = 0; i < array.Length(); ++i) { 1405 for (intptr_t i = 0; i < array.Length(); ++i) {
1478 element = array.At(i); 1406 element = array.At(i);
1479 if (!(element.IsInstance() || element.IsNull())) { 1407 if (!(element.IsInstance() || element.IsNull())) {
1480 return true; 1408 return true;
1481 } 1409 }
1482 } 1410 }
1483 return false; 1411 return false;
1484 } else { 1412 } else {
1485 return !(obj.IsInstance() || obj.IsNull()); 1413 return !(obj.IsInstance() || obj.IsNull());
1486 } 1414 }
1487 } 1415 }
1488 1416
1489
1490 static RawObject* LookupObjectId(Thread* thread, 1417 static RawObject* LookupObjectId(Thread* thread,
1491 const char* arg, 1418 const char* arg,
1492 ObjectIdRing::LookupResult* kind) { 1419 ObjectIdRing::LookupResult* kind) {
1493 *kind = ObjectIdRing::kValid; 1420 *kind = ObjectIdRing::kValid;
1494 if (strncmp(arg, "int-", 4) == 0) { 1421 if (strncmp(arg, "int-", 4) == 0) {
1495 arg += 4; 1422 arg += 4;
1496 int64_t value = 0; 1423 int64_t value = 0;
1497 if (!OS::StringToInt64(arg, &value) || !Smi::IsValid(value)) { 1424 if (!OS::StringToInt64(arg, &value) || !Smi::IsValid(value)) {
1498 *kind = ObjectIdRing::kInvalid; 1425 *kind = ObjectIdRing::kInvalid;
1499 return Object::null(); 1426 return Object::null();
(...skipping 12 matching lines...) Expand all
1512 ObjectIdRing* ring = thread->isolate()->object_id_ring(); 1439 ObjectIdRing* ring = thread->isolate()->object_id_ring();
1513 ASSERT(ring != NULL); 1440 ASSERT(ring != NULL);
1514 intptr_t id = -1; 1441 intptr_t id = -1;
1515 if (!GetIntegerId(arg, &id)) { 1442 if (!GetIntegerId(arg, &id)) {
1516 *kind = ObjectIdRing::kInvalid; 1443 *kind = ObjectIdRing::kInvalid;
1517 return Object::null(); 1444 return Object::null();
1518 } 1445 }
1519 return ring->GetObjectForId(id, kind); 1446 return ring->GetObjectForId(id, kind);
1520 } 1447 }
1521 1448
1522
1523 static RawObject* LookupHeapObjectLibraries(Isolate* isolate, 1449 static RawObject* LookupHeapObjectLibraries(Isolate* isolate,
1524 char** parts, 1450 char** parts,
1525 int num_parts) { 1451 int num_parts) {
1526 // Library ids look like "libraries/35" 1452 // Library ids look like "libraries/35"
1527 if (num_parts < 2) { 1453 if (num_parts < 2) {
1528 return Object::sentinel().raw(); 1454 return Object::sentinel().raw();
1529 } 1455 }
1530 const GrowableObjectArray& libs = 1456 const GrowableObjectArray& libs =
1531 GrowableObjectArray::Handle(isolate->object_store()->libraries()); 1457 GrowableObjectArray::Handle(isolate->object_store()->libraries());
1532 ASSERT(!libs.IsNull()); 1458 ASSERT(!libs.IsNull());
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 const Type& type = Type::Handle(zone, cls.CanonicalType()); 1627 const Type& type = Type::Handle(zone, cls.CanonicalType());
1702 if (!type.IsNull()) { 1628 if (!type.IsNull()) {
1703 return type.raw(); 1629 return type.raw();
1704 } 1630 }
1705 } 1631 }
1706 1632
1707 // Not found. 1633 // Not found.
1708 return Object::sentinel().raw(); 1634 return Object::sentinel().raw();
1709 } 1635 }
1710 1636
1711
1712 static RawObject* LookupHeapObjectTypeArguments(Thread* thread, 1637 static RawObject* LookupHeapObjectTypeArguments(Thread* thread,
1713 char** parts, 1638 char** parts,
1714 int num_parts) { 1639 int num_parts) {
1715 Isolate* isolate = thread->isolate(); 1640 Isolate* isolate = thread->isolate();
1716 // TypeArguments ids look like: "typearguments/17" 1641 // TypeArguments ids look like: "typearguments/17"
1717 if (num_parts < 2) { 1642 if (num_parts < 2) {
1718 return Object::sentinel().raw(); 1643 return Object::sentinel().raw();
1719 } 1644 }
1720 intptr_t id; 1645 intptr_t id;
1721 if (!GetIntegerId(parts[1], &id)) { 1646 if (!GetIntegerId(parts[1], &id)) {
1722 return Object::sentinel().raw(); 1647 return Object::sentinel().raw();
1723 } 1648 }
1724 ObjectStore* object_store = isolate->object_store(); 1649 ObjectStore* object_store = isolate->object_store();
1725 const Array& table = 1650 const Array& table =
1726 Array::Handle(thread->zone(), object_store->canonical_type_arguments()); 1651 Array::Handle(thread->zone(), object_store->canonical_type_arguments());
1727 ASSERT(table.Length() > 0); 1652 ASSERT(table.Length() > 0);
1728 const intptr_t table_size = table.Length() - 1; 1653 const intptr_t table_size = table.Length() - 1;
1729 if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) { 1654 if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) {
1730 return Object::sentinel().raw(); 1655 return Object::sentinel().raw();
1731 } 1656 }
1732 return table.At(id); 1657 return table.At(id);
1733 } 1658 }
1734 1659
1735
1736 static RawObject* LookupHeapObjectCode(Isolate* isolate, 1660 static RawObject* LookupHeapObjectCode(Isolate* isolate,
1737 char** parts, 1661 char** parts,
1738 int num_parts) { 1662 int num_parts) {
1739 if (num_parts != 2) { 1663 if (num_parts != 2) {
1740 return Object::sentinel().raw(); 1664 return Object::sentinel().raw();
1741 } 1665 }
1742 uword pc; 1666 uword pc;
1743 static const char* const kCollectedPrefix = "collected-"; 1667 static const char* const kCollectedPrefix = "collected-";
1744 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); 1668 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix);
1745 static const char* const kNativePrefix = "native-"; 1669 static const char* const kNativePrefix = "native-";
(...skipping 28 matching lines...) Expand all
1774 } 1698 }
1775 Code& code = Code::Handle(Code::FindCode(pc, timestamp)); 1699 Code& code = Code::Handle(Code::FindCode(pc, timestamp));
1776 if (!code.IsNull()) { 1700 if (!code.IsNull()) {
1777 return code.raw(); 1701 return code.raw();
1778 } 1702 }
1779 1703
1780 // Not found. 1704 // Not found.
1781 return Object::sentinel().raw(); 1705 return Object::sentinel().raw();
1782 } 1706 }
1783 1707
1784
1785 static RawObject* LookupHeapObjectMessage(Thread* thread, 1708 static RawObject* LookupHeapObjectMessage(Thread* thread,
1786 char** parts, 1709 char** parts,
1787 int num_parts) { 1710 int num_parts) {
1788 if (num_parts != 2) { 1711 if (num_parts != 2) {
1789 return Object::sentinel().raw(); 1712 return Object::sentinel().raw();
1790 } 1713 }
1791 uword message_id = 0; 1714 uword message_id = 0;
1792 if (!GetUnsignedIntegerId(parts[1], &message_id, 16)) { 1715 if (!GetUnsignedIntegerId(parts[1], &message_id, 16)) {
1793 return Object::sentinel().raw(); 1716 return Object::sentinel().raw();
1794 } 1717 }
1795 MessageHandler::AcquiredQueues aq(thread->isolate()->message_handler()); 1718 MessageHandler::AcquiredQueues aq(thread->isolate()->message_handler());
1796 Message* message = aq.queue()->FindMessageById(message_id); 1719 Message* message = aq.queue()->FindMessageById(message_id);
1797 if (message == NULL) { 1720 if (message == NULL) {
1798 // The user may try to load an expired message. 1721 // The user may try to load an expired message.
1799 return Object::sentinel().raw(); 1722 return Object::sentinel().raw();
1800 } 1723 }
1801 if (message->len() > 0) { 1724 if (message->len() > 0) {
1802 MessageSnapshotReader reader(message->data(), message->len(), thread); 1725 MessageSnapshotReader reader(message->data(), message->len(), thread);
1803 return reader.ReadObject(); 1726 return reader.ReadObject();
1804 } else { 1727 } else {
1805 return message->raw_obj(); 1728 return message->raw_obj();
1806 } 1729 }
1807 } 1730 }
1808 1731
1809
1810 static RawObject* LookupHeapObject(Thread* thread, 1732 static RawObject* LookupHeapObject(Thread* thread,
1811 const char* id_original, 1733 const char* id_original,
1812 ObjectIdRing::LookupResult* result) { 1734 ObjectIdRing::LookupResult* result) {
1813 char* id = thread->zone()->MakeCopyOfString(id_original); 1735 char* id = thread->zone()->MakeCopyOfString(id_original);
1814 1736
1815 // Parse the id by splitting at each '/'. 1737 // Parse the id by splitting at each '/'.
1816 const int MAX_PARTS = 8; 1738 const int MAX_PARTS = 8;
1817 char* parts[MAX_PARTS]; 1739 char* parts[MAX_PARTS];
1818 int num_parts = 0; 1740 int num_parts = 0;
1819 int i = 0; 1741 int i = 0;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 } else if (strcmp(parts[0], "code") == 0) { 1783 } else if (strcmp(parts[0], "code") == 0) {
1862 return LookupHeapObjectCode(isolate, parts, num_parts); 1784 return LookupHeapObjectCode(isolate, parts, num_parts);
1863 } else if (strcmp(parts[0], "messages") == 0) { 1785 } else if (strcmp(parts[0], "messages") == 0) {
1864 return LookupHeapObjectMessage(thread, parts, num_parts); 1786 return LookupHeapObjectMessage(thread, parts, num_parts);
1865 } 1787 }
1866 1788
1867 // Not found. 1789 // Not found.
1868 return Object::sentinel().raw(); 1790 return Object::sentinel().raw();
1869 } 1791 }
1870 1792
1871
1872 enum SentinelType { 1793 enum SentinelType {
1873 kCollectedSentinel, 1794 kCollectedSentinel,
1874 kExpiredSentinel, 1795 kExpiredSentinel,
1875 kFreeSentinel, 1796 kFreeSentinel,
1876 }; 1797 };
1877 1798
1878
1879 static void PrintSentinel(JSONStream* js, SentinelType sentinel_type) { 1799 static void PrintSentinel(JSONStream* js, SentinelType sentinel_type) {
1880 JSONObject jsobj(js); 1800 JSONObject jsobj(js);
1881 jsobj.AddProperty("type", "Sentinel"); 1801 jsobj.AddProperty("type", "Sentinel");
1882 switch (sentinel_type) { 1802 switch (sentinel_type) {
1883 case kCollectedSentinel: 1803 case kCollectedSentinel:
1884 jsobj.AddProperty("kind", "Collected"); 1804 jsobj.AddProperty("kind", "Collected");
1885 jsobj.AddProperty("valueAsString", "<collected>"); 1805 jsobj.AddProperty("valueAsString", "<collected>");
1886 break; 1806 break;
1887 case kExpiredSentinel: 1807 case kExpiredSentinel:
1888 jsobj.AddProperty("kind", "Expired"); 1808 jsobj.AddProperty("kind", "Expired");
1889 jsobj.AddProperty("valueAsString", "<expired>"); 1809 jsobj.AddProperty("valueAsString", "<expired>");
1890 break; 1810 break;
1891 case kFreeSentinel: 1811 case kFreeSentinel:
1892 jsobj.AddProperty("kind", "Free"); 1812 jsobj.AddProperty("kind", "Free");
1893 jsobj.AddProperty("valueAsString", "<free>"); 1813 jsobj.AddProperty("valueAsString", "<free>");
1894 break; 1814 break;
1895 default: 1815 default:
1896 UNIMPLEMENTED(); 1816 UNIMPLEMENTED();
1897 break; 1817 break;
1898 } 1818 }
1899 } 1819 }
1900 1820
1901
1902 static Breakpoint* LookupBreakpoint(Isolate* isolate, 1821 static Breakpoint* LookupBreakpoint(Isolate* isolate,
1903 const char* id, 1822 const char* id,
1904 ObjectIdRing::LookupResult* result) { 1823 ObjectIdRing::LookupResult* result) {
1905 *result = ObjectIdRing::kInvalid; 1824 *result = ObjectIdRing::kInvalid;
1906 size_t end_pos = strcspn(id, "/"); 1825 size_t end_pos = strcspn(id, "/");
1907 if (end_pos == strlen(id)) { 1826 if (end_pos == strlen(id)) {
1908 return NULL; 1827 return NULL;
1909 } 1828 }
1910 const char* rest = id + end_pos + 1; // +1 for '/'. 1829 const char* rest = id + end_pos + 1; // +1 for '/'.
1911 if (strncmp("breakpoints", id, end_pos) == 0) { 1830 if (strncmp("breakpoints", id, end_pos) == 0) {
1912 intptr_t bpt_id = 0; 1831 intptr_t bpt_id = 0;
1913 Breakpoint* bpt = NULL; 1832 Breakpoint* bpt = NULL;
1914 if (GetIntegerId(rest, &bpt_id)) { 1833 if (GetIntegerId(rest, &bpt_id)) {
1915 bpt = isolate->debugger()->GetBreakpointById(bpt_id); 1834 bpt = isolate->debugger()->GetBreakpointById(bpt_id);
1916 if (bpt) { 1835 if (bpt) {
1917 *result = ObjectIdRing::kValid; 1836 *result = ObjectIdRing::kValid;
1918 return bpt; 1837 return bpt;
1919 } 1838 }
1920 if (bpt_id < isolate->debugger()->limitBreakpointId()) { 1839 if (bpt_id < isolate->debugger()->limitBreakpointId()) {
1921 *result = ObjectIdRing::kCollected; 1840 *result = ObjectIdRing::kCollected;
1922 return NULL; 1841 return NULL;
1923 } 1842 }
1924 } 1843 }
1925 } 1844 }
1926 return NULL; 1845 return NULL;
1927 } 1846 }
1928 1847
1929
1930 static bool PrintInboundReferences(Thread* thread, 1848 static bool PrintInboundReferences(Thread* thread,
1931 Object* target, 1849 Object* target,
1932 intptr_t limit, 1850 intptr_t limit,
1933 JSONStream* js) { 1851 JSONStream* js) {
1934 ObjectGraph graph(thread); 1852 ObjectGraph graph(thread);
1935 Array& path = Array::Handle(Array::New(limit * 2)); 1853 Array& path = Array::Handle(Array::New(limit * 2));
1936 intptr_t length = graph.InboundReferences(target, path); 1854 intptr_t length = graph.InboundReferences(target, path);
1937 JSONObject jsobj(js); 1855 JSONObject jsobj(js);
1938 jsobj.AddProperty("type", "InboundReferences"); 1856 jsobj.AddProperty("type", "InboundReferences");
1939 { 1857 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 // We nil out the array after generating the response to prevent 1890 // We nil out the array after generating the response to prevent
1973 // reporting suprious references when repeatedly looking for the 1891 // reporting suprious references when repeatedly looking for the
1974 // references to an object. 1892 // references to an object.
1975 for (intptr_t i = 0; i < path.Length(); i++) { 1893 for (intptr_t i = 0; i < path.Length(); i++) {
1976 path.SetAt(i, Object::null_object()); 1894 path.SetAt(i, Object::null_object());
1977 } 1895 }
1978 1896
1979 return true; 1897 return true;
1980 } 1898 }
1981 1899
1982
1983 static const MethodParameter* get_inbound_references_params[] = { 1900 static const MethodParameter* get_inbound_references_params[] = {
1984 RUNNABLE_ISOLATE_PARAMETER, NULL, 1901 RUNNABLE_ISOLATE_PARAMETER, NULL,
1985 }; 1902 };
1986 1903
1987
1988 static bool GetInboundReferences(Thread* thread, JSONStream* js) { 1904 static bool GetInboundReferences(Thread* thread, JSONStream* js) {
1989 const char* target_id = js->LookupParam("targetId"); 1905 const char* target_id = js->LookupParam("targetId");
1990 if (target_id == NULL) { 1906 if (target_id == NULL) {
1991 PrintMissingParamError(js, "targetId"); 1907 PrintMissingParamError(js, "targetId");
1992 return true; 1908 return true;
1993 } 1909 }
1994 const char* limit_cstr = js->LookupParam("limit"); 1910 const char* limit_cstr = js->LookupParam("limit");
1995 if (limit_cstr == NULL) { 1911 if (limit_cstr == NULL) {
1996 PrintMissingParamError(js, "limit"); 1912 PrintMissingParamError(js, "limit");
1997 return true; 1913 return true;
(...skipping 16 matching lines...) Expand all
2014 } else if (lookup_result == ObjectIdRing::kExpired) { 1930 } else if (lookup_result == ObjectIdRing::kExpired) {
2015 PrintSentinel(js, kExpiredSentinel); 1931 PrintSentinel(js, kExpiredSentinel);
2016 } else { 1932 } else {
2017 PrintInvalidParamError(js, "targetId"); 1933 PrintInvalidParamError(js, "targetId");
2018 } 1934 }
2019 return true; 1935 return true;
2020 } 1936 }
2021 return PrintInboundReferences(thread, &obj, limit, js); 1937 return PrintInboundReferences(thread, &obj, limit, js);
2022 } 1938 }
2023 1939
2024
2025 static bool PrintRetainingPath(Thread* thread, 1940 static bool PrintRetainingPath(Thread* thread,
2026 Object* obj, 1941 Object* obj,
2027 intptr_t limit, 1942 intptr_t limit,
2028 JSONStream* js) { 1943 JSONStream* js) {
2029 ObjectGraph graph(thread); 1944 ObjectGraph graph(thread);
2030 Array& path = Array::Handle(Array::New(limit * 2)); 1945 Array& path = Array::Handle(Array::New(limit * 2));
2031 intptr_t length = graph.RetainingPath(obj, path); 1946 intptr_t length = graph.RetainingPath(obj, path);
2032 JSONObject jsobj(js); 1947 JSONObject jsobj(js);
2033 jsobj.AddProperty("type", "RetainingPath"); 1948 jsobj.AddProperty("type", "RetainingPath");
2034 jsobj.AddProperty("length", length); 1949 jsobj.AddProperty("length", length);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2086 // We nil out the array after generating the response to prevent 2001 // We nil out the array after generating the response to prevent
2087 // reporting spurious references when looking for inbound references 2002 // reporting spurious references when looking for inbound references
2088 // after looking for a retaining path. 2003 // after looking for a retaining path.
2089 for (intptr_t i = 0; i < path.Length(); i++) { 2004 for (intptr_t i = 0; i < path.Length(); i++) {
2090 path.SetAt(i, Object::null_object()); 2005 path.SetAt(i, Object::null_object());
2091 } 2006 }
2092 2007
2093 return true; 2008 return true;
2094 } 2009 }
2095 2010
2096
2097 static const MethodParameter* get_retaining_path_params[] = { 2011 static const MethodParameter* get_retaining_path_params[] = {
2098 RUNNABLE_ISOLATE_PARAMETER, NULL, 2012 RUNNABLE_ISOLATE_PARAMETER, NULL,
2099 }; 2013 };
2100 2014
2101
2102 static bool GetRetainingPath(Thread* thread, JSONStream* js) { 2015 static bool GetRetainingPath(Thread* thread, JSONStream* js) {
2103 const char* target_id = js->LookupParam("targetId"); 2016 const char* target_id = js->LookupParam("targetId");
2104 if (target_id == NULL) { 2017 if (target_id == NULL) {
2105 PrintMissingParamError(js, "targetId"); 2018 PrintMissingParamError(js, "targetId");
2106 return true; 2019 return true;
2107 } 2020 }
2108 const char* limit_cstr = js->LookupParam("limit"); 2021 const char* limit_cstr = js->LookupParam("limit");
2109 if (limit_cstr == NULL) { 2022 if (limit_cstr == NULL) {
2110 PrintMissingParamError(js, "limit"); 2023 PrintMissingParamError(js, "limit");
2111 return true; 2024 return true;
(...skipping 16 matching lines...) Expand all
2128 } else if (lookup_result == ObjectIdRing::kExpired) { 2041 } else if (lookup_result == ObjectIdRing::kExpired) {
2129 PrintSentinel(js, kExpiredSentinel); 2042 PrintSentinel(js, kExpiredSentinel);
2130 } else { 2043 } else {
2131 PrintInvalidParamError(js, "targetId"); 2044 PrintInvalidParamError(js, "targetId");
2132 } 2045 }
2133 return true; 2046 return true;
2134 } 2047 }
2135 return PrintRetainingPath(thread, &obj, limit, js); 2048 return PrintRetainingPath(thread, &obj, limit, js);
2136 } 2049 }
2137 2050
2138
2139 static const MethodParameter* get_retained_size_params[] = { 2051 static const MethodParameter* get_retained_size_params[] = {
2140 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL, 2052 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL,
2141 }; 2053 };
2142 2054
2143
2144 static bool GetRetainedSize(Thread* thread, JSONStream* js) { 2055 static bool GetRetainedSize(Thread* thread, JSONStream* js) {
2145 const char* target_id = js->LookupParam("targetId"); 2056 const char* target_id = js->LookupParam("targetId");
2146 ASSERT(target_id != NULL); 2057 ASSERT(target_id != NULL);
2147 ObjectIdRing::LookupResult lookup_result; 2058 ObjectIdRing::LookupResult lookup_result;
2148 Object& obj = 2059 Object& obj =
2149 Object::Handle(LookupHeapObject(thread, target_id, &lookup_result)); 2060 Object::Handle(LookupHeapObject(thread, target_id, &lookup_result));
2150 if (obj.raw() == Object::sentinel().raw()) { 2061 if (obj.raw() == Object::sentinel().raw()) {
2151 if (lookup_result == ObjectIdRing::kCollected) { 2062 if (lookup_result == ObjectIdRing::kCollected) {
2152 PrintSentinel(js, kCollectedSentinel); 2063 PrintSentinel(js, kCollectedSentinel);
2153 } else if (lookup_result == ObjectIdRing::kExpired) { 2064 } else if (lookup_result == ObjectIdRing::kExpired) {
(...skipping 14 matching lines...) Expand all
2168 return true; 2079 return true;
2169 } 2080 }
2170 2081
2171 ObjectGraph graph(thread); 2082 ObjectGraph graph(thread);
2172 intptr_t retained_size = graph.SizeRetainedByInstance(obj); 2083 intptr_t retained_size = graph.SizeRetainedByInstance(obj);
2173 const Object& result = Object::Handle(Integer::New(retained_size)); 2084 const Object& result = Object::Handle(Integer::New(retained_size));
2174 result.PrintJSON(js, true); 2085 result.PrintJSON(js, true);
2175 return true; 2086 return true;
2176 } 2087 }
2177 2088
2178
2179 static const MethodParameter* get_reachable_size_params[] = { 2089 static const MethodParameter* get_reachable_size_params[] = {
2180 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL, 2090 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL,
2181 }; 2091 };
2182 2092
2183
2184 static bool GetReachableSize(Thread* thread, JSONStream* js) { 2093 static bool GetReachableSize(Thread* thread, JSONStream* js) {
2185 const char* target_id = js->LookupParam("targetId"); 2094 const char* target_id = js->LookupParam("targetId");
2186 ASSERT(target_id != NULL); 2095 ASSERT(target_id != NULL);
2187 ObjectIdRing::LookupResult lookup_result; 2096 ObjectIdRing::LookupResult lookup_result;
2188 Object& obj = 2097 Object& obj =
2189 Object::Handle(LookupHeapObject(thread, target_id, &lookup_result)); 2098 Object::Handle(LookupHeapObject(thread, target_id, &lookup_result));
2190 if (obj.raw() == Object::sentinel().raw()) { 2099 if (obj.raw() == Object::sentinel().raw()) {
2191 if (lookup_result == ObjectIdRing::kCollected) { 2100 if (lookup_result == ObjectIdRing::kCollected) {
2192 PrintSentinel(js, kCollectedSentinel); 2101 PrintSentinel(js, kCollectedSentinel);
2193 } else if (lookup_result == ObjectIdRing::kExpired) { 2102 } else if (lookup_result == ObjectIdRing::kExpired) {
(...skipping 14 matching lines...) Expand all
2208 return true; 2117 return true;
2209 } 2118 }
2210 2119
2211 ObjectGraph graph(thread); 2120 ObjectGraph graph(thread);
2212 intptr_t retained_size = graph.SizeReachableByInstance(obj); 2121 intptr_t retained_size = graph.SizeReachableByInstance(obj);
2213 const Object& result = Object::Handle(Integer::New(retained_size)); 2122 const Object& result = Object::Handle(Integer::New(retained_size));
2214 result.PrintJSON(js, true); 2123 result.PrintJSON(js, true);
2215 return true; 2124 return true;
2216 } 2125 }
2217 2126
2218
2219 static const MethodParameter* evaluate_params[] = { 2127 static const MethodParameter* evaluate_params[] = {
2220 RUNNABLE_ISOLATE_PARAMETER, NULL, 2128 RUNNABLE_ISOLATE_PARAMETER, NULL,
2221 }; 2129 };
2222 2130
2223
2224 static bool IsAlpha(char c) { 2131 static bool IsAlpha(char c) {
2225 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); 2132 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
2226 } 2133 }
2227 static bool IsAlphaNum(char c) { 2134 static bool IsAlphaNum(char c) {
2228 return (c >= '0' && c <= '9') || IsAlpha(c); 2135 return (c >= '0' && c <= '9') || IsAlpha(c);
2229 } 2136 }
2230 static bool IsWhitespace(char c) { 2137 static bool IsWhitespace(char c) {
2231 return c <= ' '; 2138 return c <= ' ';
2232 } 2139 }
2233 static bool IsObjectIdChar(char c) { 2140 static bool IsObjectIdChar(char c) {
2234 return IsAlphaNum(c) || c == '/' || c == '-' || c == '@' || c == '%'; 2141 return IsAlphaNum(c) || c == '/' || c == '-' || c == '@' || c == '%';
2235 } 2142 }
2236 2143
2237
2238 // TODO(vm-service): Consider whether we should pass structured objects in 2144 // TODO(vm-service): Consider whether we should pass structured objects in
2239 // service messages instead of always flattening them to C strings. 2145 // service messages instead of always flattening them to C strings.
2240 static bool ParseScope(const char* scope, 2146 static bool ParseScope(const char* scope,
2241 GrowableArray<const char*>* names, 2147 GrowableArray<const char*>* names,
2242 GrowableArray<const char*>* ids) { 2148 GrowableArray<const char*>* ids) {
2243 Zone* zone = Thread::Current()->zone(); 2149 Zone* zone = Thread::Current()->zone();
2244 const char* c = scope; 2150 const char* c = scope;
2245 if (*c++ != '{') return false; 2151 if (*c++ != '{') return false;
2246 2152
2247 for (;;) { 2153 for (;;) {
(...skipping 29 matching lines...) Expand all
2277 2183
2278 while (IsWhitespace(*c)) { 2184 while (IsWhitespace(*c)) {
2279 c++; 2185 c++;
2280 } 2186 }
2281 if (*c == ',') c++; 2187 if (*c == ',') c++;
2282 } 2188 }
2283 2189
2284 return false; 2190 return false;
2285 } 2191 }
2286 2192
2287
2288 static bool BuildScope(Thread* thread, 2193 static bool BuildScope(Thread* thread,
2289 JSONStream* js, 2194 JSONStream* js,
2290 const GrowableObjectArray& names, 2195 const GrowableObjectArray& names,
2291 const GrowableObjectArray& values) { 2196 const GrowableObjectArray& values) {
2292 const char* scope = js->LookupParam("scope"); 2197 const char* scope = js->LookupParam("scope");
2293 GrowableArray<const char*> cnames; 2198 GrowableArray<const char*> cnames;
2294 GrowableArray<const char*> cids; 2199 GrowableArray<const char*> cids;
2295 if (scope != NULL) { 2200 if (scope != NULL) {
2296 if (!ParseScope(scope, &cnames, &cids)) { 2201 if (!ParseScope(scope, &cnames, &cids)) {
2297 PrintInvalidParamError(js, "scope"); 2202 PrintInvalidParamError(js, "scope");
(...skipping 22 matching lines...) Expand all
2320 return true; 2225 return true;
2321 } 2226 }
2322 name = String::New(cnames[i]); 2227 name = String::New(cnames[i]);
2323 names.Add(name); 2228 names.Add(name);
2324 values.Add(obj); 2229 values.Add(obj);
2325 } 2230 }
2326 } 2231 }
2327 return false; 2232 return false;
2328 } 2233 }
2329 2234
2330
2331 static bool Evaluate(Thread* thread, JSONStream* js) { 2235 static bool Evaluate(Thread* thread, JSONStream* js) {
2332 if (!thread->isolate()->compilation_allowed()) { 2236 if (!thread->isolate()->compilation_allowed()) {
2333 js->PrintError(kFeatureDisabled, 2237 js->PrintError(kFeatureDisabled,
2334 "Cannot evaluate when running a precompiled program."); 2238 "Cannot evaluate when running a precompiled program.");
2335 return true; 2239 return true;
2336 } 2240 }
2337 const char* target_id = js->LookupParam("targetId"); 2241 const char* target_id = js->LookupParam("targetId");
2338 if (target_id == NULL) { 2242 if (target_id == NULL) {
2339 PrintMissingParamError(js, "targetId"); 2243 PrintMissingParamError(js, "targetId");
2340 return true; 2244 return true;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2396 result.PrintJSON(js, true); 2300 result.PrintJSON(js, true);
2397 return true; 2301 return true;
2398 } 2302 }
2399 js->PrintError(kInvalidParams, 2303 js->PrintError(kInvalidParams,
2400 "%s: invalid 'targetId' parameter: " 2304 "%s: invalid 'targetId' parameter: "
2401 "Cannot evaluate against a VM-internal object", 2305 "Cannot evaluate against a VM-internal object",
2402 js->method()); 2306 js->method());
2403 return true; 2307 return true;
2404 } 2308 }
2405 2309
2406
2407 static const MethodParameter* evaluate_in_frame_params[] = { 2310 static const MethodParameter* evaluate_in_frame_params[] = {
2408 RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("frameIndex", true), 2311 RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("frameIndex", true),
2409 new MethodParameter("expression", true), NULL, 2312 new MethodParameter("expression", true), NULL,
2410 }; 2313 };
2411 2314
2412
2413 static bool EvaluateInFrame(Thread* thread, JSONStream* js) { 2315 static bool EvaluateInFrame(Thread* thread, JSONStream* js) {
2414 Isolate* isolate = thread->isolate(); 2316 Isolate* isolate = thread->isolate();
2415 if (!isolate->compilation_allowed()) { 2317 if (!isolate->compilation_allowed()) {
2416 js->PrintError(kFeatureDisabled, 2318 js->PrintError(kFeatureDisabled,
2417 "Cannot evaluate when running a precompiled program."); 2319 "Cannot evaluate when running a precompiled program.");
2418 return true; 2320 return true;
2419 } 2321 }
2420 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); 2322 DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
2421 intptr_t framePos = UIntParameter::Parse(js->LookupParam("frameIndex")); 2323 intptr_t framePos = UIntParameter::Parse(js->LookupParam("frameIndex"));
2422 if (framePos >= stack->Length()) { 2324 if (framePos >= stack->Length()) {
(...skipping 13 matching lines...) Expand all
2436 2338
2437 const char* expr = js->LookupParam("expression"); 2339 const char* expr = js->LookupParam("expression");
2438 const String& expr_str = String::Handle(zone, String::New(expr)); 2340 const String& expr_str = String::Handle(zone, String::New(expr));
2439 2341
2440 const Object& result = 2342 const Object& result =
2441 Object::Handle(zone, frame->Evaluate(expr_str, names, values)); 2343 Object::Handle(zone, frame->Evaluate(expr_str, names, values));
2442 result.PrintJSON(js, true); 2344 result.PrintJSON(js, true);
2443 return true; 2345 return true;
2444 } 2346 }
2445 2347
2446
2447 class GetInstancesVisitor : public ObjectGraph::Visitor { 2348 class GetInstancesVisitor : public ObjectGraph::Visitor {
2448 public: 2349 public:
2449 GetInstancesVisitor(const Class& cls, const Array& storage) 2350 GetInstancesVisitor(const Class& cls, const Array& storage)
2450 : cls_(cls), storage_(storage), count_(0) {} 2351 : cls_(cls), storage_(storage), count_(0) {}
2451 2352
2452 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { 2353 virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
2453 RawObject* raw_obj = it->Get(); 2354 RawObject* raw_obj = it->Get();
2454 if (raw_obj->IsPseudoObject()) { 2355 if (raw_obj->IsPseudoObject()) {
2455 return kProceed; 2356 return kProceed;
2456 } 2357 }
(...skipping 11 matching lines...) Expand all
2468 } 2369 }
2469 2370
2470 intptr_t count() const { return count_; } 2371 intptr_t count() const { return count_; }
2471 2372
2472 private: 2373 private:
2473 const Class& cls_; 2374 const Class& cls_;
2474 const Array& storage_; 2375 const Array& storage_;
2475 intptr_t count_; 2376 intptr_t count_;
2476 }; 2377 };
2477 2378
2478
2479 static const MethodParameter* get_instances_params[] = { 2379 static const MethodParameter* get_instances_params[] = {
2480 RUNNABLE_ISOLATE_PARAMETER, NULL, 2380 RUNNABLE_ISOLATE_PARAMETER, NULL,
2481 }; 2381 };
2482 2382
2483
2484 static bool GetInstances(Thread* thread, JSONStream* js) { 2383 static bool GetInstances(Thread* thread, JSONStream* js) {
2485 const char* target_id = js->LookupParam("classId"); 2384 const char* target_id = js->LookupParam("classId");
2486 if (target_id == NULL) { 2385 if (target_id == NULL) {
2487 PrintMissingParamError(js, "classId"); 2386 PrintMissingParamError(js, "classId");
2488 return true; 2387 return true;
2489 } 2388 }
2490 const char* limit_cstr = js->LookupParam("limit"); 2389 const char* limit_cstr = js->LookupParam("limit");
2491 if (limit_cstr == NULL) { 2390 if (limit_cstr == NULL) {
2492 PrintMissingParamError(js, "limit"); 2391 PrintMissingParamError(js, "limit");
2493 return true; 2392 return true;
(...skipping 29 matching lines...) Expand all
2523 // We nil out the array after generating the response to prevent 2422 // We nil out the array after generating the response to prevent
2524 // reporting spurious references when looking for inbound references 2423 // reporting spurious references when looking for inbound references
2525 // after looking at allInstances. 2424 // after looking at allInstances.
2526 for (intptr_t i = 0; i < storage.Length(); i++) { 2425 for (intptr_t i = 0; i < storage.Length(); i++) {
2527 storage.SetAt(i, Object::null_object()); 2426 storage.SetAt(i, Object::null_object());
2528 } 2427 }
2529 2428
2530 return true; 2429 return true;
2531 } 2430 }
2532 2431
2533
2534 static const char* const report_enum_names[] = { 2432 static const char* const report_enum_names[] = {
2535 SourceReport::kCallSitesStr, 2433 SourceReport::kCallSitesStr,
2536 SourceReport::kCoverageStr, 2434 SourceReport::kCoverageStr,
2537 SourceReport::kPossibleBreakpointsStr, 2435 SourceReport::kPossibleBreakpointsStr,
2538 SourceReport::kProfileStr, 2436 SourceReport::kProfileStr,
2539 NULL, 2437 NULL,
2540 }; 2438 };
2541 2439
2542
2543 static const MethodParameter* get_source_report_params[] = { 2440 static const MethodParameter* get_source_report_params[] = {
2544 RUNNABLE_ISOLATE_PARAMETER, 2441 RUNNABLE_ISOLATE_PARAMETER,
2545 new EnumListParameter("reports", true, report_enum_names), 2442 new EnumListParameter("reports", true, report_enum_names),
2546 new IdParameter("scriptId", false), 2443 new IdParameter("scriptId", false),
2547 new UIntParameter("tokenPos", false), 2444 new UIntParameter("tokenPos", false),
2548 new UIntParameter("endTokenPos", false), 2445 new UIntParameter("endTokenPos", false),
2549 new BoolParameter("forceCompile", false), 2446 new BoolParameter("forceCompile", false),
2550 NULL, 2447 NULL,
2551 }; 2448 };
2552 2449
2553
2554 static bool GetSourceReport(Thread* thread, JSONStream* js) { 2450 static bool GetSourceReport(Thread* thread, JSONStream* js) {
2555 if (!thread->isolate()->compilation_allowed()) { 2451 if (!thread->isolate()->compilation_allowed()) {
2556 js->PrintError( 2452 js->PrintError(
2557 kFeatureDisabled, 2453 kFeatureDisabled,
2558 "Cannot get source report when running a precompiled program."); 2454 "Cannot get source report when running a precompiled program.");
2559 return true; 2455 return true;
2560 } 2456 }
2561 const char* reports_str = js->LookupParam("reports"); 2457 const char* reports_str = js->LookupParam("reports");
2562 const EnumListParameter* reports_parameter = 2458 const EnumListParameter* reports_parameter =
2563 static_cast<const EnumListParameter*>(get_source_report_params[1]); 2459 static_cast<const EnumListParameter*>(get_source_report_params[1]);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2610 js->method()); 2506 js->method());
2611 return true; 2507 return true;
2612 } 2508 }
2613 } 2509 }
2614 SourceReport report(report_set, compile_mode); 2510 SourceReport report(report_set, compile_mode);
2615 report.PrintJSON(js, script, TokenPosition(start_pos), 2511 report.PrintJSON(js, script, TokenPosition(start_pos),
2616 TokenPosition(end_pos)); 2512 TokenPosition(end_pos));
2617 return true; 2513 return true;
2618 } 2514 }
2619 2515
2620
2621 static const MethodParameter* reload_sources_params[] = { 2516 static const MethodParameter* reload_sources_params[] = {
2622 RUNNABLE_ISOLATE_PARAMETER, 2517 RUNNABLE_ISOLATE_PARAMETER,
2623 new BoolParameter("force", false), 2518 new BoolParameter("force", false),
2624 new BoolParameter("pause", false), 2519 new BoolParameter("pause", false),
2625 new StringParameter("rootLibUri", false), 2520 new StringParameter("rootLibUri", false),
2626 new StringParameter("packagesUri", false), 2521 new StringParameter("packagesUri", false),
2627 NULL, 2522 NULL,
2628 }; 2523 };
2629 2524
2630
2631 static bool ReloadSources(Thread* thread, JSONStream* js) { 2525 static bool ReloadSources(Thread* thread, JSONStream* js) {
2632 Isolate* isolate = thread->isolate(); 2526 Isolate* isolate = thread->isolate();
2633 if (!isolate->compilation_allowed()) { 2527 if (!isolate->compilation_allowed()) {
2634 js->PrintError(kFeatureDisabled, 2528 js->PrintError(kFeatureDisabled,
2635 "Cannot reload source when running a precompiled program."); 2529 "Cannot reload source when running a precompiled program.");
2636 return true; 2530 return true;
2637 } 2531 }
2638 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); 2532 Dart_LibraryTagHandler handler = isolate->library_tag_handler();
2639 if (handler == NULL) { 2533 if (handler == NULL) {
2640 js->PrintError(kFeatureDisabled, 2534 js->PrintError(kFeatureDisabled,
(...skipping 20 matching lines...) Expand all
2661 BoolParameter::Parse(js->LookupParam("force"), false); 2555 BoolParameter::Parse(js->LookupParam("force"), false);
2662 2556
2663 isolate->ReloadSources(js, force_reload, js->LookupParam("rootLibUri"), 2557 isolate->ReloadSources(js, force_reload, js->LookupParam("rootLibUri"),
2664 js->LookupParam("packagesUri")); 2558 js->LookupParam("packagesUri"));
2665 2559
2666 Service::CheckForPause(isolate, js); 2560 Service::CheckForPause(isolate, js);
2667 2561
2668 return true; 2562 return true;
2669 } 2563 }
2670 2564
2671
2672 void Service::CheckForPause(Isolate* isolate, JSONStream* stream) { 2565 void Service::CheckForPause(Isolate* isolate, JSONStream* stream) {
2673 // Should we pause? 2566 // Should we pause?
2674 isolate->set_should_pause_post_service_request( 2567 isolate->set_should_pause_post_service_request(
2675 BoolParameter::Parse(stream->LookupParam("pause"), false)); 2568 BoolParameter::Parse(stream->LookupParam("pause"), false));
2676 } 2569 }
2677 2570
2678
2679 RawError* Service::MaybePause(Isolate* isolate, const Error& error) { 2571 RawError* Service::MaybePause(Isolate* isolate, const Error& error) {
2680 // Don't pause twice. 2572 // Don't pause twice.
2681 if (!isolate->IsPaused()) { 2573 if (!isolate->IsPaused()) {
2682 if (isolate->should_pause_post_service_request()) { 2574 if (isolate->should_pause_post_service_request()) {
2683 isolate->set_should_pause_post_service_request(false); 2575 isolate->set_should_pause_post_service_request(false);
2684 if (!error.IsNull()) { 2576 if (!error.IsNull()) {
2685 // Before pausing, restore the sticky error. The debugger will return it 2577 // Before pausing, restore the sticky error. The debugger will return it
2686 // from PausePostRequest. 2578 // from PausePostRequest.
2687 Thread::Current()->set_sticky_error(error); 2579 Thread::Current()->set_sticky_error(error);
2688 } 2580 }
2689 return isolate->PausePostRequest(); 2581 return isolate->PausePostRequest();
2690 } 2582 }
2691 } 2583 }
2692 return error.raw(); 2584 return error.raw();
2693 } 2585 }
2694 2586
2695
2696 static bool AddBreakpointCommon(Thread* thread, 2587 static bool AddBreakpointCommon(Thread* thread,
2697 JSONStream* js, 2588 JSONStream* js,
2698 const String& script_uri) { 2589 const String& script_uri) {
2699 if (!thread->isolate()->compilation_allowed()) { 2590 if (!thread->isolate()->compilation_allowed()) {
2700 js->PrintError( 2591 js->PrintError(
2701 kFeatureDisabled, 2592 kFeatureDisabled,
2702 "Cannot use breakpoints when running a precompiled program."); 2593 "Cannot use breakpoints when running a precompiled program.");
2703 return true; 2594 return true;
2704 } 2595 }
2705 const char* line_param = js->LookupParam("line"); 2596 const char* line_param = js->LookupParam("line");
(...skipping 15 matching lines...) Expand all
2721 if (bpt == NULL) { 2612 if (bpt == NULL) {
2722 js->PrintError(kCannotAddBreakpoint, 2613 js->PrintError(kCannotAddBreakpoint,
2723 "%s: Cannot add breakpoint at line '%s'", js->method(), 2614 "%s: Cannot add breakpoint at line '%s'", js->method(),
2724 line_param); 2615 line_param);
2725 return true; 2616 return true;
2726 } 2617 }
2727 bpt->PrintJSON(js); 2618 bpt->PrintJSON(js);
2728 return true; 2619 return true;
2729 } 2620 }
2730 2621
2731
2732 static const MethodParameter* add_breakpoint_params[] = { 2622 static const MethodParameter* add_breakpoint_params[] = {
2733 RUNNABLE_ISOLATE_PARAMETER, 2623 RUNNABLE_ISOLATE_PARAMETER,
2734 new IdParameter("scriptId", true), 2624 new IdParameter("scriptId", true),
2735 new UIntParameter("line", true), 2625 new UIntParameter("line", true),
2736 new UIntParameter("column", false), 2626 new UIntParameter("column", false),
2737 NULL, 2627 NULL,
2738 }; 2628 };
2739 2629
2740
2741 static bool AddBreakpoint(Thread* thread, JSONStream* js) { 2630 static bool AddBreakpoint(Thread* thread, JSONStream* js) {
2742 if (!thread->isolate()->compilation_allowed()) { 2631 if (!thread->isolate()->compilation_allowed()) {
2743 js->PrintError( 2632 js->PrintError(
2744 kFeatureDisabled, 2633 kFeatureDisabled,
2745 "Cannot use breakpoints when running a precompiled program."); 2634 "Cannot use breakpoints when running a precompiled program.");
2746 return true; 2635 return true;
2747 } 2636 }
2748 const char* script_id_param = js->LookupParam("scriptId"); 2637 const char* script_id_param = js->LookupParam("scriptId");
2749 Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL)); 2638 Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL));
2750 if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) { 2639 if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) {
2751 PrintInvalidParamError(js, "scriptId"); 2640 PrintInvalidParamError(js, "scriptId");
2752 return true; 2641 return true;
2753 } 2642 }
2754 const Script& script = Script::Cast(obj); 2643 const Script& script = Script::Cast(obj);
2755 const String& script_uri = String::Handle(script.url()); 2644 const String& script_uri = String::Handle(script.url());
2756 ASSERT(!script_uri.IsNull()); 2645 ASSERT(!script_uri.IsNull());
2757 return AddBreakpointCommon(thread, js, script_uri); 2646 return AddBreakpointCommon(thread, js, script_uri);
2758 } 2647 }
2759 2648
2760
2761 static const MethodParameter* add_breakpoint_with_script_uri_params[] = { 2649 static const MethodParameter* add_breakpoint_with_script_uri_params[] = {
2762 RUNNABLE_ISOLATE_PARAMETER, 2650 RUNNABLE_ISOLATE_PARAMETER,
2763 new IdParameter("scriptUri", true), 2651 new IdParameter("scriptUri", true),
2764 new UIntParameter("line", true), 2652 new UIntParameter("line", true),
2765 new UIntParameter("column", false), 2653 new UIntParameter("column", false),
2766 NULL, 2654 NULL,
2767 }; 2655 };
2768 2656
2769
2770 static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) { 2657 static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) {
2771 if (!thread->isolate()->compilation_allowed()) { 2658 if (!thread->isolate()->compilation_allowed()) {
2772 js->PrintError( 2659 js->PrintError(
2773 kFeatureDisabled, 2660 kFeatureDisabled,
2774 "Cannot use breakpoints when running a precompiled program."); 2661 "Cannot use breakpoints when running a precompiled program.");
2775 return true; 2662 return true;
2776 } 2663 }
2777 const char* script_uri_param = js->LookupParam("scriptUri"); 2664 const char* script_uri_param = js->LookupParam("scriptUri");
2778 const String& script_uri = String::Handle(String::New(script_uri_param)); 2665 const String& script_uri = String::Handle(String::New(script_uri_param));
2779 return AddBreakpointCommon(thread, js, script_uri); 2666 return AddBreakpointCommon(thread, js, script_uri);
2780 } 2667 }
2781 2668
2782
2783 static const MethodParameter* add_breakpoint_at_entry_params[] = { 2669 static const MethodParameter* add_breakpoint_at_entry_params[] = {
2784 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("functionId", true), NULL, 2670 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("functionId", true), NULL,
2785 }; 2671 };
2786 2672
2787
2788 static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) { 2673 static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) {
2789 if (!thread->isolate()->compilation_allowed()) { 2674 if (!thread->isolate()->compilation_allowed()) {
2790 js->PrintError( 2675 js->PrintError(
2791 kFeatureDisabled, 2676 kFeatureDisabled,
2792 "Cannot use breakpoints when running a precompiled program."); 2677 "Cannot use breakpoints when running a precompiled program.");
2793 return true; 2678 return true;
2794 } 2679 }
2795 const char* function_id = js->LookupParam("functionId"); 2680 const char* function_id = js->LookupParam("functionId");
2796 Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL)); 2681 Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL));
2797 if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) { 2682 if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) {
2798 PrintInvalidParamError(js, "functionId"); 2683 PrintInvalidParamError(js, "functionId");
2799 return true; 2684 return true;
2800 } 2685 }
2801 const Function& function = Function::Cast(obj); 2686 const Function& function = Function::Cast(obj);
2802 Breakpoint* bpt = 2687 Breakpoint* bpt =
2803 thread->isolate()->debugger()->SetBreakpointAtEntry(function, false); 2688 thread->isolate()->debugger()->SetBreakpointAtEntry(function, false);
2804 if (bpt == NULL) { 2689 if (bpt == NULL) {
2805 js->PrintError(kCannotAddBreakpoint, 2690 js->PrintError(kCannotAddBreakpoint,
2806 "%s: Cannot add breakpoint at function '%s'", js->method(), 2691 "%s: Cannot add breakpoint at function '%s'", js->method(),
2807 function.ToCString()); 2692 function.ToCString());
2808 return true; 2693 return true;
2809 } 2694 }
2810 bpt->PrintJSON(js); 2695 bpt->PrintJSON(js);
2811 return true; 2696 return true;
2812 } 2697 }
2813 2698
2814
2815 static const MethodParameter* add_breakpoint_at_activation_params[] = { 2699 static const MethodParameter* add_breakpoint_at_activation_params[] = {
2816 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("objectId", true), NULL, 2700 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("objectId", true), NULL,
2817 }; 2701 };
2818 2702
2819
2820 static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) { 2703 static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) {
2821 if (!thread->isolate()->compilation_allowed()) { 2704 if (!thread->isolate()->compilation_allowed()) {
2822 js->PrintError( 2705 js->PrintError(
2823 kFeatureDisabled, 2706 kFeatureDisabled,
2824 "Cannot use breakpoints when running a precompiled program."); 2707 "Cannot use breakpoints when running a precompiled program.");
2825 return true; 2708 return true;
2826 } 2709 }
2827 const char* object_id = js->LookupParam("objectId"); 2710 const char* object_id = js->LookupParam("objectId");
2828 Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL)); 2711 Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL));
2829 if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) { 2712 if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) {
2830 PrintInvalidParamError(js, "objectId"); 2713 PrintInvalidParamError(js, "objectId");
2831 return true; 2714 return true;
2832 } 2715 }
2833 const Instance& closure = Instance::Cast(obj); 2716 const Instance& closure = Instance::Cast(obj);
2834 Breakpoint* bpt = 2717 Breakpoint* bpt =
2835 thread->isolate()->debugger()->SetBreakpointAtActivation(closure, false); 2718 thread->isolate()->debugger()->SetBreakpointAtActivation(closure, false);
2836 if (bpt == NULL) { 2719 if (bpt == NULL) {
2837 js->PrintError(kCannotAddBreakpoint, 2720 js->PrintError(kCannotAddBreakpoint,
2838 "%s: Cannot add breakpoint at activation", js->method()); 2721 "%s: Cannot add breakpoint at activation", js->method());
2839 return true; 2722 return true;
2840 } 2723 }
2841 bpt->PrintJSON(js); 2724 bpt->PrintJSON(js);
2842 return true; 2725 return true;
2843 } 2726 }
2844 2727
2845
2846 static const MethodParameter* remove_breakpoint_params[] = { 2728 static const MethodParameter* remove_breakpoint_params[] = {
2847 RUNNABLE_ISOLATE_PARAMETER, NULL, 2729 RUNNABLE_ISOLATE_PARAMETER, NULL,
2848 }; 2730 };
2849 2731
2850
2851 static bool RemoveBreakpoint(Thread* thread, JSONStream* js) { 2732 static bool RemoveBreakpoint(Thread* thread, JSONStream* js) {
2852 if (!thread->isolate()->compilation_allowed()) { 2733 if (!thread->isolate()->compilation_allowed()) {
2853 js->PrintError( 2734 js->PrintError(
2854 kFeatureDisabled, 2735 kFeatureDisabled,
2855 "Cannot use breakpoints when running a precompiled program."); 2736 "Cannot use breakpoints when running a precompiled program.");
2856 return true; 2737 return true;
2857 } 2738 }
2858 if (!js->HasParam("breakpointId")) { 2739 if (!js->HasParam("breakpointId")) {
2859 PrintMissingParamError(js, "breakpointId"); 2740 PrintMissingParamError(js, "breakpointId");
2860 return true; 2741 return true;
2861 } 2742 }
2862 const char* bpt_id = js->LookupParam("breakpointId"); 2743 const char* bpt_id = js->LookupParam("breakpointId");
2863 ObjectIdRing::LookupResult lookup_result; 2744 ObjectIdRing::LookupResult lookup_result;
2864 Isolate* isolate = thread->isolate(); 2745 Isolate* isolate = thread->isolate();
2865 Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result); 2746 Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result);
2866 // TODO(turnidge): Should we return a different error for bpts whic 2747 // TODO(turnidge): Should we return a different error for bpts whic
2867 // have been already removed? 2748 // have been already removed?
2868 if (bpt == NULL) { 2749 if (bpt == NULL) {
2869 PrintInvalidParamError(js, "breakpointId"); 2750 PrintInvalidParamError(js, "breakpointId");
2870 return true; 2751 return true;
2871 } 2752 }
2872 isolate->debugger()->RemoveBreakpoint(bpt->id()); 2753 isolate->debugger()->RemoveBreakpoint(bpt->id());
2873 PrintSuccess(js); 2754 PrintSuccess(js);
2874 return true; 2755 return true;
2875 } 2756 }
2876 2757
2877
2878 static RawClass* GetMetricsClass(Thread* thread) { 2758 static RawClass* GetMetricsClass(Thread* thread) {
2879 Zone* zone = thread->zone(); 2759 Zone* zone = thread->zone();
2880 const Library& prof_lib = Library::Handle(zone, Library::DeveloperLibrary()); 2760 const Library& prof_lib = Library::Handle(zone, Library::DeveloperLibrary());
2881 ASSERT(!prof_lib.IsNull()); 2761 ASSERT(!prof_lib.IsNull());
2882 const String& metrics_cls_name = String::Handle(zone, String::New("Metrics")); 2762 const String& metrics_cls_name = String::Handle(zone, String::New("Metrics"));
2883 ASSERT(!metrics_cls_name.IsNull()); 2763 ASSERT(!metrics_cls_name.IsNull());
2884 const Class& metrics_cls = 2764 const Class& metrics_cls =
2885 Class::Handle(zone, prof_lib.LookupClass(metrics_cls_name)); 2765 Class::Handle(zone, prof_lib.LookupClass(metrics_cls_name));
2886 ASSERT(!metrics_cls.IsNull()); 2766 ASSERT(!metrics_cls.IsNull());
2887 return metrics_cls.raw(); 2767 return metrics_cls.raw();
2888 } 2768 }
2889 2769
2890
2891 static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) { 2770 static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) {
2892 JSONObject obj(js); 2771 JSONObject obj(js);
2893 obj.AddProperty("type", "MetricList"); 2772 obj.AddProperty("type", "MetricList");
2894 { 2773 {
2895 JSONArray metrics(&obj, "metrics"); 2774 JSONArray metrics(&obj, "metrics");
2896 Metric* current = thread->isolate()->metrics_list_head(); 2775 Metric* current = thread->isolate()->metrics_list_head();
2897 while (current != NULL) { 2776 while (current != NULL) {
2898 metrics.AddValue(current); 2777 metrics.AddValue(current);
2899 current = current->next(); 2778 current = current->next();
2900 } 2779 }
2901 } 2780 }
2902 return true; 2781 return true;
2903 } 2782 }
2904 2783
2905
2906 static bool HandleNativeMetric(Thread* thread, JSONStream* js, const char* id) { 2784 static bool HandleNativeMetric(Thread* thread, JSONStream* js, const char* id) {
2907 Metric* current = thread->isolate()->metrics_list_head(); 2785 Metric* current = thread->isolate()->metrics_list_head();
2908 while (current != NULL) { 2786 while (current != NULL) {
2909 const char* name = current->name(); 2787 const char* name = current->name();
2910 ASSERT(name != NULL); 2788 ASSERT(name != NULL);
2911 if (strcmp(name, id) == 0) { 2789 if (strcmp(name, id) == 0) {
2912 current->PrintJSON(js); 2790 current->PrintJSON(js);
2913 return true; 2791 return true;
2914 } 2792 }
2915 current = current->next(); 2793 current = current->next();
2916 } 2794 }
2917 PrintInvalidParamError(js, "metricId"); 2795 PrintInvalidParamError(js, "metricId");
2918 return true; 2796 return true;
2919 } 2797 }
2920 2798
2921
2922 static bool HandleDartMetricsList(Thread* thread, JSONStream* js) { 2799 static bool HandleDartMetricsList(Thread* thread, JSONStream* js) {
2923 Zone* zone = thread->zone(); 2800 Zone* zone = thread->zone();
2924 const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(thread)); 2801 const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(thread));
2925 const String& print_metrics_name = 2802 const String& print_metrics_name =
2926 String::Handle(String::New("_printMetrics")); 2803 String::Handle(String::New("_printMetrics"));
2927 ASSERT(!print_metrics_name.IsNull()); 2804 ASSERT(!print_metrics_name.IsNull());
2928 const Function& print_metrics = Function::Handle( 2805 const Function& print_metrics = Function::Handle(
2929 zone, metrics_cls.LookupStaticFunctionAllowPrivate(print_metrics_name)); 2806 zone, metrics_cls.LookupStaticFunctionAllowPrivate(print_metrics_name));
2930 ASSERT(!print_metrics.IsNull()); 2807 ASSERT(!print_metrics.IsNull());
2931 const Array& args = Object::empty_array(); 2808 const Array& args = Object::empty_array();
2932 const Object& result = 2809 const Object& result =
2933 Object::Handle(zone, DartEntry::InvokeFunction(print_metrics, args)); 2810 Object::Handle(zone, DartEntry::InvokeFunction(print_metrics, args));
2934 ASSERT(!result.IsNull()); 2811 ASSERT(!result.IsNull());
2935 ASSERT(result.IsString()); 2812 ASSERT(result.IsString());
2936 TextBuffer* buffer = js->buffer(); 2813 TextBuffer* buffer = js->buffer();
2937 buffer->AddString(String::Cast(result).ToCString()); 2814 buffer->AddString(String::Cast(result).ToCString());
2938 return true; 2815 return true;
2939 } 2816 }
2940 2817
2941
2942 static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) { 2818 static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) {
2943 Zone* zone = thread->zone(); 2819 Zone* zone = thread->zone();
2944 const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(thread)); 2820 const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(thread));
2945 const String& print_metric_name = String::Handle(String::New("_printMetric")); 2821 const String& print_metric_name = String::Handle(String::New("_printMetric"));
2946 ASSERT(!print_metric_name.IsNull()); 2822 ASSERT(!print_metric_name.IsNull());
2947 const Function& print_metric = Function::Handle( 2823 const Function& print_metric = Function::Handle(
2948 zone, metrics_cls.LookupStaticFunctionAllowPrivate(print_metric_name)); 2824 zone, metrics_cls.LookupStaticFunctionAllowPrivate(print_metric_name));
2949 ASSERT(!print_metric.IsNull()); 2825 ASSERT(!print_metric.IsNull());
2950 const String& arg0 = String::Handle(String::New(id)); 2826 const String& arg0 = String::Handle(String::New(id));
2951 ASSERT(!arg0.IsNull()); 2827 ASSERT(!arg0.IsNull());
2952 const Array& args = Array::Handle(Array::New(1)); 2828 const Array& args = Array::Handle(Array::New(1));
2953 ASSERT(!args.IsNull()); 2829 ASSERT(!args.IsNull());
2954 args.SetAt(0, arg0); 2830 args.SetAt(0, arg0);
2955 const Object& result = 2831 const Object& result =
2956 Object::Handle(zone, DartEntry::InvokeFunction(print_metric, args)); 2832 Object::Handle(zone, DartEntry::InvokeFunction(print_metric, args));
2957 if (!result.IsNull()) { 2833 if (!result.IsNull()) {
2958 ASSERT(result.IsString()); 2834 ASSERT(result.IsString());
2959 TextBuffer* buffer = js->buffer(); 2835 TextBuffer* buffer = js->buffer();
2960 buffer->AddString(String::Cast(result).ToCString()); 2836 buffer->AddString(String::Cast(result).ToCString());
2961 return true; 2837 return true;
2962 } 2838 }
2963 PrintInvalidParamError(js, "metricId"); 2839 PrintInvalidParamError(js, "metricId");
2964 return true; 2840 return true;
2965 } 2841 }
2966 2842
2967
2968 static const MethodParameter* get_isolate_metric_list_params[] = { 2843 static const MethodParameter* get_isolate_metric_list_params[] = {
2969 RUNNABLE_ISOLATE_PARAMETER, NULL, 2844 RUNNABLE_ISOLATE_PARAMETER, NULL,
2970 }; 2845 };
2971 2846
2972
2973 static bool GetIsolateMetricList(Thread* thread, JSONStream* js) { 2847 static bool GetIsolateMetricList(Thread* thread, JSONStream* js) {
2974 bool native_metrics = false; 2848 bool native_metrics = false;
2975 if (js->HasParam("type")) { 2849 if (js->HasParam("type")) {
2976 if (js->ParamIs("type", "Native")) { 2850 if (js->ParamIs("type", "Native")) {
2977 native_metrics = true; 2851 native_metrics = true;
2978 } else if (js->ParamIs("type", "Dart")) { 2852 } else if (js->ParamIs("type", "Dart")) {
2979 native_metrics = false; 2853 native_metrics = false;
2980 } else { 2854 } else {
2981 PrintInvalidParamError(js, "type"); 2855 PrintInvalidParamError(js, "type");
2982 return true; 2856 return true;
2983 } 2857 }
2984 } else { 2858 } else {
2985 PrintMissingParamError(js, "type"); 2859 PrintMissingParamError(js, "type");
2986 return true; 2860 return true;
2987 } 2861 }
2988 if (native_metrics) { 2862 if (native_metrics) {
2989 return HandleNativeMetricsList(thread, js); 2863 return HandleNativeMetricsList(thread, js);
2990 } 2864 }
2991 return HandleDartMetricsList(thread, js); 2865 return HandleDartMetricsList(thread, js);
2992 } 2866 }
2993 2867
2994
2995 static const MethodParameter* get_isolate_metric_params[] = { 2868 static const MethodParameter* get_isolate_metric_params[] = {
2996 RUNNABLE_ISOLATE_PARAMETER, NULL, 2869 RUNNABLE_ISOLATE_PARAMETER, NULL,
2997 }; 2870 };
2998 2871
2999
3000 static bool GetIsolateMetric(Thread* thread, JSONStream* js) { 2872 static bool GetIsolateMetric(Thread* thread, JSONStream* js) {
3001 const char* metric_id = js->LookupParam("metricId"); 2873 const char* metric_id = js->LookupParam("metricId");
3002 if (metric_id == NULL) { 2874 if (metric_id == NULL) {
3003 PrintMissingParamError(js, "metricId"); 2875 PrintMissingParamError(js, "metricId");
3004 return true; 2876 return true;
3005 } 2877 }
3006 // Verify id begins with "metrics/". 2878 // Verify id begins with "metrics/".
3007 static const char* const kMetricIdPrefix = "metrics/"; 2879 static const char* const kMetricIdPrefix = "metrics/";
3008 static intptr_t kMetricIdPrefixLen = strlen(kMetricIdPrefix); 2880 static intptr_t kMetricIdPrefixLen = strlen(kMetricIdPrefix);
3009 if (strncmp(metric_id, kMetricIdPrefix, kMetricIdPrefixLen) != 0) { 2881 if (strncmp(metric_id, kMetricIdPrefix, kMetricIdPrefixLen) != 0) {
3010 PrintInvalidParamError(js, "metricId"); 2882 PrintInvalidParamError(js, "metricId");
3011 return true; 2883 return true;
3012 } 2884 }
3013 // Check if id begins with "metrics/native/". 2885 // Check if id begins with "metrics/native/".
3014 static const char* const kNativeMetricIdPrefix = "metrics/native/"; 2886 static const char* const kNativeMetricIdPrefix = "metrics/native/";
3015 static intptr_t kNativeMetricIdPrefixLen = strlen(kNativeMetricIdPrefix); 2887 static intptr_t kNativeMetricIdPrefixLen = strlen(kNativeMetricIdPrefix);
3016 const bool native_metric = 2888 const bool native_metric =
3017 strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0; 2889 strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0;
3018 if (native_metric) { 2890 if (native_metric) {
3019 const char* id = metric_id + kNativeMetricIdPrefixLen; 2891 const char* id = metric_id + kNativeMetricIdPrefixLen;
3020 return HandleNativeMetric(thread, js, id); 2892 return HandleNativeMetric(thread, js, id);
3021 } 2893 }
3022 const char* id = metric_id + kMetricIdPrefixLen; 2894 const char* id = metric_id + kMetricIdPrefixLen;
3023 return HandleDartMetric(thread, js, id); 2895 return HandleDartMetric(thread, js, id);
3024 } 2896 }
3025 2897
3026
3027 static const MethodParameter* get_vm_metric_list_params[] = { 2898 static const MethodParameter* get_vm_metric_list_params[] = {
3028 NO_ISOLATE_PARAMETER, NULL, 2899 NO_ISOLATE_PARAMETER, NULL,
3029 }; 2900 };
3030 2901
3031
3032 static bool GetVMMetricList(Thread* thread, JSONStream* js) { 2902 static bool GetVMMetricList(Thread* thread, JSONStream* js) {
3033 return false; 2903 return false;
3034 } 2904 }
3035 2905
3036
3037 static const MethodParameter* get_vm_metric_params[] = { 2906 static const MethodParameter* get_vm_metric_params[] = {
3038 NO_ISOLATE_PARAMETER, NULL, 2907 NO_ISOLATE_PARAMETER, NULL,
3039 }; 2908 };
3040 2909
3041
3042 static bool GetVMMetric(Thread* thread, JSONStream* js) { 2910 static bool GetVMMetric(Thread* thread, JSONStream* js) {
3043 const char* metric_id = js->LookupParam("metricId"); 2911 const char* metric_id = js->LookupParam("metricId");
3044 if (metric_id == NULL) { 2912 if (metric_id == NULL) {
3045 PrintMissingParamError(js, "metricId"); 2913 PrintMissingParamError(js, "metricId");
3046 } 2914 }
3047 return false; 2915 return false;
3048 } 2916 }
3049 2917
3050 static const char* const timeline_streams_enum_names[] = { 2918 static const char* const timeline_streams_enum_names[] = {
3051 "all", 2919 "all",
3052 #define DEFINE_NAME(name, unused) #name, 2920 #define DEFINE_NAME(name, unused) #name,
3053 TIMELINE_STREAM_LIST(DEFINE_NAME) 2921 TIMELINE_STREAM_LIST(DEFINE_NAME)
3054 #undef DEFINE_NAME 2922 #undef DEFINE_NAME
3055 NULL}; 2923 NULL};
3056 2924
3057 static const MethodParameter* set_vm_timeline_flags_params[] = { 2925 static const MethodParameter* set_vm_timeline_flags_params[] = {
3058 NO_ISOLATE_PARAMETER, 2926 NO_ISOLATE_PARAMETER,
3059 new EnumListParameter("recordedStreams", 2927 new EnumListParameter("recordedStreams",
3060 false, 2928 false,
3061 timeline_streams_enum_names), 2929 timeline_streams_enum_names),
3062 NULL, 2930 NULL,
3063 }; 2931 };
3064 2932
3065
3066 static bool HasStream(const char** recorded_streams, const char* stream) { 2933 static bool HasStream(const char** recorded_streams, const char* stream) {
3067 while (*recorded_streams != NULL) { 2934 while (*recorded_streams != NULL) {
3068 if ((strstr(*recorded_streams, "all") != NULL) || 2935 if ((strstr(*recorded_streams, "all") != NULL) ||
3069 (strstr(*recorded_streams, stream) != NULL)) { 2936 (strstr(*recorded_streams, stream) != NULL)) {
3070 return true; 2937 return true;
3071 } 2938 }
3072 recorded_streams++; 2939 recorded_streams++;
3073 } 2940 }
3074 return false; 2941 return false;
3075 } 2942 }
3076 2943
3077
3078 static bool SetVMTimelineFlags(Thread* thread, JSONStream* js) { 2944 static bool SetVMTimelineFlags(Thread* thread, JSONStream* js) {
3079 if (!FLAG_support_timeline) { 2945 if (!FLAG_support_timeline) {
3080 PrintSuccess(js); 2946 PrintSuccess(js);
3081 return true; 2947 return true;
3082 } 2948 }
3083 Isolate* isolate = thread->isolate(); 2949 Isolate* isolate = thread->isolate();
3084 ASSERT(isolate != NULL); 2950 ASSERT(isolate != NULL);
3085 StackZone zone(thread); 2951 StackZone zone(thread);
3086 2952
3087 const EnumListParameter* recorded_streams_param = 2953 const EnumListParameter* recorded_streams_param =
3088 static_cast<const EnumListParameter*>(set_vm_timeline_flags_params[1]); 2954 static_cast<const EnumListParameter*>(set_vm_timeline_flags_params[1]);
3089 2955
3090 const char* recorded_streams_str = js->LookupParam("recordedStreams"); 2956 const char* recorded_streams_str = js->LookupParam("recordedStreams");
3091 const char** recorded_streams = 2957 const char** recorded_streams =
3092 recorded_streams_param->Parse(thread->zone(), recorded_streams_str); 2958 recorded_streams_param->Parse(thread->zone(), recorded_streams_str);
3093 2959
3094 #define SET_ENABLE_STREAM(name, unused) \ 2960 #define SET_ENABLE_STREAM(name, unused) \
3095 Timeline::SetStream##name##Enabled(HasStream(recorded_streams, #name)); 2961 Timeline::SetStream##name##Enabled(HasStream(recorded_streams, #name));
3096 TIMELINE_STREAM_LIST(SET_ENABLE_STREAM); 2962 TIMELINE_STREAM_LIST(SET_ENABLE_STREAM);
3097 #undef SET_ENABLE_STREAM 2963 #undef SET_ENABLE_STREAM
3098 2964
3099 PrintSuccess(js); 2965 PrintSuccess(js);
3100 2966
3101 return true; 2967 return true;
3102 } 2968 }
3103 2969
3104
3105 static const MethodParameter* get_vm_timeline_flags_params[] = { 2970 static const MethodParameter* get_vm_timeline_flags_params[] = {
3106 NO_ISOLATE_PARAMETER, NULL, 2971 NO_ISOLATE_PARAMETER, NULL,
3107 }; 2972 };
3108 2973
3109
3110 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) { 2974 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) {
3111 if (!FLAG_support_timeline) { 2975 if (!FLAG_support_timeline) {
3112 JSONObject obj(js); 2976 JSONObject obj(js);
3113 obj.AddProperty("type", "TimelineFlags"); 2977 obj.AddProperty("type", "TimelineFlags");
3114 return true; 2978 return true;
3115 } 2979 }
3116 Isolate* isolate = thread->isolate(); 2980 Isolate* isolate = thread->isolate();
3117 ASSERT(isolate != NULL); 2981 ASSERT(isolate != NULL);
3118 StackZone zone(thread); 2982 StackZone zone(thread);
3119 Timeline::PrintFlagsToJSON(js); 2983 Timeline::PrintFlagsToJSON(js);
3120 return true; 2984 return true;
3121 } 2985 }
3122 2986
3123
3124 static const MethodParameter* clear_vm_timeline_params[] = { 2987 static const MethodParameter* clear_vm_timeline_params[] = {
3125 NO_ISOLATE_PARAMETER, NULL, 2988 NO_ISOLATE_PARAMETER, NULL,
3126 }; 2989 };
3127 2990
3128
3129 static bool ClearVMTimeline(Thread* thread, JSONStream* js) { 2991 static bool ClearVMTimeline(Thread* thread, JSONStream* js) {
3130 Isolate* isolate = thread->isolate(); 2992 Isolate* isolate = thread->isolate();
3131 ASSERT(isolate != NULL); 2993 ASSERT(isolate != NULL);
3132 StackZone zone(thread); 2994 StackZone zone(thread);
3133 2995
3134 Timeline::Clear(); 2996 Timeline::Clear();
3135 2997
3136 PrintSuccess(js); 2998 PrintSuccess(js);
3137 2999
3138 return true; 3000 return true;
3139 } 3001 }
3140 3002
3141
3142 static const MethodParameter* get_vm_timeline_params[] = { 3003 static const MethodParameter* get_vm_timeline_params[] = {
3143 NO_ISOLATE_PARAMETER, new Int64Parameter("timeOriginMicros", false), 3004 NO_ISOLATE_PARAMETER, new Int64Parameter("timeOriginMicros", false),
3144 new Int64Parameter("timeExtentMicros", false), NULL, 3005 new Int64Parameter("timeExtentMicros", false), NULL,
3145 }; 3006 };
3146 3007
3147
3148 static bool GetVMTimeline(Thread* thread, JSONStream* js) { 3008 static bool GetVMTimeline(Thread* thread, JSONStream* js) {
3149 Isolate* isolate = thread->isolate(); 3009 Isolate* isolate = thread->isolate();
3150 ASSERT(isolate != NULL); 3010 ASSERT(isolate != NULL);
3151 StackZone zone(thread); 3011 StackZone zone(thread);
3152 Timeline::ReclaimCachedBlocksFromThreads(); 3012 Timeline::ReclaimCachedBlocksFromThreads();
3153 TimelineEventRecorder* timeline_recorder = Timeline::recorder(); 3013 TimelineEventRecorder* timeline_recorder = Timeline::recorder();
3154 // TODO(johnmccutchan): Return an error. 3014 // TODO(johnmccutchan): Return an error.
3155 ASSERT(timeline_recorder != NULL); 3015 ASSERT(timeline_recorder != NULL);
3156 int64_t time_origin_micros = 3016 int64_t time_origin_micros =
3157 Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); 3017 Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
3158 int64_t time_extent_micros = 3018 int64_t time_extent_micros =
3159 Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); 3019 Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
3160 TimelineEventFilter filter(time_origin_micros, time_extent_micros); 3020 TimelineEventFilter filter(time_origin_micros, time_extent_micros);
3161 timeline_recorder->PrintJSON(js, &filter); 3021 timeline_recorder->PrintJSON(js, &filter);
3162 return true; 3022 return true;
3163 } 3023 }
3164 3024
3165
3166 static const char* const step_enum_names[] = { 3025 static const char* const step_enum_names[] = {
3167 "None", "Into", "Over", "Out", "Rewind", "OverAsyncSuspension", NULL, 3026 "None", "Into", "Over", "Out", "Rewind", "OverAsyncSuspension", NULL,
3168 }; 3027 };
3169 3028
3170
3171 static const Debugger::ResumeAction step_enum_values[] = { 3029 static const Debugger::ResumeAction step_enum_values[] = {
3172 Debugger::kContinue, Debugger::kStepInto, 3030 Debugger::kContinue, Debugger::kStepInto,
3173 Debugger::kStepOver, Debugger::kStepOut, 3031 Debugger::kStepOver, Debugger::kStepOut,
3174 Debugger::kStepRewind, Debugger::kStepOverAsyncSuspension, 3032 Debugger::kStepRewind, Debugger::kStepOverAsyncSuspension,
3175 Debugger::kContinue, // Default value 3033 Debugger::kContinue, // Default value
3176 }; 3034 };
3177 3035
3178
3179 static const MethodParameter* resume_params[] = { 3036 static const MethodParameter* resume_params[] = {
3180 RUNNABLE_ISOLATE_PARAMETER, 3037 RUNNABLE_ISOLATE_PARAMETER,
3181 new EnumParameter("step", false, step_enum_names), 3038 new EnumParameter("step", false, step_enum_names),
3182 new UIntParameter("frameIndex", false), NULL, 3039 new UIntParameter("frameIndex", false), NULL,
3183 }; 3040 };
3184 3041
3185
3186 static bool Resume(Thread* thread, JSONStream* js) { 3042 static bool Resume(Thread* thread, JSONStream* js) {
3187 const char* step_param = js->LookupParam("step"); 3043 const char* step_param = js->LookupParam("step");
3188 Debugger::ResumeAction step = Debugger::kContinue; 3044 Debugger::ResumeAction step = Debugger::kContinue;
3189 if (step_param != NULL) { 3045 if (step_param != NULL) {
3190 step = EnumMapper(step_param, step_enum_names, step_enum_values); 3046 step = EnumMapper(step_param, step_enum_names, step_enum_values);
3191 } 3047 }
3192 intptr_t frame_index = 1; 3048 intptr_t frame_index = 1;
3193 const char* frame_index_param = js->LookupParam("frameIndex"); 3049 const char* frame_index_param = js->LookupParam("frameIndex");
3194 if (frame_index_param != NULL) { 3050 if (frame_index_param != NULL) {
3195 if (step != Debugger::kStepRewind) { 3051 if (step != Debugger::kStepRewind) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3243 const char* error = NULL; 3099 const char* error = NULL;
3244 if (!isolate->debugger()->SetResumeAction(step, frame_index, &error)) { 3100 if (!isolate->debugger()->SetResumeAction(step, frame_index, &error)) {
3245 js->PrintError(kCannotResume, error); 3101 js->PrintError(kCannotResume, error);
3246 return true; 3102 return true;
3247 } 3103 }
3248 isolate->SetResumeRequest(); 3104 isolate->SetResumeRequest();
3249 PrintSuccess(js); 3105 PrintSuccess(js);
3250 return true; 3106 return true;
3251 } 3107 }
3252 3108
3253
3254 static const MethodParameter* pause_params[] = { 3109 static const MethodParameter* pause_params[] = {
3255 RUNNABLE_ISOLATE_PARAMETER, NULL, 3110 RUNNABLE_ISOLATE_PARAMETER, NULL,
3256 }; 3111 };
3257 3112
3258
3259 static bool Pause(Thread* thread, JSONStream* js) { 3113 static bool Pause(Thread* thread, JSONStream* js) {
3260 // TODO(turnidge): This interrupt message could have been sent from 3114 // TODO(turnidge): This interrupt message could have been sent from
3261 // the service isolate directly, but would require some special case 3115 // the service isolate directly, but would require some special case
3262 // code. That would prevent this isolate getting double-interrupted 3116 // code. That would prevent this isolate getting double-interrupted
3263 // with OOB messages. 3117 // with OOB messages.
3264 Isolate* isolate = thread->isolate(); 3118 Isolate* isolate = thread->isolate();
3265 isolate->SendInternalLibMessage(Isolate::kInterruptMsg, 3119 isolate->SendInternalLibMessage(Isolate::kInterruptMsg,
3266 isolate->pause_capability()); 3120 isolate->pause_capability());
3267 PrintSuccess(js); 3121 PrintSuccess(js);
3268 return true; 3122 return true;
3269 } 3123 }
3270 3124
3271
3272 static const MethodParameter* get_tag_profile_params[] = { 3125 static const MethodParameter* get_tag_profile_params[] = {
3273 RUNNABLE_ISOLATE_PARAMETER, NULL, 3126 RUNNABLE_ISOLATE_PARAMETER, NULL,
3274 }; 3127 };
3275 3128
3276
3277 static bool GetTagProfile(Thread* thread, JSONStream* js) { 3129 static bool GetTagProfile(Thread* thread, JSONStream* js) {
3278 JSONObject miniProfile(js); 3130 JSONObject miniProfile(js);
3279 miniProfile.AddProperty("type", "TagProfile"); 3131 miniProfile.AddProperty("type", "TagProfile");
3280 thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile); 3132 thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile);
3281 return true; 3133 return true;
3282 } 3134 }
3283 3135
3284
3285 static const char* const tags_enum_names[] = { 3136 static const char* const tags_enum_names[] = {
3286 "None", "UserVM", "UserOnly", "VMUser", "VMOnly", NULL, 3137 "None", "UserVM", "UserOnly", "VMUser", "VMOnly", NULL,
3287 }; 3138 };
3288 3139
3289
3290 static const Profile::TagOrder tags_enum_values[] = { 3140 static const Profile::TagOrder tags_enum_values[] = {
3291 Profile::kNoTags, Profile::kUserVM, Profile::kUser, 3141 Profile::kNoTags, Profile::kUserVM, Profile::kUser,
3292 Profile::kVMUser, Profile::kVM, 3142 Profile::kVMUser, Profile::kVM,
3293 Profile::kNoTags, // Default value. 3143 Profile::kNoTags, // Default value.
3294 }; 3144 };
3295 3145
3296
3297 static const MethodParameter* get_cpu_profile_params[] = { 3146 static const MethodParameter* get_cpu_profile_params[] = {
3298 RUNNABLE_ISOLATE_PARAMETER, 3147 RUNNABLE_ISOLATE_PARAMETER,
3299 new EnumParameter("tags", true, tags_enum_names), 3148 new EnumParameter("tags", true, tags_enum_names),
3300 new BoolParameter("_codeTransitionTags", false), 3149 new BoolParameter("_codeTransitionTags", false),
3301 new Int64Parameter("timeOriginMicros", false), 3150 new Int64Parameter("timeOriginMicros", false),
3302 new Int64Parameter("timeExtentMicros", false), 3151 new Int64Parameter("timeExtentMicros", false),
3303 NULL, 3152 NULL,
3304 }; 3153 };
3305 3154
3306
3307 // TODO(johnmccutchan): Rename this to GetCpuSamples. 3155 // TODO(johnmccutchan): Rename this to GetCpuSamples.
3308 static bool GetCpuProfile(Thread* thread, JSONStream* js) { 3156 static bool GetCpuProfile(Thread* thread, JSONStream* js) {
3309 Profile::TagOrder tag_order = 3157 Profile::TagOrder tag_order =
3310 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); 3158 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
3311 intptr_t extra_tags = 0; 3159 intptr_t extra_tags = 0;
3312 if (BoolParameter::Parse(js->LookupParam("_codeTransitionTags"))) { 3160 if (BoolParameter::Parse(js->LookupParam("_codeTransitionTags"))) {
3313 extra_tags |= ProfilerService::kCodeTransitionTagsBit; 3161 extra_tags |= ProfilerService::kCodeTransitionTagsBit;
3314 } 3162 }
3315 int64_t time_origin_micros = 3163 int64_t time_origin_micros =
3316 Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); 3164 Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
3317 int64_t time_extent_micros = 3165 int64_t time_extent_micros =
3318 Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); 3166 Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
3319 ProfilerService::PrintJSON(js, tag_order, extra_tags, time_origin_micros, 3167 ProfilerService::PrintJSON(js, tag_order, extra_tags, time_origin_micros,
3320 time_extent_micros); 3168 time_extent_micros);
3321 return true; 3169 return true;
3322 } 3170 }
3323 3171
3324
3325 static const MethodParameter* get_cpu_profile_timeline_params[] = { 3172 static const MethodParameter* get_cpu_profile_timeline_params[] = {
3326 RUNNABLE_ISOLATE_PARAMETER, 3173 RUNNABLE_ISOLATE_PARAMETER,
3327 new EnumParameter("tags", true, tags_enum_names), 3174 new EnumParameter("tags", true, tags_enum_names),
3328 new Int64Parameter("timeOriginMicros", false), 3175 new Int64Parameter("timeOriginMicros", false),
3329 new Int64Parameter("timeExtentMicros", false), 3176 new Int64Parameter("timeExtentMicros", false),
3330 NULL, 3177 NULL,
3331 }; 3178 };
3332 3179
3333
3334 static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) { 3180 static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) {
3335 Profile::TagOrder tag_order = 3181 Profile::TagOrder tag_order =
3336 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); 3182 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
3337 int64_t time_origin_micros = 3183 int64_t time_origin_micros =
3338 UIntParameter::Parse(js->LookupParam("timeOriginMicros")); 3184 UIntParameter::Parse(js->LookupParam("timeOriginMicros"));
3339 int64_t time_extent_micros = 3185 int64_t time_extent_micros =
3340 UIntParameter::Parse(js->LookupParam("timeExtentMicros")); 3186 UIntParameter::Parse(js->LookupParam("timeExtentMicros"));
3341 ProfilerService::PrintTimelineJSON(js, tag_order, time_origin_micros, 3187 ProfilerService::PrintTimelineJSON(js, tag_order, time_origin_micros,
3342 time_extent_micros); 3188 time_extent_micros);
3343 return true; 3189 return true;
3344 } 3190 }
3345 3191
3346
3347 static const MethodParameter* get_allocation_samples_params[] = { 3192 static const MethodParameter* get_allocation_samples_params[] = {
3348 RUNNABLE_ISOLATE_PARAMETER, 3193 RUNNABLE_ISOLATE_PARAMETER,
3349 new EnumParameter("tags", true, tags_enum_names), 3194 new EnumParameter("tags", true, tags_enum_names),
3350 new IdParameter("classId", false), 3195 new IdParameter("classId", false),
3351 new Int64Parameter("timeOriginMicros", false), 3196 new Int64Parameter("timeOriginMicros", false),
3352 new Int64Parameter("timeExtentMicros", false), 3197 new Int64Parameter("timeExtentMicros", false),
3353 NULL, 3198 NULL,
3354 }; 3199 };
3355 3200
3356
3357 static bool GetAllocationSamples(Thread* thread, JSONStream* js) { 3201 static bool GetAllocationSamples(Thread* thread, JSONStream* js) {
3358 Profile::TagOrder tag_order = 3202 Profile::TagOrder tag_order =
3359 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); 3203 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
3360 int64_t time_origin_micros = 3204 int64_t time_origin_micros =
3361 Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); 3205 Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
3362 int64_t time_extent_micros = 3206 int64_t time_extent_micros =
3363 Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); 3207 Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
3364 const char* class_id = js->LookupParam("classId"); 3208 const char* class_id = js->LookupParam("classId");
3365 intptr_t cid = -1; 3209 intptr_t cid = -1;
3366 GetPrefixedIntegerId(class_id, "classes/", &cid); 3210 GetPrefixedIntegerId(class_id, "classes/", &cid);
3367 Isolate* isolate = thread->isolate(); 3211 Isolate* isolate = thread->isolate();
3368 if (IsValidClassId(isolate, cid)) { 3212 if (IsValidClassId(isolate, cid)) {
3369 const Class& cls = Class::Handle(GetClassForId(isolate, cid)); 3213 const Class& cls = Class::Handle(GetClassForId(isolate, cid));
3370 ProfilerService::PrintAllocationJSON(js, tag_order, cls, time_origin_micros, 3214 ProfilerService::PrintAllocationJSON(js, tag_order, cls, time_origin_micros,
3371 time_extent_micros); 3215 time_extent_micros);
3372 } else { 3216 } else {
3373 PrintInvalidParamError(js, "classId"); 3217 PrintInvalidParamError(js, "classId");
3374 } 3218 }
3375 return true; 3219 return true;
3376 } 3220 }
3377 3221
3378
3379 static const MethodParameter* get_native_allocation_samples_params[] = { 3222 static const MethodParameter* get_native_allocation_samples_params[] = {
3380 NO_ISOLATE_PARAMETER, 3223 NO_ISOLATE_PARAMETER,
3381 new EnumParameter("tags", true, tags_enum_names), 3224 new EnumParameter("tags", true, tags_enum_names),
3382 new Int64Parameter("timeOriginMicros", false), 3225 new Int64Parameter("timeOriginMicros", false),
3383 new Int64Parameter("timeExtentMicros", false), 3226 new Int64Parameter("timeExtentMicros", false),
3384 NULL, 3227 NULL,
3385 }; 3228 };
3386 3229
3387
3388 static bool GetNativeAllocationSamples(Thread* thread, JSONStream* js) { 3230 static bool GetNativeAllocationSamples(Thread* thread, JSONStream* js) {
3389 Profile::TagOrder tag_order = 3231 Profile::TagOrder tag_order =
3390 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); 3232 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
3391 int64_t time_origin_micros = 3233 int64_t time_origin_micros =
3392 Int64Parameter::Parse(js->LookupParam("timeOriginMicros")); 3234 Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
3393 int64_t time_extent_micros = 3235 int64_t time_extent_micros =
3394 Int64Parameter::Parse(js->LookupParam("timeExtentMicros")); 3236 Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
3395 #if defined(DEBUG) 3237 #if defined(DEBUG)
3396 Isolate::Current()->heap()->CollectAllGarbage(); 3238 Isolate::Current()->heap()->CollectAllGarbage();
3397 #endif 3239 #endif
3398 ProfilerService::PrintNativeAllocationJSON(js, tag_order, time_origin_micros, 3240 ProfilerService::PrintNativeAllocationJSON(js, tag_order, time_origin_micros,
3399 time_extent_micros); 3241 time_extent_micros);
3400 return true; 3242 return true;
3401 } 3243 }
3402 3244
3403
3404 static const MethodParameter* clear_cpu_profile_params[] = { 3245 static const MethodParameter* clear_cpu_profile_params[] = {
3405 RUNNABLE_ISOLATE_PARAMETER, NULL, 3246 RUNNABLE_ISOLATE_PARAMETER, NULL,
3406 }; 3247 };
3407 3248
3408
3409 static bool ClearCpuProfile(Thread* thread, JSONStream* js) { 3249 static bool ClearCpuProfile(Thread* thread, JSONStream* js) {
3410 ProfilerService::ClearSamples(); 3250 ProfilerService::ClearSamples();
3411 PrintSuccess(js); 3251 PrintSuccess(js);
3412 return true; 3252 return true;
3413 } 3253 }
3414 3254
3415
3416 static const MethodParameter* get_allocation_profile_params[] = { 3255 static const MethodParameter* get_allocation_profile_params[] = {
3417 RUNNABLE_ISOLATE_PARAMETER, NULL, 3256 RUNNABLE_ISOLATE_PARAMETER, NULL,
3418 }; 3257 };
3419 3258
3420
3421 static bool GetAllocationProfile(Thread* thread, JSONStream* js) { 3259 static bool GetAllocationProfile(Thread* thread, JSONStream* js) {
3422 bool should_reset_accumulator = false; 3260 bool should_reset_accumulator = false;
3423 bool should_collect = false; 3261 bool should_collect = false;
3424 if (js->HasParam("reset")) { 3262 if (js->HasParam("reset")) {
3425 if (js->ParamIs("reset", "true")) { 3263 if (js->ParamIs("reset", "true")) {
3426 should_reset_accumulator = true; 3264 should_reset_accumulator = true;
3427 } else { 3265 } else {
3428 PrintInvalidParamError(js, "reset"); 3266 PrintInvalidParamError(js, "reset");
3429 return true; 3267 return true;
3430 } 3268 }
(...skipping 12 matching lines...) Expand all
3443 isolate->class_table()->ResetAllocationAccumulators(); 3281 isolate->class_table()->ResetAllocationAccumulators();
3444 } 3282 }
3445 if (should_collect) { 3283 if (should_collect) {
3446 isolate->UpdateLastAllocationProfileGCTimestamp(); 3284 isolate->UpdateLastAllocationProfileGCTimestamp();
3447 isolate->heap()->CollectAllGarbage(); 3285 isolate->heap()->CollectAllGarbage();
3448 } 3286 }
3449 isolate->class_table()->AllocationProfilePrintJSON(js); 3287 isolate->class_table()->AllocationProfilePrintJSON(js);
3450 return true; 3288 return true;
3451 } 3289 }
3452 3290
3453
3454 static const MethodParameter* collect_all_garbage_params[] = { 3291 static const MethodParameter* collect_all_garbage_params[] = {
3455 RUNNABLE_ISOLATE_PARAMETER, NULL, 3292 RUNNABLE_ISOLATE_PARAMETER, NULL,
3456 }; 3293 };
3457 3294
3458 #if defined(DEBUG) 3295 #if defined(DEBUG)
3459 static bool CollectAllGarbage(Thread* thread, JSONStream* js) { 3296 static bool CollectAllGarbage(Thread* thread, JSONStream* js) {
3460 Isolate* isolate = thread->isolate(); 3297 Isolate* isolate = thread->isolate();
3461 isolate->heap()->CollectAllGarbage(); 3298 isolate->heap()->CollectAllGarbage();
3462 PrintSuccess(js); 3299 PrintSuccess(js);
3463 return true; 3300 return true;
3464 } 3301 }
3465 #else 3302 #else
3466 static bool CollectAllGarbage(Thread* thread, JSONStream* js) { 3303 static bool CollectAllGarbage(Thread* thread, JSONStream* js) {
3467 PrintSuccess(js); 3304 PrintSuccess(js);
3468 return true; 3305 return true;
3469 } 3306 }
3470 #endif // defined(DEBUG) 3307 #endif // defined(DEBUG)
3471 3308
3472
3473 static const MethodParameter* get_heap_map_params[] = { 3309 static const MethodParameter* get_heap_map_params[] = {
3474 RUNNABLE_ISOLATE_PARAMETER, NULL, 3310 RUNNABLE_ISOLATE_PARAMETER, NULL,
3475 }; 3311 };
3476 3312
3477
3478 static bool GetHeapMap(Thread* thread, JSONStream* js) { 3313 static bool GetHeapMap(Thread* thread, JSONStream* js) {
3479 Isolate* isolate = thread->isolate(); 3314 Isolate* isolate = thread->isolate();
3480 bool should_collect = false; 3315 bool should_collect = false;
3481 if (js->HasParam("gc")) { 3316 if (js->HasParam("gc")) {
3482 if (js->ParamIs("gc", "full")) { 3317 if (js->ParamIs("gc", "full")) {
3483 should_collect = true; 3318 should_collect = true;
3484 } else { 3319 } else {
3485 PrintInvalidParamError(js, "gc"); 3320 PrintInvalidParamError(js, "gc");
3486 return true; 3321 return true;
3487 } 3322 }
3488 } 3323 }
3489 if (should_collect) { 3324 if (should_collect) {
3490 isolate->heap()->CollectAllGarbage(); 3325 isolate->heap()->CollectAllGarbage();
3491 } 3326 }
3492 isolate->heap()->PrintHeapMapToJSONStream(isolate, js); 3327 isolate->heap()->PrintHeapMapToJSONStream(isolate, js);
3493 return true; 3328 return true;
3494 } 3329 }
3495 3330
3496
3497 static const char* snapshot_roots_names[] = { 3331 static const char* snapshot_roots_names[] = {
3498 "User", "VM", NULL, 3332 "User", "VM", NULL,
3499 }; 3333 };
3500 3334
3501
3502 static ObjectGraph::SnapshotRoots snapshot_roots_values[] = { 3335 static ObjectGraph::SnapshotRoots snapshot_roots_values[] = {
3503 ObjectGraph::kUser, ObjectGraph::kVM, 3336 ObjectGraph::kUser, ObjectGraph::kVM,
3504 }; 3337 };
3505 3338
3506
3507 static const MethodParameter* request_heap_snapshot_params[] = { 3339 static const MethodParameter* request_heap_snapshot_params[] = {
3508 RUNNABLE_ISOLATE_PARAMETER, 3340 RUNNABLE_ISOLATE_PARAMETER,
3509 new EnumParameter("roots", false /* not required */, snapshot_roots_names), 3341 new EnumParameter("roots", false /* not required */, snapshot_roots_names),
3510 new BoolParameter("collectGarbage", false /* not required */), NULL, 3342 new BoolParameter("collectGarbage", false /* not required */), NULL,
3511 }; 3343 };
3512 3344
3513
3514 static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) { 3345 static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) {
3515 ObjectGraph::SnapshotRoots roots = ObjectGraph::kVM; 3346 ObjectGraph::SnapshotRoots roots = ObjectGraph::kVM;
3516 const char* roots_arg = js->LookupParam("roots"); 3347 const char* roots_arg = js->LookupParam("roots");
3517 if (roots_arg != NULL) { 3348 if (roots_arg != NULL) {
3518 roots = EnumMapper(roots_arg, snapshot_roots_names, snapshot_roots_values); 3349 roots = EnumMapper(roots_arg, snapshot_roots_names, snapshot_roots_values);
3519 } 3350 }
3520 const bool collect_garbage = 3351 const bool collect_garbage =
3521 BoolParameter::Parse(js->LookupParam("collectGarbage"), true); 3352 BoolParameter::Parse(js->LookupParam("collectGarbage"), true);
3522 if (Service::graph_stream.enabled()) { 3353 if (Service::graph_stream.enabled()) {
3523 Service::SendGraphEvent(thread, roots, collect_garbage); 3354 Service::SendGraphEvent(thread, roots, collect_garbage);
3524 } 3355 }
3525 // TODO(koda): Provide some id that ties this request to async response(s). 3356 // TODO(koda): Provide some id that ties this request to async response(s).
3526 PrintSuccess(js); 3357 PrintSuccess(js);
3527 return true; 3358 return true;
3528 } 3359 }
3529 3360
3530
3531 void Service::SendGraphEvent(Thread* thread, 3361 void Service::SendGraphEvent(Thread* thread,
3532 ObjectGraph::SnapshotRoots roots, 3362 ObjectGraph::SnapshotRoots roots,
3533 bool collect_garbage) { 3363 bool collect_garbage) {
3534 uint8_t* buffer = NULL; 3364 uint8_t* buffer = NULL;
3535 WriteStream stream(&buffer, &allocator, 1 * MB); 3365 WriteStream stream(&buffer, &allocator, 1 * MB);
3536 ObjectGraph graph(thread); 3366 ObjectGraph graph(thread);
3537 intptr_t node_count = graph.Serialize(&stream, roots, collect_garbage); 3367 intptr_t node_count = graph.Serialize(&stream, roots, collect_garbage);
3538 3368
3539 // Chrome crashes receiving a single tens-of-megabytes blob, so send the 3369 // Chrome crashes receiving a single tens-of-megabytes blob, so send the
3540 // snapshot in megabyte-sized chunks instead. 3370 // snapshot in megabyte-sized chunks instead.
(...skipping 26 matching lines...) Expand all
3567 uint8_t* chunk_start = buffer + (i * kChunkSize); 3397 uint8_t* chunk_start = buffer + (i * kChunkSize);
3568 intptr_t chunk_size = (i + 1 == num_chunks) 3398 intptr_t chunk_size = (i + 1 == num_chunks)
3569 ? stream.bytes_written() - (i * kChunkSize) 3399 ? stream.bytes_written() - (i * kChunkSize)
3570 : kChunkSize; 3400 : kChunkSize;
3571 3401
3572 SendEventWithData(graph_stream.id(), "_Graph", js.buffer()->buf(), 3402 SendEventWithData(graph_stream.id(), "_Graph", js.buffer()->buf(),
3573 js.buffer()->length(), chunk_start, chunk_size); 3403 js.buffer()->length(), chunk_start, chunk_size);
3574 } 3404 }
3575 } 3405 }
3576 3406
3577
3578 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) { 3407 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) {
3579 if (!Service::debug_stream.enabled()) { 3408 if (!Service::debug_stream.enabled()) {
3580 return; 3409 return;
3581 } 3410 }
3582 ServiceEvent event(isolate, ServiceEvent::kInspect); 3411 ServiceEvent event(isolate, ServiceEvent::kInspect);
3583 event.set_inspectee(&inspectee); 3412 event.set_inspectee(&inspectee);
3584 Service::HandleEvent(&event); 3413 Service::HandleEvent(&event);
3585 } 3414 }
3586 3415
3587
3588 void Service::SendEmbedderEvent(Isolate* isolate, 3416 void Service::SendEmbedderEvent(Isolate* isolate,
3589 const char* stream_id, 3417 const char* stream_id,
3590 const char* event_kind, 3418 const char* event_kind,
3591 const uint8_t* bytes, 3419 const uint8_t* bytes,
3592 intptr_t bytes_len) { 3420 intptr_t bytes_len) {
3593 if (!Service::debug_stream.enabled()) { 3421 if (!Service::debug_stream.enabled()) {
3594 return; 3422 return;
3595 } 3423 }
3596 ServiceEvent event(isolate, ServiceEvent::kEmbedder); 3424 ServiceEvent event(isolate, ServiceEvent::kEmbedder);
3597 event.set_embedder_kind(event_kind); 3425 event.set_embedder_kind(event_kind);
3598 event.set_embedder_stream_id(stream_id); 3426 event.set_embedder_stream_id(stream_id);
3599 event.set_bytes(bytes, bytes_len); 3427 event.set_bytes(bytes, bytes_len);
3600 Service::HandleEvent(&event); 3428 Service::HandleEvent(&event);
3601 } 3429 }
3602 3430
3603
3604 void Service::SendLogEvent(Isolate* isolate, 3431 void Service::SendLogEvent(Isolate* isolate,
3605 int64_t sequence_number, 3432 int64_t sequence_number,
3606 int64_t timestamp, 3433 int64_t timestamp,
3607 intptr_t level, 3434 intptr_t level,
3608 const String& name, 3435 const String& name,
3609 const String& message, 3436 const String& message,
3610 const Instance& zone, 3437 const Instance& zone,
3611 const Object& error, 3438 const Object& error,
3612 const Instance& stack_trace) { 3439 const Instance& stack_trace) {
3613 if (!Service::logging_stream.enabled()) { 3440 if (!Service::logging_stream.enabled()) {
3614 return; 3441 return;
3615 } 3442 }
3616 ServiceEvent::LogRecord log_record; 3443 ServiceEvent::LogRecord log_record;
3617 log_record.sequence_number = sequence_number; 3444 log_record.sequence_number = sequence_number;
3618 log_record.timestamp = timestamp; 3445 log_record.timestamp = timestamp;
3619 log_record.level = level; 3446 log_record.level = level;
3620 log_record.name = &name; 3447 log_record.name = &name;
3621 log_record.message = &message; 3448 log_record.message = &message;
3622 log_record.zone = &zone; 3449 log_record.zone = &zone;
3623 log_record.error = &error; 3450 log_record.error = &error;
3624 log_record.stack_trace = &stack_trace; 3451 log_record.stack_trace = &stack_trace;
3625 ServiceEvent event(isolate, ServiceEvent::kLogging); 3452 ServiceEvent event(isolate, ServiceEvent::kLogging);
3626 event.set_log_record(log_record); 3453 event.set_log_record(log_record);
3627 Service::HandleEvent(&event); 3454 Service::HandleEvent(&event);
3628 } 3455 }
3629 3456
3630
3631 void Service::SendExtensionEvent(Isolate* isolate, 3457 void Service::SendExtensionEvent(Isolate* isolate,
3632 const String& event_kind, 3458 const String& event_kind,
3633 const String& event_data) { 3459 const String& event_data) {
3634 if (!Service::extension_stream.enabled()) { 3460 if (!Service::extension_stream.enabled()) {
3635 return; 3461 return;
3636 } 3462 }
3637 ServiceEvent::ExtensionEvent extension_event; 3463 ServiceEvent::ExtensionEvent extension_event;
3638 extension_event.event_kind = &event_kind; 3464 extension_event.event_kind = &event_kind;
3639 extension_event.event_data = &event_data; 3465 extension_event.event_data = &event_data;
3640 ServiceEvent event(isolate, ServiceEvent::kExtension); 3466 ServiceEvent event(isolate, ServiceEvent::kExtension);
3641 event.set_extension_event(extension_event); 3467 event.set_extension_event(extension_event);
3642 Service::HandleEvent(&event); 3468 Service::HandleEvent(&event);
3643 } 3469 }
3644 3470
3645
3646 class ContainsAddressVisitor : public FindObjectVisitor { 3471 class ContainsAddressVisitor : public FindObjectVisitor {
3647 public: 3472 public:
3648 explicit ContainsAddressVisitor(uword addr) : addr_(addr) {} 3473 explicit ContainsAddressVisitor(uword addr) : addr_(addr) {}
3649 virtual ~ContainsAddressVisitor() {} 3474 virtual ~ContainsAddressVisitor() {}
3650 3475
3651 virtual uword filter_addr() const { return addr_; } 3476 virtual uword filter_addr() const { return addr_; }
3652 3477
3653 virtual bool FindObject(RawObject* obj) const { 3478 virtual bool FindObject(RawObject* obj) const {
3654 if (obj->IsPseudoObject()) { 3479 if (obj->IsPseudoObject()) {
3655 return false; 3480 return false;
3656 } 3481 }
3657 uword obj_begin = RawObject::ToAddr(obj); 3482 uword obj_begin = RawObject::ToAddr(obj);
3658 uword obj_end = obj_begin + obj->Size(); 3483 uword obj_end = obj_begin + obj->Size();
3659 return obj_begin <= addr_ && addr_ < obj_end; 3484 return obj_begin <= addr_ && addr_ < obj_end;
3660 } 3485 }
3661 3486
3662 private: 3487 private:
3663 uword addr_; 3488 uword addr_;
3664 }; 3489 };
3665 3490
3666
3667 static const MethodParameter* get_object_by_address_params[] = { 3491 static const MethodParameter* get_object_by_address_params[] = {
3668 RUNNABLE_ISOLATE_PARAMETER, NULL, 3492 RUNNABLE_ISOLATE_PARAMETER, NULL,
3669 }; 3493 };
3670 3494
3671
3672 static RawObject* GetObjectHelper(Thread* thread, uword addr) { 3495 static RawObject* GetObjectHelper(Thread* thread, uword addr) {
3673 Object& object = Object::Handle(thread->zone()); 3496 Object& object = Object::Handle(thread->zone());
3674 3497
3675 { 3498 {
3676 NoSafepointScope no_safepoint; 3499 NoSafepointScope no_safepoint;
3677 Isolate* isolate = thread->isolate(); 3500 Isolate* isolate = thread->isolate();
3678 ContainsAddressVisitor visitor(addr); 3501 ContainsAddressVisitor visitor(addr);
3679 object = isolate->heap()->FindObject(&visitor); 3502 object = isolate->heap()->FindObject(&visitor);
3680 } 3503 }
3681 3504
3682 if (!object.IsNull()) { 3505 if (!object.IsNull()) {
3683 return object.raw(); 3506 return object.raw();
3684 } 3507 }
3685 3508
3686 { 3509 {
3687 NoSafepointScope no_safepoint; 3510 NoSafepointScope no_safepoint;
3688 ContainsAddressVisitor visitor(addr); 3511 ContainsAddressVisitor visitor(addr);
3689 object = Dart::vm_isolate()->heap()->FindObject(&visitor); 3512 object = Dart::vm_isolate()->heap()->FindObject(&visitor);
3690 } 3513 }
3691 3514
3692 return object.raw(); 3515 return object.raw();
3693 } 3516 }
3694 3517
3695
3696 static bool GetObjectByAddress(Thread* thread, JSONStream* js) { 3518 static bool GetObjectByAddress(Thread* thread, JSONStream* js) {
3697 const char* addr_str = js->LookupParam("address"); 3519 const char* addr_str = js->LookupParam("address");
3698 if (addr_str == NULL) { 3520 if (addr_str == NULL) {
3699 PrintMissingParamError(js, "address"); 3521 PrintMissingParamError(js, "address");
3700 return true; 3522 return true;
3701 } 3523 }
3702 3524
3703 // Handle heap objects. 3525 // Handle heap objects.
3704 uword addr = 0; 3526 uword addr = 0;
3705 if (!GetUnsignedIntegerId(addr_str, &addr, 16)) { 3527 if (!GetUnsignedIntegerId(addr_str, &addr, 16)) {
3706 PrintInvalidParamError(js, "address"); 3528 PrintInvalidParamError(js, "address");
3707 return true; 3529 return true;
3708 } 3530 }
3709 bool ref = js->HasParam("ref") && js->ParamIs("ref", "true"); 3531 bool ref = js->HasParam("ref") && js->ParamIs("ref", "true");
3710 const Object& obj = 3532 const Object& obj =
3711 Object::Handle(thread->zone(), GetObjectHelper(thread, addr)); 3533 Object::Handle(thread->zone(), GetObjectHelper(thread, addr));
3712 if (obj.IsNull()) { 3534 if (obj.IsNull()) {
3713 PrintSentinel(js, kFreeSentinel); 3535 PrintSentinel(js, kFreeSentinel);
3714 } else { 3536 } else {
3715 obj.PrintJSON(js, ref); 3537 obj.PrintJSON(js, ref);
3716 } 3538 }
3717 return true; 3539 return true;
3718 } 3540 }
3719 3541
3720
3721 static const MethodParameter* get_persistent_handles_params[] = { 3542 static const MethodParameter* get_persistent_handles_params[] = {
3722 ISOLATE_PARAMETER, NULL, 3543 ISOLATE_PARAMETER, NULL,
3723 }; 3544 };
3724 3545
3725
3726 template <typename T> 3546 template <typename T>
3727 class PersistentHandleVisitor : public HandleVisitor { 3547 class PersistentHandleVisitor : public HandleVisitor {
3728 public: 3548 public:
3729 PersistentHandleVisitor(Thread* thread, JSONArray* handles) 3549 PersistentHandleVisitor(Thread* thread, JSONArray* handles)
3730 : HandleVisitor(thread), handles_(handles) { 3550 : HandleVisitor(thread), handles_(handles) {
3731 ASSERT(handles_ != NULL); 3551 ASSERT(handles_ != NULL);
3732 } 3552 }
3733 3553
3734 void Append(PersistentHandle* persistent_handle) { 3554 void Append(PersistentHandle* persistent_handle) {
3735 JSONObject obj(handles_); 3555 JSONObject obj(handles_);
(...skipping 30 matching lines...) Expand all
3766 3586
3767 protected: 3587 protected:
3768 virtual void VisitHandle(uword addr) { 3588 virtual void VisitHandle(uword addr) {
3769 T* handle = reinterpret_cast<T*>(addr); 3589 T* handle = reinterpret_cast<T*>(addr);
3770 Append(handle); 3590 Append(handle);
3771 } 3591 }
3772 3592
3773 JSONArray* handles_; 3593 JSONArray* handles_;
3774 }; 3594 };
3775 3595
3776
3777 static bool GetPersistentHandles(Thread* thread, JSONStream* js) { 3596 static bool GetPersistentHandles(Thread* thread, JSONStream* js) {
3778 Isolate* isolate = thread->isolate(); 3597 Isolate* isolate = thread->isolate();
3779 ASSERT(isolate != NULL); 3598 ASSERT(isolate != NULL);
3780 3599
3781 ApiState* api_state = isolate->api_state(); 3600 ApiState* api_state = isolate->api_state();
3782 ASSERT(api_state != NULL); 3601 ASSERT(api_state != NULL);
3783 3602
3784 { 3603 {
3785 JSONObject obj(js); 3604 JSONObject obj(js);
3786 obj.AddProperty("type", "_PersistentHandles"); 3605 obj.AddProperty("type", "_PersistentHandles");
(...skipping 12 matching lines...) Expand all
3799 api_state->weak_persistent_handles(); 3618 api_state->weak_persistent_handles();
3800 PersistentHandleVisitor<FinalizablePersistentHandle> visitor( 3619 PersistentHandleVisitor<FinalizablePersistentHandle> visitor(
3801 thread, &weak_persistent_handles); 3620 thread, &weak_persistent_handles);
3802 handles.VisitHandles(&visitor); 3621 handles.VisitHandles(&visitor);
3803 } 3622 }
3804 } 3623 }
3805 3624
3806 return true; 3625 return true;
3807 } 3626 }
3808 3627
3809
3810 static const MethodParameter* get_ports_params[] = { 3628 static const MethodParameter* get_ports_params[] = {
3811 RUNNABLE_ISOLATE_PARAMETER, NULL, 3629 RUNNABLE_ISOLATE_PARAMETER, NULL,
3812 }; 3630 };
3813 3631
3814
3815 static bool GetPorts(Thread* thread, JSONStream* js) { 3632 static bool GetPorts(Thread* thread, JSONStream* js) {
3816 MessageHandler* message_handler = thread->isolate()->message_handler(); 3633 MessageHandler* message_handler = thread->isolate()->message_handler();
3817 PortMap::PrintPortsForMessageHandler(message_handler, js); 3634 PortMap::PrintPortsForMessageHandler(message_handler, js);
3818 return true; 3635 return true;
3819 } 3636 }
3820 3637
3821
3822 static bool RespondWithMalformedJson(Thread* thread, JSONStream* js) { 3638 static bool RespondWithMalformedJson(Thread* thread, JSONStream* js) {
3823 JSONObject jsobj(js); 3639 JSONObject jsobj(js);
3824 jsobj.AddProperty("a", "a"); 3640 jsobj.AddProperty("a", "a");
3825 JSONObject jsobj1(js); 3641 JSONObject jsobj1(js);
3826 jsobj1.AddProperty("a", "a"); 3642 jsobj1.AddProperty("a", "a");
3827 JSONObject jsobj2(js); 3643 JSONObject jsobj2(js);
3828 jsobj2.AddProperty("a", "a"); 3644 jsobj2.AddProperty("a", "a");
3829 JSONObject jsobj3(js); 3645 JSONObject jsobj3(js);
3830 jsobj3.AddProperty("a", "a"); 3646 jsobj3.AddProperty("a", "a");
3831 return true; 3647 return true;
3832 } 3648 }
3833 3649
3834
3835 static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) { 3650 static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) {
3836 JSONObject jsobj(js); 3651 JSONObject jsobj(js);
3837 jsobj.AddProperty("bart", "simpson"); 3652 jsobj.AddProperty("bart", "simpson");
3838 return true; 3653 return true;
3839 } 3654 }
3840 3655
3841
3842 static const MethodParameter* get_object_params[] = { 3656 static const MethodParameter* get_object_params[] = {
3843 RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("offset", false), 3657 RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("offset", false),
3844 new UIntParameter("count", false), NULL, 3658 new UIntParameter("count", false), NULL,
3845 }; 3659 };
3846 3660
3847
3848 static bool GetObject(Thread* thread, JSONStream* js) { 3661 static bool GetObject(Thread* thread, JSONStream* js) {
3849 const char* id = js->LookupParam("objectId"); 3662 const char* id = js->LookupParam("objectId");
3850 if (id == NULL) { 3663 if (id == NULL) {
3851 PrintMissingParamError(js, "objectId"); 3664 PrintMissingParamError(js, "objectId");
3852 return true; 3665 return true;
3853 } 3666 }
3854 if (js->HasParam("offset")) { 3667 if (js->HasParam("offset")) {
3855 intptr_t value = UIntParameter::Parse(js->LookupParam("offset")); 3668 intptr_t value = UIntParameter::Parse(js->LookupParam("offset"));
3856 if (value < 0) { 3669 if (value < 0) {
3857 PrintInvalidParamError(js, "offset"); 3670 PrintInvalidParamError(js, "offset");
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3891 return true; 3704 return true;
3892 } else if (lookup_result == ObjectIdRing::kCollected) { 3705 } else if (lookup_result == ObjectIdRing::kCollected) {
3893 PrintSentinel(js, kCollectedSentinel); 3706 PrintSentinel(js, kCollectedSentinel);
3894 return true; 3707 return true;
3895 } 3708 }
3896 3709
3897 PrintInvalidParamError(js, "objectId"); 3710 PrintInvalidParamError(js, "objectId");
3898 return true; 3711 return true;
3899 } 3712 }
3900 3713
3901
3902 static const MethodParameter* get_object_store_params[] = { 3714 static const MethodParameter* get_object_store_params[] = {
3903 RUNNABLE_ISOLATE_PARAMETER, NULL, 3715 RUNNABLE_ISOLATE_PARAMETER, NULL,
3904 }; 3716 };
3905 3717
3906
3907 static bool GetObjectStore(Thread* thread, JSONStream* js) { 3718 static bool GetObjectStore(Thread* thread, JSONStream* js) {
3908 JSONObject jsobj(js); 3719 JSONObject jsobj(js);
3909 thread->isolate()->object_store()->PrintToJSONObject(&jsobj); 3720 thread->isolate()->object_store()->PrintToJSONObject(&jsobj);
3910 return true; 3721 return true;
3911 } 3722 }
3912 3723
3913
3914 static const MethodParameter* get_class_list_params[] = { 3724 static const MethodParameter* get_class_list_params[] = {
3915 RUNNABLE_ISOLATE_PARAMETER, NULL, 3725 RUNNABLE_ISOLATE_PARAMETER, NULL,
3916 }; 3726 };
3917 3727
3918
3919 static bool GetClassList(Thread* thread, JSONStream* js) { 3728 static bool GetClassList(Thread* thread, JSONStream* js) {
3920 ClassTable* table = thread->isolate()->class_table(); 3729 ClassTable* table = thread->isolate()->class_table();
3921 JSONObject jsobj(js); 3730 JSONObject jsobj(js);
3922 table->PrintToJSONObject(&jsobj); 3731 table->PrintToJSONObject(&jsobj);
3923 return true; 3732 return true;
3924 } 3733 }
3925 3734
3926
3927 static const MethodParameter* get_type_arguments_list_params[] = { 3735 static const MethodParameter* get_type_arguments_list_params[] = {
3928 RUNNABLE_ISOLATE_PARAMETER, NULL, 3736 RUNNABLE_ISOLATE_PARAMETER, NULL,
3929 }; 3737 };
3930 3738
3931
3932 static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) { 3739 static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) {
3933 bool only_with_instantiations = false; 3740 bool only_with_instantiations = false;
3934 if (js->ParamIs("onlyWithInstantiations", "true")) { 3741 if (js->ParamIs("onlyWithInstantiations", "true")) {
3935 only_with_instantiations = true; 3742 only_with_instantiations = true;
3936 } 3743 }
3937 Zone* zone = thread->zone(); 3744 Zone* zone = thread->zone();
3938 ObjectStore* object_store = thread->isolate()->object_store(); 3745 ObjectStore* object_store = thread->isolate()->object_store();
3939 CanonicalTypeArgumentsSet typeargs_table( 3746 CanonicalTypeArgumentsSet typeargs_table(
3940 zone, object_store->canonical_type_arguments()); 3747 zone, object_store->canonical_type_arguments());
3941 const intptr_t table_size = typeargs_table.NumEntries(); 3748 const intptr_t table_size = typeargs_table.NumEntries();
(...skipping 12 matching lines...) Expand all
3954 if (!typeargs.IsNull()) { 3761 if (!typeargs.IsNull()) {
3955 if (!only_with_instantiations || typeargs.HasInstantiations()) { 3762 if (!only_with_instantiations || typeargs.HasInstantiations()) {
3956 members.AddValue(typeargs); 3763 members.AddValue(typeargs);
3957 } 3764 }
3958 } 3765 }
3959 } 3766 }
3960 typeargs_table.Release(); 3767 typeargs_table.Release();
3961 return true; 3768 return true;
3962 } 3769 }
3963 3770
3964
3965 static const MethodParameter* get_version_params[] = { 3771 static const MethodParameter* get_version_params[] = {
3966 NO_ISOLATE_PARAMETER, NULL, 3772 NO_ISOLATE_PARAMETER, NULL,
3967 }; 3773 };
3968 3774
3969
3970 static bool GetVersion(Thread* thread, JSONStream* js) { 3775 static bool GetVersion(Thread* thread, JSONStream* js) {
3971 JSONObject jsobj(js); 3776 JSONObject jsobj(js);
3972 jsobj.AddProperty("type", "Version"); 3777 jsobj.AddProperty("type", "Version");
3973 jsobj.AddProperty("major", 3778 jsobj.AddProperty("major",
3974 static_cast<intptr_t>(SERVICE_PROTOCOL_MAJOR_VERSION)); 3779 static_cast<intptr_t>(SERVICE_PROTOCOL_MAJOR_VERSION));
3975 jsobj.AddProperty("minor", 3780 jsobj.AddProperty("minor",
3976 static_cast<intptr_t>(SERVICE_PROTOCOL_MINOR_VERSION)); 3781 static_cast<intptr_t>(SERVICE_PROTOCOL_MINOR_VERSION));
3977 jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0)); 3782 jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0));
3978 jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0)); 3783 jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0));
3979 return true; 3784 return true;
3980 } 3785 }
3981 3786
3982
3983 class ServiceIsolateVisitor : public IsolateVisitor { 3787 class ServiceIsolateVisitor : public IsolateVisitor {
3984 public: 3788 public:
3985 explicit ServiceIsolateVisitor(JSONArray* jsarr) : jsarr_(jsarr) {} 3789 explicit ServiceIsolateVisitor(JSONArray* jsarr) : jsarr_(jsarr) {}
3986 virtual ~ServiceIsolateVisitor() {} 3790 virtual ~ServiceIsolateVisitor() {}
3987 3791
3988 void VisitIsolate(Isolate* isolate) { 3792 void VisitIsolate(Isolate* isolate) {
3989 bool is_kernel_isolate = false; 3793 bool is_kernel_isolate = false;
3990 #ifndef DART_PRECOMPILED_RUNTIME 3794 #ifndef DART_PRECOMPILED_RUNTIME
3991 is_kernel_isolate = 3795 is_kernel_isolate =
3992 KernelIsolate::IsKernelIsolate(isolate) && !FLAG_show_kernel_isolate; 3796 KernelIsolate::IsKernelIsolate(isolate) && !FLAG_show_kernel_isolate;
3993 #endif 3797 #endif
3994 if (!IsVMInternalIsolate(isolate) && !is_kernel_isolate) { 3798 if (!IsVMInternalIsolate(isolate) && !is_kernel_isolate) {
3995 jsarr_->AddValue(isolate); 3799 jsarr_->AddValue(isolate);
3996 } 3800 }
3997 } 3801 }
3998 3802
3999 private: 3803 private:
4000 JSONArray* jsarr_; 3804 JSONArray* jsarr_;
4001 }; 3805 };
4002 3806
4003
4004 static const MethodParameter* get_vm_params[] = { 3807 static const MethodParameter* get_vm_params[] = {
4005 NO_ISOLATE_PARAMETER, NULL, 3808 NO_ISOLATE_PARAMETER, NULL,
4006 }; 3809 };
4007 3810
4008
4009 void Service::PrintJSONForVM(JSONStream* js, bool ref) { 3811 void Service::PrintJSONForVM(JSONStream* js, bool ref) {
4010 JSONObject jsobj(js); 3812 JSONObject jsobj(js);
4011 jsobj.AddProperty("type", (ref ? "@VM" : "VM")); 3813 jsobj.AddProperty("type", (ref ? "@VM" : "VM"));
4012 jsobj.AddProperty("name", GetVMName()); 3814 jsobj.AddProperty("name", GetVMName());
4013 if (ref) { 3815 if (ref) {
4014 return; 3816 return;
4015 } 3817 }
4016 jsobj.AddProperty("architectureBits", static_cast<intptr_t>(kBitsPerWord)); 3818 jsobj.AddProperty("architectureBits", static_cast<intptr_t>(kBitsPerWord));
4017 jsobj.AddProperty("targetCPU", CPU::Id()); 3819 jsobj.AddProperty("targetCPU", CPU::Id());
4018 jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware()); 3820 jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware());
4019 jsobj.AddProperty("version", Version::String()); 3821 jsobj.AddProperty("version", Version::String());
4020 jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart"); 3822 jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart");
4021 jsobj.AddProperty64("_nativeZoneMemoryUsage", 3823 jsobj.AddProperty64("_nativeZoneMemoryUsage",
4022 ApiNativeScope::current_memory_usage()); 3824 ApiNativeScope::current_memory_usage());
4023 jsobj.AddProperty64("pid", OS::ProcessId()); 3825 jsobj.AddProperty64("pid", OS::ProcessId());
4024 jsobj.AddProperty64("_maxRSS", OS::MaxRSS()); 3826 jsobj.AddProperty64("_maxRSS", OS::MaxRSS());
4025 jsobj.AddPropertyTimeMillis( 3827 jsobj.AddPropertyTimeMillis(
4026 "startTime", OS::GetCurrentTimeMillis() - Dart::UptimeMillis()); 3828 "startTime", OS::GetCurrentTimeMillis() - Dart::UptimeMillis());
4027 MallocHooks::PrintToJSONObject(&jsobj); 3829 MallocHooks::PrintToJSONObject(&jsobj);
4028 // Construct the isolate list. 3830 // Construct the isolate list.
4029 { 3831 {
4030 JSONArray jsarr(&jsobj, "isolates"); 3832 JSONArray jsarr(&jsobj, "isolates");
4031 ServiceIsolateVisitor visitor(&jsarr); 3833 ServiceIsolateVisitor visitor(&jsarr);
4032 Isolate::VisitIsolates(&visitor); 3834 Isolate::VisitIsolates(&visitor);
4033 } 3835 }
4034 } 3836 }
4035 3837
4036
4037 static bool GetVM(Thread* thread, JSONStream* js) { 3838 static bool GetVM(Thread* thread, JSONStream* js) {
4038 Service::PrintJSONForVM(js, false); 3839 Service::PrintJSONForVM(js, false);
4039 return true; 3840 return true;
4040 } 3841 }
4041 3842
4042
4043 static const char* exception_pause_mode_names[] = { 3843 static const char* exception_pause_mode_names[] = {
4044 "All", "None", "Unhandled", NULL, 3844 "All", "None", "Unhandled", NULL,
4045 }; 3845 };
4046 3846
4047
4048 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = { 3847 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = {
4049 kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions, 3848 kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions,
4050 kInvalidExceptionPauseInfo, 3849 kInvalidExceptionPauseInfo,
4051 }; 3850 };
4052 3851
4053
4054 static const MethodParameter* set_exception_pause_mode_params[] = { 3852 static const MethodParameter* set_exception_pause_mode_params[] = {
4055 ISOLATE_PARAMETER, 3853 ISOLATE_PARAMETER,
4056 new EnumParameter("mode", true, exception_pause_mode_names), NULL, 3854 new EnumParameter("mode", true, exception_pause_mode_names), NULL,
4057 }; 3855 };
4058 3856
4059
4060 static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) { 3857 static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) {
4061 const char* mode = js->LookupParam("mode"); 3858 const char* mode = js->LookupParam("mode");
4062 if (mode == NULL) { 3859 if (mode == NULL) {
4063 PrintMissingParamError(js, "mode"); 3860 PrintMissingParamError(js, "mode");
4064 return true; 3861 return true;
4065 } 3862 }
4066 Dart_ExceptionPauseInfo info = 3863 Dart_ExceptionPauseInfo info =
4067 EnumMapper(mode, exception_pause_mode_names, exception_pause_mode_values); 3864 EnumMapper(mode, exception_pause_mode_names, exception_pause_mode_values);
4068 if (info == kInvalidExceptionPauseInfo) { 3865 if (info == kInvalidExceptionPauseInfo) {
4069 PrintInvalidParamError(js, "mode"); 3866 PrintInvalidParamError(js, "mode");
4070 return true; 3867 return true;
4071 } 3868 }
4072 Isolate* isolate = thread->isolate(); 3869 Isolate* isolate = thread->isolate();
4073 isolate->debugger()->SetExceptionPauseInfo(info); 3870 isolate->debugger()->SetExceptionPauseInfo(info);
4074 if (Service::debug_stream.enabled()) { 3871 if (Service::debug_stream.enabled()) {
4075 ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate); 3872 ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate);
4076 Service::HandleEvent(&event); 3873 Service::HandleEvent(&event);
4077 } 3874 }
4078 PrintSuccess(js); 3875 PrintSuccess(js);
4079 return true; 3876 return true;
4080 } 3877 }
4081 3878
4082
4083 static const MethodParameter* get_flag_list_params[] = { 3879 static const MethodParameter* get_flag_list_params[] = {
4084 NO_ISOLATE_PARAMETER, NULL, 3880 NO_ISOLATE_PARAMETER, NULL,
4085 }; 3881 };
4086 3882
4087
4088 static bool GetFlagList(Thread* thread, JSONStream* js) { 3883 static bool GetFlagList(Thread* thread, JSONStream* js) {
4089 Flags::PrintJSON(js); 3884 Flags::PrintJSON(js);
4090 return true; 3885 return true;
4091 } 3886 }
4092 3887
4093
4094 static const MethodParameter* set_flags_params[] = { 3888 static const MethodParameter* set_flags_params[] = {
4095 NO_ISOLATE_PARAMETER, NULL, 3889 NO_ISOLATE_PARAMETER, NULL,
4096 }; 3890 };
4097 3891
4098
4099 static bool SetFlag(Thread* thread, JSONStream* js) { 3892 static bool SetFlag(Thread* thread, JSONStream* js) {
4100 const char* flag_name = js->LookupParam("name"); 3893 const char* flag_name = js->LookupParam("name");
4101 if (flag_name == NULL) { 3894 if (flag_name == NULL) {
4102 PrintMissingParamError(js, "name"); 3895 PrintMissingParamError(js, "name");
4103 return true; 3896 return true;
4104 } 3897 }
4105 const char* flag_value = js->LookupParam("value"); 3898 const char* flag_value = js->LookupParam("value");
4106 if (flag_value == NULL) { 3899 if (flag_value == NULL) {
4107 PrintMissingParamError(js, "value"); 3900 PrintMissingParamError(js, "value");
4108 return true; 3901 return true;
4109 } 3902 }
4110 const char* error = NULL; 3903 const char* error = NULL;
4111 if (Flags::SetFlag(flag_name, flag_value, &error)) { 3904 if (Flags::SetFlag(flag_name, flag_value, &error)) {
4112 PrintSuccess(js); 3905 PrintSuccess(js);
4113 return true; 3906 return true;
4114 } else { 3907 } else {
4115 JSONObject jsobj(js); 3908 JSONObject jsobj(js);
4116 jsobj.AddProperty("type", "Error"); 3909 jsobj.AddProperty("type", "Error");
4117 jsobj.AddProperty("message", error); 3910 jsobj.AddProperty("message", error);
4118 return true; 3911 return true;
4119 } 3912 }
4120 } 3913 }
4121 3914
4122
4123 static const MethodParameter* set_library_debuggable_params[] = { 3915 static const MethodParameter* set_library_debuggable_params[] = {
4124 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("libraryId", true), 3916 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("libraryId", true),
4125 new BoolParameter("isDebuggable", true), NULL, 3917 new BoolParameter("isDebuggable", true), NULL,
4126 }; 3918 };
4127 3919
4128
4129 static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) { 3920 static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) {
4130 const char* lib_id = js->LookupParam("libraryId"); 3921 const char* lib_id = js->LookupParam("libraryId");
4131 ObjectIdRing::LookupResult lookup_result; 3922 ObjectIdRing::LookupResult lookup_result;
4132 Object& obj = 3923 Object& obj =
4133 Object::Handle(LookupHeapObject(thread, lib_id, &lookup_result)); 3924 Object::Handle(LookupHeapObject(thread, lib_id, &lookup_result));
4134 const bool is_debuggable = 3925 const bool is_debuggable =
4135 BoolParameter::Parse(js->LookupParam("isDebuggable"), false); 3926 BoolParameter::Parse(js->LookupParam("isDebuggable"), false);
4136 if (obj.IsLibrary()) { 3927 if (obj.IsLibrary()) {
4137 const Library& lib = Library::Cast(obj); 3928 const Library& lib = Library::Cast(obj);
4138 if (lib.is_dart_scheme()) { 3929 if (lib.is_dart_scheme()) {
4139 const String& url = String::Handle(lib.url()); 3930 const String& url = String::Handle(lib.url());
4140 if (url.StartsWith(Symbols::DartSchemePrivate())) { 3931 if (url.StartsWith(Symbols::DartSchemePrivate())) {
4141 PrintIllegalParamError(js, "libraryId"); 3932 PrintIllegalParamError(js, "libraryId");
4142 return true; 3933 return true;
4143 } 3934 }
4144 } 3935 }
4145 lib.set_debuggable(is_debuggable); 3936 lib.set_debuggable(is_debuggable);
4146 PrintSuccess(js); 3937 PrintSuccess(js);
4147 return true; 3938 return true;
4148 } 3939 }
4149 PrintInvalidParamError(js, "libraryId"); 3940 PrintInvalidParamError(js, "libraryId");
4150 return true; 3941 return true;
4151 } 3942 }
4152 3943
4153
4154 static const MethodParameter* set_name_params[] = { 3944 static const MethodParameter* set_name_params[] = {
4155 ISOLATE_PARAMETER, new MethodParameter("name", true), NULL, 3945 ISOLATE_PARAMETER, new MethodParameter("name", true), NULL,
4156 }; 3946 };
4157 3947
4158
4159 static bool SetName(Thread* thread, JSONStream* js) { 3948 static bool SetName(Thread* thread, JSONStream* js) {
4160 Isolate* isolate = thread->isolate(); 3949 Isolate* isolate = thread->isolate();
4161 isolate->set_debugger_name(js->LookupParam("name")); 3950 isolate->set_debugger_name(js->LookupParam("name"));
4162 if (Service::isolate_stream.enabled()) { 3951 if (Service::isolate_stream.enabled()) {
4163 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); 3952 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate);
4164 Service::HandleEvent(&event); 3953 Service::HandleEvent(&event);
4165 } 3954 }
4166 PrintSuccess(js); 3955 PrintSuccess(js);
4167 return true; 3956 return true;
4168 } 3957 }
4169 3958
4170
4171 static const MethodParameter* set_vm_name_params[] = { 3959 static const MethodParameter* set_vm_name_params[] = {
4172 NO_ISOLATE_PARAMETER, new MethodParameter("name", true), NULL, 3960 NO_ISOLATE_PARAMETER, new MethodParameter("name", true), NULL,
4173 }; 3961 };
4174 3962
4175
4176 static bool SetVMName(Thread* thread, JSONStream* js) { 3963 static bool SetVMName(Thread* thread, JSONStream* js) {
4177 const char* name_param = js->LookupParam("name"); 3964 const char* name_param = js->LookupParam("name");
4178 free(vm_name); 3965 free(vm_name);
4179 vm_name = strdup(name_param); 3966 vm_name = strdup(name_param);
4180 if (Service::vm_stream.enabled()) { 3967 if (Service::vm_stream.enabled()) {
4181 ServiceEvent event(NULL, ServiceEvent::kVMUpdate); 3968 ServiceEvent event(NULL, ServiceEvent::kVMUpdate);
4182 Service::HandleEvent(&event); 3969 Service::HandleEvent(&event);
4183 } 3970 }
4184 PrintSuccess(js); 3971 PrintSuccess(js);
4185 return true; 3972 return true;
4186 } 3973 }
4187 3974
4188
4189 static const MethodParameter* set_trace_class_allocation_params[] = { 3975 static const MethodParameter* set_trace_class_allocation_params[] = {
4190 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("classId", true), 3976 RUNNABLE_ISOLATE_PARAMETER, new IdParameter("classId", true),
4191 new BoolParameter("enable", true), NULL, 3977 new BoolParameter("enable", true), NULL,
4192 }; 3978 };
4193 3979
4194
4195 static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) { 3980 static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) {
4196 if (!thread->isolate()->compilation_allowed()) { 3981 if (!thread->isolate()->compilation_allowed()) {
4197 js->PrintError( 3982 js->PrintError(
4198 kFeatureDisabled, 3983 kFeatureDisabled,
4199 "Cannot trace allocation when running a precompiled program."); 3984 "Cannot trace allocation when running a precompiled program.");
4200 return true; 3985 return true;
4201 } 3986 }
4202 const char* class_id = js->LookupParam("classId"); 3987 const char* class_id = js->LookupParam("classId");
4203 const bool enable = BoolParameter::Parse(js->LookupParam("enable")); 3988 const bool enable = BoolParameter::Parse(js->LookupParam("enable"));
4204 intptr_t cid = -1; 3989 intptr_t cid = -1;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4244 return true; 4029 return true;
4245 } else if (lookup_result == ObjectIdRing::kExpired) { 4030 } else if (lookup_result == ObjectIdRing::kExpired) {
4246 PrintSentinel(js, kExpiredSentinel); 4031 PrintSentinel(js, kExpiredSentinel);
4247 return true; 4032 return true;
4248 } 4033 }
4249 PrintInvalidParamError(js, "objectId"); 4034 PrintInvalidParamError(js, "objectId");
4250 4035
4251 return true; 4036 return true;
4252 } 4037 }
4253 4038
4254
4255 // clang-format off 4039 // clang-format off
4256 static const ServiceMethodDescriptor service_methods_[] = { 4040 static const ServiceMethodDescriptor service_methods_[] = {
4257 { "_dumpIdZone", DumpIdZone, NULL }, 4041 { "_dumpIdZone", DumpIdZone, NULL },
4258 { "_echo", Echo, 4042 { "_echo", Echo,
4259 NULL }, 4043 NULL },
4260 { "_respondWithMalformedJson", RespondWithMalformedJson, 4044 { "_respondWithMalformedJson", RespondWithMalformedJson,
4261 NULL }, 4045 NULL },
4262 { "_respondWithMalformedObject", RespondWithMalformedObject, 4046 { "_respondWithMalformedObject", RespondWithMalformedObject,
4263 NULL }, 4047 NULL },
4264 { "_triggerEchoEvent", TriggerEchoEvent, 4048 { "_triggerEchoEvent", TriggerEchoEvent,
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
4381 if (strcmp(method_name, method.name) == 0) { 4165 if (strcmp(method_name, method.name) == 0) {
4382 return &method; 4166 return &method;
4383 } 4167 }
4384 } 4168 }
4385 return NULL; 4169 return NULL;
4386 } 4170 }
4387 4171
4388 #endif // !PRODUCT 4172 #endif // !PRODUCT
4389 4173
4390 } // namespace dart 4174 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/service.h ('k') | runtime/vm/service_event.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698