OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/isolate_reload.h" | 5 #include "vm/isolate_reload.h" |
6 | 6 |
7 #include "vm/become.h" | 7 #include "vm/become.h" |
8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
12 #include "vm/hash_table.h" | 12 #include "vm/hash_table.h" |
13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
14 #include "vm/log.h" | 14 #include "vm/log.h" |
15 #include "vm/object.h" | 15 #include "vm/object.h" |
16 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
17 #include "vm/parser.h" | 17 #include "vm/parser.h" |
18 #include "vm/safepoint.h" | 18 #include "vm/safepoint.h" |
19 #include "vm/service_event.h" | 19 #include "vm/service_event.h" |
20 #include "vm/stack_frame.h" | 20 #include "vm/stack_frame.h" |
21 #include "vm/thread.h" | 21 #include "vm/thread.h" |
22 #include "vm/timeline.h" | 22 #include "vm/timeline.h" |
23 #include "vm/visitor.h" | 23 #include "vm/visitor.h" |
24 | 24 |
25 namespace dart { | 25 namespace dart { |
26 | 26 |
27 DEFINE_FLAG(bool, trace_reload, false, "Trace isolate reloading"); | 27 DEFINE_FLAG(bool, trace_reload, false, "Trace isolate reloading"); |
28 DEFINE_FLAG(bool, trace_reload_verbose, false, | 28 DEFINE_FLAG(bool, |
| 29 trace_reload_verbose, |
| 30 false, |
29 "trace isolate reloading verbose"); | 31 "trace isolate reloading verbose"); |
30 DEFINE_FLAG(bool, identity_reload, false, "Enable checks for identity reload."); | 32 DEFINE_FLAG(bool, identity_reload, false, "Enable checks for identity reload."); |
31 DEFINE_FLAG(int, reload_every, 0, "Reload every N stack overflow checks."); | 33 DEFINE_FLAG(int, reload_every, 0, "Reload every N stack overflow checks."); |
32 DEFINE_FLAG(bool, reload_every_optimized, true, "Only from optimized code."); | 34 DEFINE_FLAG(bool, reload_every_optimized, true, "Only from optimized code."); |
33 DEFINE_FLAG(bool, reload_every_back_off, false, | 35 DEFINE_FLAG(bool, |
| 36 reload_every_back_off, |
| 37 false, |
34 "Double the --reload-every value after each reload."); | 38 "Double the --reload-every value after each reload."); |
35 DEFINE_FLAG(bool, reload_force_rollback, false, | 39 DEFINE_FLAG(bool, |
| 40 reload_force_rollback, |
| 41 false, |
36 "Force all reloads to fail and rollback."); | 42 "Force all reloads to fail and rollback."); |
37 DEFINE_FLAG(bool, check_reloaded, false, | 43 DEFINE_FLAG(bool, |
| 44 check_reloaded, |
| 45 false, |
38 "Assert that an isolate has reloaded at least once.") | 46 "Assert that an isolate has reloaded at least once.") |
39 #ifndef PRODUCT | 47 #ifndef PRODUCT |
40 | 48 |
41 #define I (isolate()) | 49 #define I (isolate()) |
42 #define Z (thread->zone()) | 50 #define Z (thread->zone()) |
43 | 51 |
44 #define TIMELINE_SCOPE(name) \ | 52 #define TIMELINE_SCOPE(name) \ |
45 TimelineDurationScope tds##name(Thread::Current(), \ | 53 TimelineDurationScope tds##name(Thread::Current(), \ |
46 Timeline::GetIsolateStream(), \ | 54 Timeline::GetIsolateStream(), #name) |
47 #name) | |
48 | 55 |
49 | 56 |
50 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to) | 57 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to) |
51 : from_(Class::Handle(zone, from.raw())), | 58 : from_(Class::Handle(zone, from.raw())), |
52 to_(Class::Handle(zone, to.raw())), | 59 to_(Class::Handle(zone, to.raw())), |
53 mapping_(zone, 0) { | 60 mapping_(zone, 0) { |
54 ComputeMapping(); | 61 ComputeMapping(); |
55 before_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0); | 62 before_ = new (zone) ZoneGrowableArray<const Instance*>(zone, 0); |
56 after_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0); | 63 after_ = new (zone) ZoneGrowableArray<const Instance*>(zone, 0); |
57 ASSERT(from_.id() == to_.id()); | 64 ASSERT(from_.id() == to_.id()); |
58 cid_ = from_.id(); | 65 cid_ = from_.id(); |
59 } | 66 } |
60 | 67 |
61 | 68 |
62 void InstanceMorpher::AddObject(RawObject* object) const { | 69 void InstanceMorpher::AddObject(RawObject* object) const { |
63 ASSERT(object->GetClassId() == cid()); | 70 ASSERT(object->GetClassId() == cid()); |
64 const Instance& instance = Instance::Cast(Object::Handle(object)); | 71 const Instance& instance = Instance::Cast(Object::Handle(object)); |
65 before_->Add(&instance); | 72 before_->Add(&instance); |
66 } | 73 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 mapping_.Add(to_field.Offset()); | 109 mapping_.Add(to_field.Offset()); |
103 } | 110 } |
104 } | 111 } |
105 } | 112 } |
106 } | 113 } |
107 | 114 |
108 | 115 |
109 RawInstance* InstanceMorpher::Morph(const Instance& instance) const { | 116 RawInstance* InstanceMorpher::Morph(const Instance& instance) const { |
110 const Instance& result = Instance::Handle(Instance::New(to_)); | 117 const Instance& result = Instance::Handle(Instance::New(to_)); |
111 // Morph the context from instance to result using mapping_. | 118 // Morph the context from instance to result using mapping_. |
112 for (intptr_t i = 0; i < mapping_.length(); i +=2) { | 119 for (intptr_t i = 0; i < mapping_.length(); i += 2) { |
113 intptr_t from_offset = mapping_.At(i); | 120 intptr_t from_offset = mapping_.At(i); |
114 intptr_t to_offset = mapping_.At(i+1); | 121 intptr_t to_offset = mapping_.At(i + 1); |
115 const Object& value = | 122 const Object& value = |
116 Object::Handle(instance.RawGetFieldAtOffset(from_offset)); | 123 Object::Handle(instance.RawGetFieldAtOffset(from_offset)); |
117 result.RawSetFieldAtOffset(to_offset, value); | 124 result.RawSetFieldAtOffset(to_offset, value); |
118 } | 125 } |
119 // Convert the instance into a filler object. | 126 // Convert the instance into a filler object. |
120 Become::MakeDummyObject(instance); | 127 Become::MakeDummyObject(instance); |
121 return result.raw(); | 128 return result.raw(); |
122 } | 129 } |
123 | 130 |
124 | 131 |
(...skipping 18 matching lines...) Expand all Loading... |
143 for (intptr_t i = 0; i < fields.Length(); i++) { | 150 for (intptr_t i = 0; i < fields.Length(); i++) { |
144 if (fields.At(i) != Field::null()) { | 151 if (fields.At(i) != Field::null()) { |
145 field = Field::RawCast(fields.At(i)); | 152 field = Field::RawCast(fields.At(i)); |
146 ASSERT(field.is_instance()); | 153 ASSERT(field.is_instance()); |
147 name = field.name(); | 154 name = field.name(); |
148 THR_Print(" - @%" Pd " %s\n", field.Offset(), name.ToCString()); | 155 THR_Print(" - @%" Pd " %s\n", field.Offset(), name.ToCString()); |
149 } | 156 } |
150 } | 157 } |
151 | 158 |
152 THR_Print("Mapping: "); | 159 THR_Print("Mapping: "); |
153 for (int i = 0; i < mapping_.length(); i +=2) { | 160 for (int i = 0; i < mapping_.length(); i += 2) { |
154 THR_Print(" %" Pd "->%" Pd, mapping_.At(i), mapping_.At(i+1)); | 161 THR_Print(" %" Pd "->%" Pd, mapping_.At(i), mapping_.At(i + 1)); |
155 } | 162 } |
156 THR_Print("\n"); | 163 THR_Print("\n"); |
157 } | 164 } |
158 | 165 |
159 | 166 |
160 void InstanceMorpher::Dump() const { | 167 void InstanceMorpher::Dump() const { |
161 LogBlock blocker; | 168 LogBlock blocker; |
162 THR_Print("Morphing from "); | 169 THR_Print("Morphing from "); |
163 DumpFormatFor(from_); | 170 DumpFormatFor(from_); |
164 THR_Print("To "); | 171 THR_Print("To "); |
165 DumpFormatFor(to_); | 172 DumpFormatFor(to_); |
166 THR_Print("\n"); | 173 THR_Print("\n"); |
167 } | 174 } |
168 | 175 |
169 | 176 |
170 void InstanceMorpher::AppendTo(JSONArray* array) { | 177 void InstanceMorpher::AppendTo(JSONArray* array) { |
171 JSONObject jsobj(array); | 178 JSONObject jsobj(array); |
172 jsobj.AddProperty("type", "ShapeChangeMapping"); | 179 jsobj.AddProperty("type", "ShapeChangeMapping"); |
173 jsobj.AddProperty("class", to_); | 180 jsobj.AddProperty("class", to_); |
174 jsobj.AddProperty("instanceCount", before()->length()); | 181 jsobj.AddProperty("instanceCount", before()->length()); |
175 JSONArray map(&jsobj, "fieldOffsetMappings"); | 182 JSONArray map(&jsobj, "fieldOffsetMappings"); |
176 for (int i = 0; i < mapping_.length(); i += 2) { | 183 for (int i = 0; i < mapping_.length(); i += 2) { |
177 JSONArray pair(&map); | 184 JSONArray pair(&map); |
178 pair.AddValue(mapping_.At(i)); | 185 pair.AddValue(mapping_.At(i)); |
179 pair.AddValue(mapping_.At(i+1)); | 186 pair.AddValue(mapping_.At(i + 1)); |
180 } | 187 } |
181 } | 188 } |
182 | 189 |
183 | 190 |
184 void ReasonForCancelling::Report(IsolateReloadContext* context) { | 191 void ReasonForCancelling::Report(IsolateReloadContext* context) { |
185 const Error& error = Error::Handle(ToError()); | 192 const Error& error = Error::Handle(ToError()); |
186 context->ReportError(error); | 193 context->ReportError(error); |
187 } | 194 } |
188 | 195 |
189 | 196 |
(...skipping 16 matching lines...) Expand all Loading... |
206 const String& message = String::Handle(ToString()); | 213 const String& message = String::Handle(ToString()); |
207 jsobj.AddProperty("message", message.ToCString()); | 214 jsobj.AddProperty("message", message.ToCString()); |
208 } | 215 } |
209 | 216 |
210 | 217 |
211 ClassReasonForCancelling::ClassReasonForCancelling(Zone* zone, | 218 ClassReasonForCancelling::ClassReasonForCancelling(Zone* zone, |
212 const Class& from, | 219 const Class& from, |
213 const Class& to) | 220 const Class& to) |
214 : ReasonForCancelling(zone), | 221 : ReasonForCancelling(zone), |
215 from_(Class::ZoneHandle(zone, from.raw())), | 222 from_(Class::ZoneHandle(zone, from.raw())), |
216 to_(Class::ZoneHandle(zone, to.raw())) { | 223 to_(Class::ZoneHandle(zone, to.raw())) {} |
217 } | |
218 | 224 |
219 | 225 |
220 void ClassReasonForCancelling::AppendTo(JSONArray* array) { | 226 void ClassReasonForCancelling::AppendTo(JSONArray* array) { |
221 JSONObject jsobj(array); | 227 JSONObject jsobj(array); |
222 jsobj.AddProperty("type", "ReasonForCancelling"); | 228 jsobj.AddProperty("type", "ReasonForCancelling"); |
223 jsobj.AddProperty("class", from_); | 229 jsobj.AddProperty("class", from_); |
224 const String& message = String::Handle(ToString()); | 230 const String& message = String::Handle(ToString()); |
225 jsobj.AddProperty("message", message.ToCString()); | 231 jsobj.AddProperty("message", message.ToCString()); |
226 } | 232 } |
227 | 233 |
(...skipping 11 matching lines...) Expand all Loading... |
239 static const char* Name() { return "ScriptUrlSetTraits"; } | 245 static const char* Name() { return "ScriptUrlSetTraits"; } |
240 | 246 |
241 static bool IsMatch(const Object& a, const Object& b) { | 247 static bool IsMatch(const Object& a, const Object& b) { |
242 if (!a.IsString() || !b.IsString()) { | 248 if (!a.IsString() || !b.IsString()) { |
243 return false; | 249 return false; |
244 } | 250 } |
245 | 251 |
246 return String::Cast(a).Equals(String::Cast(b)); | 252 return String::Cast(a).Equals(String::Cast(b)); |
247 } | 253 } |
248 | 254 |
249 static uword Hash(const Object& obj) { | 255 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } |
250 return String::Cast(obj).Hash(); | |
251 } | |
252 }; | 256 }; |
253 | 257 |
254 | 258 |
255 class ClassMapTraits { | 259 class ClassMapTraits { |
256 public: | 260 public: |
257 static bool ReportStats() { return false; } | 261 static bool ReportStats() { return false; } |
258 static const char* Name() { return "ClassMapTraits"; } | 262 static const char* Name() { return "ClassMapTraits"; } |
259 | 263 |
260 static bool IsMatch(const Object& a, const Object& b) { | 264 static bool IsMatch(const Object& a, const Object& b) { |
261 if (!a.IsClass() || !b.IsClass()) { | 265 if (!a.IsClass() || !b.IsClass()) { |
(...skipping 10 matching lines...) Expand all Loading... |
272 | 276 |
273 class LibraryMapTraits { | 277 class LibraryMapTraits { |
274 public: | 278 public: |
275 static bool ReportStats() { return false; } | 279 static bool ReportStats() { return false; } |
276 static const char* Name() { return "LibraryMapTraits"; } | 280 static const char* Name() { return "LibraryMapTraits"; } |
277 | 281 |
278 static bool IsMatch(const Object& a, const Object& b) { | 282 static bool IsMatch(const Object& a, const Object& b) { |
279 if (!a.IsLibrary() || !b.IsLibrary()) { | 283 if (!a.IsLibrary() || !b.IsLibrary()) { |
280 return false; | 284 return false; |
281 } | 285 } |
282 return IsolateReloadContext::IsSameLibrary( | 286 return IsolateReloadContext::IsSameLibrary(Library::Cast(a), |
283 Library::Cast(a), Library::Cast(b)); | 287 Library::Cast(b)); |
284 } | 288 } |
285 | 289 |
286 static uword Hash(const Object& obj) { | 290 static uword Hash(const Object& obj) { return Library::Cast(obj).UrlHash(); } |
287 return Library::Cast(obj).UrlHash(); | |
288 } | |
289 }; | 291 }; |
290 | 292 |
291 | 293 |
292 class BecomeMapTraits { | 294 class BecomeMapTraits { |
293 public: | 295 public: |
294 static bool ReportStats() { return false; } | 296 static bool ReportStats() { return false; } |
295 static const char* Name() { return "BecomeMapTraits"; } | 297 static const char* Name() { return "BecomeMapTraits"; } |
296 | 298 |
297 static bool IsMatch(const Object& a, const Object& b) { | 299 static bool IsMatch(const Object& a, const Object& b) { |
298 return a.raw() == b.raw(); | 300 return a.raw() == b.raw(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 if (!a_name.Equals(b_name)) { | 351 if (!a_name.Equals(b_name)) { |
350 return false; | 352 return false; |
351 } | 353 } |
352 | 354 |
353 const Library& a_lib = Library::Handle(a.library()); | 355 const Library& a_lib = Library::Handle(a.library()); |
354 const Library& b_lib = Library::Handle(b.library()); | 356 const Library& b_lib = Library::Handle(b.library()); |
355 return IsSameLibrary(a_lib, b_lib); | 357 return IsSameLibrary(a_lib, b_lib); |
356 } | 358 } |
357 | 359 |
358 | 360 |
359 bool IsolateReloadContext::IsSameLibrary( | 361 bool IsolateReloadContext::IsSameLibrary(const Library& a_lib, |
360 const Library& a_lib, const Library& b_lib) { | 362 const Library& b_lib) { |
361 const String& a_lib_url = | 363 const String& a_lib_url = |
362 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); | 364 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); |
363 const String& b_lib_url = | 365 const String& b_lib_url = |
364 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); | 366 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); |
365 return a_lib_url.Equals(b_lib_url); | 367 return a_lib_url.Equals(b_lib_url); |
366 } | 368 } |
367 | 369 |
368 | 370 |
369 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, | 371 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, JSONStream* js) |
370 JSONStream* js) | |
371 : zone_(Thread::Current()->zone()), | 372 : zone_(Thread::Current()->zone()), |
372 start_time_micros_(OS::GetCurrentMonotonicMicros()), | 373 start_time_micros_(OS::GetCurrentMonotonicMicros()), |
373 reload_timestamp_(OS::GetCurrentTimeMillis()), | 374 reload_timestamp_(OS::GetCurrentTimeMillis()), |
374 isolate_(isolate), | 375 isolate_(isolate), |
375 reload_skipped_(false), | 376 reload_skipped_(false), |
376 reload_aborted_(false), | 377 reload_aborted_(false), |
377 reload_finalized_(false), | 378 reload_finalized_(false), |
378 js_(js), | 379 js_(js), |
379 saved_num_cids_(-1), | 380 saved_num_cids_(-1), |
380 saved_class_table_(NULL), | 381 saved_class_table_(NULL), |
(...skipping 12 matching lines...) Expand all Loading... |
393 become_enum_mappings_(GrowableObjectArray::null()), | 394 become_enum_mappings_(GrowableObjectArray::null()), |
394 saved_root_library_(Library::null()), | 395 saved_root_library_(Library::null()), |
395 saved_libraries_(GrowableObjectArray::null()) { | 396 saved_libraries_(GrowableObjectArray::null()) { |
396 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not | 397 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not |
397 // associated with the isolate yet and if a GC is triggered here the raw | 398 // associated with the isolate yet and if a GC is triggered here the raw |
398 // objects will not be properly accounted for. | 399 // objects will not be properly accounted for. |
399 ASSERT(zone_ != NULL); | 400 ASSERT(zone_ != NULL); |
400 } | 401 } |
401 | 402 |
402 | 403 |
403 IsolateReloadContext::~IsolateReloadContext() { | 404 IsolateReloadContext::~IsolateReloadContext() {} |
404 } | |
405 | 405 |
406 | 406 |
407 void IsolateReloadContext::ReportError(const Error& error) { | 407 void IsolateReloadContext::ReportError(const Error& error) { |
408 if (FLAG_trace_reload) { | 408 if (FLAG_trace_reload) { |
409 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); | 409 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); |
410 } | 410 } |
411 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); | 411 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); |
412 service_event.set_reload_error(&error); | 412 service_event.set_reload_error(&error); |
413 Service::HandleEvent(&service_event); | 413 Service::HandleEvent(&service_event); |
414 } | 414 } |
415 | 415 |
416 | 416 |
417 void IsolateReloadContext::ReportSuccess() { | 417 void IsolateReloadContext::ReportSuccess() { |
418 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); | 418 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); |
419 Service::HandleEvent(&service_event); | 419 Service::HandleEvent(&service_event); |
420 } | 420 } |
421 | 421 |
422 | 422 |
423 class Aborted : public ReasonForCancelling { | 423 class Aborted : public ReasonForCancelling { |
424 public: | 424 public: |
425 Aborted(Zone* zone, const Error& error) | 425 Aborted(Zone* zone, const Error& error) |
426 : ReasonForCancelling(zone), | 426 : ReasonForCancelling(zone), |
427 error_(Error::ZoneHandle(zone, error.raw())) { | 427 error_(Error::ZoneHandle(zone, error.raw())) {} |
428 } | |
429 | 428 |
430 private: | 429 private: |
431 const Error& error_; | 430 const Error& error_; |
432 | 431 |
433 RawError* ToError() { return error_.raw(); } | 432 RawError* ToError() { return error_.raw(); } |
434 RawString* ToString() { | 433 RawString* ToString() { |
435 return String::NewFormatted("%s", error_.ToErrorCString()); | 434 return String::NewFormatted("%s", error_.ToErrorCString()); |
436 } | 435 } |
437 }; | 436 }; |
438 | 437 |
(...skipping 17 matching lines...) Expand all Loading... |
456 ReportOnJSON(js_); | 455 ReportOnJSON(js_); |
457 TIR_Print("---- SKIPPING RELOAD (No libraries were modified)\n"); | 456 TIR_Print("---- SKIPPING RELOAD (No libraries were modified)\n"); |
458 return; | 457 return; |
459 } | 458 } |
460 | 459 |
461 TIR_Print("---- STARTING RELOAD\n"); | 460 TIR_Print("---- STARTING RELOAD\n"); |
462 | 461 |
463 // Preallocate storage for maps. | 462 // Preallocate storage for maps. |
464 old_classes_set_storage_ = | 463 old_classes_set_storage_ = |
465 HashTables::New<UnorderedHashSet<ClassMapTraits> >(4); | 464 HashTables::New<UnorderedHashSet<ClassMapTraits> >(4); |
466 class_map_storage_ = | 465 class_map_storage_ = HashTables::New<UnorderedHashMap<ClassMapTraits> >(4); |
467 HashTables::New<UnorderedHashMap<ClassMapTraits> >(4); | |
468 old_libraries_set_storage_ = | 466 old_libraries_set_storage_ = |
469 HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4); | 467 HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4); |
470 library_map_storage_ = | 468 library_map_storage_ = |
471 HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4); | 469 HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4); |
472 become_map_storage_ = | 470 become_map_storage_ = HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4); |
473 HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4); | |
474 // Keep a separate array for enum mappings to avoid having to invoke | 471 // Keep a separate array for enum mappings to avoid having to invoke |
475 // hashCode on the instances. | 472 // hashCode on the instances. |
476 become_enum_mappings_ = GrowableObjectArray::New(Heap::kOld); | 473 become_enum_mappings_ = GrowableObjectArray::New(Heap::kOld); |
477 | 474 |
478 // Disable the background compiler while we are performing the reload. | 475 // Disable the background compiler while we are performing the reload. |
479 BackgroundCompiler::Disable(); | 476 BackgroundCompiler::Disable(); |
480 | 477 |
481 // Ensure all functions on the stack have unoptimized code. | 478 // Ensure all functions on the stack have unoptimized code. |
482 EnsuredUnoptimizedCodeForStack(); | 479 EnsuredUnoptimizedCodeForStack(); |
483 // Deoptimize all code that had optimizing decisions that are dependent on | 480 // Deoptimize all code that had optimizing decisions that are dependent on |
(...skipping 20 matching lines...) Expand all Loading... |
504 // Even after a successful reload the Dart code invoked in (5) can result | 501 // Even after a successful reload the Dart code invoked in (5) can result |
505 // in an Unwind error or an UnhandledException error. This error will be | 502 // in an Unwind error or an UnhandledException error. This error will be |
506 // returned by the tag handler. The tag handler can return other errors, | 503 // returned by the tag handler. The tag handler can return other errors, |
507 // for example, top level parse errors. We want to capture these errors while | 504 // for example, top level parse errors. We want to capture these errors while |
508 // propagating the UnwindError or an UnhandledException error. | 505 // propagating the UnwindError or an UnhandledException error. |
509 Object& result = Object::Handle(thread->zone()); | 506 Object& result = Object::Handle(thread->zone()); |
510 { | 507 { |
511 TransitionVMToNative transition(thread); | 508 TransitionVMToNative transition(thread); |
512 Api::Scope api_scope(thread); | 509 Api::Scope api_scope(thread); |
513 | 510 |
514 Dart_Handle retval = | 511 Dart_Handle retval = (I->library_tag_handler())( |
515 (I->library_tag_handler())(Dart_kScriptTag, | 512 Dart_kScriptTag, Api::NewHandle(thread, Library::null()), |
516 Api::NewHandle(thread, Library::null()), | 513 Api::NewHandle(thread, root_lib_url.raw())); |
517 Api::NewHandle(thread, root_lib_url.raw())); | |
518 result = Api::UnwrapHandle(retval); | 514 result = Api::UnwrapHandle(retval); |
519 } | 515 } |
520 // | 516 // |
521 // WEIRD CONTROL FLOW ENDS. | 517 // WEIRD CONTROL FLOW ENDS. |
522 | 518 |
523 BackgroundCompiler::Enable(); | 519 BackgroundCompiler::Enable(); |
524 | 520 |
525 if (result.IsUnwindError() || | 521 if (result.IsUnwindError() || result.IsUnhandledException()) { |
526 result.IsUnhandledException()) { | |
527 // If the tag handler returns with an UnwindError or an UnhandledException | 522 // If the tag handler returns with an UnwindError or an UnhandledException |
528 // error, propagate it and give up. | 523 // error, propagate it and give up. |
529 Exceptions::PropagateError(Error::Cast(result)); | 524 Exceptions::PropagateError(Error::Cast(result)); |
530 UNREACHABLE(); | 525 UNREACHABLE(); |
531 } | 526 } |
532 | 527 |
533 // Other errors (e.g. a parse error) are captured by the reload system. | 528 // Other errors (e.g. a parse error) are captured by the reload system. |
534 if (result.IsError()) { | 529 if (result.IsError()) { |
535 FinalizeFailedLoad(Error::Cast(result)); | 530 FinalizeFailedLoad(Error::Cast(result)); |
536 } | 531 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 // Copy the size of the class table. | 707 // Copy the size of the class table. |
713 saved_num_cids_ = I->class_table()->NumCids(); | 708 saved_num_cids_ = I->class_table()->NumCids(); |
714 | 709 |
715 // Copy of the class table. | 710 // Copy of the class table. |
716 RawClass** local_saved_class_table = | 711 RawClass** local_saved_class_table = |
717 reinterpret_cast<RawClass**>(malloc(sizeof(RawClass*) * saved_num_cids_)); | 712 reinterpret_cast<RawClass**>(malloc(sizeof(RawClass*) * saved_num_cids_)); |
718 | 713 |
719 Class& cls = Class::Handle(); | 714 Class& cls = Class::Handle(); |
720 UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_); | 715 UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_); |
721 for (intptr_t i = 0; i < saved_num_cids_; i++) { | 716 for (intptr_t i = 0; i < saved_num_cids_; i++) { |
722 if (class_table->IsValidIndex(i) && | 717 if (class_table->IsValidIndex(i) && class_table->HasValidClassAt(i)) { |
723 class_table->HasValidClassAt(i)) { | |
724 // Copy the class into the saved class table and add it to the set. | 718 // Copy the class into the saved class table and add it to the set. |
725 local_saved_class_table[i] = class_table->At(i); | 719 local_saved_class_table[i] = class_table->At(i); |
726 if (i != kFreeListElement && i != kForwardingCorpse) { | 720 if (i != kFreeListElement && i != kForwardingCorpse) { |
727 cls = class_table->At(i); | 721 cls = class_table->At(i); |
728 bool already_present = old_classes_set.Insert(cls); | 722 bool already_present = old_classes_set.Insert(cls); |
729 ASSERT(!already_present); | 723 ASSERT(!already_present); |
730 } | 724 } |
731 } else { | 725 } else { |
732 // No class at this index, mark it as NULL. | 726 // No class at this index, mark it as NULL. |
733 local_saved_class_table[i] = NULL; | 727 local_saved_class_table[i] = NULL; |
(...skipping 15 matching lines...) Expand all Loading... |
749 return true; | 743 return true; |
750 } | 744 } |
751 // We use the resolved url to determine if the script has been modified. | 745 // We use the resolved url to determine if the script has been modified. |
752 const String& url = String::Handle(script.resolved_url()); | 746 const String& url = String::Handle(script.resolved_url()); |
753 const char* url_chars = url.ToCString(); | 747 const char* url_chars = url.ToCString(); |
754 return (*file_modified_callback_)(url_chars, since); | 748 return (*file_modified_callback_)(url_chars, since); |
755 } | 749 } |
756 | 750 |
757 | 751 |
758 static void PropagateLibraryModified( | 752 static void PropagateLibraryModified( |
759 const ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >* imported_by, | 753 const ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by, |
760 intptr_t lib_index, | 754 intptr_t lib_index, |
761 BitVector* modified_libs) { | 755 BitVector* modified_libs) { |
762 ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index]; | 756 ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index]; |
763 for (intptr_t i = 0; i < dep_libs->length(); i++) { | 757 for (intptr_t i = 0; i < dep_libs->length(); i++) { |
764 intptr_t dep_lib_index = (*dep_libs)[i]; | 758 intptr_t dep_lib_index = (*dep_libs)[i]; |
765 if (!modified_libs->Contains(dep_lib_index)) { | 759 if (!modified_libs->Contains(dep_lib_index)) { |
766 modified_libs->Add(dep_lib_index); | 760 modified_libs->Add(dep_lib_index); |
767 PropagateLibraryModified(imported_by, dep_lib_index, modified_libs); | 761 PropagateLibraryModified(imported_by, dep_lib_index, modified_libs); |
768 } | 762 } |
769 } | 763 } |
770 } | 764 } |
771 | 765 |
772 | 766 |
773 BitVector* IsolateReloadContext::FindModifiedLibraries(bool force_reload) { | 767 BitVector* IsolateReloadContext::FindModifiedLibraries(bool force_reload) { |
774 Thread* thread = Thread::Current(); | 768 Thread* thread = Thread::Current(); |
775 int64_t last_reload = I->last_reload_timestamp(); | 769 int64_t last_reload = I->last_reload_timestamp(); |
776 | 770 |
777 const GrowableObjectArray& libs = | 771 const GrowableObjectArray& libs = |
778 GrowableObjectArray::Handle(object_store()->libraries()); | 772 GrowableObjectArray::Handle(object_store()->libraries()); |
779 Library& lib = Library::Handle(); | 773 Library& lib = Library::Handle(); |
780 Array& scripts = Array::Handle(); | 774 Array& scripts = Array::Handle(); |
781 Script& script = Script::Handle(); | 775 Script& script = Script::Handle(); |
782 intptr_t num_libs = libs.Length(); | 776 intptr_t num_libs = libs.Length(); |
783 | 777 |
784 // Construct the imported-by graph. | 778 // Construct the imported-by graph. |
785 ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >* imported_by = | 779 ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by = new (zone_) |
786 new(zone_) ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >( | 780 ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>(zone_, num_libs); |
787 zone_, num_libs); | |
788 imported_by->SetLength(num_libs); | 781 imported_by->SetLength(num_libs); |
789 for (intptr_t i = 0; i < num_libs; i++) { | 782 for (intptr_t i = 0; i < num_libs; i++) { |
790 (*imported_by)[i] = new(zone_) ZoneGrowableArray<intptr_t>(zone_, 0); | 783 (*imported_by)[i] = new (zone_) ZoneGrowableArray<intptr_t>(zone_, 0); |
791 } | 784 } |
792 Array& ports = Array::Handle(); | 785 Array& ports = Array::Handle(); |
793 Namespace& ns = Namespace::Handle(); | 786 Namespace& ns = Namespace::Handle(); |
794 Library& target = Library::Handle(); | 787 Library& target = Library::Handle(); |
795 | 788 |
796 for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) { | 789 for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) { |
797 lib ^= libs.At(lib_idx); | 790 lib ^= libs.At(lib_idx); |
798 ASSERT(lib_idx == lib.index()); | 791 ASSERT(lib_idx == lib.index()); |
799 if (lib.is_dart_scheme()) { | 792 if (lib.is_dart_scheme()) { |
800 // We don't care about imports among dart scheme libraries. | 793 // We don't care about imports among dart scheme libraries. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 ns ^= ports.At(import_idx); | 828 ns ^= ports.At(import_idx); |
836 if (!ns.IsNull()) { | 829 if (!ns.IsNull()) { |
837 target = ns.library(); | 830 target = ns.library(); |
838 (*imported_by)[target.index()]->Add(lib.index()); | 831 (*imported_by)[target.index()]->Add(lib.index()); |
839 } | 832 } |
840 } | 833 } |
841 } | 834 } |
842 } | 835 } |
843 } | 836 } |
844 | 837 |
845 BitVector* modified_libs = new(Z) BitVector(Z, num_libs); | 838 BitVector* modified_libs = new (Z) BitVector(Z, num_libs); |
846 | 839 |
847 for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) { | 840 for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) { |
848 lib ^= libs.At(lib_idx); | 841 lib ^= libs.At(lib_idx); |
849 if (lib.is_dart_scheme() || modified_libs->Contains(lib_idx)) { | 842 if (lib.is_dart_scheme() || modified_libs->Contains(lib_idx)) { |
850 // We don't consider dart scheme libraries during reload. If | 843 // We don't consider dart scheme libraries during reload. If |
851 // the modified libs set already contains this library, then we | 844 // the modified libs set already contains this library, then we |
852 // have already visited it. | 845 // have already visited it. |
853 continue; | 846 continue; |
854 } | 847 } |
855 scripts = lib.LoadedScripts(); | 848 scripts = lib.LoadedScripts(); |
856 for (intptr_t script_idx = 0; script_idx < scripts.Length(); script_idx++) { | 849 for (intptr_t script_idx = 0; script_idx < scripts.Length(); script_idx++) { |
857 script ^= scripts.At(script_idx); | 850 script ^= scripts.At(script_idx); |
858 if (force_reload || ScriptModifiedSince(script, last_reload)) { | 851 if (force_reload || ScriptModifiedSince(script, last_reload)) { |
859 modified_libs->Add(lib_idx); | 852 modified_libs->Add(lib_idx); |
860 PropagateLibraryModified(imported_by, lib_idx, modified_libs); | 853 PropagateLibraryModified(imported_by, lib_idx, modified_libs); |
861 break; | 854 break; |
862 } | 855 } |
863 } | 856 } |
864 } | 857 } |
865 | 858 |
866 return modified_libs; | 859 return modified_libs; |
867 } | 860 } |
868 | 861 |
869 | 862 |
870 void IsolateReloadContext::CheckpointLibraries() { | 863 void IsolateReloadContext::CheckpointLibraries() { |
871 TIMELINE_SCOPE(CheckpointLibraries); | 864 TIMELINE_SCOPE(CheckpointLibraries); |
872 TIR_Print("---- CHECKPOINTING LIBRARIES\n"); | 865 TIR_Print("---- CHECKPOINTING LIBRARIES\n"); |
873 // Save the root library in case we abort the reload. | 866 // Save the root library in case we abort the reload. |
874 const Library& root_lib = | 867 const Library& root_lib = Library::Handle(object_store()->root_library()); |
875 Library::Handle(object_store()->root_library()); | |
876 set_saved_root_library(root_lib); | 868 set_saved_root_library(root_lib); |
877 | 869 |
878 // Save the old libraries array in case we abort the reload. | 870 // Save the old libraries array in case we abort the reload. |
879 const GrowableObjectArray& libs = | 871 const GrowableObjectArray& libs = |
880 GrowableObjectArray::Handle(object_store()->libraries()); | 872 GrowableObjectArray::Handle(object_store()->libraries()); |
881 set_saved_libraries(libs); | 873 set_saved_libraries(libs); |
882 | 874 |
883 // Make a filtered copy of the old libraries array. Keep "clean" libraries | 875 // Make a filtered copy of the old libraries array. Keep "clean" libraries |
884 // that we will use instead of reloading. | 876 // that we will use instead of reloading. |
885 const GrowableObjectArray& new_libs = GrowableObjectArray::Handle( | 877 const GrowableObjectArray& new_libs = |
886 GrowableObjectArray::New(Heap::kOld)); | 878 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); |
887 Library& lib = Library::Handle(); | 879 Library& lib = Library::Handle(); |
888 UnorderedHashSet<LibraryMapTraits> | 880 UnorderedHashSet<LibraryMapTraits> old_libraries_set( |
889 old_libraries_set(old_libraries_set_storage_); | 881 old_libraries_set_storage_); |
890 num_saved_libs_ = 0; | 882 num_saved_libs_ = 0; |
891 for (intptr_t i = 0; i < libs.Length(); i++) { | 883 for (intptr_t i = 0; i < libs.Length(); i++) { |
892 lib ^= libs.At(i); | 884 lib ^= libs.At(i); |
893 if (modified_libs_->Contains(i)) { | 885 if (modified_libs_->Contains(i)) { |
894 // We are going to reload this library. Clear the index. | 886 // We are going to reload this library. Clear the index. |
895 lib.set_index(-1); | 887 lib.set_index(-1); |
896 } else { | 888 } else { |
897 // We are preserving this library across the reload, assign its new index | 889 // We are preserving this library across the reload, assign its new index |
898 lib.set_index(new_libs.Length()); | 890 lib.set_index(new_libs.Length()); |
899 new_libs.Add(lib, Heap::kOld); | 891 new_libs.Add(lib, Heap::kOld); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 // be suspended between loading the table pointer and loading the table | 934 // be suspended between loading the table pointer and loading the table |
943 // element. Table will be freed at the next major GC or isolate shutdown. | 935 // element. Table will be freed at the next major GC or isolate shutdown. |
944 class_table->AddOldTable(local_saved_class_table); | 936 class_table->AddOldTable(local_saved_class_table); |
945 } | 937 } |
946 | 938 |
947 | 939 |
948 void IsolateReloadContext::RollbackLibraries() { | 940 void IsolateReloadContext::RollbackLibraries() { |
949 TIR_Print("---- ROLLING BACK LIBRARY CHANGES\n"); | 941 TIR_Print("---- ROLLING BACK LIBRARY CHANGES\n"); |
950 Thread* thread = Thread::Current(); | 942 Thread* thread = Thread::Current(); |
951 Library& lib = Library::Handle(); | 943 Library& lib = Library::Handle(); |
952 GrowableObjectArray& saved_libs = GrowableObjectArray::Handle( | 944 GrowableObjectArray& saved_libs = |
953 Z, saved_libraries()); | 945 GrowableObjectArray::Handle(Z, saved_libraries()); |
954 if (!saved_libs.IsNull()) { | 946 if (!saved_libs.IsNull()) { |
955 for (intptr_t i = 0; i < saved_libs.Length(); i++) { | 947 for (intptr_t i = 0; i < saved_libs.Length(); i++) { |
956 lib = Library::RawCast(saved_libs.At(i)); | 948 lib = Library::RawCast(saved_libs.At(i)); |
957 // Restore indexes that were modified in CheckpointLibraries. | 949 // Restore indexes that were modified in CheckpointLibraries. |
958 lib.set_index(i); | 950 lib.set_index(i); |
959 } | 951 } |
960 | 952 |
961 // Reset the registered libraries to the filtered array. | 953 // Reset the registered libraries to the filtered array. |
962 Library::RegisterLibraries(thread, saved_libs); | 954 Library::RegisterLibraries(thread, saved_libs); |
963 } | 955 } |
(...skipping 20 matching lines...) Expand all Loading... |
984 TIMELINE_SCOPE(VerifyMaps); | 976 TIMELINE_SCOPE(VerifyMaps); |
985 Class& cls = Class::Handle(); | 977 Class& cls = Class::Handle(); |
986 Class& new_cls = Class::Handle(); | 978 Class& new_cls = Class::Handle(); |
987 Class& cls2 = Class::Handle(); | 979 Class& cls2 = Class::Handle(); |
988 | 980 |
989 // Verify that two old classes aren't both mapped to the same new | 981 // Verify that two old classes aren't both mapped to the same new |
990 // class. This could happen is the IsSameClass function is broken. | 982 // class. This could happen is the IsSameClass function is broken. |
991 UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_); | 983 UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_); |
992 UnorderedHashMap<ClassMapTraits> reverse_class_map( | 984 UnorderedHashMap<ClassMapTraits> reverse_class_map( |
993 HashTables::New<UnorderedHashMap<ClassMapTraits> >( | 985 HashTables::New<UnorderedHashMap<ClassMapTraits> >( |
994 class_map.NumOccupied())); | 986 class_map.NumOccupied())); |
995 { | 987 { |
996 UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map); | 988 UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map); |
997 while (it.MoveNext()) { | 989 while (it.MoveNext()) { |
998 const intptr_t entry = it.Current(); | 990 const intptr_t entry = it.Current(); |
999 new_cls = Class::RawCast(class_map.GetKey(entry)); | 991 new_cls = Class::RawCast(class_map.GetKey(entry)); |
1000 cls = Class::RawCast(class_map.GetPayload(entry, 0)); | 992 cls = Class::RawCast(class_map.GetPayload(entry, 0)); |
1001 cls2 ^= reverse_class_map.GetOrNull(new_cls); | 993 cls2 ^= reverse_class_map.GetOrNull(new_cls); |
1002 if (!cls2.IsNull()) { | 994 if (!cls2.IsNull()) { |
1003 OS::PrintErr("Classes '%s' and '%s' are distinct classes but both map " | 995 OS::PrintErr( |
1004 " to class '%s'\n", | 996 "Classes '%s' and '%s' are distinct classes but both map " |
1005 cls.ToCString(), cls2.ToCString(), new_cls.ToCString()); | 997 " to class '%s'\n", |
| 998 cls.ToCString(), cls2.ToCString(), new_cls.ToCString()); |
1006 UNREACHABLE(); | 999 UNREACHABLE(); |
1007 } | 1000 } |
1008 bool update = reverse_class_map.UpdateOrInsert(cls, new_cls); | 1001 bool update = reverse_class_map.UpdateOrInsert(cls, new_cls); |
1009 ASSERT(!update); | 1002 ASSERT(!update); |
1010 } | 1003 } |
1011 } | 1004 } |
1012 class_map.Release(); | 1005 class_map.Release(); |
1013 reverse_class_map.Release(); | 1006 reverse_class_map.Release(); |
1014 } | 1007 } |
1015 #endif | 1008 #endif |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 } | 1083 } |
1091 | 1084 |
1092 // Release the library map. | 1085 // Release the library map. |
1093 lib_map.Release(); | 1086 lib_map.Release(); |
1094 } | 1087 } |
1095 | 1088 |
1096 { | 1089 { |
1097 TIMELINE_SCOPE(UpdateLibrariesArray); | 1090 TIMELINE_SCOPE(UpdateLibrariesArray); |
1098 // Update the libraries array. | 1091 // Update the libraries array. |
1099 Library& lib = Library::Handle(); | 1092 Library& lib = Library::Handle(); |
1100 const GrowableObjectArray& libs = GrowableObjectArray::Handle( | 1093 const GrowableObjectArray& libs = |
1101 I->object_store()->libraries()); | 1094 GrowableObjectArray::Handle(I->object_store()->libraries()); |
1102 for (intptr_t i = 0; i < libs.Length(); i++) { | 1095 for (intptr_t i = 0; i < libs.Length(); i++) { |
1103 lib = Library::RawCast(libs.At(i)); | 1096 lib = Library::RawCast(libs.At(i)); |
1104 VTIR_Print("Lib '%s' at index %" Pd "\n", lib.ToCString(), i); | 1097 VTIR_Print("Lib '%s' at index %" Pd "\n", lib.ToCString(), i); |
1105 lib.set_index(i); | 1098 lib.set_index(i); |
1106 } | 1099 } |
1107 | 1100 |
1108 // Initialize library side table. | 1101 // Initialize library side table. |
1109 library_infos_.SetLength(libs.Length()); | 1102 library_infos_.SetLength(libs.Length()); |
1110 for (intptr_t i = 0; i < libs.Length(); i++) { | 1103 for (intptr_t i = 0; i < libs.Length(); i++) { |
1111 lib = Library::RawCast(libs.At(i)); | 1104 lib = Library::RawCast(libs.At(i)); |
1112 // Mark the library dirty if it comes after the libraries we saved. | 1105 // Mark the library dirty if it comes after the libraries we saved. |
1113 library_infos_[i].dirty = i >= num_saved_libs_; | 1106 library_infos_[i].dirty = i >= num_saved_libs_; |
1114 } | 1107 } |
1115 } | 1108 } |
1116 | 1109 |
1117 { | 1110 { |
1118 const GrowableObjectArray& become_enum_mappings = | 1111 const GrowableObjectArray& become_enum_mappings = |
1119 GrowableObjectArray::Handle(become_enum_mappings_); | 1112 GrowableObjectArray::Handle(become_enum_mappings_); |
1120 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_); | 1113 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_); |
1121 intptr_t replacement_count = become_map.NumOccupied() + | 1114 intptr_t replacement_count = |
1122 become_enum_mappings.Length() / 2; | 1115 become_map.NumOccupied() + become_enum_mappings.Length() / 2; |
1123 const Array& before = | 1116 const Array& before = |
1124 Array::Handle(Array::New(replacement_count, Heap::kOld)); | 1117 Array::Handle(Array::New(replacement_count, Heap::kOld)); |
1125 const Array& after = | 1118 const Array& after = |
1126 Array::Handle(Array::New(replacement_count, Heap::kOld)); | 1119 Array::Handle(Array::New(replacement_count, Heap::kOld)); |
1127 Object& obj = Object::Handle(); | 1120 Object& obj = Object::Handle(); |
1128 intptr_t replacement_index = 0; | 1121 intptr_t replacement_index = 0; |
1129 UnorderedHashMap<BecomeMapTraits>::Iterator it(&become_map); | 1122 UnorderedHashMap<BecomeMapTraits>::Iterator it(&become_map); |
1130 while (it.MoveNext()) { | 1123 while (it.MoveNext()) { |
1131 const intptr_t entry = it.Current(); | 1124 const intptr_t entry = it.Current(); |
1132 obj = become_map.GetKey(entry); | 1125 obj = become_map.GetKey(entry); |
(...skipping 11 matching lines...) Expand all Loading... |
1144 } | 1137 } |
1145 ASSERT(replacement_index == replacement_count); | 1138 ASSERT(replacement_index == replacement_count); |
1146 become_map.Release(); | 1139 become_map.Release(); |
1147 | 1140 |
1148 Become::ElementsForwardIdentity(before, after); | 1141 Become::ElementsForwardIdentity(before, after); |
1149 } | 1142 } |
1150 | 1143 |
1151 if (FLAG_identity_reload) { | 1144 if (FLAG_identity_reload) { |
1152 if (saved_num_cids_ != I->class_table()->NumCids()) { | 1145 if (saved_num_cids_ != I->class_table()->NumCids()) { |
1153 TIR_Print("Identity reload failed! B#C=%" Pd " A#C=%" Pd "\n", | 1146 TIR_Print("Identity reload failed! B#C=%" Pd " A#C=%" Pd "\n", |
1154 saved_num_cids_, | 1147 saved_num_cids_, I->class_table()->NumCids()); |
1155 I->class_table()->NumCids()); | |
1156 } | 1148 } |
1157 const GrowableObjectArray& saved_libs = | 1149 const GrowableObjectArray& saved_libs = |
1158 GrowableObjectArray::Handle(saved_libraries()); | 1150 GrowableObjectArray::Handle(saved_libraries()); |
1159 const GrowableObjectArray& libs = | 1151 const GrowableObjectArray& libs = |
1160 GrowableObjectArray::Handle(I->object_store()->libraries()); | 1152 GrowableObjectArray::Handle(I->object_store()->libraries()); |
1161 if (saved_libs.Length() != libs.Length()) { | 1153 if (saved_libs.Length() != libs.Length()) { |
1162 TIR_Print("Identity reload failed! B#L=%" Pd " A#L=%" Pd "\n", | 1154 TIR_Print("Identity reload failed! B#L=%" Pd " A#L=%" Pd "\n", |
1163 saved_libs.Length(), | 1155 saved_libs.Length(), libs.Length()); |
1164 libs.Length()); | |
1165 } | 1156 } |
1166 } | 1157 } |
1167 } | 1158 } |
1168 | 1159 |
1169 | 1160 |
1170 bool IsolateReloadContext::IsDirty(const Library& lib) { | 1161 bool IsolateReloadContext::IsDirty(const Library& lib) { |
1171 const intptr_t index = lib.index(); | 1162 const intptr_t index = lib.index(); |
1172 if (index == static_cast<classid_t>(-1)) { | 1163 if (index == static_cast<classid_t>(-1)) { |
1173 // Treat deleted libraries as dirty. | 1164 // Treat deleted libraries as dirty. |
1174 return true; | 1165 return true; |
(...skipping 30 matching lines...) Expand all Loading... |
1205 reasons_to_cancel_reload_.At(i)->Report(this); | 1196 reasons_to_cancel_reload_.At(i)->Report(this); |
1206 } | 1197 } |
1207 } | 1198 } |
1208 | 1199 |
1209 | 1200 |
1210 // The ObjectLocator is used for collecting instances that | 1201 // The ObjectLocator is used for collecting instances that |
1211 // needs to be morphed. | 1202 // needs to be morphed. |
1212 class ObjectLocator : public ObjectVisitor { | 1203 class ObjectLocator : public ObjectVisitor { |
1213 public: | 1204 public: |
1214 explicit ObjectLocator(IsolateReloadContext* context) | 1205 explicit ObjectLocator(IsolateReloadContext* context) |
1215 : context_(context), count_(0) { | 1206 : context_(context), count_(0) {} |
1216 } | |
1217 | 1207 |
1218 void VisitObject(RawObject* obj) { | 1208 void VisitObject(RawObject* obj) { |
1219 InstanceMorpher* morpher = | 1209 InstanceMorpher* morpher = |
1220 context_->cid_mapper_.LookupValue(obj->GetClassId()); | 1210 context_->cid_mapper_.LookupValue(obj->GetClassId()); |
1221 if (morpher != NULL) { | 1211 if (morpher != NULL) { |
1222 morpher->AddObject(obj); | 1212 morpher->AddObject(obj); |
1223 count_++; | 1213 count_++; |
1224 } | 1214 } |
1225 } | 1215 } |
1226 | 1216 |
(...skipping 18 matching lines...) Expand all Loading... |
1245 } | 1235 } |
1246 | 1236 |
1247 // Find all objects that need to be morphed. | 1237 // Find all objects that need to be morphed. |
1248 ObjectLocator locator(this); | 1238 ObjectLocator locator(this); |
1249 isolate()->heap()->VisitObjects(&locator); | 1239 isolate()->heap()->VisitObjects(&locator); |
1250 | 1240 |
1251 // Return if no objects are located. | 1241 // Return if no objects are located. |
1252 intptr_t count = locator.count(); | 1242 intptr_t count = locator.count(); |
1253 if (count == 0) return; | 1243 if (count == 0) return; |
1254 | 1244 |
1255 TIR_Print("Found %" Pd " object%s subject to morphing.\n", | 1245 TIR_Print("Found %" Pd " object%s subject to morphing.\n", count, |
1256 count, (count > 1) ? "s" : ""); | 1246 (count > 1) ? "s" : ""); |
1257 | 1247 |
1258 Array& before = Array::Handle(); | 1248 Array& before = Array::Handle(); |
1259 Array& after = Array::Handle(); | 1249 Array& after = Array::Handle(); |
1260 { // Prevent GC to take place due object format confusion. | 1250 { // Prevent GC to take place due object format confusion. |
1261 // Hint: More than one class share the same cid. | 1251 // Hint: More than one class share the same cid. |
1262 NoHeapGrowthControlScope scope; | 1252 NoHeapGrowthControlScope scope; |
1263 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { | 1253 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { |
1264 instance_morphers_.At(i)->CreateMorphedCopies(); | 1254 instance_morphers_.At(i)->CreateMorphedCopies(); |
1265 } | 1255 } |
1266 // Create the inputs for Become. | 1256 // Create the inputs for Become. |
1267 intptr_t index = 0; | 1257 intptr_t index = 0; |
1268 before = Array::New(count); | 1258 before = Array::New(count); |
1269 after = Array::New(count); | 1259 after = Array::New(count); |
1270 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { | 1260 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1419 // the current megamorphic caches get GC'd and any new optimized code allocate | 1409 // the current megamorphic caches get GC'd and any new optimized code allocate |
1420 // new ones. | 1410 // new ones. |
1421 } | 1411 } |
1422 | 1412 |
1423 | 1413 |
1424 class MarkFunctionsForRecompilation : public ObjectVisitor { | 1414 class MarkFunctionsForRecompilation : public ObjectVisitor { |
1425 public: | 1415 public: |
1426 MarkFunctionsForRecompilation(Isolate* isolate, | 1416 MarkFunctionsForRecompilation(Isolate* isolate, |
1427 IsolateReloadContext* reload_context, | 1417 IsolateReloadContext* reload_context, |
1428 Zone* zone) | 1418 Zone* zone) |
1429 : ObjectVisitor(), | 1419 : ObjectVisitor(), |
1430 handle_(Object::Handle(zone)), | 1420 handle_(Object::Handle(zone)), |
1431 owning_class_(Class::Handle(zone)), | 1421 owning_class_(Class::Handle(zone)), |
1432 owning_lib_(Library::Handle(zone)), | 1422 owning_lib_(Library::Handle(zone)), |
1433 code_(Code::Handle(zone)), | 1423 code_(Code::Handle(zone)), |
1434 reload_context_(reload_context), | 1424 reload_context_(reload_context), |
1435 zone_(zone) { | 1425 zone_(zone) {} |
1436 } | |
1437 | 1426 |
1438 virtual void VisitObject(RawObject* obj) { | 1427 virtual void VisitObject(RawObject* obj) { |
1439 if (obj->IsPseudoObject()) { | 1428 if (obj->IsPseudoObject()) { |
1440 // Cannot even be wrapped in handles. | 1429 // Cannot even be wrapped in handles. |
1441 return; | 1430 return; |
1442 } | 1431 } |
1443 handle_ = obj; | 1432 handle_ = obj; |
1444 if (handle_.IsFunction()) { | 1433 if (handle_.IsFunction()) { |
1445 const Function& func = Function::Cast(handle_); | 1434 const Function& func = Function::Cast(handle_); |
1446 | 1435 |
1447 // Switch to unoptimized code or the lazy compilation stub. | 1436 // Switch to unoptimized code or the lazy compilation stub. |
1448 func.SwitchToLazyCompiledUnoptimizedCode(); | 1437 func.SwitchToLazyCompiledUnoptimizedCode(); |
1449 | 1438 |
1450 // Grab the current code. | 1439 // Grab the current code. |
1451 code_ = func.CurrentCode(); | 1440 code_ = func.CurrentCode(); |
1452 ASSERT(!code_.IsNull()); | 1441 ASSERT(!code_.IsNull()); |
1453 const bool clear_code = IsFromDirtyLibrary(func); | 1442 const bool clear_code = IsFromDirtyLibrary(func); |
1454 const bool stub_code = code_.IsStubCode(); | 1443 const bool stub_code = code_.IsStubCode(); |
1455 | 1444 |
1456 // Zero edge counters. | 1445 // Zero edge counters. |
1457 func.ZeroEdgeCounters(); | 1446 func.ZeroEdgeCounters(); |
1458 | 1447 |
1459 if (!stub_code) { | 1448 if (!stub_code) { |
1460 if (clear_code) { | 1449 if (clear_code) { |
1461 VTIR_Print("Marking %s for recompilation, clearning code\n", | 1450 VTIR_Print("Marking %s for recompilation, clearning code\n", |
1462 func.ToCString()); | 1451 func.ToCString()); |
1463 ClearAllCode(func); | 1452 ClearAllCode(func); |
1464 } else { | 1453 } else { |
1465 PreserveUnoptimizedCode(); | 1454 PreserveUnoptimizedCode(); |
1466 } | 1455 } |
1467 } | 1456 } |
1468 | 1457 |
1469 // Clear counters. | 1458 // Clear counters. |
1470 func.set_usage_counter(0); | 1459 func.set_usage_counter(0); |
1471 func.set_deoptimization_counter(0); | 1460 func.set_deoptimization_counter(0); |
1472 func.set_optimized_instruction_count(0); | 1461 func.set_optimized_instruction_count(0); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 const Library& old = Library::Handle(OldLibraryOrNull(replacement_or_new)); | 1546 const Library& old = Library::Handle(OldLibraryOrNull(replacement_or_new)); |
1558 if (old.IsNull()) { | 1547 if (old.IsNull()) { |
1559 return String::null(); | 1548 return String::null(); |
1560 } | 1549 } |
1561 return old.private_key(); | 1550 return old.private_key(); |
1562 } | 1551 } |
1563 | 1552 |
1564 | 1553 |
1565 RawLibrary* IsolateReloadContext::OldLibraryOrNull( | 1554 RawLibrary* IsolateReloadContext::OldLibraryOrNull( |
1566 const Library& replacement_or_new) { | 1555 const Library& replacement_or_new) { |
1567 UnorderedHashSet<LibraryMapTraits> | 1556 UnorderedHashSet<LibraryMapTraits> old_libraries_set( |
1568 old_libraries_set(old_libraries_set_storage_); | 1557 old_libraries_set_storage_); |
1569 Library& lib = Library::Handle(); | 1558 Library& lib = Library::Handle(); |
1570 lib ^= old_libraries_set.GetOrNull(replacement_or_new); | 1559 lib ^= old_libraries_set.GetOrNull(replacement_or_new); |
1571 old_libraries_set.Release(); | 1560 old_libraries_set.Release(); |
1572 return lib.raw(); | 1561 return lib.raw(); |
1573 } | 1562 } |
1574 | 1563 |
1575 | 1564 |
1576 void IsolateReloadContext::BuildLibraryMapping() { | 1565 void IsolateReloadContext::BuildLibraryMapping() { |
1577 const GrowableObjectArray& libs = | 1566 const GrowableObjectArray& libs = |
1578 GrowableObjectArray::Handle(object_store()->libraries()); | 1567 GrowableObjectArray::Handle(object_store()->libraries()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 const Library& original) { | 1605 const Library& original) { |
1617 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); | 1606 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); |
1618 bool update = map.UpdateOrInsert(replacement_or_new, original); | 1607 bool update = map.UpdateOrInsert(replacement_or_new, original); |
1619 ASSERT(!update); | 1608 ASSERT(!update); |
1620 // The storage given to the map may have been reallocated, remember the new | 1609 // The storage given to the map may have been reallocated, remember the new |
1621 // address. | 1610 // address. |
1622 library_map_storage_ = map.Release().raw(); | 1611 library_map_storage_ = map.Release().raw(); |
1623 } | 1612 } |
1624 | 1613 |
1625 | 1614 |
1626 void IsolateReloadContext::AddStaticFieldMapping( | 1615 void IsolateReloadContext::AddStaticFieldMapping(const Field& old_field, |
1627 const Field& old_field, const Field& new_field) { | 1616 const Field& new_field) { |
1628 ASSERT(old_field.is_static()); | 1617 ASSERT(old_field.is_static()); |
1629 ASSERT(new_field.is_static()); | 1618 ASSERT(new_field.is_static()); |
1630 | 1619 |
1631 AddBecomeMapping(old_field, new_field); | 1620 AddBecomeMapping(old_field, new_field); |
1632 } | 1621 } |
1633 | 1622 |
1634 | 1623 |
1635 void IsolateReloadContext::AddBecomeMapping(const Object& old, | 1624 void IsolateReloadContext::AddBecomeMapping(const Object& old, |
1636 const Object& neu) { | 1625 const Object& neu) { |
1637 ASSERT(become_map_storage_ != Array::null()); | 1626 ASSERT(become_map_storage_ != Array::null()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 ASSERT(!super_cls.IsNull()); | 1670 ASSERT(!super_cls.IsNull()); |
1682 super_cls.AddDirectSubclass(cls); | 1671 super_cls.AddDirectSubclass(cls); |
1683 } | 1672 } |
1684 } | 1673 } |
1685 } | 1674 } |
1686 } | 1675 } |
1687 | 1676 |
1688 #endif // !PRODUCT | 1677 #endif // !PRODUCT |
1689 | 1678 |
1690 } // namespace dart | 1679 } // namespace dart |
OLD | NEW |