| Index: runtime/vm/service.cc | 
| diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc | 
| index 797e060b6821e14c14ba8ca61c80ec008caa553b..c659d7d5590baa32af10d31a1849f44b37c58534 100644 | 
| --- a/runtime/vm/service.cc | 
| +++ b/runtime/vm/service.cc | 
| @@ -529,7 +529,7 @@ T EnumMapper(const char* value, const char** enums, T* values) { | 
| } | 
|  | 
|  | 
| -typedef bool (*ServiceMethodEntry)(Isolate* isolate, JSONStream* js); | 
| +typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js); | 
|  | 
|  | 
| struct ServiceMethodDescriptor { | 
| @@ -650,7 +650,7 @@ void Service::InvokeMethod(Isolate* I, const Array& msg) { | 
| js.PostReply(); | 
| return; | 
| } | 
| -      if (method->entry(I, &js)) { | 
| +      if (method->entry(T, &js)) { | 
| js.PostReply(); | 
| } else { | 
| // NOTE(turnidge): All message handlers currently return true, | 
| @@ -1011,8 +1011,8 @@ static const MethodParameter* get_isolate_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetIsolate(Isolate* isolate, JSONStream* js) { | 
| -  isolate->PrintJSON(js, false); | 
| +static bool GetIsolate(Thread* thread, JSONStream* js) { | 
| +  thread->isolate()->PrintJSON(js, false); | 
| return true; | 
| } | 
|  | 
| @@ -1024,7 +1024,8 @@ static const MethodParameter* get_stack_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetStack(Isolate* isolate, JSONStream* js) { | 
| +static bool GetStack(Thread* thread, JSONStream* js) { | 
| +  Isolate* isolate = thread->isolate(); | 
| DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); | 
| // Do we want the complete script object and complete local variable objects? | 
| // This is true for dump requests. | 
| @@ -1089,20 +1090,20 @@ void Service::SendEchoEvent(Isolate* isolate, const char* text) { | 
| } | 
|  | 
|  | 
| -static bool TriggerEchoEvent(Isolate* isolate, JSONStream* js) { | 
| +static bool TriggerEchoEvent(Thread* thread, JSONStream* js) { | 
| if (Service::echo_stream.enabled()) { | 
| -    Service::SendEchoEvent(isolate, js->LookupParam("text")); | 
| +    Service::SendEchoEvent(thread->isolate(), js->LookupParam("text")); | 
| } | 
| JSONObject jsobj(js); | 
| return HandleCommonEcho(&jsobj, js); | 
| } | 
|  | 
|  | 
| -static bool DumpIdZone(Isolate* isolate, JSONStream* js) { | 
| +static bool DumpIdZone(Thread* thread, JSONStream* js) { | 
| // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now, | 
| // always send the ObjectIdRing. | 
| // | 
| -  ObjectIdRing* ring = isolate->object_id_ring(); | 
| +  ObjectIdRing* ring = thread->isolate()->object_id_ring(); | 
| ASSERT(ring != NULL); | 
| // When printing the ObjectIdRing, force object id reuse policy. | 
| RingServiceIdZone reuse_zone; | 
| @@ -1113,7 +1114,7 @@ static bool DumpIdZone(Isolate* isolate, JSONStream* js) { | 
| } | 
|  | 
|  | 
| -static bool Echo(Isolate* isolate, JSONStream* js) { | 
| +static bool Echo(Thread* thread, JSONStream* js) { | 
| JSONObject jsobj(js); | 
| return HandleCommonEcho(&jsobj, js); | 
| } | 
| @@ -1421,7 +1422,7 @@ static RawObject* LookupHeapObjectCode(Isolate* isolate, | 
| } | 
|  | 
|  | 
| -static RawObject* LookupHeapObjectMessage(Isolate* isolate, | 
| +static RawObject* LookupHeapObjectMessage(Thread* thread, | 
| char** parts, int num_parts) { | 
| if (num_parts != 2) { | 
| return Object::sentinel().raw(); | 
| @@ -1431,7 +1432,7 @@ static RawObject* LookupHeapObjectMessage(Isolate* isolate, | 
| return Object::sentinel().raw(); | 
| } | 
| MessageHandler::AcquiredQueues aq; | 
| -  isolate->message_handler()->AcquireQueues(&aq); | 
| +  thread->isolate()->message_handler()->AcquireQueues(&aq); | 
| Message* message = aq.queue()->FindMessageById(message_id); | 
| if (message == NULL) { | 
| // The user may try to load an expired message. | 
| @@ -1439,15 +1440,14 @@ static RawObject* LookupHeapObjectMessage(Isolate* isolate, | 
| } | 
| MessageSnapshotReader reader(message->data(), | 
| message->len(), | 
| -                               Thread::Current()); | 
| +                               thread); | 
| return reader.ReadObject(); | 
| } | 
|  | 
|  | 
| -static RawObject* LookupHeapObject(Isolate* isolate, | 
| +static RawObject* LookupHeapObject(Thread* thread, | 
| const char* id_original, | 
| ObjectIdRing::LookupResult* result) { | 
| -  Thread* thread = Thread::Current(); | 
| char* id = thread->zone()->MakeCopyOfString(id_original); | 
|  | 
| // Parse the id by splitting at each '/'. | 
| @@ -1476,6 +1476,7 @@ static RawObject* LookupHeapObject(Isolate* isolate, | 
| *result = ObjectIdRing::kValid; | 
| } | 
|  | 
| +  Isolate* isolate = thread->isolate(); | 
| if (strcmp(parts[0], "objects") == 0) { | 
| // Object ids look like "objects/1123" | 
| Object& obj = Object::Handle(thread->zone()); | 
| @@ -1498,7 +1499,7 @@ static RawObject* LookupHeapObject(Isolate* isolate, | 
| } else if (strcmp(parts[0], "code") == 0) { | 
| return LookupHeapObjectCode(isolate, parts, num_parts); | 
| } else if (strcmp(parts[0], "messages") == 0) { | 
| -    return LookupHeapObjectMessage(isolate, parts, num_parts); | 
| +    return LookupHeapObjectMessage(thread, parts, num_parts); | 
| } | 
|  | 
| // Not found. | 
| @@ -1620,10 +1621,7 @@ static const MethodParameter* get_inbound_references_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetInboundReferences(Isolate* isolate, JSONStream* js) { | 
| -  Thread* thread = Thread::Current(); | 
| -  ASSERT(isolate == thread->isolate()); | 
| - | 
| +static bool GetInboundReferences(Thread* thread, JSONStream* js) { | 
| const char* target_id = js->LookupParam("targetId"); | 
| if (target_id == NULL) { | 
| PrintMissingParamError(js, "targetId"); | 
| @@ -1644,7 +1642,7 @@ static bool GetInboundReferences(Isolate* isolate, JSONStream* js) { | 
| ObjectIdRing::LookupResult lookup_result; | 
| { | 
| HANDLESCOPE(thread); | 
| -    obj = LookupHeapObject(isolate, target_id, &lookup_result); | 
| +    obj = LookupHeapObject(thread, target_id, &lookup_result); | 
| } | 
| if (obj.raw() == Object::sentinel().raw()) { | 
| if (lookup_result == ObjectIdRing::kCollected) { | 
| @@ -1722,10 +1720,7 @@ static const MethodParameter* get_retaining_path_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetRetainingPath(Isolate* isolate, JSONStream* js) { | 
| -  Thread* thread = Thread::Current(); | 
| -  ASSERT(isolate == thread->isolate()); | 
| - | 
| +static bool GetRetainingPath(Thread* thread, JSONStream* js) { | 
| const char* target_id = js->LookupParam("targetId"); | 
| if (target_id == NULL) { | 
| PrintMissingParamError(js, "targetId"); | 
| @@ -1746,7 +1741,7 @@ static bool GetRetainingPath(Isolate* isolate, JSONStream* js) { | 
| ObjectIdRing::LookupResult lookup_result; | 
| { | 
| HANDLESCOPE(thread); | 
| -    obj = LookupHeapObject(isolate, target_id, &lookup_result); | 
| +    obj = LookupHeapObject(thread, target_id, &lookup_result); | 
| } | 
| if (obj.raw() == Object::sentinel().raw()) { | 
| if (lookup_result == ObjectIdRing::kCollected) { | 
| @@ -1768,14 +1763,14 @@ static const MethodParameter* get_retained_size_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetRetainedSize(Isolate* isolate, JSONStream* js) { | 
| +static bool GetRetainedSize(Thread* thread, JSONStream* js) { | 
| const char* target_id = js->LookupParam("targetId"); | 
| if (target_id == NULL) { | 
| PrintMissingParamError(js, "targetId"); | 
| return true; | 
| } | 
| ObjectIdRing::LookupResult lookup_result; | 
| -  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, | 
| +  Object& obj = Object::Handle(LookupHeapObject(thread, target_id, | 
| &lookup_result)); | 
| if (obj.raw() == Object::sentinel().raw()) { | 
| if (lookup_result == ObjectIdRing::kCollected) { | 
| @@ -1787,7 +1782,6 @@ static bool GetRetainedSize(Isolate* isolate, JSONStream* js) { | 
| } | 
| return true; | 
| } | 
| -  Thread* thread = Thread::Current(); | 
| // TODO(rmacnak): There is no way to get the size retained by a class object. | 
| // SizeRetainedByClass should be a separate RPC. | 
| if (obj.IsClass()) { | 
| @@ -1813,8 +1807,8 @@ static const MethodParameter* evaluate_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool Evaluate(Isolate* isolate, JSONStream* js) { | 
| -  if (!isolate->compilation_allowed()) { | 
| +static bool Evaluate(Thread* thread, JSONStream* js) { | 
| +  if (!thread->isolate()->compilation_allowed()) { | 
| js->PrintError(kFeatureDisabled, | 
| "Cannot evaluate when running a precompiled program."); | 
| return true; | 
| @@ -1829,10 +1823,10 @@ static bool Evaluate(Isolate* isolate, JSONStream* js) { | 
| PrintMissingParamError(js, "expression"); | 
| return true; | 
| } | 
| -  Zone* zone = Thread::Current()->zone(); | 
| +  Zone* zone = thread->zone(); | 
| const String& expr_str = String::Handle(zone, String::New(expr)); | 
| ObjectIdRing::LookupResult lookup_result; | 
| -  Object& obj = Object::Handle(zone, LookupHeapObject(isolate, target_id, | 
| +  Object& obj = Object::Handle(zone, LookupHeapObject(thread, target_id, | 
| &lookup_result)); | 
| if (obj.raw() == Object::sentinel().raw()) { | 
| if (lookup_result == ObjectIdRing::kCollected) { | 
| @@ -1886,7 +1880,8 @@ static const MethodParameter* evaluate_in_frame_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool EvaluateInFrame(Isolate* isolate, JSONStream* js) { | 
| +static bool EvaluateInFrame(Thread* thread, JSONStream* js) { | 
| +  Isolate* isolate = thread->isolate(); | 
| if (!isolate->compilation_allowed()) { | 
| js->PrintError(kFeatureDisabled, | 
| "Cannot evaluate when running a precompiled program."); | 
| @@ -1900,7 +1895,7 @@ static bool EvaluateInFrame(Isolate* isolate, JSONStream* js) { | 
| } | 
| ActivationFrame* frame = stack->FrameAt(framePos); | 
|  | 
| -  Zone* zone = Thread::Current()->zone(); | 
| +  Zone* zone = thread->zone(); | 
| const char* expr = js->LookupParam("expression"); | 
| const String& expr_str = String::Handle(zone, String::New(expr)); | 
|  | 
| @@ -1948,7 +1943,7 @@ static const MethodParameter* get_instances_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetInstances(Isolate* isolate, JSONStream* js) { | 
| +static bool GetInstances(Thread* thread, JSONStream* js) { | 
| const char* target_id = js->LookupParam("classId"); | 
| if (target_id == NULL) { | 
| PrintMissingParamError(js, "classId"); | 
| @@ -1965,7 +1960,7 @@ static bool GetInstances(Isolate* isolate, JSONStream* js) { | 
| return true; | 
| } | 
| const Object& obj = | 
| -      Object::Handle(LookupHeapObject(isolate, target_id, NULL)); | 
| +      Object::Handle(LookupHeapObject(thread, target_id, NULL)); | 
| if (obj.raw() == Object::sentinel().raw() || | 
| !obj.IsClass()) { | 
| PrintInvalidParamError(js, "classId"); | 
| @@ -1974,7 +1969,7 @@ static bool GetInstances(Isolate* isolate, JSONStream* js) { | 
| const Class& cls = Class::Cast(obj); | 
| Array& storage = Array::Handle(Array::New(limit)); | 
| GetInstancesVisitor visitor(cls, storage); | 
| -  ObjectGraph graph(Thread::Current()); | 
| +  ObjectGraph graph(thread); | 
| graph.IterateObjects(&visitor); | 
| intptr_t count = visitor.count(); | 
| if (count < limit) { | 
| @@ -2055,14 +2050,13 @@ class FunctionCoverageFilter : public CoverageFilter { | 
| }; | 
|  | 
|  | 
| -static bool GetHitsOrSites(Isolate* isolate, JSONStream* js, bool as_sites) { | 
| -  Thread* thread = Thread::Current(); | 
| +static bool GetHitsOrSites(Thread* thread, JSONStream* js, bool as_sites) { | 
| if (!js->HasParam("targetId")) { | 
| CodeCoverage::PrintJSON(thread, js, NULL, as_sites); | 
| return true; | 
| } | 
| const char* target_id = js->LookupParam("targetId"); | 
| -  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, NULL)); | 
| +  Object& obj = Object::Handle(LookupHeapObject(thread, target_id, NULL)); | 
| if (obj.raw() == Object::sentinel().raw()) { | 
| PrintInvalidParamError(js, "targetId"); | 
| return true; | 
| @@ -2103,9 +2097,9 @@ static const MethodParameter* get_coverage_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetCoverage(Isolate* isolate, JSONStream* js) { | 
| +static bool GetCoverage(Thread* thread, JSONStream* js) { | 
| // TODO(rmacnak): Remove this response; it is subsumed by GetCallSiteData. | 
| -  return GetHitsOrSites(isolate, js, false); | 
| +  return GetHitsOrSites(thread, js, false); | 
| } | 
|  | 
|  | 
| @@ -2116,12 +2110,12 @@ static const MethodParameter* get_call_site_data_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetCallSiteData(Isolate* isolate, JSONStream* js) { | 
| -  return GetHitsOrSites(isolate, js, true); | 
| +static bool GetCallSiteData(Thread* thread, JSONStream* js) { | 
| +  return GetHitsOrSites(thread, js, true); | 
| } | 
|  | 
|  | 
| -static bool AddBreakpointCommon(Isolate* isolate, | 
| +static bool AddBreakpointCommon(Thread* thread, | 
| JSONStream* js, | 
| const String& script_uri) { | 
| const char* line_param = js->LookupParam("line"); | 
| @@ -2138,7 +2132,8 @@ static bool AddBreakpointCommon(Isolate* isolate, | 
| } | 
| ASSERT(!script_uri.IsNull()); | 
| Breakpoint* bpt = NULL; | 
| -  bpt = isolate->debugger()->SetBreakpointAtLineCol(script_uri, line, col); | 
| +  bpt = thread->isolate()->debugger()-> | 
| +      SetBreakpointAtLineCol(script_uri, line, col); | 
| if (bpt == NULL) { | 
| js->PrintError(kCannotAddBreakpoint, | 
| "%s: Cannot add breakpoint at line '%s'", | 
| @@ -2159,10 +2154,9 @@ static const MethodParameter* add_breakpoint_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool AddBreakpoint(Isolate* isolate, JSONStream* js) { | 
| +static bool AddBreakpoint(Thread* thread, JSONStream* js) { | 
| const char* script_id_param = js->LookupParam("scriptId"); | 
| -  Object& obj = | 
| -      Object::Handle(LookupHeapObject(isolate, script_id_param, NULL)); | 
| +  Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL)); | 
| if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) { | 
| PrintInvalidParamError(js, "scriptId"); | 
| return true; | 
| @@ -2170,7 +2164,7 @@ static bool AddBreakpoint(Isolate* isolate, JSONStream* js) { | 
| const Script& script = Script::Cast(obj); | 
| const String& script_uri = String::Handle(script.url()); | 
| ASSERT(!script_uri.IsNull()); | 
| -  return AddBreakpointCommon(isolate, js, script_uri); | 
| +  return AddBreakpointCommon(thread, js, script_uri); | 
| } | 
|  | 
|  | 
| @@ -2183,10 +2177,10 @@ static const MethodParameter* add_breakpoint_with_script_uri_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool AddBreakpointWithScriptUri(Isolate* isolate, JSONStream* js) { | 
| +static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) { | 
| const char* script_uri_param = js->LookupParam("scriptUri"); | 
| const String& script_uri = String::Handle(String::New(script_uri_param)); | 
| -  return AddBreakpointCommon(isolate, js, script_uri); | 
| +  return AddBreakpointCommon(thread, js, script_uri); | 
| } | 
|  | 
|  | 
| @@ -2197,16 +2191,16 @@ static const MethodParameter* add_breakpoint_at_entry_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool AddBreakpointAtEntry(Isolate* isolate, JSONStream* js) { | 
| +static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) { | 
| const char* function_id = js->LookupParam("functionId"); | 
| -  Object& obj = Object::Handle(LookupHeapObject(isolate, function_id, NULL)); | 
| +  Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL)); | 
| if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) { | 
| PrintInvalidParamError(js, "functionId"); | 
| return true; | 
| } | 
| const Function& function = Function::Cast(obj); | 
| Breakpoint* bpt = | 
| -      isolate->debugger()->SetBreakpointAtEntry(function, false); | 
| +      thread->isolate()->debugger()->SetBreakpointAtEntry(function, false); | 
| if (bpt == NULL) { | 
| js->PrintError(kCannotAddBreakpoint, | 
| "%s: Cannot add breakpoint at function '%s'", | 
| @@ -2225,16 +2219,16 @@ static const MethodParameter* add_breakpoint_at_activation_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool AddBreakpointAtActivation(Isolate* isolate, JSONStream* js) { | 
| +static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) { | 
| const char* object_id = js->LookupParam("objectId"); | 
| -  Object& obj = Object::Handle(LookupHeapObject(isolate, object_id, NULL)); | 
| +  Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL)); | 
| if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) { | 
| PrintInvalidParamError(js, "objectId"); | 
| return true; | 
| } | 
| const Instance& closure = Instance::Cast(obj); | 
| Breakpoint* bpt = | 
| -      isolate->debugger()->SetBreakpointAtActivation(closure); | 
| +      thread->isolate()->debugger()->SetBreakpointAtActivation(closure); | 
| if (bpt == NULL) { | 
| js->PrintError(kCannotAddBreakpoint, | 
| "%s: Cannot add breakpoint at activation", | 
| @@ -2252,13 +2246,14 @@ static const MethodParameter* remove_breakpoint_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool RemoveBreakpoint(Isolate* isolate, JSONStream* js) { | 
| +static bool RemoveBreakpoint(Thread* thread, JSONStream* js) { | 
| if (!js->HasParam("breakpointId")) { | 
| PrintMissingParamError(js, "breakpointId"); | 
| return true; | 
| } | 
| const char* bpt_id = js->LookupParam("breakpointId"); | 
| ObjectIdRing::LookupResult lookup_result; | 
| +  Isolate* isolate = thread->isolate(); | 
| Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result); | 
| // TODO(turnidge): Should we return a different error for bpts whic | 
| // have been already removed? | 
| @@ -2272,8 +2267,8 @@ static bool RemoveBreakpoint(Isolate* isolate, JSONStream* js) { | 
| } | 
|  | 
|  | 
| -static RawClass* GetMetricsClass(Isolate* isolate) { | 
| -  Zone* zone = isolate->current_zone(); | 
| +static RawClass* GetMetricsClass(Thread* thread) { | 
| +  Zone* zone = thread->zone(); | 
| const Library& prof_lib = | 
| Library::Handle(zone, Library::DeveloperLibrary()); | 
| ASSERT(!prof_lib.IsNull()); | 
| @@ -2288,12 +2283,12 @@ static RawClass* GetMetricsClass(Isolate* isolate) { | 
|  | 
|  | 
|  | 
| -static bool HandleNativeMetricsList(Isolate* isolate, JSONStream* js) { | 
| +static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) { | 
| JSONObject obj(js); | 
| obj.AddProperty("type", "MetricList"); | 
| { | 
| JSONArray metrics(&obj, "metrics"); | 
| -    Metric* current = isolate->metrics_list_head(); | 
| +    Metric* current = thread->isolate()->metrics_list_head(); | 
| while (current != NULL) { | 
| metrics.AddValue(current); | 
| current = current->next(); | 
| @@ -2303,10 +2298,8 @@ static bool HandleNativeMetricsList(Isolate* isolate, JSONStream* js) { | 
| } | 
|  | 
|  | 
| -static bool HandleNativeMetric(Isolate* isolate, | 
| -                                JSONStream* js, | 
| -                                const char* id) { | 
| -  Metric* current = isolate->metrics_list_head(); | 
| +static bool HandleNativeMetric(Thread* thread, JSONStream* js, const char* id) { | 
| +  Metric* current = thread->isolate()->metrics_list_head(); | 
| while (current != NULL) { | 
| const char* name = current->name(); | 
| ASSERT(name != NULL); | 
| @@ -2321,9 +2314,10 @@ static bool HandleNativeMetric(Isolate* isolate, | 
| } | 
|  | 
|  | 
| -static bool HandleDartMetricsList(Isolate* isolate, JSONStream* js) { | 
| -  Zone* zone = isolate->current_zone(); | 
| -  const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(isolate)); | 
| +static bool HandleDartMetricsList(Thread* thread, JSONStream* js) { | 
| +  Zone* zone = thread->zone(); | 
| +  const Class& metrics_cls = | 
| +      Class::Handle(zone, GetMetricsClass(thread)); | 
| const String& print_metrics_name = | 
| String::Handle(String::New("_printMetrics")); | 
| ASSERT(!print_metrics_name.IsNull()); | 
| @@ -2342,9 +2336,10 @@ static bool HandleDartMetricsList(Isolate* isolate, JSONStream* js) { | 
| } | 
|  | 
|  | 
| -static bool HandleDartMetric(Isolate* isolate, JSONStream* js, const char* id) { | 
| -  Zone* zone = isolate->current_zone(); | 
| -  const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(isolate)); | 
| +static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) { | 
| +  Zone* zone = thread->zone(); | 
| +  const Class& metrics_cls = | 
| +      Class::Handle(zone, GetMetricsClass(thread)); | 
| const String& print_metric_name = | 
| String::Handle(String::New("_printMetric")); | 
| ASSERT(!print_metric_name.IsNull()); | 
| @@ -2376,7 +2371,7 @@ static const MethodParameter* get_isolate_metric_list_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetIsolateMetricList(Isolate* isolate, JSONStream* js) { | 
| +static bool GetIsolateMetricList(Thread* thread, JSONStream* js) { | 
| bool native_metrics = false; | 
| if (js->HasParam("type")) { | 
| if (js->ParamIs("type", "Native")) { | 
| @@ -2392,9 +2387,9 @@ static bool GetIsolateMetricList(Isolate* isolate, JSONStream* js) { | 
| return true; | 
| } | 
| if (native_metrics) { | 
| -    return HandleNativeMetricsList(isolate, js); | 
| +    return HandleNativeMetricsList(thread, js); | 
| } | 
| -  return HandleDartMetricsList(isolate, js); | 
| +  return HandleDartMetricsList(thread, js); | 
| } | 
|  | 
|  | 
| @@ -2404,7 +2399,7 @@ static const MethodParameter* get_isolate_metric_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetIsolateMetric(Isolate* isolate, JSONStream* js) { | 
| +static bool GetIsolateMetric(Thread* thread, JSONStream* js) { | 
| const char* metric_id = js->LookupParam("metricId"); | 
| if (metric_id == NULL) { | 
| PrintMissingParamError(js, "metricId"); | 
| @@ -2424,10 +2419,10 @@ static bool GetIsolateMetric(Isolate* isolate, JSONStream* js) { | 
| strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0; | 
| if (native_metric) { | 
| const char* id = metric_id + kNativeMetricIdPrefixLen; | 
| -    return HandleNativeMetric(isolate, js, id); | 
| +    return HandleNativeMetric(thread, js, id); | 
| } | 
| const char* id = metric_id + kMetricIdPrefixLen; | 
| -  return HandleDartMetric(isolate, js, id); | 
| +  return HandleDartMetric(thread, js, id); | 
| } | 
|  | 
|  | 
| @@ -2437,7 +2432,7 @@ static const MethodParameter* get_vm_metric_list_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetVMMetricList(Isolate* isolate, JSONStream* js) { | 
| +static bool GetVMMetricList(Thread* thread, JSONStream* js) { | 
| return false; | 
| } | 
|  | 
| @@ -2448,7 +2443,7 @@ static const MethodParameter* get_vm_metric_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetVMMetric(Isolate* isolate, JSONStream* js) { | 
| +static bool GetVMMetric(Thread* thread, JSONStream* js) { | 
| const char* metric_id = js->LookupParam("metricId"); | 
| if (metric_id == NULL) { | 
| PrintMissingParamError(js, "metricId"); | 
| @@ -2463,8 +2458,9 @@ static const MethodParameter* resume_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool Resume(Isolate* isolate, JSONStream* js) { | 
| +static bool Resume(Thread* thread, JSONStream* js) { | 
| const char* step_param = js->LookupParam("step"); | 
| +  Isolate* isolate = thread->isolate(); | 
| if (isolate->message_handler()->paused_on_start()) { | 
| // If the user is issuing a 'Over' or an 'Out' step, that is the | 
| // same as a regular resume request. | 
| @@ -2515,11 +2511,12 @@ static const MethodParameter* pause_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool Pause(Isolate* isolate, JSONStream* js) { | 
| +static bool Pause(Thread* thread, JSONStream* js) { | 
| // TODO(turnidge): This interrupt message could have been sent from | 
| // the service isolate directly, but would require some special case | 
| // code.  That would prevent this isolate getting double-interrupted | 
| // with OOB messages. | 
| +  Isolate* isolate = thread->isolate(); | 
| isolate->SendInternalLibMessage(Isolate::kInterruptMsg, | 
| isolate->pause_capability()); | 
| PrintSuccess(js); | 
| @@ -2533,10 +2530,10 @@ static const MethodParameter* get_tag_profile_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetTagProfile(Isolate* isolate, JSONStream* js) { | 
| +static bool GetTagProfile(Thread* thread, JSONStream* js) { | 
| JSONObject miniProfile(js); | 
| miniProfile.AddProperty("type", "TagProfile"); | 
| -  isolate->vm_tag_counters()->PrintToJSONObject(&miniProfile); | 
| +  thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile); | 
| return true; | 
| } | 
|  | 
| @@ -2570,7 +2567,7 @@ static const MethodParameter* get_cpu_profile_params[] = { | 
|  | 
|  | 
| // TODO(johnmccutchan): Rename this to GetCpuSamples. | 
| -static bool GetCpuProfile(Isolate* isolate, JSONStream* js) { | 
| +static bool GetCpuProfile(Thread* thread, JSONStream* js) { | 
| Profile::TagOrder tag_order = | 
| EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 
| intptr_t extra_tags = 0; | 
| @@ -2590,12 +2587,13 @@ static const MethodParameter* get_allocation_samples_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetAllocationSamples(Isolate* isolate, JSONStream* js) { | 
| +static bool GetAllocationSamples(Thread* thread, JSONStream* js) { | 
| Profile::TagOrder tag_order = | 
| EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); | 
| const char* class_id = js->LookupParam("classId"); | 
| intptr_t cid = -1; | 
| GetPrefixedIntegerId(class_id, "classes/", &cid); | 
| +  Isolate* isolate = thread->isolate(); | 
| if (IsValidClassId(isolate, cid)) { | 
| const Class& cls = Class::Handle(GetClassForId(isolate, cid)); | 
| ProfilerService::PrintAllocationJSON(js, tag_order, cls); | 
| @@ -2612,7 +2610,7 @@ static const MethodParameter* clear_cpu_profile_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool ClearCpuProfile(Isolate* isolate, JSONStream* js) { | 
| +static bool ClearCpuProfile(Thread* thread, JSONStream* js) { | 
| ProfilerService::ClearSamples(); | 
| PrintSuccess(js); | 
| return true; | 
| @@ -2625,7 +2623,7 @@ static const MethodParameter* get_allocation_profile_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetAllocationProfile(Isolate* isolate, JSONStream* js) { | 
| +static bool GetAllocationProfile(Thread* thread, JSONStream* js) { | 
| bool should_reset_accumulator = false; | 
| bool should_collect = false; | 
| if (js->HasParam("reset")) { | 
| @@ -2644,6 +2642,7 @@ static bool GetAllocationProfile(Isolate* isolate, JSONStream* js) { | 
| return true; | 
| } | 
| } | 
| +  Isolate* isolate = thread->isolate(); | 
| if (should_reset_accumulator) { | 
| isolate->UpdateLastAllocationProfileAccumulatorResetTimestamp(); | 
| isolate->class_table()->ResetAllocationAccumulators(); | 
| @@ -2663,7 +2662,8 @@ static const MethodParameter* get_heap_map_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetHeapMap(Isolate* isolate, JSONStream* js) { | 
| +static bool GetHeapMap(Thread* thread, JSONStream* js) { | 
| +  Isolate* isolate = thread->isolate(); | 
| isolate->heap()->PrintHeapMapToJSONStream(isolate, js); | 
| return true; | 
| } | 
| @@ -2675,9 +2675,9 @@ static const MethodParameter* request_heap_snapshot_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool RequestHeapSnapshot(Isolate* isolate, JSONStream* js) { | 
| +static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) { | 
| if (Service::graph_stream.enabled()) { | 
| -    Service::SendGraphEvent(isolate); | 
| +    Service::SendGraphEvent(thread); | 
| } | 
| // TODO(koda): Provide some id that ties this request to async response(s). | 
| JSONObject jsobj(js); | 
| @@ -2686,10 +2686,10 @@ static bool RequestHeapSnapshot(Isolate* isolate, JSONStream* js) { | 
| } | 
|  | 
|  | 
| -void Service::SendGraphEvent(Isolate* isolate) { | 
| +void Service::SendGraphEvent(Thread* thread) { | 
| uint8_t* buffer = NULL; | 
| WriteStream stream(&buffer, &allocator, 1 * MB); | 
| -  ObjectGraph graph(Thread::Current()); | 
| +  ObjectGraph graph(thread); | 
| intptr_t node_count = graph.Serialize(&stream); | 
|  | 
| // Chrome crashes receiving a single tens-of-megabytes blob, so send the | 
| @@ -2710,7 +2710,7 @@ void Service::SendGraphEvent(Isolate* isolate) { | 
| JSONObject event(¶ms, "event"); | 
| event.AddProperty("type", "Event"); | 
| event.AddProperty("kind", "_Graph"); | 
| -          event.AddProperty("isolate", isolate); | 
| +          event.AddProperty("isolate", thread->isolate()); | 
| event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); | 
|  | 
| event.AddProperty("chunkIndex", i); | 
| @@ -2811,11 +2811,12 @@ static const MethodParameter* get_object_by_address_params[] = { | 
| }; | 
|  | 
|  | 
| -static RawObject* GetObjectHelper(Isolate* isolate, uword addr) { | 
| -  Object& object = Object::Handle(isolate->current_zone()); | 
| +static RawObject* GetObjectHelper(Thread* thread, uword addr) { | 
| +  Object& object = Object::Handle(thread->zone()); | 
|  | 
| { | 
| NoSafepointScope no_safepoint; | 
| +    Isolate* isolate = thread->isolate(); | 
| ContainsAddressVisitor visitor(isolate, addr); | 
| object = isolate->heap()->FindObject(&visitor); | 
| } | 
| @@ -2834,7 +2835,7 @@ static RawObject* GetObjectHelper(Isolate* isolate, uword addr) { | 
| } | 
|  | 
|  | 
| -static bool GetObjectByAddress(Isolate* isolate, JSONStream* js) { | 
| +static bool GetObjectByAddress(Thread* thread, JSONStream* js) { | 
| const char* addr_str = js->LookupParam("address"); | 
| if (addr_str == NULL) { | 
| PrintMissingParamError(js, "address"); | 
| @@ -2848,8 +2849,8 @@ static bool GetObjectByAddress(Isolate* isolate, JSONStream* js) { | 
| return true; | 
| } | 
| bool ref = js->HasParam("ref") && js->ParamIs("ref", "true"); | 
| -  const Object& obj = Object::Handle(isolate->current_zone(), | 
| -      GetObjectHelper(isolate, addr)); | 
| +  const Object& obj = Object::Handle(thread->zone(), | 
| +      GetObjectHelper(thread, addr)); | 
| if (obj.IsNull()) { | 
| PrintSentinel(js, kFreeSentinel); | 
| } else { | 
| @@ -2865,15 +2866,14 @@ static const MethodParameter* get_ports_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetPorts(Isolate* isolate, JSONStream* js) { | 
| -  MessageHandler* message_handler = isolate->message_handler(); | 
| +static bool GetPorts(Thread* thread, JSONStream* js) { | 
| +  MessageHandler* message_handler = thread->isolate()->message_handler(); | 
| PortMap::PrintPortsForMessageHandler(message_handler, js); | 
| return true; | 
| } | 
|  | 
|  | 
| -static bool RespondWithMalformedJson(Isolate* isolate, | 
| -                                      JSONStream* js) { | 
| +static bool RespondWithMalformedJson(Thread* thread, JSONStream* js) { | 
| JSONObject jsobj(js); | 
| jsobj.AddProperty("a", "a"); | 
| JSONObject jsobj1(js); | 
| @@ -2886,8 +2886,7 @@ static bool RespondWithMalformedJson(Isolate* isolate, | 
| } | 
|  | 
|  | 
| -static bool RespondWithMalformedObject(Isolate* isolate, | 
| -                                        JSONStream* js) { | 
| +static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) { | 
| JSONObject jsobj(js); | 
| jsobj.AddProperty("bart", "simpson"); | 
| return true; | 
| @@ -2902,7 +2901,7 @@ static const MethodParameter* get_object_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetObject(Isolate* isolate, JSONStream* js) { | 
| +static bool GetObject(Thread* thread, JSONStream* js) { | 
| const char* id = js->LookupParam("objectId"); | 
| if (id == NULL) { | 
| PrintMissingParamError(js, "objectId"); | 
| @@ -2928,7 +2927,7 @@ static bool GetObject(Isolate* isolate, JSONStream* js) { | 
| // Handle heap objects. | 
| ObjectIdRing::LookupResult lookup_result; | 
| const Object& obj = | 
| -      Object::Handle(LookupHeapObject(isolate, id, &lookup_result)); | 
| +      Object::Handle(LookupHeapObject(thread, id, &lookup_result)); | 
| if (obj.raw() != Object::sentinel().raw()) { | 
| // We found a heap object for this id.  Return it. | 
| obj.PrintJSON(js, false); | 
| @@ -2942,7 +2941,7 @@ static bool GetObject(Isolate* isolate, JSONStream* js) { | 
| } | 
|  | 
| // Handle non-heap objects. | 
| -  Breakpoint* bpt = LookupBreakpoint(isolate, id, &lookup_result); | 
| +  Breakpoint* bpt = LookupBreakpoint(thread->isolate(), id, &lookup_result); | 
| if (bpt != NULL) { | 
| bpt->PrintJSON(js); | 
| return true; | 
| @@ -2962,8 +2961,8 @@ static const MethodParameter* get_class_list_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetClassList(Isolate* isolate, JSONStream* js) { | 
| -  ClassTable* table = isolate->class_table(); | 
| +static bool GetClassList(Thread* thread, JSONStream* js) { | 
| +  ClassTable* table = thread->isolate()->class_table(); | 
| JSONObject jsobj(js); | 
| table->PrintToJSONObject(&jsobj); | 
| return true; | 
| @@ -2976,12 +2975,12 @@ static const MethodParameter* get_type_arguments_list_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetTypeArgumentsList(Isolate* isolate, JSONStream* js) { | 
| +static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) { | 
| bool only_with_instantiations = false; | 
| if (js->ParamIs("onlyWithInstantiations", "true")) { | 
| only_with_instantiations = true; | 
| } | 
| -  ObjectStore* object_store = isolate->object_store(); | 
| +  ObjectStore* object_store = thread->isolate()->object_store(); | 
| const Array& table = Array::Handle(object_store->canonical_type_arguments()); | 
| ASSERT(table.Length() > 0); | 
| TypeArguments& type_args = TypeArguments::Handle(); | 
| @@ -3010,7 +3009,7 @@ static const MethodParameter* get_version_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetVersion(Isolate* isolate, JSONStream* js) { | 
| +static bool GetVersion(Thread* thread, JSONStream* js) { | 
| JSONObject jsobj(js); | 
| jsobj.AddProperty("type", "Version"); | 
| jsobj.AddProperty("major", static_cast<intptr_t>(3)); | 
| @@ -3072,7 +3071,7 @@ void Service::PrintJSONForVM(JSONStream* js, bool ref) { | 
| } | 
|  | 
|  | 
| -static bool GetVM(Isolate* isolate, JSONStream* js) { | 
| +static bool GetVM(Thread* thread, JSONStream* js) { | 
| Service::PrintJSONForVM(js, false); | 
| return true; | 
| } | 
| @@ -3084,7 +3083,7 @@ static const MethodParameter* restart_vm_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool RestartVM(Isolate* isolate, JSONStream* js) { | 
| +static bool RestartVM(Thread* thread, JSONStream* js) { | 
| Isolate::KillAllIsolates(Isolate::kVMRestartMsg); | 
| PrintSuccess(js); | 
| return true; | 
| @@ -3114,7 +3113,7 @@ static const MethodParameter* set_exception_pause_mode_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool SetExceptionPauseMode(Isolate* isolate, JSONStream* js) { | 
| +static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) { | 
| const char* mode = js->LookupParam("mode"); | 
| if (mode == NULL) { | 
| PrintMissingParamError(js, "mode"); | 
| @@ -3126,6 +3125,7 @@ static bool SetExceptionPauseMode(Isolate* isolate, JSONStream* js) { | 
| PrintInvalidParamError(js, "mode"); | 
| return true; | 
| } | 
| +  Isolate* isolate = thread->isolate(); | 
| isolate->debugger()->SetExceptionPauseInfo(info); | 
| if (Service::debug_stream.enabled()) { | 
| ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate); | 
| @@ -3142,7 +3142,7 @@ static const MethodParameter* get_flag_list_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool GetFlagList(Isolate* isolate, JSONStream* js) { | 
| +static bool GetFlagList(Thread* thread, JSONStream* js) { | 
| Flags::PrintJSON(js); | 
| return true; | 
| } | 
| @@ -3154,7 +3154,7 @@ static const MethodParameter* set_flags_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool SetFlag(Isolate* isolate, JSONStream* js) { | 
| +static bool SetFlag(Thread* thread, JSONStream* js) { | 
| const char* flag_name = js->LookupParam("name"); | 
| if (flag_name == NULL) { | 
| PrintMissingParamError(js, "name"); | 
| @@ -3186,10 +3186,10 @@ static const MethodParameter* set_library_debuggable_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool SetLibraryDebuggable(Isolate* isolate, JSONStream* js) { | 
| +static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) { | 
| const char* lib_id = js->LookupParam("libraryId"); | 
| ObjectIdRing::LookupResult lookup_result; | 
| -  Object& obj = Object::Handle(LookupHeapObject(isolate, lib_id, | 
| +  Object& obj = Object::Handle(LookupHeapObject(thread, lib_id, | 
| &lookup_result)); | 
| const bool is_debuggable = | 
| BoolParameter::Parse(js->LookupParam("isDebuggable"), false); | 
| @@ -3211,7 +3211,8 @@ static const MethodParameter* set_name_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool SetName(Isolate* isolate, JSONStream* js) { | 
| +static bool SetName(Thread* thread, JSONStream* js) { | 
| +  Isolate* isolate = thread->isolate(); | 
| isolate->set_debugger_name(js->LookupParam("name")); | 
| if (Service::isolate_stream.enabled()) { | 
| ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); | 
| @@ -3228,7 +3229,7 @@ static const MethodParameter* set_vm_name_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool SetVMName(Isolate* isolate, JSONStream* js) { | 
| +static bool SetVMName(Thread* thread, JSONStream* js) { | 
| const char* name_param = js->LookupParam("name"); | 
| free(vm_name); | 
| vm_name = strdup(name_param); | 
| @@ -3249,11 +3250,12 @@ static const MethodParameter* set_trace_class_allocation_params[] = { | 
| }; | 
|  | 
|  | 
| -static bool SetTraceClassAllocation(Isolate* isolate, JSONStream* js) { | 
| +static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) { | 
| const char* class_id = js->LookupParam("classId"); | 
| const bool enable = BoolParameter::Parse(js->LookupParam("enable")); | 
| intptr_t cid = -1; | 
| GetPrefixedIntegerId(class_id, "classes/", &cid); | 
| +  Isolate* isolate = thread->isolate(); | 
| if (!IsValidClassId(isolate, cid)) { | 
| PrintInvalidParamError(js, "classId"); | 
| return true; | 
|  |