OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/service.h" | 5 #include "vm/service.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 | 10 |
11 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
12 #include "vm/cpu.h" | 12 #include "vm/cpu.h" |
13 #include "vm/dart_api_impl.h" | 13 #include "vm/dart_api_impl.h" |
14 #include "vm/dart_api_state.h" | 14 #include "vm/dart_api_state.h" |
15 #include "vm/dart_entry.h" | 15 #include "vm/dart_entry.h" |
16 #include "vm/debugger.h" | 16 #include "vm/debugger.h" |
17 #include "vm/isolate.h" | 17 #include "vm/isolate.h" |
18 #include "vm/kernel_isolate.h" | |
18 #include "vm/lockers.h" | 19 #include "vm/lockers.h" |
19 #include "vm/malloc_hooks.h" | 20 #include "vm/malloc_hooks.h" |
20 #include "vm/message.h" | 21 #include "vm/message.h" |
21 #include "vm/message_handler.h" | 22 #include "vm/message_handler.h" |
23 #include "vm/native_arguments.h" | |
22 #include "vm/native_entry.h" | 24 #include "vm/native_entry.h" |
23 #include "vm/native_arguments.h" | |
24 #include "vm/native_symbol.h" | 25 #include "vm/native_symbol.h" |
25 #include "vm/object.h" | 26 #include "vm/object.h" |
26 #include "vm/object_graph.h" | 27 #include "vm/object_graph.h" |
27 #include "vm/object_id_ring.h" | 28 #include "vm/object_id_ring.h" |
28 #include "vm/object_store.h" | 29 #include "vm/object_store.h" |
29 #include "vm/parser.h" | 30 #include "vm/parser.h" |
30 #include "vm/port.h" | 31 #include "vm/port.h" |
31 #include "vm/profiler_service.h" | 32 #include "vm/profiler_service.h" |
32 #include "vm/reusable_handles.h" | 33 #include "vm/reusable_handles.h" |
33 #include "vm/safepoint.h" | 34 #include "vm/safepoint.h" |
34 #include "vm/service_event.h" | 35 #include "vm/service_event.h" |
35 #include "vm/service_isolate.h" | 36 #include "vm/service_isolate.h" |
36 #include "vm/source_report.h" | 37 #include "vm/source_report.h" |
37 #include "vm/stack_frame.h" | 38 #include "vm/stack_frame.h" |
38 #include "vm/symbols.h" | 39 #include "vm/symbols.h" |
39 #include "vm/timeline.h" | 40 #include "vm/timeline.h" |
40 #include "vm/type_table.h" | 41 #include "vm/type_table.h" |
41 #include "vm/unicode.h" | 42 #include "vm/unicode.h" |
42 #include "vm/version.h" | 43 #include "vm/version.h" |
43 #include "vm/kernel_isolate.h" | |
44 | 44 |
45 namespace dart { | 45 namespace dart { |
46 | 46 |
47 #define Z (T->zone()) | 47 #define Z (T->zone()) |
48 | 48 |
49 | 49 |
50 DECLARE_FLAG(bool, trace_service); | 50 DECLARE_FLAG(bool, trace_service); |
51 DECLARE_FLAG(bool, trace_service_pause_events); | 51 DECLARE_FLAG(bool, trace_service_pause_events); |
52 DECLARE_FLAG(bool, profile_vm); | 52 DECLARE_FLAG(bool, profile_vm); |
53 DEFINE_FLAG(charp, | 53 DEFINE_FLAG(charp, |
(...skipping 2160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2214 result.PrintJSON(js, true); | 2214 result.PrintJSON(js, true); |
2215 return true; | 2215 return true; |
2216 } | 2216 } |
2217 | 2217 |
2218 | 2218 |
2219 static const MethodParameter* evaluate_params[] = { | 2219 static const MethodParameter* evaluate_params[] = { |
2220 RUNNABLE_ISOLATE_PARAMETER, NULL, | 2220 RUNNABLE_ISOLATE_PARAMETER, NULL, |
2221 }; | 2221 }; |
2222 | 2222 |
2223 | 2223 |
2224 static bool IsAlpha(char c) { | |
2225 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); | |
2226 } | |
2227 static bool IsAlphaNum(char c) { | |
2228 return (c >= '0' && c <= '9') || IsAlpha(c); | |
2229 } | |
2230 static bool IsWhitespace(char c) { | |
2231 return c <= ' '; | |
siva
2017/05/18 20:56:48
should this also include tab?
rmacnak
2017/05/19 00:56:44
This includes tab.
| |
2232 } | |
2233 static bool IsObjectIdChar(char c) { | |
2234 return IsAlphaNum(c) || c == '/' || c == '-' || c == '@' || c == '%'; | |
2235 } | |
2236 | |
2237 | |
2238 // TODO(vm-service): Consider whether we should pass structured objects in | |
2239 // service messages instead of always flattening them to C strings. | |
2240 static bool ParseScope(const char* scope, | |
2241 const GrowableObjectArray& names, | |
2242 const GrowableObjectArray& values) { | |
2243 const char* c = scope; | |
2244 if (*c++ != '{') return false; | |
2245 | |
2246 String& str = String::Handle(); | |
2247 for (;;) { | |
2248 while (IsWhitespace(*c)) { | |
2249 c++; | |
2250 } | |
2251 | |
2252 if (*c == '}') return true; | |
2253 | |
2254 const char* name = c; | |
2255 if (!IsAlpha(*c)) return false; | |
2256 while (IsAlphaNum(*c)) { | |
2257 c++; | |
2258 } | |
2259 str = String::FromUTF8(reinterpret_cast<const uint8_t*>(name), c - name); | |
siva
2017/05/18 20:56:48
Is this really a UTF8 array or can you just use On
rmacnak
2017/05/19 00:56:44
The input came from a String::ToCString(). But swi
| |
2260 names.Add(str); | |
2261 | |
2262 while (IsWhitespace(*c)) { | |
2263 c++; | |
2264 } | |
2265 | |
2266 if (*c++ != ':') return false; | |
2267 | |
2268 while (IsWhitespace(*c)) { | |
2269 c++; | |
2270 } | |
2271 | |
2272 const char* id = c; | |
2273 if (!IsObjectIdChar(*c)) return false; | |
2274 while (IsObjectIdChar(*c)) { | |
2275 c++; | |
2276 } | |
2277 str = String::FromUTF8(reinterpret_cast<const uint8_t*>(id), c - id); | |
siva
2017/05/18 20:56:49
Ditto comment here.
Also why do we need to create
| |
2278 values.Add(str); | |
2279 | |
2280 while (IsWhitespace(*c)) { | |
2281 c++; | |
2282 } | |
2283 if (*c == ',') c++; | |
2284 } | |
2285 | |
2286 return false; | |
2287 } | |
2288 | |
2289 | |
2290 static bool BuildScope(Thread* thread, | |
2291 JSONStream* js, | |
2292 const GrowableObjectArray& names, | |
2293 const GrowableObjectArray& values) { | |
2294 const char* scope = js->LookupParam("scope"); | |
2295 if (scope != NULL) { | |
2296 if (!ParseScope(scope, names, values)) { | |
2297 PrintInvalidParamError(js, "scope"); | |
2298 return true; | |
2299 } | |
2300 String& id = String::Handle(); | |
2301 Object& obj = Object::Handle(); | |
2302 for (intptr_t i = 0; i < values.Length(); i++) { | |
2303 id ^= values.At(i); | |
2304 ObjectIdRing::LookupResult lookup_result; | |
2305 obj = LookupHeapObject(thread, id.ToCString(), &lookup_result); | |
2306 if (obj.raw() == Object::sentinel().raw()) { | |
2307 if (lookup_result == ObjectIdRing::kCollected) { | |
2308 PrintSentinel(js, kCollectedSentinel); | |
2309 } else if (lookup_result == ObjectIdRing::kExpired) { | |
2310 PrintSentinel(js, kExpiredSentinel); | |
2311 } else { | |
2312 PrintInvalidParamError(js, "targetId"); | |
2313 } | |
2314 return true; | |
2315 } | |
2316 if ((!obj.IsInstance() && !obj.IsNull()) || ContainsNonInstance(obj)) { | |
2317 js->PrintError(kInvalidParams, | |
2318 "%s: invalid scope 'targetId' parameter: " | |
2319 "Cannot evaluate against a VM-internal object", | |
2320 js->method()); | |
2321 return true; | |
2322 } | |
2323 values.SetAt(i, obj); | |
2324 } | |
2325 } | |
2326 return false; | |
2327 } | |
2328 | |
2329 | |
2224 static bool Evaluate(Thread* thread, JSONStream* js) { | 2330 static bool Evaluate(Thread* thread, JSONStream* js) { |
2225 if (!thread->isolate()->compilation_allowed()) { | 2331 if (!thread->isolate()->compilation_allowed()) { |
2226 js->PrintError(kFeatureDisabled, | 2332 js->PrintError(kFeatureDisabled, |
2227 "Cannot evaluate when running a precompiled program."); | 2333 "Cannot evaluate when running a precompiled program."); |
2228 return true; | 2334 return true; |
2229 } | 2335 } |
2230 const char* target_id = js->LookupParam("targetId"); | 2336 const char* target_id = js->LookupParam("targetId"); |
2231 if (target_id == NULL) { | 2337 if (target_id == NULL) { |
2232 PrintMissingParamError(js, "targetId"); | 2338 PrintMissingParamError(js, "targetId"); |
2233 return true; | 2339 return true; |
2234 } | 2340 } |
2235 const char* expr = js->LookupParam("expression"); | 2341 const char* expr = js->LookupParam("expression"); |
2236 if (expr == NULL) { | 2342 if (expr == NULL) { |
2237 PrintMissingParamError(js, "expression"); | 2343 PrintMissingParamError(js, "expression"); |
2238 return true; | 2344 return true; |
2239 } | 2345 } |
2346 | |
2240 Zone* zone = thread->zone(); | 2347 Zone* zone = thread->zone(); |
2348 const GrowableObjectArray& names = | |
2349 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | |
2350 const GrowableObjectArray& values = | |
2351 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | |
2352 if (BuildScope(thread, js, names, values)) { | |
2353 return true; | |
2354 } | |
2355 const Array& names_array = Array::Handle(zone, Array::MakeArray(names)); | |
2356 const Array& values_array = Array::Handle(zone, Array::MakeArray(values)); | |
2357 | |
2241 const String& expr_str = String::Handle(zone, String::New(expr)); | 2358 const String& expr_str = String::Handle(zone, String::New(expr)); |
2242 ObjectIdRing::LookupResult lookup_result; | 2359 ObjectIdRing::LookupResult lookup_result; |
2243 Object& obj = | 2360 Object& obj = |
2244 Object::Handle(zone, LookupHeapObject(thread, target_id, &lookup_result)); | 2361 Object::Handle(zone, LookupHeapObject(thread, target_id, &lookup_result)); |
2245 if (obj.raw() == Object::sentinel().raw()) { | 2362 if (obj.raw() == Object::sentinel().raw()) { |
2246 if (lookup_result == ObjectIdRing::kCollected) { | 2363 if (lookup_result == ObjectIdRing::kCollected) { |
2247 PrintSentinel(js, kCollectedSentinel); | 2364 PrintSentinel(js, kCollectedSentinel); |
2248 } else if (lookup_result == ObjectIdRing::kExpired) { | 2365 } else if (lookup_result == ObjectIdRing::kExpired) { |
2249 PrintSentinel(js, kExpiredSentinel); | 2366 PrintSentinel(js, kExpiredSentinel); |
2250 } else { | 2367 } else { |
2251 PrintInvalidParamError(js, "targetId"); | 2368 PrintInvalidParamError(js, "targetId"); |
2252 } | 2369 } |
2253 return true; | 2370 return true; |
2254 } | 2371 } |
2255 if (obj.IsLibrary()) { | 2372 if (obj.IsLibrary()) { |
2256 const Library& lib = Library::Cast(obj); | 2373 const Library& lib = Library::Cast(obj); |
2257 const Object& result = Object::Handle( | 2374 const Object& result = |
2258 zone, | 2375 Object::Handle(zone, lib.Evaluate(expr_str, names_array, values_array)); |
2259 lib.Evaluate(expr_str, Array::empty_array(), Array::empty_array())); | |
2260 result.PrintJSON(js, true); | 2376 result.PrintJSON(js, true); |
2261 return true; | 2377 return true; |
2262 } | 2378 } |
2263 if (obj.IsClass()) { | 2379 if (obj.IsClass()) { |
2264 const Class& cls = Class::Cast(obj); | 2380 const Class& cls = Class::Cast(obj); |
2265 const Object& result = Object::Handle( | 2381 const Object& result = |
2266 zone, | 2382 Object::Handle(zone, cls.Evaluate(expr_str, names_array, values_array)); |
2267 cls.Evaluate(expr_str, Array::empty_array(), Array::empty_array())); | |
2268 result.PrintJSON(js, true); | 2383 result.PrintJSON(js, true); |
2269 return true; | 2384 return true; |
2270 } | 2385 } |
2271 if ((obj.IsInstance() || obj.IsNull()) && !ContainsNonInstance(obj)) { | 2386 if ((obj.IsInstance() || obj.IsNull()) && !ContainsNonInstance(obj)) { |
2272 // We don't use Instance::Cast here because it doesn't allow null. | 2387 // We don't use Instance::Cast here because it doesn't allow null. |
2273 Instance& instance = Instance::Handle(zone); | 2388 Instance& instance = Instance::Handle(zone); |
2274 instance ^= obj.raw(); | 2389 instance ^= obj.raw(); |
2275 const Class& receiver_cls = Class::Handle(zone, instance.clazz()); | 2390 const Class& receiver_cls = Class::Handle(zone, instance.clazz()); |
2276 const Object& result = Object::Handle( | 2391 const Object& result = Object::Handle( |
2277 zone, instance.Evaluate(receiver_cls, expr_str, Array::empty_array(), | 2392 zone, |
2278 Array::empty_array())); | 2393 instance.Evaluate(receiver_cls, expr_str, names_array, values_array)); |
2279 result.PrintJSON(js, true); | 2394 result.PrintJSON(js, true); |
2280 return true; | 2395 return true; |
2281 } | 2396 } |
2282 js->PrintError(kInvalidParams, | 2397 js->PrintError(kInvalidParams, |
2283 "%s: invalid 'targetId' parameter: " | 2398 "%s: invalid 'targetId' parameter: " |
2284 "Cannot evaluate against a VM-internal object", | 2399 "Cannot evaluate against a VM-internal object", |
2285 js->method()); | 2400 js->method()); |
2286 return true; | 2401 return true; |
2287 } | 2402 } |
2288 | 2403 |
(...skipping 13 matching lines...) Expand all Loading... | |
2302 } | 2417 } |
2303 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); | 2418 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
2304 intptr_t framePos = UIntParameter::Parse(js->LookupParam("frameIndex")); | 2419 intptr_t framePos = UIntParameter::Parse(js->LookupParam("frameIndex")); |
2305 if (framePos >= stack->Length()) { | 2420 if (framePos >= stack->Length()) { |
2306 PrintInvalidParamError(js, "frameIndex"); | 2421 PrintInvalidParamError(js, "frameIndex"); |
2307 return true; | 2422 return true; |
2308 } | 2423 } |
2309 ActivationFrame* frame = stack->FrameAt(framePos); | 2424 ActivationFrame* frame = stack->FrameAt(framePos); |
2310 | 2425 |
2311 Zone* zone = thread->zone(); | 2426 Zone* zone = thread->zone(); |
2427 const GrowableObjectArray& names = | |
2428 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | |
2429 const GrowableObjectArray& values = | |
2430 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | |
2431 if (BuildScope(thread, js, names, values)) { | |
2432 return true; | |
2433 } | |
2434 | |
2312 const char* expr = js->LookupParam("expression"); | 2435 const char* expr = js->LookupParam("expression"); |
2313 const String& expr_str = String::Handle(zone, String::New(expr)); | 2436 const String& expr_str = String::Handle(zone, String::New(expr)); |
2314 | 2437 |
2315 const Object& result = Object::Handle(zone, frame->Evaluate(expr_str)); | 2438 const Object& result = |
2439 Object::Handle(zone, frame->Evaluate(expr_str, names, values)); | |
2316 result.PrintJSON(js, true); | 2440 result.PrintJSON(js, true); |
2317 return true; | 2441 return true; |
2318 } | 2442 } |
2319 | 2443 |
2320 | 2444 |
2321 class GetInstancesVisitor : public ObjectGraph::Visitor { | 2445 class GetInstancesVisitor : public ObjectGraph::Visitor { |
2322 public: | 2446 public: |
2323 GetInstancesVisitor(const Class& cls, const Array& storage) | 2447 GetInstancesVisitor(const Class& cls, const Array& storage) |
2324 : cls_(cls), storage_(storage), count_(0) {} | 2448 : cls_(cls), storage_(storage), count_(0) {} |
2325 | 2449 |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2922 } | 3046 } |
2923 | 3047 |
2924 static const char* const timeline_streams_enum_names[] = { | 3048 static const char* const timeline_streams_enum_names[] = { |
2925 "all", | 3049 "all", |
2926 #define DEFINE_NAME(name, unused) #name, | 3050 #define DEFINE_NAME(name, unused) #name, |
2927 TIMELINE_STREAM_LIST(DEFINE_NAME) | 3051 TIMELINE_STREAM_LIST(DEFINE_NAME) |
2928 #undef DEFINE_NAME | 3052 #undef DEFINE_NAME |
2929 NULL}; | 3053 NULL}; |
2930 | 3054 |
2931 static const MethodParameter* set_vm_timeline_flags_params[] = { | 3055 static const MethodParameter* set_vm_timeline_flags_params[] = { |
2932 NO_ISOLATE_PARAMETER, new EnumListParameter("recordedStreams", | 3056 NO_ISOLATE_PARAMETER, |
2933 false, | 3057 new EnumListParameter("recordedStreams", |
2934 timeline_streams_enum_names), | 3058 false, |
3059 timeline_streams_enum_names), | |
2935 NULL, | 3060 NULL, |
2936 }; | 3061 }; |
2937 | 3062 |
2938 | 3063 |
2939 static bool HasStream(const char** recorded_streams, const char* stream) { | 3064 static bool HasStream(const char** recorded_streams, const char* stream) { |
2940 while (*recorded_streams != NULL) { | 3065 while (*recorded_streams != NULL) { |
2941 if ((strstr(*recorded_streams, "all") != NULL) || | 3066 if ((strstr(*recorded_streams, "all") != NULL) || |
2942 (strstr(*recorded_streams, stream) != NULL)) { | 3067 (strstr(*recorded_streams, stream) != NULL)) { |
2943 return true; | 3068 return true; |
2944 } | 3069 } |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3602 | 3727 |
3603 void Append(FinalizablePersistentHandle* weak_persistent_handle) { | 3728 void Append(FinalizablePersistentHandle* weak_persistent_handle) { |
3604 if (!weak_persistent_handle->raw()->IsHeapObject()) { | 3729 if (!weak_persistent_handle->raw()->IsHeapObject()) { |
3605 return; // Free handle. | 3730 return; // Free handle. |
3606 } | 3731 } |
3607 | 3732 |
3608 JSONObject obj(handles_); | 3733 JSONObject obj(handles_); |
3609 obj.AddProperty("type", "_WeakPersistentHandle"); | 3734 obj.AddProperty("type", "_WeakPersistentHandle"); |
3610 const Object& object = Object::Handle(weak_persistent_handle->raw()); | 3735 const Object& object = Object::Handle(weak_persistent_handle->raw()); |
3611 obj.AddProperty("object", object); | 3736 obj.AddProperty("object", object); |
3612 obj.AddPropertyF("peer", "0x%" Px "", reinterpret_cast<uintptr_t>( | 3737 obj.AddPropertyF( |
3613 weak_persistent_handle->peer())); | 3738 "peer", "0x%" Px "", |
3739 reinterpret_cast<uintptr_t>(weak_persistent_handle->peer())); | |
3614 obj.AddPropertyF( | 3740 obj.AddPropertyF( |
3615 "callbackAddress", "0x%" Px "", | 3741 "callbackAddress", "0x%" Px "", |
3616 reinterpret_cast<uintptr_t>(weak_persistent_handle->callback())); | 3742 reinterpret_cast<uintptr_t>(weak_persistent_handle->callback())); |
3617 // Attempt to include a native symbol name. | 3743 // Attempt to include a native symbol name. |
3618 char* name = NativeSymbolResolver::LookupSymbolName( | 3744 char* name = NativeSymbolResolver::LookupSymbolName( |
3619 reinterpret_cast<uintptr_t>(weak_persistent_handle->callback()), NULL); | 3745 reinterpret_cast<uintptr_t>(weak_persistent_handle->callback()), NULL); |
3620 obj.AddProperty("callbackSymbolName", (name == NULL) ? "" : name); | 3746 obj.AddProperty("callbackSymbolName", (name == NULL) ? "" : name); |
3621 if (name != NULL) { | 3747 if (name != NULL) { |
3622 NativeSymbolResolver::FreeSymbolName(name); | 3748 NativeSymbolResolver::FreeSymbolName(name); |
3623 } | 3749 } |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4204 if (strcmp(method_name, method.name) == 0) { | 4330 if (strcmp(method_name, method.name) == 0) { |
4205 return &method; | 4331 return &method; |
4206 } | 4332 } |
4207 } | 4333 } |
4208 return NULL; | 4334 return NULL; |
4209 } | 4335 } |
4210 | 4336 |
4211 #endif // !PRODUCT | 4337 #endif // !PRODUCT |
4212 | 4338 |
4213 } // namespace dart | 4339 } // namespace dart |
OLD | NEW |