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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | runtime/vm/isolate_reload_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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/runtime_entry.h"
10 #include "vm/compiler.h" 9 #include "vm/compiler.h"
11 #include "vm/dart_api_impl.h" 10 #include "vm/dart_api_impl.h"
12 #include "vm/hash_table.h" 11 #include "vm/hash_table.h"
13 #include "vm/isolate.h" 12 #include "vm/isolate.h"
14 #include "vm/log.h" 13 #include "vm/log.h"
15 #include "vm/object.h" 14 #include "vm/object.h"
16 #include "vm/object_store.h" 15 #include "vm/object_store.h"
17 #include "vm/parser.h" 16 #include "vm/parser.h"
17 #include "vm/runtime_entry.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");
(...skipping 18 matching lines...) Expand all
46 "Assert that an isolate has reloaded at least once.") 46 "Assert that an isolate has reloaded at least once.")
47 #ifndef PRODUCT 47 #ifndef PRODUCT
48 48
49 #define I (isolate()) 49 #define I (isolate())
50 #define Z (thread->zone()) 50 #define Z (thread->zone())
51 51
52 #define TIMELINE_SCOPE(name) \ 52 #define TIMELINE_SCOPE(name) \
53 TimelineDurationScope tds##name(Thread::Current(), \ 53 TimelineDurationScope tds##name(Thread::Current(), \
54 Timeline::GetIsolateStream(), #name) 54 Timeline::GetIsolateStream(), #name)
55 55
56
57 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to) 56 InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to)
58 : from_(Class::Handle(zone, from.raw())), 57 : from_(Class::Handle(zone, from.raw())),
59 to_(Class::Handle(zone, to.raw())), 58 to_(Class::Handle(zone, to.raw())),
60 mapping_(zone, 0) { 59 mapping_(zone, 0) {
61 before_ = new (zone) ZoneGrowableArray<const Instance*>(zone, 0); 60 before_ = new (zone) ZoneGrowableArray<const Instance*>(zone, 0);
62 after_ = new (zone) ZoneGrowableArray<const Instance*>(zone, 0); 61 after_ = new (zone) ZoneGrowableArray<const Instance*>(zone, 0);
63 new_fields_ = new (zone) ZoneGrowableArray<const Field*>(zone, 0); 62 new_fields_ = new (zone) ZoneGrowableArray<const Field*>(zone, 0);
64 ASSERT(from_.id() == to_.id()); 63 ASSERT(from_.id() == to_.id());
65 cid_ = from_.id(); 64 cid_ = from_.id();
66 ComputeMapping(); 65 ComputeMapping();
67 } 66 }
68 67
69
70 void InstanceMorpher::AddObject(RawObject* object) const { 68 void InstanceMorpher::AddObject(RawObject* object) const {
71 ASSERT(object->GetClassId() == cid()); 69 ASSERT(object->GetClassId() == cid());
72 const Instance& instance = Instance::Cast(Object::Handle(object)); 70 const Instance& instance = Instance::Cast(Object::Handle(object));
73 before_->Add(&instance); 71 before_->Add(&instance);
74 } 72 }
75 73
76
77 void InstanceMorpher::ComputeMapping() { 74 void InstanceMorpher::ComputeMapping() {
78 if (from_.NumTypeArguments()) { 75 if (from_.NumTypeArguments()) {
79 // Add copying of the optional type argument field. 76 // Add copying of the optional type argument field.
80 intptr_t from_offset = from_.type_arguments_field_offset(); 77 intptr_t from_offset = from_.type_arguments_field_offset();
81 ASSERT(from_offset != Class::kNoTypeArguments); 78 ASSERT(from_offset != Class::kNoTypeArguments);
82 intptr_t to_offset = to_.type_arguments_field_offset(); 79 intptr_t to_offset = to_.type_arguments_field_offset();
83 ASSERT(to_offset != Class::kNoTypeArguments); 80 ASSERT(to_offset != Class::kNoTypeArguments);
84 mapping_.Add(from_offset); 81 mapping_.Add(from_offset);
85 mapping_.Add(to_offset); 82 mapping_.Add(to_offset);
86 } 83 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 if (new_field) { 126 if (new_field) {
130 if (to_field.has_initializer()) { 127 if (to_field.has_initializer()) {
131 // This is a new field with an initializer. 128 // This is a new field with an initializer.
132 const Field& field = Field::Handle(to_field.raw()); 129 const Field& field = Field::Handle(to_field.raw());
133 new_fields_->Add(&field); 130 new_fields_->Add(&field);
134 } 131 }
135 } 132 }
136 } 133 }
137 } 134 }
138 135
139
140 RawInstance* InstanceMorpher::Morph(const Instance& instance) const { 136 RawInstance* InstanceMorpher::Morph(const Instance& instance) const {
141 const Instance& result = Instance::Handle(Instance::New(to_)); 137 const Instance& result = Instance::Handle(Instance::New(to_));
142 // Morph the context from instance to result using mapping_. 138 // Morph the context from instance to result using mapping_.
143 for (intptr_t i = 0; i < mapping_.length(); i += 2) { 139 for (intptr_t i = 0; i < mapping_.length(); i += 2) {
144 intptr_t from_offset = mapping_.At(i); 140 intptr_t from_offset = mapping_.At(i);
145 intptr_t to_offset = mapping_.At(i + 1); 141 intptr_t to_offset = mapping_.At(i + 1);
146 const Object& value = 142 const Object& value =
147 Object::Handle(instance.RawGetFieldAtOffset(from_offset)); 143 Object::Handle(instance.RawGetFieldAtOffset(from_offset));
148 result.RawSetFieldAtOffset(to_offset, value); 144 result.RawSetFieldAtOffset(to_offset, value);
149 } 145 }
150 // Convert the instance into a filler object. 146 // Convert the instance into a filler object.
151 Become::MakeDummyObject(instance); 147 Become::MakeDummyObject(instance);
152 return result.raw(); 148 return result.raw();
153 } 149 }
154 150
155
156 void InstanceMorpher::RunNewFieldInitializers() const { 151 void InstanceMorpher::RunNewFieldInitializers() const {
157 if ((new_fields_->length() == 0) || (after_->length() == 0)) { 152 if ((new_fields_->length() == 0) || (after_->length() == 0)) {
158 return; 153 return;
159 } 154 }
160 155
161 TIR_Print("Running new field initializers for class: %s\n", to_.ToCString()); 156 TIR_Print("Running new field initializers for class: %s\n", to_.ToCString());
162 String& initializing_expression = String::Handle(); 157 String& initializing_expression = String::Handle();
163 Function& eval_func = Function::Handle(); 158 Function& eval_func = Function::Handle();
164 Object& result = Object::Handle(); 159 Object& result = Object::Handle();
165 Class& owning_class = Class::Handle(); 160 Class& owning_class = Class::Handle();
(...skipping 21 matching lines...) Expand all
187 "RELOAD: Running initializer for new field `%s` resulted in " 182 "RELOAD: Running initializer for new field `%s` resulted in "
188 "an error: %s\n", 183 "an error: %s\n",
189 field->ToCString(), Error::Cast(result).ToErrorCString()); 184 field->ToCString(), Error::Cast(result).ToErrorCString());
190 continue; 185 continue;
191 } 186 }
192 instance->RawSetFieldAtOffset(field->Offset(), result); 187 instance->RawSetFieldAtOffset(field->Offset(), result);
193 } 188 }
194 } 189 }
195 } 190 }
196 191
197
198 void InstanceMorpher::CreateMorphedCopies() const { 192 void InstanceMorpher::CreateMorphedCopies() const {
199 for (intptr_t i = 0; i < before()->length(); i++) { 193 for (intptr_t i = 0; i < before()->length(); i++) {
200 const Instance& copy = Instance::Handle(Morph(*before()->At(i))); 194 const Instance& copy = Instance::Handle(Morph(*before()->At(i)));
201 after()->Add(&copy); 195 after()->Add(&copy);
202 } 196 }
203 } 197 }
204 198
205
206 void InstanceMorpher::DumpFormatFor(const Class& cls) const { 199 void InstanceMorpher::DumpFormatFor(const Class& cls) const {
207 THR_Print("%s\n", cls.ToCString()); 200 THR_Print("%s\n", cls.ToCString());
208 if (cls.NumTypeArguments()) { 201 if (cls.NumTypeArguments()) {
209 intptr_t field_offset = cls.type_arguments_field_offset(); 202 intptr_t field_offset = cls.type_arguments_field_offset();
210 ASSERT(field_offset != Class::kNoTypeArguments); 203 ASSERT(field_offset != Class::kNoTypeArguments);
211 THR_Print(" - @%" Pd " <type arguments>\n", field_offset); 204 THR_Print(" - @%" Pd " <type arguments>\n", field_offset);
212 } 205 }
213 const Array& fields = Array::Handle(cls.OffsetToFieldMap()); 206 const Array& fields = Array::Handle(cls.OffsetToFieldMap());
214 Field& field = Field::Handle(); 207 Field& field = Field::Handle();
215 String& name = String::Handle(); 208 String& name = String::Handle();
216 for (intptr_t i = 0; i < fields.Length(); i++) { 209 for (intptr_t i = 0; i < fields.Length(); i++) {
217 if (fields.At(i) != Field::null()) { 210 if (fields.At(i) != Field::null()) {
218 field = Field::RawCast(fields.At(i)); 211 field = Field::RawCast(fields.At(i));
219 ASSERT(field.is_instance()); 212 ASSERT(field.is_instance());
220 name = field.name(); 213 name = field.name();
221 THR_Print(" - @%" Pd " %s\n", field.Offset(), name.ToCString()); 214 THR_Print(" - @%" Pd " %s\n", field.Offset(), name.ToCString());
222 } 215 }
223 } 216 }
224 217
225 THR_Print("Mapping: "); 218 THR_Print("Mapping: ");
226 for (int i = 0; i < mapping_.length(); i += 2) { 219 for (int i = 0; i < mapping_.length(); i += 2) {
227 THR_Print(" %" Pd "->%" Pd, mapping_.At(i), mapping_.At(i + 1)); 220 THR_Print(" %" Pd "->%" Pd, mapping_.At(i), mapping_.At(i + 1));
228 } 221 }
229 THR_Print("\n"); 222 THR_Print("\n");
230 } 223 }
231 224
232
233 void InstanceMorpher::Dump() const { 225 void InstanceMorpher::Dump() const {
234 LogBlock blocker; 226 LogBlock blocker;
235 THR_Print("Morphing from "); 227 THR_Print("Morphing from ");
236 DumpFormatFor(from_); 228 DumpFormatFor(from_);
237 THR_Print("To "); 229 THR_Print("To ");
238 DumpFormatFor(to_); 230 DumpFormatFor(to_);
239 THR_Print("\n"); 231 THR_Print("\n");
240 } 232 }
241 233
242
243 void InstanceMorpher::AppendTo(JSONArray* array) { 234 void InstanceMorpher::AppendTo(JSONArray* array) {
244 JSONObject jsobj(array); 235 JSONObject jsobj(array);
245 jsobj.AddProperty("type", "ShapeChangeMapping"); 236 jsobj.AddProperty("type", "ShapeChangeMapping");
246 jsobj.AddProperty("class", to_); 237 jsobj.AddProperty("class", to_);
247 jsobj.AddProperty("instanceCount", before()->length()); 238 jsobj.AddProperty("instanceCount", before()->length());
248 JSONArray map(&jsobj, "fieldOffsetMappings"); 239 JSONArray map(&jsobj, "fieldOffsetMappings");
249 for (int i = 0; i < mapping_.length(); i += 2) { 240 for (int i = 0; i < mapping_.length(); i += 2) {
250 JSONArray pair(&map); 241 JSONArray pair(&map);
251 pair.AddValue(mapping_.At(i)); 242 pair.AddValue(mapping_.At(i));
252 pair.AddValue(mapping_.At(i + 1)); 243 pair.AddValue(mapping_.At(i + 1));
253 } 244 }
254 } 245 }
255 246
256
257 void ReasonForCancelling::Report(IsolateReloadContext* context) { 247 void ReasonForCancelling::Report(IsolateReloadContext* context) {
258 const Error& error = Error::Handle(ToError()); 248 const Error& error = Error::Handle(ToError());
259 context->ReportError(error); 249 context->ReportError(error);
260 } 250 }
261 251
262
263 RawError* ReasonForCancelling::ToError() { 252 RawError* ReasonForCancelling::ToError() {
264 // By default create the error returned from ToString. 253 // By default create the error returned from ToString.
265 const String& message = String::Handle(ToString()); 254 const String& message = String::Handle(ToString());
266 return LanguageError::New(message); 255 return LanguageError::New(message);
267 } 256 }
268 257
269
270 RawString* ReasonForCancelling::ToString() { 258 RawString* ReasonForCancelling::ToString() {
271 UNREACHABLE(); 259 UNREACHABLE();
272 return NULL; 260 return NULL;
273 } 261 }
274 262
275
276 void ReasonForCancelling::AppendTo(JSONArray* array) { 263 void ReasonForCancelling::AppendTo(JSONArray* array) {
277 JSONObject jsobj(array); 264 JSONObject jsobj(array);
278 jsobj.AddProperty("type", "ReasonForCancelling"); 265 jsobj.AddProperty("type", "ReasonForCancelling");
279 const String& message = String::Handle(ToString()); 266 const String& message = String::Handle(ToString());
280 jsobj.AddProperty("message", message.ToCString()); 267 jsobj.AddProperty("message", message.ToCString());
281 } 268 }
282 269
283
284 ClassReasonForCancelling::ClassReasonForCancelling(Zone* zone, 270 ClassReasonForCancelling::ClassReasonForCancelling(Zone* zone,
285 const Class& from, 271 const Class& from,
286 const Class& to) 272 const Class& to)
287 : ReasonForCancelling(zone), 273 : ReasonForCancelling(zone),
288 from_(Class::ZoneHandle(zone, from.raw())), 274 from_(Class::ZoneHandle(zone, from.raw())),
289 to_(Class::ZoneHandle(zone, to.raw())) {} 275 to_(Class::ZoneHandle(zone, to.raw())) {}
290 276
291
292 void ClassReasonForCancelling::AppendTo(JSONArray* array) { 277 void ClassReasonForCancelling::AppendTo(JSONArray* array) {
293 JSONObject jsobj(array); 278 JSONObject jsobj(array);
294 jsobj.AddProperty("type", "ReasonForCancelling"); 279 jsobj.AddProperty("type", "ReasonForCancelling");
295 jsobj.AddProperty("class", from_); 280 jsobj.AddProperty("class", from_);
296 const String& message = String::Handle(ToString()); 281 const String& message = String::Handle(ToString());
297 jsobj.AddProperty("message", message.ToCString()); 282 jsobj.AddProperty("message", message.ToCString());
298 } 283 }
299 284
300
301 RawError* IsolateReloadContext::error() const { 285 RawError* IsolateReloadContext::error() const {
302 ASSERT(reload_aborted()); 286 ASSERT(reload_aborted());
303 // Report the first error to the surroundings. 287 // Report the first error to the surroundings.
304 return reasons_to_cancel_reload_.At(0)->ToError(); 288 return reasons_to_cancel_reload_.At(0)->ToError();
305 } 289 }
306 290
307
308 class ScriptUrlSetTraits { 291 class ScriptUrlSetTraits {
309 public: 292 public:
310 static bool ReportStats() { return false; } 293 static bool ReportStats() { return false; }
311 static const char* Name() { return "ScriptUrlSetTraits"; } 294 static const char* Name() { return "ScriptUrlSetTraits"; }
312 295
313 static bool IsMatch(const Object& a, const Object& b) { 296 static bool IsMatch(const Object& a, const Object& b) {
314 if (!a.IsString() || !b.IsString()) { 297 if (!a.IsString() || !b.IsString()) {
315 return false; 298 return false;
316 } 299 }
317 300
318 return String::Cast(a).Equals(String::Cast(b)); 301 return String::Cast(a).Equals(String::Cast(b));
319 } 302 }
320 303
321 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } 304 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); }
322 }; 305 };
323 306
324
325 class ClassMapTraits { 307 class ClassMapTraits {
326 public: 308 public:
327 static bool ReportStats() { return false; } 309 static bool ReportStats() { return false; }
328 static const char* Name() { return "ClassMapTraits"; } 310 static const char* Name() { return "ClassMapTraits"; }
329 311
330 static bool IsMatch(const Object& a, const Object& b) { 312 static bool IsMatch(const Object& a, const Object& b) {
331 if (!a.IsClass() || !b.IsClass()) { 313 if (!a.IsClass() || !b.IsClass()) {
332 return false; 314 return false;
333 } 315 }
334 return IsolateReloadContext::IsSameClass(Class::Cast(a), Class::Cast(b)); 316 return IsolateReloadContext::IsSameClass(Class::Cast(a), Class::Cast(b));
335 } 317 }
336 318
337 static uword Hash(const Object& obj) { 319 static uword Hash(const Object& obj) {
338 return String::HashRawSymbol(Class::Cast(obj).Name()); 320 return String::HashRawSymbol(Class::Cast(obj).Name());
339 } 321 }
340 }; 322 };
341 323
342
343 class LibraryMapTraits { 324 class LibraryMapTraits {
344 public: 325 public:
345 static bool ReportStats() { return false; } 326 static bool ReportStats() { return false; }
346 static const char* Name() { return "LibraryMapTraits"; } 327 static const char* Name() { return "LibraryMapTraits"; }
347 328
348 static bool IsMatch(const Object& a, const Object& b) { 329 static bool IsMatch(const Object& a, const Object& b) {
349 if (!a.IsLibrary() || !b.IsLibrary()) { 330 if (!a.IsLibrary() || !b.IsLibrary()) {
350 return false; 331 return false;
351 } 332 }
352 return IsolateReloadContext::IsSameLibrary(Library::Cast(a), 333 return IsolateReloadContext::IsSameLibrary(Library::Cast(a),
353 Library::Cast(b)); 334 Library::Cast(b));
354 } 335 }
355 336
356 static uword Hash(const Object& obj) { return Library::Cast(obj).UrlHash(); } 337 static uword Hash(const Object& obj) { return Library::Cast(obj).UrlHash(); }
357 }; 338 };
358 339
359
360 class BecomeMapTraits { 340 class BecomeMapTraits {
361 public: 341 public:
362 static bool ReportStats() { return false; } 342 static bool ReportStats() { return false; }
363 static const char* Name() { return "BecomeMapTraits"; } 343 static const char* Name() { return "BecomeMapTraits"; }
364 344
365 static bool IsMatch(const Object& a, const Object& b) { 345 static bool IsMatch(const Object& a, const Object& b) {
366 return a.raw() == b.raw(); 346 return a.raw() == b.raw();
367 } 347 }
368 348
369 static uword Hash(const Object& obj) { 349 static uword Hash(const Object& obj) {
370 if (obj.IsLibrary()) { 350 if (obj.IsLibrary()) {
371 return Library::Cast(obj).UrlHash(); 351 return Library::Cast(obj).UrlHash();
372 } else if (obj.IsClass()) { 352 } else if (obj.IsClass()) {
373 if (Class::Cast(obj).id() == kFreeListElement) { 353 if (Class::Cast(obj).id() == kFreeListElement) {
374 return 0; 354 return 0;
375 } 355 }
376 return String::HashRawSymbol(Class::Cast(obj).Name()); 356 return String::HashRawSymbol(Class::Cast(obj).Name());
377 } else if (obj.IsField()) { 357 } else if (obj.IsField()) {
378 return String::HashRawSymbol(Field::Cast(obj).name()); 358 return String::HashRawSymbol(Field::Cast(obj).name());
379 } else if (obj.IsInstance()) { 359 } else if (obj.IsInstance()) {
380 return Smi::Handle(Smi::RawCast(Instance::Cast(obj).HashCode())).Value(); 360 return Smi::Handle(Smi::RawCast(Instance::Cast(obj).HashCode())).Value();
381 } 361 }
382 return 0; 362 return 0;
383 } 363 }
384 }; 364 };
385 365
386
387 bool IsolateReloadContext::IsSameField(const Field& a, const Field& b) { 366 bool IsolateReloadContext::IsSameField(const Field& a, const Field& b) {
388 if (a.is_static() != b.is_static()) { 367 if (a.is_static() != b.is_static()) {
389 return false; 368 return false;
390 } 369 }
391 const Class& a_cls = Class::Handle(a.Owner()); 370 const Class& a_cls = Class::Handle(a.Owner());
392 const Class& b_cls = Class::Handle(b.Owner()); 371 const Class& b_cls = Class::Handle(b.Owner());
393 372
394 if (!IsSameClass(a_cls, b_cls)) { 373 if (!IsSameClass(a_cls, b_cls)) {
395 return false; 374 return false;
396 } 375 }
397 376
398 const String& a_name = String::Handle(a.name()); 377 const String& a_name = String::Handle(a.name());
399 const String& b_name = String::Handle(b.name()); 378 const String& b_name = String::Handle(b.name());
400 379
401 return a_name.Equals(b_name); 380 return a_name.Equals(b_name);
402 } 381 }
403 382
404
405 bool IsolateReloadContext::IsSameClass(const Class& a, const Class& b) { 383 bool IsolateReloadContext::IsSameClass(const Class& a, const Class& b) {
406 if (a.is_patch() != b.is_patch()) { 384 if (a.is_patch() != b.is_patch()) {
407 // TODO(johnmccutchan): Should we just check the class kind bits? 385 // TODO(johnmccutchan): Should we just check the class kind bits?
408 return false; 386 return false;
409 } 387 }
410 388
411 // TODO(turnidge): We need to look at generic type arguments for 389 // TODO(turnidge): We need to look at generic type arguments for
412 // synthetic mixin classes. Their names are not necessarily unique 390 // synthetic mixin classes. Their names are not necessarily unique
413 // currently. 391 // currently.
414 const String& a_name = String::Handle(a.Name()); 392 const String& a_name = String::Handle(a.Name());
415 const String& b_name = String::Handle(b.Name()); 393 const String& b_name = String::Handle(b.Name());
416 394
417 if (!a_name.Equals(b_name)) { 395 if (!a_name.Equals(b_name)) {
418 return false; 396 return false;
419 } 397 }
420 398
421 const Library& a_lib = Library::Handle(a.library()); 399 const Library& a_lib = Library::Handle(a.library());
422 const Library& b_lib = Library::Handle(b.library()); 400 const Library& b_lib = Library::Handle(b.library());
423 401
424 if (a_lib.IsNull() || b_lib.IsNull()) { 402 if (a_lib.IsNull() || b_lib.IsNull()) {
425 return a_lib.raw() == b_lib.raw(); 403 return a_lib.raw() == b_lib.raw();
426 } 404 }
427 return (a_lib.private_key() == b_lib.private_key()); 405 return (a_lib.private_key() == b_lib.private_key());
428 } 406 }
429 407
430
431 bool IsolateReloadContext::IsSameLibrary(const Library& a_lib, 408 bool IsolateReloadContext::IsSameLibrary(const Library& a_lib,
432 const Library& b_lib) { 409 const Library& b_lib) {
433 const String& a_lib_url = 410 const String& a_lib_url =
434 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); 411 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url());
435 const String& b_lib_url = 412 const String& b_lib_url =
436 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); 413 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url());
437 return a_lib_url.Equals(b_lib_url); 414 return a_lib_url.Equals(b_lib_url);
438 } 415 }
439 416
440
441 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, JSONStream* js) 417 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, JSONStream* js)
442 : zone_(Thread::Current()->zone()), 418 : zone_(Thread::Current()->zone()),
443 start_time_micros_(OS::GetCurrentMonotonicMicros()), 419 start_time_micros_(OS::GetCurrentMonotonicMicros()),
444 reload_timestamp_(OS::GetCurrentTimeMillis()), 420 reload_timestamp_(OS::GetCurrentTimeMillis()),
445 isolate_(isolate), 421 isolate_(isolate),
446 reload_skipped_(false), 422 reload_skipped_(false),
447 reload_aborted_(false), 423 reload_aborted_(false),
448 reload_finalized_(false), 424 reload_finalized_(false),
449 js_(js), 425 js_(js),
450 saved_num_cids_(-1), 426 saved_num_cids_(-1),
(...skipping 14 matching lines...) Expand all
465 saved_root_library_(Library::null()), 441 saved_root_library_(Library::null()),
466 saved_libraries_(GrowableObjectArray::null()), 442 saved_libraries_(GrowableObjectArray::null()),
467 root_url_prefix_(String::null()), 443 root_url_prefix_(String::null()),
468 old_root_url_prefix_(String::null()) { 444 old_root_url_prefix_(String::null()) {
469 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not 445 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not
470 // associated with the isolate yet and if a GC is triggered here the raw 446 // associated with the isolate yet and if a GC is triggered here the raw
471 // objects will not be properly accounted for. 447 // objects will not be properly accounted for.
472 ASSERT(zone_ != NULL); 448 ASSERT(zone_ != NULL);
473 } 449 }
474 450
475
476 IsolateReloadContext::~IsolateReloadContext() { 451 IsolateReloadContext::~IsolateReloadContext() {
477 ASSERT(saved_class_table_ == NULL); 452 ASSERT(saved_class_table_ == NULL);
478 } 453 }
479 454
480
481 void IsolateReloadContext::ReportError(const Error& error) { 455 void IsolateReloadContext::ReportError(const Error& error) {
482 if (FLAG_trace_reload) { 456 if (FLAG_trace_reload) {
483 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); 457 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
484 } 458 }
485 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); 459 ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
486 service_event.set_reload_error(&error); 460 service_event.set_reload_error(&error);
487 Service::HandleEvent(&service_event); 461 Service::HandleEvent(&service_event);
488 } 462 }
489 463
490
491 void IsolateReloadContext::ReportSuccess() { 464 void IsolateReloadContext::ReportSuccess() {
492 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); 465 ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
493 Service::HandleEvent(&service_event); 466 Service::HandleEvent(&service_event);
494 } 467 }
495 468
496
497 class Aborted : public ReasonForCancelling { 469 class Aborted : public ReasonForCancelling {
498 public: 470 public:
499 Aborted(Zone* zone, const Error& error) 471 Aborted(Zone* zone, const Error& error)
500 : ReasonForCancelling(zone), 472 : ReasonForCancelling(zone),
501 error_(Error::ZoneHandle(zone, error.raw())) {} 473 error_(Error::ZoneHandle(zone, error.raw())) {}
502 474
503 private: 475 private:
504 const Error& error_; 476 const Error& error_;
505 477
506 RawError* ToError() { return error_.raw(); } 478 RawError* ToError() { return error_.raw(); }
507 RawString* ToString() { 479 RawString* ToString() {
508 return String::NewFormatted("%s", error_.ToErrorCString()); 480 return String::NewFormatted("%s", error_.ToErrorCString());
509 } 481 }
510 }; 482 };
511 483
512
513 static intptr_t CommonSuffixLength(const char* a, const char* b) { 484 static intptr_t CommonSuffixLength(const char* a, const char* b) {
514 const intptr_t a_length = strlen(a); 485 const intptr_t a_length = strlen(a);
515 const intptr_t b_length = strlen(b); 486 const intptr_t b_length = strlen(b);
516 intptr_t a_cursor = a_length; 487 intptr_t a_cursor = a_length;
517 intptr_t b_cursor = b_length; 488 intptr_t b_cursor = b_length;
518 489
519 while ((a_cursor >= 0) && (b_cursor >= 0)) { 490 while ((a_cursor >= 0) && (b_cursor >= 0)) {
520 if (a[a_cursor] != b[b_cursor]) { 491 if (a[a_cursor] != b[b_cursor]) {
521 break; 492 break;
522 } 493 }
523 a_cursor--; 494 a_cursor--;
524 b_cursor--; 495 b_cursor--;
525 } 496 }
526 497
527 ASSERT((a_length - a_cursor) == (b_length - b_cursor)); 498 ASSERT((a_length - a_cursor) == (b_length - b_cursor));
528 return (a_length - a_cursor); 499 return (a_length - a_cursor);
529 } 500 }
530 501
531
532 // NOTE: This function returns *after* FinalizeLoading is called. 502 // NOTE: This function returns *after* FinalizeLoading is called.
533 void IsolateReloadContext::Reload(bool force_reload, 503 void IsolateReloadContext::Reload(bool force_reload,
534 const char* root_script_url, 504 const char* root_script_url,
535 const char* packages_url_) { 505 const char* packages_url_) {
536 TIMELINE_SCOPE(Reload); 506 TIMELINE_SCOPE(Reload);
537 Thread* thread = Thread::Current(); 507 Thread* thread = Thread::Current();
538 ASSERT(isolate() == thread->isolate()); 508 ASSERT(isolate() == thread->isolate());
539 509
540 // Grab root library before calling CheckpointBeforeReload. 510 // Grab root library before calling CheckpointBeforeReload.
541 const Library& old_root_lib = Library::Handle(object_store()->root_library()); 511 const Library& old_root_lib = Library::Handle(object_store()->root_library());
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 UNREACHABLE(); 623 UNREACHABLE();
654 } 624 }
655 } 625 }
656 626
657 // Other errors (e.g. a parse error) are captured by the reload system. 627 // Other errors (e.g. a parse error) are captured by the reload system.
658 if (result.IsError()) { 628 if (result.IsError()) {
659 FinalizeFailedLoad(Error::Cast(result)); 629 FinalizeFailedLoad(Error::Cast(result));
660 } 630 }
661 } 631 }
662 632
663
664 void IsolateReloadContext::RegisterClass(const Class& new_cls) { 633 void IsolateReloadContext::RegisterClass(const Class& new_cls) {
665 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); 634 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls));
666 if (old_cls.IsNull()) { 635 if (old_cls.IsNull()) {
667 I->class_table()->Register(new_cls); 636 I->class_table()->Register(new_cls);
668 637
669 if (FLAG_identity_reload) { 638 if (FLAG_identity_reload) {
670 TIR_Print("Could not find replacement class for %s\n", 639 TIR_Print("Could not find replacement class for %s\n",
671 new_cls.ToCString()); 640 new_cls.ToCString());
672 UNREACHABLE(); 641 UNREACHABLE();
673 } 642 }
674 643
675 // New class maps to itself. 644 // New class maps to itself.
676 AddClassMapping(new_cls, new_cls); 645 AddClassMapping(new_cls, new_cls);
677 return; 646 return;
678 } 647 }
679 VTIR_Print("Registering class: %s\n", new_cls.ToCString()); 648 VTIR_Print("Registering class: %s\n", new_cls.ToCString());
680 new_cls.set_id(old_cls.id()); 649 new_cls.set_id(old_cls.id());
681 isolate()->class_table()->SetAt(old_cls.id(), new_cls.raw()); 650 isolate()->class_table()->SetAt(old_cls.id(), new_cls.raw());
682 if (!old_cls.is_enum_class()) { 651 if (!old_cls.is_enum_class()) {
683 new_cls.CopyCanonicalConstants(old_cls); 652 new_cls.CopyCanonicalConstants(old_cls);
684 } 653 }
685 new_cls.CopyCanonicalType(old_cls); 654 new_cls.CopyCanonicalType(old_cls);
686 AddBecomeMapping(old_cls, new_cls); 655 AddBecomeMapping(old_cls, new_cls);
687 AddClassMapping(new_cls, old_cls); 656 AddClassMapping(new_cls, old_cls);
688 } 657 }
689 658
690
691 // FinalizeLoading will be called *before* Reload() returns but will not be 659 // FinalizeLoading will be called *before* Reload() returns but will not be
692 // called if the embedder fails to load sources. 660 // called if the embedder fails to load sources.
693 void IsolateReloadContext::FinalizeLoading() { 661 void IsolateReloadContext::FinalizeLoading() {
694 if (reload_skipped_) { 662 if (reload_skipped_) {
695 return; 663 return;
696 } 664 }
697 ASSERT(!reload_finalized_); 665 ASSERT(!reload_finalized_);
698 BuildLibraryMapping(); 666 BuildLibraryMapping();
699 TIR_Print("---- LOAD SUCCEEDED\n"); 667 TIR_Print("---- LOAD SUCCEEDED\n");
700 if (ValidateReload()) { 668 if (ValidateReload()) {
701 Commit(); 669 Commit();
702 PostCommit(); 670 PostCommit();
703 isolate()->set_last_reload_timestamp(reload_timestamp_); 671 isolate()->set_last_reload_timestamp(reload_timestamp_);
704 } else { 672 } else {
705 ReportReasonsForCancelling(); 673 ReportReasonsForCancelling();
706 Rollback(); 674 Rollback();
707 } 675 }
708 // ValidateReload mutates the direct subclass information and does 676 // ValidateReload mutates the direct subclass information and does
709 // not remove dead subclasses. Rebuild the direct subclass 677 // not remove dead subclasses. Rebuild the direct subclass
710 // information from scratch. 678 // information from scratch.
711 RebuildDirectSubclasses(); 679 RebuildDirectSubclasses();
712 CommonFinalizeTail(); 680 CommonFinalizeTail();
713 } 681 }
714 682
715
716 // FinalizeFailedLoad will be called *before* Reload() returns and will only 683 // FinalizeFailedLoad will be called *before* Reload() returns and will only
717 // be called if the embedder fails to load sources. 684 // be called if the embedder fails to load sources.
718 void IsolateReloadContext::FinalizeFailedLoad(const Error& error) { 685 void IsolateReloadContext::FinalizeFailedLoad(const Error& error) {
719 TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n"); 686 TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n");
720 AddReasonForCancelling(new Aborted(zone_, error)); 687 AddReasonForCancelling(new Aborted(zone_, error));
721 ReportReasonsForCancelling(); 688 ReportReasonsForCancelling();
722 if (!reload_finalized_) { 689 if (!reload_finalized_) {
723 Rollback(); 690 Rollback();
724 } 691 }
725 CommonFinalizeTail(); 692 CommonFinalizeTail();
726 } 693 }
727 694
728
729 void IsolateReloadContext::CommonFinalizeTail() { 695 void IsolateReloadContext::CommonFinalizeTail() {
730 ReportOnJSON(js_); 696 ReportOnJSON(js_);
731 reload_finalized_ = true; 697 reload_finalized_ = true;
732 } 698 }
733 699
734
735 void IsolateReloadContext::ReportOnJSON(JSONStream* stream) { 700 void IsolateReloadContext::ReportOnJSON(JSONStream* stream) {
736 JSONObject jsobj(stream); 701 JSONObject jsobj(stream);
737 jsobj.AddProperty("type", "ReloadReport"); 702 jsobj.AddProperty("type", "ReloadReport");
738 jsobj.AddProperty("success", reload_skipped_ || !HasReasonsForCancelling()); 703 jsobj.AddProperty("success", reload_skipped_ || !HasReasonsForCancelling());
739 { 704 {
740 JSONObject details(&jsobj, "details"); 705 JSONObject details(&jsobj, "details");
741 if (reload_skipped_) { 706 if (reload_skipped_) {
742 // Reload was skipped. 707 // Reload was skipped.
743 const GrowableObjectArray& libs = 708 const GrowableObjectArray& libs =
744 GrowableObjectArray::Handle(object_store()->libraries()); 709 GrowableObjectArray::Handle(object_store()->libraries());
(...skipping 19 matching lines...) Expand all
764 details.AddProperty("loadedLibraryCount", loaded_library_count); 729 details.AddProperty("loadedLibraryCount", loaded_library_count);
765 details.AddProperty("finalLibraryCount", final_library_count); 730 details.AddProperty("finalLibraryCount", final_library_count);
766 JSONArray array(&jsobj, "shapeChangeMappings"); 731 JSONArray array(&jsobj, "shapeChangeMappings");
767 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { 732 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
768 instance_morphers_.At(i)->AppendTo(&array); 733 instance_morphers_.At(i)->AppendTo(&array);
769 } 734 }
770 } 735 }
771 } 736 }
772 } 737 }
773 738
774
775 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() { 739 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() {
776 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack); 740 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack);
777 StackFrameIterator it(StackFrameIterator::kDontValidateFrames, 741 StackFrameIterator it(StackFrameIterator::kDontValidateFrames,
778 Thread::Current(), 742 Thread::Current(),
779 StackFrameIterator::kNoCrossThreadIteration); 743 StackFrameIterator::kNoCrossThreadIteration);
780 744
781 Function& func = Function::Handle(); 745 Function& func = Function::Handle();
782 while (it.HasNextFrame()) { 746 while (it.HasNextFrame()) {
783 StackFrame* frame = it.NextFrame(); 747 StackFrame* frame = it.NextFrame();
784 if (frame->IsDartFrame()) { 748 if (frame->IsDartFrame()) {
785 func = frame->LookupDartFunction(); 749 func = frame->LookupDartFunction();
786 ASSERT(!func.IsNull()); 750 ASSERT(!func.IsNull());
787 func.EnsureHasCompiledUnoptimizedCode(); 751 func.EnsureHasCompiledUnoptimizedCode();
788 } 752 }
789 } 753 }
790 } 754 }
791 755
792
793 void IsolateReloadContext::DeoptimizeDependentCode() { 756 void IsolateReloadContext::DeoptimizeDependentCode() {
794 TIMELINE_SCOPE(DeoptimizeDependentCode); 757 TIMELINE_SCOPE(DeoptimizeDependentCode);
795 ClassTable* class_table = I->class_table(); 758 ClassTable* class_table = I->class_table();
796 759
797 const intptr_t bottom = Dart::vm_isolate()->class_table()->NumCids(); 760 const intptr_t bottom = Dart::vm_isolate()->class_table()->NumCids();
798 const intptr_t top = I->class_table()->NumCids(); 761 const intptr_t top = I->class_table()->NumCids();
799 Class& cls = Class::Handle(); 762 Class& cls = Class::Handle();
800 Array& fields = Array::Handle(); 763 Array& fields = Array::Handle();
801 Field& field = Field::Handle(); 764 Field& field = Field::Handle();
802 for (intptr_t cls_idx = bottom; cls_idx < top; cls_idx++) { 765 for (intptr_t cls_idx = bottom; cls_idx < top; cls_idx++) {
(...skipping 14 matching lines...) Expand all
817 for (intptr_t field_idx = 0; field_idx < fields.Length(); field_idx++) { 780 for (intptr_t field_idx = 0; field_idx < fields.Length(); field_idx++) {
818 field = Field::RawCast(fields.At(field_idx)); 781 field = Field::RawCast(fields.At(field_idx));
819 ASSERT(!field.IsNull()); 782 ASSERT(!field.IsNull());
820 field.DeoptimizeDependentCode(); 783 field.DeoptimizeDependentCode();
821 } 784 }
822 } 785 }
823 786
824 // TODO(johnmccutchan): Also call LibraryPrefix::InvalidateDependentCode. 787 // TODO(johnmccutchan): Also call LibraryPrefix::InvalidateDependentCode.
825 } 788 }
826 789
827
828 void IsolateReloadContext::CheckpointClasses() { 790 void IsolateReloadContext::CheckpointClasses() {
829 TIMELINE_SCOPE(CheckpointClasses); 791 TIMELINE_SCOPE(CheckpointClasses);
830 TIR_Print("---- CHECKPOINTING CLASSES\n"); 792 TIR_Print("---- CHECKPOINTING CLASSES\n");
831 // Checkpoint classes before a reload. We need to copy the following: 793 // Checkpoint classes before a reload. We need to copy the following:
832 // 1) The size of the class table. 794 // 1) The size of the class table.
833 // 2) The class table itself. 795 // 2) The class table itself.
834 // For efficiency, we build a set of classes before the reload. This set 796 // For efficiency, we build a set of classes before the reload. This set
835 // is used to pair new classes with old classes. 797 // is used to pair new classes with old classes.
836 798
837 ClassTable* class_table = I->class_table(); 799 ClassTable* class_table = I->class_table();
(...skipping 20 matching lines...) Expand all
858 // No class at this index, mark it as NULL. 820 // No class at this index, mark it as NULL.
859 local_saved_class_table[i] = NULL; 821 local_saved_class_table[i] = NULL;
860 } 822 }
861 } 823 }
862 old_classes_set_storage_ = old_classes_set.Release().raw(); 824 old_classes_set_storage_ = old_classes_set.Release().raw();
863 // Assigning the field must be done after saving the class table. 825 // Assigning the field must be done after saving the class table.
864 saved_class_table_ = local_saved_class_table; 826 saved_class_table_ = local_saved_class_table;
865 TIR_Print("---- System had %" Pd " classes\n", saved_num_cids_); 827 TIR_Print("---- System had %" Pd " classes\n", saved_num_cids_);
866 } 828 }
867 829
868
869 Dart_FileModifiedCallback IsolateReloadContext::file_modified_callback_ = NULL; 830 Dart_FileModifiedCallback IsolateReloadContext::file_modified_callback_ = NULL;
870 831
871
872 bool IsolateReloadContext::ScriptModifiedSince(const Script& script, 832 bool IsolateReloadContext::ScriptModifiedSince(const Script& script,
873 int64_t since) { 833 int64_t since) {
874 if (file_modified_callback_ == NULL) { 834 if (file_modified_callback_ == NULL) {
875 return true; 835 return true;
876 } 836 }
877 // We use the resolved url to determine if the script has been modified. 837 // We use the resolved url to determine if the script has been modified.
878 const String& url = String::Handle(script.resolved_url()); 838 const String& url = String::Handle(script.resolved_url());
879 const char* url_chars = url.ToCString(); 839 const char* url_chars = url.ToCString();
880 return (*file_modified_callback_)(url_chars, since); 840 return (*file_modified_callback_)(url_chars, since);
881 } 841 }
882 842
883
884 static void PropagateLibraryModified( 843 static void PropagateLibraryModified(
885 const ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by, 844 const ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by,
886 intptr_t lib_index, 845 intptr_t lib_index,
887 BitVector* modified_libs) { 846 BitVector* modified_libs) {
888 ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index]; 847 ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index];
889 for (intptr_t i = 0; i < dep_libs->length(); i++) { 848 for (intptr_t i = 0; i < dep_libs->length(); i++) {
890 intptr_t dep_lib_index = (*dep_libs)[i]; 849 intptr_t dep_lib_index = (*dep_libs)[i];
891 if (!modified_libs->Contains(dep_lib_index)) { 850 if (!modified_libs->Contains(dep_lib_index)) {
892 modified_libs->Add(dep_lib_index); 851 modified_libs->Add(dep_lib_index);
893 PropagateLibraryModified(imported_by, dep_lib_index, modified_libs); 852 PropagateLibraryModified(imported_by, dep_lib_index, modified_libs);
894 } 853 }
895 } 854 }
896 } 855 }
897 856
898
899 BitVector* IsolateReloadContext::FindModifiedLibraries(bool force_reload) { 857 BitVector* IsolateReloadContext::FindModifiedLibraries(bool force_reload) {
900 Thread* thread = Thread::Current(); 858 Thread* thread = Thread::Current();
901 int64_t last_reload = I->last_reload_timestamp(); 859 int64_t last_reload = I->last_reload_timestamp();
902 860
903 const GrowableObjectArray& libs = 861 const GrowableObjectArray& libs =
904 GrowableObjectArray::Handle(object_store()->libraries()); 862 GrowableObjectArray::Handle(object_store()->libraries());
905 Library& lib = Library::Handle(); 863 Library& lib = Library::Handle();
906 Array& scripts = Array::Handle(); 864 Array& scripts = Array::Handle();
907 Script& script = Script::Handle(); 865 Script& script = Script::Handle();
908 intptr_t num_libs = libs.Length(); 866 intptr_t num_libs = libs.Length();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 modified_libs->Add(lib_idx); 942 modified_libs->Add(lib_idx);
985 PropagateLibraryModified(imported_by, lib_idx, modified_libs); 943 PropagateLibraryModified(imported_by, lib_idx, modified_libs);
986 break; 944 break;
987 } 945 }
988 } 946 }
989 } 947 }
990 948
991 return modified_libs; 949 return modified_libs;
992 } 950 }
993 951
994
995 void IsolateReloadContext::CheckpointLibraries() { 952 void IsolateReloadContext::CheckpointLibraries() {
996 TIMELINE_SCOPE(CheckpointLibraries); 953 TIMELINE_SCOPE(CheckpointLibraries);
997 TIR_Print("---- CHECKPOINTING LIBRARIES\n"); 954 TIR_Print("---- CHECKPOINTING LIBRARIES\n");
998 // Save the root library in case we abort the reload. 955 // Save the root library in case we abort the reload.
999 const Library& root_lib = Library::Handle(object_store()->root_library()); 956 const Library& root_lib = Library::Handle(object_store()->root_library());
1000 set_saved_root_library(root_lib); 957 set_saved_root_library(root_lib);
1001 958
1002 // Save the old libraries array in case we abort the reload. 959 // Save the old libraries array in case we abort the reload.
1003 const GrowableObjectArray& libs = 960 const GrowableObjectArray& libs =
1004 GrowableObjectArray::Handle(object_store()->libraries()); 961 GrowableObjectArray::Handle(object_store()->libraries());
(...skipping 24 matching lines...) Expand all
1029 } 986 }
1030 modified_libs_ = NULL; // Renumbering the libraries has invalidated this. 987 modified_libs_ = NULL; // Renumbering the libraries has invalidated this.
1031 old_libraries_set_storage_ = old_libraries_set.Release().raw(); 988 old_libraries_set_storage_ = old_libraries_set.Release().raw();
1032 989
1033 // Reset the registered libraries to the filtered array. 990 // Reset the registered libraries to the filtered array.
1034 Library::RegisterLibraries(Thread::Current(), new_libs); 991 Library::RegisterLibraries(Thread::Current(), new_libs);
1035 // Reset the root library to null. 992 // Reset the root library to null.
1036 object_store()->set_root_library(Library::Handle()); 993 object_store()->set_root_library(Library::Handle());
1037 } 994 }
1038 995
1039
1040 // While reloading everything we do must be reversible so that we can abort 996 // While reloading everything we do must be reversible so that we can abort
1041 // safely if the reload fails. This function stashes things to the side and 997 // safely if the reload fails. This function stashes things to the side and
1042 // prepares the isolate for the reload attempt. 998 // prepares the isolate for the reload attempt.
1043 void IsolateReloadContext::Checkpoint() { 999 void IsolateReloadContext::Checkpoint() {
1044 TIMELINE_SCOPE(Checkpoint); 1000 TIMELINE_SCOPE(Checkpoint);
1045 CheckpointClasses(); 1001 CheckpointClasses();
1046 CheckpointLibraries(); 1002 CheckpointLibraries();
1047 } 1003 }
1048 1004
1049
1050 void IsolateReloadContext::RollbackClasses() { 1005 void IsolateReloadContext::RollbackClasses() {
1051 TIR_Print("---- ROLLING BACK CLASS TABLE\n"); 1006 TIR_Print("---- ROLLING BACK CLASS TABLE\n");
1052 ASSERT(saved_num_cids_ > 0); 1007 ASSERT(saved_num_cids_ > 0);
1053 ASSERT(saved_class_table_ != NULL); 1008 ASSERT(saved_class_table_ != NULL);
1054 ClassTable* class_table = I->class_table(); 1009 ClassTable* class_table = I->class_table();
1055 class_table->SetNumCids(saved_num_cids_); 1010 class_table->SetNumCids(saved_num_cids_);
1056 // Overwrite classes in class table with the saved classes. 1011 // Overwrite classes in class table with the saved classes.
1057 for (intptr_t i = 0; i < saved_num_cids_; i++) { 1012 for (intptr_t i = 0; i < saved_num_cids_; i++) {
1058 if (class_table->IsValidIndex(i)) { 1013 if (class_table->IsValidIndex(i)) {
1059 class_table->SetAt(i, saved_class_table_[i]); 1014 class_table->SetAt(i, saved_class_table_[i]);
1060 } 1015 }
1061 } 1016 }
1062 1017
1063 RawClass** local_saved_class_table = saved_class_table_; 1018 RawClass** local_saved_class_table = saved_class_table_;
1064 saved_class_table_ = NULL; 1019 saved_class_table_ = NULL;
1065 // Can't free this table immediately as another thread (e.g., the sweeper) may 1020 // Can't free this table immediately as another thread (e.g., the sweeper) may
1066 // be suspended between loading the table pointer and loading the table 1021 // be suspended between loading the table pointer and loading the table
1067 // element. Table will be freed at the next major GC or isolate shutdown. 1022 // element. Table will be freed at the next major GC or isolate shutdown.
1068 class_table->AddOldTable(local_saved_class_table); 1023 class_table->AddOldTable(local_saved_class_table);
1069 } 1024 }
1070 1025
1071
1072 void IsolateReloadContext::RollbackLibraries() { 1026 void IsolateReloadContext::RollbackLibraries() {
1073 TIR_Print("---- ROLLING BACK LIBRARY CHANGES\n"); 1027 TIR_Print("---- ROLLING BACK LIBRARY CHANGES\n");
1074 Thread* thread = Thread::Current(); 1028 Thread* thread = Thread::Current();
1075 Library& lib = Library::Handle(); 1029 Library& lib = Library::Handle();
1076 GrowableObjectArray& saved_libs = 1030 GrowableObjectArray& saved_libs =
1077 GrowableObjectArray::Handle(Z, saved_libraries()); 1031 GrowableObjectArray::Handle(Z, saved_libraries());
1078 if (!saved_libs.IsNull()) { 1032 if (!saved_libs.IsNull()) {
1079 for (intptr_t i = 0; i < saved_libs.Length(); i++) { 1033 for (intptr_t i = 0; i < saved_libs.Length(); i++) {
1080 lib = Library::RawCast(saved_libs.At(i)); 1034 lib = Library::RawCast(saved_libs.At(i));
1081 // Restore indexes that were modified in CheckpointLibraries. 1035 // Restore indexes that were modified in CheckpointLibraries.
1082 lib.set_index(i); 1036 lib.set_index(i);
1083 } 1037 }
1084 1038
1085 // Reset the registered libraries to the filtered array. 1039 // Reset the registered libraries to the filtered array.
1086 Library::RegisterLibraries(thread, saved_libs); 1040 Library::RegisterLibraries(thread, saved_libs);
1087 } 1041 }
1088 1042
1089 Library& saved_root_lib = Library::Handle(Z, saved_root_library()); 1043 Library& saved_root_lib = Library::Handle(Z, saved_root_library());
1090 if (!saved_root_lib.IsNull()) { 1044 if (!saved_root_lib.IsNull()) {
1091 object_store()->set_root_library(saved_root_lib); 1045 object_store()->set_root_library(saved_root_lib);
1092 } 1046 }
1093 1047
1094 set_saved_root_library(Library::Handle()); 1048 set_saved_root_library(Library::Handle());
1095 set_saved_libraries(GrowableObjectArray::Handle()); 1049 set_saved_libraries(GrowableObjectArray::Handle());
1096 } 1050 }
1097 1051
1098
1099 void IsolateReloadContext::Rollback() { 1052 void IsolateReloadContext::Rollback() {
1100 TIR_Print("---- ROLLING BACK"); 1053 TIR_Print("---- ROLLING BACK");
1101 RollbackClasses(); 1054 RollbackClasses();
1102 RollbackLibraries(); 1055 RollbackLibraries();
1103 } 1056 }
1104 1057
1105
1106 #ifdef DEBUG 1058 #ifdef DEBUG
1107 void IsolateReloadContext::VerifyMaps() { 1059 void IsolateReloadContext::VerifyMaps() {
1108 TIMELINE_SCOPE(VerifyMaps); 1060 TIMELINE_SCOPE(VerifyMaps);
1109 Class& cls = Class::Handle(); 1061 Class& cls = Class::Handle();
1110 Class& new_cls = Class::Handle(); 1062 Class& new_cls = Class::Handle();
1111 Class& cls2 = Class::Handle(); 1063 Class& cls2 = Class::Handle();
1112 1064
1113 // Verify that two old classes aren't both mapped to the same new 1065 // Verify that two old classes aren't both mapped to the same new
1114 // class. This could happen is the IsSameClass function is broken. 1066 // class. This could happen is the IsSameClass function is broken.
1115 UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_); 1067 UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_);
(...skipping 16 matching lines...) Expand all
1132 } 1084 }
1133 bool update = reverse_class_map.UpdateOrInsert(cls, new_cls); 1085 bool update = reverse_class_map.UpdateOrInsert(cls, new_cls);
1134 ASSERT(!update); 1086 ASSERT(!update);
1135 } 1087 }
1136 } 1088 }
1137 class_map.Release(); 1089 class_map.Release();
1138 reverse_class_map.Release(); 1090 reverse_class_map.Release();
1139 } 1091 }
1140 #endif 1092 #endif
1141 1093
1142
1143 void IsolateReloadContext::Commit() { 1094 void IsolateReloadContext::Commit() {
1144 TIMELINE_SCOPE(Commit); 1095 TIMELINE_SCOPE(Commit);
1145 TIR_Print("---- COMMITTING RELOAD\n"); 1096 TIR_Print("---- COMMITTING RELOAD\n");
1146 1097
1147 // Note that the object heap contains before and after instances 1098 // Note that the object heap contains before and after instances
1148 // used for morphing. It is therefore important that morphing takes 1099 // used for morphing. It is therefore important that morphing takes
1149 // place prior to any heap walking. 1100 // place prior to any heap walking.
1150 // So please keep this code at the top of Commit(). 1101 // So please keep this code at the top of Commit().
1151 if (HasInstanceMorphers()) { 1102 if (HasInstanceMorphers()) {
1152 // Perform shape shifting of instances if necessary. 1103 // Perform shape shifting of instances if necessary.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 #ifdef DEBUG 1251 #ifdef DEBUG
1301 // Verify that all canonical instances are correctly setup in the 1252 // Verify that all canonical instances are correctly setup in the
1302 // corresponding canonical tables. 1253 // corresponding canonical tables.
1303 Thread* thread = Thread::Current(); 1254 Thread* thread = Thread::Current();
1304 I->heap()->CollectAllGarbage(); 1255 I->heap()->CollectAllGarbage();
1305 VerifyCanonicalVisitor check_canonical(thread); 1256 VerifyCanonicalVisitor check_canonical(thread);
1306 I->heap()->IterateObjects(&check_canonical); 1257 I->heap()->IterateObjects(&check_canonical);
1307 #endif // DEBUG 1258 #endif // DEBUG
1308 } 1259 }
1309 1260
1310
1311 void IsolateReloadContext::RehashConstants() { 1261 void IsolateReloadContext::RehashConstants() {
1312 TIMELINE_SCOPE(RehashConstants); 1262 TIMELINE_SCOPE(RehashConstants);
1313 ClassTable* class_table = I->class_table(); 1263 ClassTable* class_table = I->class_table();
1314 Class& cls = Class::Handle(zone_); 1264 Class& cls = Class::Handle(zone_);
1315 const intptr_t top = class_table->NumCids(); 1265 const intptr_t top = class_table->NumCids();
1316 for (intptr_t cid = kInstanceCid; cid < top; cid++) { 1266 for (intptr_t cid = kInstanceCid; cid < top; cid++) {
1317 if (!class_table->IsValidIndex(cid) || !class_table->HasValidClassAt(cid)) { 1267 if (!class_table->IsValidIndex(cid) || !class_table->HasValidClassAt(cid)) {
1318 // Skip invalid classes. 1268 // Skip invalid classes.
1319 continue; 1269 continue;
1320 } 1270 }
1321 if (RawObject::IsNumberClassId(cid) || RawObject::IsStringClassId(cid)) { 1271 if (RawObject::IsNumberClassId(cid) || RawObject::IsStringClassId(cid)) {
1322 // Skip classes that cannot be affected by the 'become' operation. 1272 // Skip classes that cannot be affected by the 'become' operation.
1323 continue; 1273 continue;
1324 } 1274 }
1325 // Rehash constants. 1275 // Rehash constants.
1326 cls = class_table->At(cid); 1276 cls = class_table->At(cid);
1327 VTIR_Print("Rehashing constants in class `%s`\n", cls.ToCString()); 1277 VTIR_Print("Rehashing constants in class `%s`\n", cls.ToCString());
1328 cls.RehashConstants(zone_); 1278 cls.RehashConstants(zone_);
1329 } 1279 }
1330 } 1280 }
1331 1281
1332
1333 bool IsolateReloadContext::IsDirty(const Library& lib) { 1282 bool IsolateReloadContext::IsDirty(const Library& lib) {
1334 const intptr_t index = lib.index(); 1283 const intptr_t index = lib.index();
1335 if (index == static_cast<classid_t>(-1)) { 1284 if (index == static_cast<classid_t>(-1)) {
1336 // Treat deleted libraries as dirty. 1285 // Treat deleted libraries as dirty.
1337 return true; 1286 return true;
1338 } 1287 }
1339 ASSERT((index >= 0) && (index < library_infos_.length())); 1288 ASSERT((index >= 0) && (index < library_infos_.length()));
1340 return library_infos_[index].dirty; 1289 return library_infos_[index].dirty;
1341 } 1290 }
1342 1291
1343
1344 void IsolateReloadContext::PostCommit() { 1292 void IsolateReloadContext::PostCommit() {
1345 TIMELINE_SCOPE(PostCommit); 1293 TIMELINE_SCOPE(PostCommit);
1346 set_saved_root_library(Library::Handle()); 1294 set_saved_root_library(Library::Handle());
1347 set_saved_libraries(GrowableObjectArray::Handle()); 1295 set_saved_libraries(GrowableObjectArray::Handle());
1348 InvalidateWorld(); 1296 InvalidateWorld();
1349 TIR_Print("---- DONE COMMIT\n"); 1297 TIR_Print("---- DONE COMMIT\n");
1350 } 1298 }
1351 1299
1352
1353 void IsolateReloadContext::AddReasonForCancelling(ReasonForCancelling* reason) { 1300 void IsolateReloadContext::AddReasonForCancelling(ReasonForCancelling* reason) {
1354 reload_aborted_ = true; 1301 reload_aborted_ = true;
1355 reasons_to_cancel_reload_.Add(reason); 1302 reasons_to_cancel_reload_.Add(reason);
1356 } 1303 }
1357 1304
1358
1359 void IsolateReloadContext::AddInstanceMorpher(InstanceMorpher* morpher) { 1305 void IsolateReloadContext::AddInstanceMorpher(InstanceMorpher* morpher) {
1360 instance_morphers_.Add(morpher); 1306 instance_morphers_.Add(morpher);
1361 cid_mapper_.Insert(morpher); 1307 cid_mapper_.Insert(morpher);
1362 } 1308 }
1363 1309
1364
1365 void IsolateReloadContext::ReportReasonsForCancelling() { 1310 void IsolateReloadContext::ReportReasonsForCancelling() {
1366 ASSERT(FLAG_reload_force_rollback || HasReasonsForCancelling()); 1311 ASSERT(FLAG_reload_force_rollback || HasReasonsForCancelling());
1367 for (int i = 0; i < reasons_to_cancel_reload_.length(); i++) { 1312 for (int i = 0; i < reasons_to_cancel_reload_.length(); i++) {
1368 reasons_to_cancel_reload_.At(i)->Report(this); 1313 reasons_to_cancel_reload_.At(i)->Report(this);
1369 } 1314 }
1370 } 1315 }
1371 1316
1372
1373 // The ObjectLocator is used for collecting instances that 1317 // The ObjectLocator is used for collecting instances that
1374 // needs to be morphed. 1318 // needs to be morphed.
1375 class ObjectLocator : public ObjectVisitor { 1319 class ObjectLocator : public ObjectVisitor {
1376 public: 1320 public:
1377 explicit ObjectLocator(IsolateReloadContext* context) 1321 explicit ObjectLocator(IsolateReloadContext* context)
1378 : context_(context), count_(0) {} 1322 : context_(context), count_(0) {}
1379 1323
1380 void VisitObject(RawObject* obj) { 1324 void VisitObject(RawObject* obj) {
1381 InstanceMorpher* morpher = 1325 InstanceMorpher* morpher =
1382 context_->cid_mapper_.LookupValue(obj->GetClassId()); 1326 context_->cid_mapper_.LookupValue(obj->GetClassId());
1383 if (morpher != NULL) { 1327 if (morpher != NULL) {
1384 morpher->AddObject(obj); 1328 morpher->AddObject(obj);
1385 count_++; 1329 count_++;
1386 } 1330 }
1387 } 1331 }
1388 1332
1389 // Return the number of located objects for morphing. 1333 // Return the number of located objects for morphing.
1390 intptr_t count() { return count_; } 1334 intptr_t count() { return count_; }
1391 1335
1392 private: 1336 private:
1393 IsolateReloadContext* context_; 1337 IsolateReloadContext* context_;
1394 intptr_t count_; 1338 intptr_t count_;
1395 }; 1339 };
1396 1340
1397
1398 void IsolateReloadContext::MorphInstances() { 1341 void IsolateReloadContext::MorphInstances() {
1399 TIMELINE_SCOPE(MorphInstances); 1342 TIMELINE_SCOPE(MorphInstances);
1400 ASSERT(HasInstanceMorphers()); 1343 ASSERT(HasInstanceMorphers());
1401 if (FLAG_trace_reload) { 1344 if (FLAG_trace_reload) {
1402 LogBlock blocker; 1345 LogBlock blocker;
1403 TIR_Print("MorphInstance: \n"); 1346 TIR_Print("MorphInstance: \n");
1404 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { 1347 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
1405 instance_morphers_.At(i)->Dump(); 1348 instance_morphers_.At(i)->Dump();
1406 } 1349 }
1407 } 1350 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 } 1384 }
1442 1385
1443 // This is important: The saved class table (describing before objects) 1386 // This is important: The saved class table (describing before objects)
1444 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt. 1387 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt.
1445 // Instance will from now be described by the isolate's class table. 1388 // Instance will from now be described by the isolate's class table.
1446 free(saved_class_table_); 1389 free(saved_class_table_);
1447 saved_class_table_ = NULL; 1390 saved_class_table_ = NULL;
1448 Become::ElementsForwardIdentity(before, after); 1391 Become::ElementsForwardIdentity(before, after);
1449 } 1392 }
1450 1393
1451
1452 void IsolateReloadContext::RunNewFieldInitializers() { 1394 void IsolateReloadContext::RunNewFieldInitializers() {
1453 // Run new field initializers on all instances. 1395 // Run new field initializers on all instances.
1454 for (intptr_t i = 0; i < instance_morphers_.length(); i++) { 1396 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
1455 instance_morphers_.At(i)->RunNewFieldInitializers(); 1397 instance_morphers_.At(i)->RunNewFieldInitializers();
1456 } 1398 }
1457 } 1399 }
1458 1400
1459
1460 bool IsolateReloadContext::ValidateReload() { 1401 bool IsolateReloadContext::ValidateReload() {
1461 TIMELINE_SCOPE(ValidateReload); 1402 TIMELINE_SCOPE(ValidateReload);
1462 if (reload_aborted()) return false; 1403 if (reload_aborted()) return false;
1463 1404
1464 TIR_Print("---- VALIDATING RELOAD\n"); 1405 TIR_Print("---- VALIDATING RELOAD\n");
1465 1406
1466 // Validate libraries. 1407 // Validate libraries.
1467 { 1408 {
1468 ASSERT(library_map_storage_ != Array::null()); 1409 ASSERT(library_map_storage_ != Array::null());
1469 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); 1410 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_);
(...skipping 25 matching lines...) Expand all
1495 if (new_cls.raw() != cls.raw()) { 1436 if (new_cls.raw() != cls.raw()) {
1496 cls.CheckReload(new_cls, this); 1437 cls.CheckReload(new_cls, this);
1497 } 1438 }
1498 } 1439 }
1499 map.Release(); 1440 map.Release();
1500 } 1441 }
1501 1442
1502 return !FLAG_reload_force_rollback && !HasReasonsForCancelling(); 1443 return !FLAG_reload_force_rollback && !HasReasonsForCancelling();
1503 } 1444 }
1504 1445
1505
1506 RawClass* IsolateReloadContext::FindOriginalClass(const Class& cls) { 1446 RawClass* IsolateReloadContext::FindOriginalClass(const Class& cls) {
1507 return MappedClass(cls); 1447 return MappedClass(cls);
1508 } 1448 }
1509 1449
1510
1511 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) { 1450 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
1512 RawClass** class_table = AtomicOperations::LoadRelaxed(&saved_class_table_); 1451 RawClass** class_table = AtomicOperations::LoadRelaxed(&saved_class_table_);
1513 if (class_table != NULL) { 1452 if (class_table != NULL) {
1514 ASSERT(cid > 0); 1453 ASSERT(cid > 0);
1515 ASSERT(cid < saved_num_cids_); 1454 ASSERT(cid < saved_num_cids_);
1516 return class_table[cid]; 1455 return class_table[cid];
1517 } else { 1456 } else {
1518 return isolate_->class_table()->At(cid); 1457 return isolate_->class_table()->At(cid);
1519 } 1458 }
1520 } 1459 }
1521 1460
1522
1523 RawLibrary* IsolateReloadContext::saved_root_library() const { 1461 RawLibrary* IsolateReloadContext::saved_root_library() const {
1524 return saved_root_library_; 1462 return saved_root_library_;
1525 } 1463 }
1526 1464
1527
1528 void IsolateReloadContext::set_saved_root_library(const Library& value) { 1465 void IsolateReloadContext::set_saved_root_library(const Library& value) {
1529 saved_root_library_ = value.raw(); 1466 saved_root_library_ = value.raw();
1530 } 1467 }
1531 1468
1532
1533 RawGrowableObjectArray* IsolateReloadContext::saved_libraries() const { 1469 RawGrowableObjectArray* IsolateReloadContext::saved_libraries() const {
1534 return saved_libraries_; 1470 return saved_libraries_;
1535 } 1471 }
1536 1472
1537
1538 void IsolateReloadContext::set_saved_libraries( 1473 void IsolateReloadContext::set_saved_libraries(
1539 const GrowableObjectArray& value) { 1474 const GrowableObjectArray& value) {
1540 saved_libraries_ = value.raw(); 1475 saved_libraries_ = value.raw();
1541 } 1476 }
1542 1477
1543
1544 void IsolateReloadContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { 1478 void IsolateReloadContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
1545 visitor->VisitPointers(from(), to()); 1479 visitor->VisitPointers(from(), to());
1546 if (saved_class_table_ != NULL) { 1480 if (saved_class_table_ != NULL) {
1547 visitor->VisitPointers( 1481 visitor->VisitPointers(
1548 reinterpret_cast<RawObject**>(&saved_class_table_[0]), saved_num_cids_); 1482 reinterpret_cast<RawObject**>(&saved_class_table_[0]), saved_num_cids_);
1549 } 1483 }
1550 } 1484 }
1551 1485
1552
1553 ObjectStore* IsolateReloadContext::object_store() { 1486 ObjectStore* IsolateReloadContext::object_store() {
1554 return isolate_->object_store(); 1487 return isolate_->object_store();
1555 } 1488 }
1556 1489
1557
1558 void IsolateReloadContext::ResetUnoptimizedICsOnStack() { 1490 void IsolateReloadContext::ResetUnoptimizedICsOnStack() {
1559 Thread* thread = Thread::Current(); 1491 Thread* thread = Thread::Current();
1560 StackZone stack_zone(thread); 1492 StackZone stack_zone(thread);
1561 Zone* zone = stack_zone.GetZone(); 1493 Zone* zone = stack_zone.GetZone();
1562 1494
1563 Code& code = Code::Handle(zone); 1495 Code& code = Code::Handle(zone);
1564 Function& function = Function::Handle(zone); 1496 Function& function = Function::Handle(zone);
1565 DartFrameIterator iterator(thread, 1497 DartFrameIterator iterator(thread,
1566 StackFrameIterator::kNoCrossThreadIteration); 1498 StackFrameIterator::kNoCrossThreadIteration);
1567 StackFrame* frame = iterator.NextFrame(); 1499 StackFrame* frame = iterator.NextFrame();
1568 while (frame != NULL) { 1500 while (frame != NULL) {
1569 code = frame->LookupDartCode(); 1501 code = frame->LookupDartCode();
1570 if (code.is_optimized()) { 1502 if (code.is_optimized()) {
1571 // If this code is optimized, we need to reset the ICs in the 1503 // If this code is optimized, we need to reset the ICs in the
1572 // corresponding unoptimized code, which will be executed when the stack 1504 // corresponding unoptimized code, which will be executed when the stack
1573 // unwinds to the optimized code. 1505 // unwinds to the optimized code.
1574 function = code.function(); 1506 function = code.function();
1575 code = function.unoptimized_code(); 1507 code = function.unoptimized_code();
1576 ASSERT(!code.IsNull()); 1508 ASSERT(!code.IsNull());
1577 code.ResetICDatas(zone); 1509 code.ResetICDatas(zone);
1578 } else { 1510 } else {
1579 code.ResetICDatas(zone); 1511 code.ResetICDatas(zone);
1580 } 1512 }
1581 frame = iterator.NextFrame(); 1513 frame = iterator.NextFrame();
1582 } 1514 }
1583 } 1515 }
1584 1516
1585
1586 void IsolateReloadContext::ResetMegamorphicCaches() { 1517 void IsolateReloadContext::ResetMegamorphicCaches() {
1587 object_store()->set_megamorphic_cache_table(GrowableObjectArray::Handle()); 1518 object_store()->set_megamorphic_cache_table(GrowableObjectArray::Handle());
1588 // Since any current optimized code will not make any more calls, it may be 1519 // Since any current optimized code will not make any more calls, it may be
1589 // better to clear the table instead of clearing each of the caches, allow 1520 // better to clear the table instead of clearing each of the caches, allow
1590 // the current megamorphic caches get GC'd and any new optimized code allocate 1521 // the current megamorphic caches get GC'd and any new optimized code allocate
1591 // new ones. 1522 // new ones.
1592 } 1523 }
1593 1524
1594
1595 class MarkFunctionsForRecompilation : public ObjectVisitor { 1525 class MarkFunctionsForRecompilation : public ObjectVisitor {
1596 public: 1526 public:
1597 MarkFunctionsForRecompilation(Isolate* isolate, 1527 MarkFunctionsForRecompilation(Isolate* isolate,
1598 IsolateReloadContext* reload_context, 1528 IsolateReloadContext* reload_context,
1599 Zone* zone) 1529 Zone* zone)
1600 : ObjectVisitor(), 1530 : ObjectVisitor(),
1601 handle_(Object::Handle(zone)), 1531 handle_(Object::Handle(zone)),
1602 owning_class_(Class::Handle(zone)), 1532 owning_class_(Class::Handle(zone)),
1603 owning_lib_(Library::Handle(zone)), 1533 owning_lib_(Library::Handle(zone)),
1604 code_(Code::Handle(zone)), 1534 code_(Code::Handle(zone)),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 } 1599 }
1670 1600
1671 Object& handle_; 1601 Object& handle_;
1672 Class& owning_class_; 1602 Class& owning_class_;
1673 Library& owning_lib_; 1603 Library& owning_lib_;
1674 Code& code_; 1604 Code& code_;
1675 IsolateReloadContext* reload_context_; 1605 IsolateReloadContext* reload_context_;
1676 Zone* zone_; 1606 Zone* zone_;
1677 }; 1607 };
1678 1608
1679
1680 void IsolateReloadContext::MarkAllFunctionsForRecompilation() { 1609 void IsolateReloadContext::MarkAllFunctionsForRecompilation() {
1681 TIMELINE_SCOPE(MarkAllFunctionsForRecompilation); 1610 TIMELINE_SCOPE(MarkAllFunctionsForRecompilation);
1682 TIR_Print("---- MARKING ALL FUNCTIONS FOR RECOMPILATION\n"); 1611 TIR_Print("---- MARKING ALL FUNCTIONS FOR RECOMPILATION\n");
1683 Thread* thread = Thread::Current(); 1612 Thread* thread = Thread::Current();
1684 StackZone stack_zone(thread); 1613 StackZone stack_zone(thread);
1685 Zone* zone = stack_zone.GetZone(); 1614 Zone* zone = stack_zone.GetZone();
1686 NoSafepointScope no_safepoint; 1615 NoSafepointScope no_safepoint;
1687 HeapIterationScope heap_iteration_scope; 1616 HeapIterationScope heap_iteration_scope;
1688 MarkFunctionsForRecompilation visitor(isolate_, this, zone); 1617 MarkFunctionsForRecompilation visitor(isolate_, this, zone);
1689 isolate_->heap()->VisitObjects(&visitor); 1618 isolate_->heap()->VisitObjects(&visitor);
1690 } 1619 }
1691 1620
1692
1693 void IsolateReloadContext::InvalidateWorld() { 1621 void IsolateReloadContext::InvalidateWorld() {
1694 TIR_Print("---- INVALIDATING WORLD\n"); 1622 TIR_Print("---- INVALIDATING WORLD\n");
1695 ResetMegamorphicCaches(); 1623 ResetMegamorphicCaches();
1696 DeoptimizeFunctionsOnStack(); 1624 DeoptimizeFunctionsOnStack();
1697 ResetUnoptimizedICsOnStack(); 1625 ResetUnoptimizedICsOnStack();
1698 MarkAllFunctionsForRecompilation(); 1626 MarkAllFunctionsForRecompilation();
1699 } 1627 }
1700 1628
1701
1702 RawClass* IsolateReloadContext::MappedClass(const Class& replacement_or_new) { 1629 RawClass* IsolateReloadContext::MappedClass(const Class& replacement_or_new) {
1703 UnorderedHashMap<ClassMapTraits> map(class_map_storage_); 1630 UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
1704 Class& cls = Class::Handle(); 1631 Class& cls = Class::Handle();
1705 cls ^= map.GetOrNull(replacement_or_new); 1632 cls ^= map.GetOrNull(replacement_or_new);
1706 // No need to update storage address because no mutation occurred. 1633 // No need to update storage address because no mutation occurred.
1707 map.Release(); 1634 map.Release();
1708 return cls.raw(); 1635 return cls.raw();
1709 } 1636 }
1710 1637
1711
1712 RawLibrary* IsolateReloadContext::MappedLibrary( 1638 RawLibrary* IsolateReloadContext::MappedLibrary(
1713 const Library& replacement_or_new) { 1639 const Library& replacement_or_new) {
1714 return Library::null(); 1640 return Library::null();
1715 } 1641 }
1716 1642
1717
1718 RawClass* IsolateReloadContext::OldClassOrNull( 1643 RawClass* IsolateReloadContext::OldClassOrNull(
1719 const Class& replacement_or_new) { 1644 const Class& replacement_or_new) {
1720 UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_); 1645 UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_);
1721 Class& cls = Class::Handle(); 1646 Class& cls = Class::Handle();
1722 cls ^= old_classes_set.GetOrNull(replacement_or_new); 1647 cls ^= old_classes_set.GetOrNull(replacement_or_new);
1723 old_classes_set_storage_ = old_classes_set.Release().raw(); 1648 old_classes_set_storage_ = old_classes_set.Release().raw();
1724 return cls.raw(); 1649 return cls.raw();
1725 } 1650 }
1726 1651
1727
1728 RawString* IsolateReloadContext::FindLibraryPrivateKey( 1652 RawString* IsolateReloadContext::FindLibraryPrivateKey(
1729 const Library& replacement_or_new) { 1653 const Library& replacement_or_new) {
1730 const Library& old = Library::Handle(OldLibraryOrNull(replacement_or_new)); 1654 const Library& old = Library::Handle(OldLibraryOrNull(replacement_or_new));
1731 if (old.IsNull()) { 1655 if (old.IsNull()) {
1732 return String::null(); 1656 return String::null();
1733 } 1657 }
1734 #if defined(DEBUG) 1658 #if defined(DEBUG)
1735 VTIR_Print("`%s` is getting `%s`'s private key.\n", 1659 VTIR_Print("`%s` is getting `%s`'s private key.\n",
1736 String::Handle(replacement_or_new.url()).ToCString(), 1660 String::Handle(replacement_or_new.url()).ToCString(),
1737 String::Handle(old.url()).ToCString()); 1661 String::Handle(old.url()).ToCString());
1738 #endif 1662 #endif
1739 return old.private_key(); 1663 return old.private_key();
1740 } 1664 }
1741 1665
1742
1743 RawLibrary* IsolateReloadContext::OldLibraryOrNull( 1666 RawLibrary* IsolateReloadContext::OldLibraryOrNull(
1744 const Library& replacement_or_new) { 1667 const Library& replacement_or_new) {
1745 UnorderedHashSet<LibraryMapTraits> old_libraries_set( 1668 UnorderedHashSet<LibraryMapTraits> old_libraries_set(
1746 old_libraries_set_storage_); 1669 old_libraries_set_storage_);
1747 Library& lib = Library::Handle(); 1670 Library& lib = Library::Handle();
1748 lib ^= old_libraries_set.GetOrNull(replacement_or_new); 1671 lib ^= old_libraries_set.GetOrNull(replacement_or_new);
1749 old_libraries_set.Release(); 1672 old_libraries_set.Release();
1750 if (lib.IsNull() && (root_url_prefix_ != String::null()) && 1673 if (lib.IsNull() && (root_url_prefix_ != String::null()) &&
1751 (old_root_url_prefix_ != String::null())) { 1674 (old_root_url_prefix_ != String::null())) {
1752 return OldLibraryOrNullBaseMoved(replacement_or_new); 1675 return OldLibraryOrNullBaseMoved(replacement_or_new);
1753 } 1676 }
1754 return lib.raw(); 1677 return lib.raw();
1755 } 1678 }
1756 1679
1757
1758 // Attempt to find the pair to |replacement_or_new| with the knowledge that 1680 // Attempt to find the pair to |replacement_or_new| with the knowledge that
1759 // the base url prefix has moved. 1681 // the base url prefix has moved.
1760 RawLibrary* IsolateReloadContext::OldLibraryOrNullBaseMoved( 1682 RawLibrary* IsolateReloadContext::OldLibraryOrNullBaseMoved(
1761 const Library& replacement_or_new) { 1683 const Library& replacement_or_new) {
1762 const String& url_prefix = String::Handle(root_url_prefix_); 1684 const String& url_prefix = String::Handle(root_url_prefix_);
1763 const String& old_url_prefix = String::Handle(old_root_url_prefix_); 1685 const String& old_url_prefix = String::Handle(old_root_url_prefix_);
1764 const intptr_t prefix_length = url_prefix.Length(); 1686 const intptr_t prefix_length = url_prefix.Length();
1765 const intptr_t old_prefix_length = old_url_prefix.Length(); 1687 const intptr_t old_prefix_length = old_url_prefix.Length();
1766 const String& new_url = String::Handle(replacement_or_new.url()); 1688 const String& new_url = String::Handle(replacement_or_new.url());
1767 const String& suffix = 1689 const String& suffix =
(...skipping 19 matching lines...) Expand all
1787 } 1709 }
1788 if (old_suffix.Equals(suffix)) { 1710 if (old_suffix.Equals(suffix)) {
1789 TIR_Print("`%s` is moving to `%s`\n", old_url.ToCString(), 1711 TIR_Print("`%s` is moving to `%s`\n", old_url.ToCString(),
1790 new_url.ToCString()); 1712 new_url.ToCString());
1791 return old.raw(); 1713 return old.raw();
1792 } 1714 }
1793 } 1715 }
1794 return Library::null(); 1716 return Library::null();
1795 } 1717 }
1796 1718
1797
1798 void IsolateReloadContext::BuildLibraryMapping() { 1719 void IsolateReloadContext::BuildLibraryMapping() {
1799 const GrowableObjectArray& libs = 1720 const GrowableObjectArray& libs =
1800 GrowableObjectArray::Handle(object_store()->libraries()); 1721 GrowableObjectArray::Handle(object_store()->libraries());
1801 1722
1802 Library& replacement_or_new = Library::Handle(); 1723 Library& replacement_or_new = Library::Handle();
1803 Library& old = Library::Handle(); 1724 Library& old = Library::Handle();
1804 for (intptr_t i = num_saved_libs_; i < libs.Length(); i++) { 1725 for (intptr_t i = num_saved_libs_; i < libs.Length(); i++) {
1805 replacement_or_new = Library::RawCast(libs.At(i)); 1726 replacement_or_new = Library::RawCast(libs.At(i));
1806 old ^= OldLibraryOrNull(replacement_or_new); 1727 old ^= OldLibraryOrNull(replacement_or_new);
1807 if (old.IsNull()) { 1728 if (old.IsNull()) {
1808 if (FLAG_identity_reload) { 1729 if (FLAG_identity_reload) {
1809 TIR_Print("Could not find original library for %s\n", 1730 TIR_Print("Could not find original library for %s\n",
1810 replacement_or_new.ToCString()); 1731 replacement_or_new.ToCString());
1811 UNREACHABLE(); 1732 UNREACHABLE();
1812 } 1733 }
1813 // New library. 1734 // New library.
1814 AddLibraryMapping(replacement_or_new, replacement_or_new); 1735 AddLibraryMapping(replacement_or_new, replacement_or_new);
1815 } else { 1736 } else {
1816 ASSERT(!replacement_or_new.is_dart_scheme()); 1737 ASSERT(!replacement_or_new.is_dart_scheme());
1817 // Replaced class. 1738 // Replaced class.
1818 AddLibraryMapping(replacement_or_new, old); 1739 AddLibraryMapping(replacement_or_new, old);
1819 1740
1820 AddBecomeMapping(old, replacement_or_new); 1741 AddBecomeMapping(old, replacement_or_new);
1821 } 1742 }
1822 } 1743 }
1823 } 1744 }
1824 1745
1825
1826 void IsolateReloadContext::AddClassMapping(const Class& replacement_or_new, 1746 void IsolateReloadContext::AddClassMapping(const Class& replacement_or_new,
1827 const Class& original) { 1747 const Class& original) {
1828 UnorderedHashMap<ClassMapTraits> map(class_map_storage_); 1748 UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
1829 bool update = map.UpdateOrInsert(replacement_or_new, original); 1749 bool update = map.UpdateOrInsert(replacement_or_new, original);
1830 ASSERT(!update); 1750 ASSERT(!update);
1831 // The storage given to the map may have been reallocated, remember the new 1751 // The storage given to the map may have been reallocated, remember the new
1832 // address. 1752 // address.
1833 class_map_storage_ = map.Release().raw(); 1753 class_map_storage_ = map.Release().raw();
1834 } 1754 }
1835 1755
1836
1837 void IsolateReloadContext::AddLibraryMapping(const Library& replacement_or_new, 1756 void IsolateReloadContext::AddLibraryMapping(const Library& replacement_or_new,
1838 const Library& original) { 1757 const Library& original) {
1839 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); 1758 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_);
1840 bool update = map.UpdateOrInsert(replacement_or_new, original); 1759 bool update = map.UpdateOrInsert(replacement_or_new, original);
1841 ASSERT(!update); 1760 ASSERT(!update);
1842 // The storage given to the map may have been reallocated, remember the new 1761 // The storage given to the map may have been reallocated, remember the new
1843 // address. 1762 // address.
1844 library_map_storage_ = map.Release().raw(); 1763 library_map_storage_ = map.Release().raw();
1845 } 1764 }
1846 1765
1847
1848 void IsolateReloadContext::AddStaticFieldMapping(const Field& old_field, 1766 void IsolateReloadContext::AddStaticFieldMapping(const Field& old_field,
1849 const Field& new_field) { 1767 const Field& new_field) {
1850 ASSERT(old_field.is_static()); 1768 ASSERT(old_field.is_static());
1851 ASSERT(new_field.is_static()); 1769 ASSERT(new_field.is_static());
1852 1770
1853 AddBecomeMapping(old_field, new_field); 1771 AddBecomeMapping(old_field, new_field);
1854 } 1772 }
1855 1773
1856
1857 void IsolateReloadContext::AddBecomeMapping(const Object& old, 1774 void IsolateReloadContext::AddBecomeMapping(const Object& old,
1858 const Object& neu) { 1775 const Object& neu) {
1859 ASSERT(become_map_storage_ != Array::null()); 1776 ASSERT(become_map_storage_ != Array::null());
1860 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_); 1777 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_);
1861 bool update = become_map.UpdateOrInsert(old, neu); 1778 bool update = become_map.UpdateOrInsert(old, neu);
1862 ASSERT(!update); 1779 ASSERT(!update);
1863 become_map_storage_ = become_map.Release().raw(); 1780 become_map_storage_ = become_map.Release().raw();
1864 } 1781 }
1865 1782
1866
1867 void IsolateReloadContext::AddEnumBecomeMapping(const Object& old, 1783 void IsolateReloadContext::AddEnumBecomeMapping(const Object& old,
1868 const Object& neu) { 1784 const Object& neu) {
1869 const GrowableObjectArray& become_enum_mappings = 1785 const GrowableObjectArray& become_enum_mappings =
1870 GrowableObjectArray::Handle(become_enum_mappings_); 1786 GrowableObjectArray::Handle(become_enum_mappings_);
1871 become_enum_mappings.Add(old); 1787 become_enum_mappings.Add(old);
1872 become_enum_mappings.Add(neu); 1788 become_enum_mappings.Add(neu);
1873 ASSERT((become_enum_mappings.Length() % 2) == 0); 1789 ASSERT((become_enum_mappings.Length() % 2) == 0);
1874 } 1790 }
1875 1791
1876
1877 void IsolateReloadContext::RebuildDirectSubclasses() { 1792 void IsolateReloadContext::RebuildDirectSubclasses() {
1878 ClassTable* class_table = I->class_table(); 1793 ClassTable* class_table = I->class_table();
1879 intptr_t num_cids = class_table->NumCids(); 1794 intptr_t num_cids = class_table->NumCids();
1880 1795
1881 // Clear the direct subclasses for all classes. 1796 // Clear the direct subclasses for all classes.
1882 Class& cls = Class::Handle(); 1797 Class& cls = Class::Handle();
1883 GrowableObjectArray& subclasses = GrowableObjectArray::Handle(); 1798 GrowableObjectArray& subclasses = GrowableObjectArray::Handle();
1884 for (intptr_t i = 1; i < num_cids; i++) { 1799 for (intptr_t i = 1; i < num_cids; i++) {
1885 if (class_table->HasValidClassAt(i)) { 1800 if (class_table->HasValidClassAt(i)) {
1886 cls = class_table->At(i); 1801 cls = class_table->At(i);
(...skipping 16 matching lines...) Expand all
1903 ASSERT(!super_cls.IsNull()); 1818 ASSERT(!super_cls.IsNull());
1904 super_cls.AddDirectSubclass(cls); 1819 super_cls.AddDirectSubclass(cls);
1905 } 1820 }
1906 } 1821 }
1907 } 1822 }
1908 } 1823 }
1909 1824
1910 #endif // !PRODUCT 1825 #endif // !PRODUCT
1911 1826
1912 } // namespace dart 1827 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | runtime/vm/isolate_reload_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698