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

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

Issue 2032153003: Use clustered serialization for full snapshots. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: round1 Created 4 years, 6 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/clustered_snapshot.h"
6
7 #include "platform/assert.h"
8 #include "vm/bootstrap.h"
9 #include "vm/class_finalizer.h"
10 #include "vm/dart.h"
11 #include "vm/dart_entry.h"
12 #include "vm/exceptions.h"
13 #include "vm/heap.h"
14 #include "vm/lockers.h"
15 #include "vm/longjump.h"
16 #include "vm/native_entry.h"
17 #include "vm/object.h"
18 #include "vm/object_store.h"
19 #include "vm/stub_code.h"
20 #include "vm/symbols.h"
21 #include "vm/timeline.h"
22 #include "vm/version.h"
23
24 namespace dart {
25
26 static RawObject* AllocateUninitialized(PageSpace* old_space, intptr_t size) {
27 ASSERT(Utils::IsAligned(size, kObjectAlignment));
28 uword address = old_space->TryAllocateDataBumpLocked(size,
29 PageSpace::kForceGrowth);
30 if (address == 0) {
31 FATAL("Out of memory");
32 }
33 return reinterpret_cast<RawObject*>(address + kHeapObjectTag);
34 }
35
36
37 void Deserializer::InitializeHeader(RawObject* raw,
38 intptr_t class_id,
39 intptr_t size,
40 bool is_vm_isolate,
41 bool is_canonical) {
42 ASSERT(Utils::IsAligned(size, kObjectAlignment));
43 uword tags = 0;
44 tags = RawObject::ClassIdTag::update(class_id, tags);
45 tags = RawObject::SizeTag::update(size, tags);
46 tags = RawObject::VMHeapObjectTag::update(is_vm_isolate, tags);
47 tags = RawObject::CanonicalObjectTag::update(is_canonical, tags);
48 raw->ptr()->tags_ = tags;
49 }
50
51
52 class ClassSerializationCluster : public SerializationCluster {
53 public:
54 ClassSerializationCluster() { }
siva 2016/06/30 00:06:08 Maybe ClassSerializationCluster() :: predefined
rmacnak 2016/06/30 01:39:21 For a full snapshot we actually should expect the
55 virtual ~ClassSerializationCluster() { }
56
57 void Trace(Serializer* s, RawObject* object) {
58 RawClass* cls = Class::RawCast(object);
59 intptr_t class_id = cls->ptr()->id_;
60
61 if (class_id < kNumPredefinedCids) {
62 // These classes are allocated by Object::Init or Object::InitOnce, so the
63 // deserializer must find them in the class table instead of allocating
64 // them.
65 predefined_.Add(cls);
66 } else {
67 objects_.Add(cls);
68 }
69
70 RawObject** from = cls->from();
71 RawObject** to = cls->to_snapshot(s->kind());
72 for (RawObject** p = from; p <= to; p++) {
73 s->Push(*p);
74 }
75 }
76
77 void WriteAlloc(Serializer* s) {
78 s->WriteCid(kClassCid);
79 intptr_t count = predefined_.length();
80 s->Write<intptr_t>(count);
81 for (intptr_t i = 0; i < count; i++) {
82 RawClass* cls = predefined_[i];
83 intptr_t class_id = cls->ptr()->id_;
84 s->Write<intptr_t>(class_id);
85 s->AssignRef(cls);
86 }
87 count = objects_.length();
88 s->Write<intptr_t>(count);
89 for (intptr_t i = 0; i < count; i++) {
90 RawClass* cls = objects_[i];
91 s->AssignRef(cls);
92 }
93 }
94
95 void WriteFill(Serializer* s) {
96 #define WRITE_CLASS() \
97 RawObject** from = cls->from(); \
98 RawObject** to = cls->to_snapshot(kind); \
99 for (RawObject** p = from; p <= to; p++) { \
100 s->WriteRef(*p); \
101 } \
102 intptr_t class_id = cls->ptr()->id_; \
103 s->WriteCid(class_id); \
104 s->Write<int32_t>(cls->ptr()->instance_size_in_words_); \
105 s->Write<int32_t>(cls->ptr()->next_field_offset_in_words_); \
106 s->Write<int32_t>(cls->ptr()->type_arguments_field_offset_in_words_); \
107 s->Write<uint16_t>(cls->ptr()->num_type_arguments_); \
108 s->Write<uint16_t>(cls->ptr()->num_own_type_arguments_); \
109 s->Write<uint16_t>(cls->ptr()->num_native_fields_); \
110 s->WriteTokenPosition(cls->ptr()->token_pos_); \
111 s->Write<uint16_t>(cls->ptr()->state_bits_); \
siva 2016/06/30 00:06:08 Why not make this a static helper function and cal
rmacnak 2016/06/30 01:39:21 Done.
112
113 Snapshot::Kind kind = s->kind();
114 intptr_t count = predefined_.length();
115 for (intptr_t i = 0; i < count; i++) {
116 RawClass* cls = predefined_[i];
117 WRITE_CLASS()
118 }
119 count = objects_.length();
120 for (intptr_t i = 0; i < count; i++) {
121 RawClass* cls = objects_[i];
122 WRITE_CLASS()
123 }
124 #undef WRITE_CLASS
125 }
126
127 private:
128 GrowableArray<RawClass*> predefined_;
129 GrowableArray<RawClass*> objects_;
130 };
131
132
133 class ClassDeserializationCluster : public DeserializationCluster {
134 public:
135 ClassDeserializationCluster() { }
136 virtual ~ClassDeserializationCluster() { }
137
138 void ReadAlloc(Deserializer* d) {
139 predefined_start_index_ = d->next_index();
140 PageSpace* old_space = d->heap()->old_space();
141 intptr_t count = d->Read<intptr_t>();
142 ClassTable* table = d->isolate()->class_table();
143 for (intptr_t i = 0; i < count; i++) {
144 intptr_t class_id = d->Read<intptr_t>();
145 ASSERT(table->HasValidClassAt(class_id));
146 RawClass* cls = table->At(class_id);
147 ASSERT(cls != NULL);
148 d->AssignRef(cls);
149 }
150 predefined_stop_index_ = d->next_index();
151
152 start_index_ = d->next_index();
153 count = d->Read<intptr_t>();
154 for (intptr_t i = 0; i < count; i++) {
155 d->AssignRef(AllocateUninitialized(old_space,
156 Class::InstanceSize()));
157 }
158 stop_index_ = d->next_index();
159 }
160
161 void ReadFill(Deserializer* d) {
162 Snapshot::Kind kind = d->kind();
163 bool is_vm_object = d->isolate() == Dart::vm_isolate();
164 ClassTable* table = d->isolate()->class_table();
165
166 for (intptr_t id = predefined_start_index_;
167 id < predefined_stop_index_;
168 id++) {
169 RawClass* cls = reinterpret_cast<RawClass*>(d->Ref(id));
170 RawObject** from = cls->from();
171 RawObject** to_snapshot = cls->to_snapshot(kind);
172 RawObject** to = cls->to();
173 for (RawObject** p = from; p <= to_snapshot; p++) {
174 *p = d->ReadRef();
175 }
176 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
177 *p = Object::null();
178 }
siva 2016/06/30 00:06:07 Predefined classes are allocated in Object::Init u
rmacnak 2016/06/30 01:39:21 True, removed.
179
180 intptr_t class_id = d->ReadCid();
181 cls->ptr()->id_ = class_id;
182 cls->ptr()->instance_size_in_words_ = d->Read<int32_t>();
183 cls->ptr()->next_field_offset_in_words_ = d->Read<int32_t>();
184 cls->ptr()->type_arguments_field_offset_in_words_ = d->Read<int32_t>();
185 cls->ptr()->num_type_arguments_ = d->Read<uint16_t>();
186 cls->ptr()->num_own_type_arguments_ = d->Read<uint16_t>();
187 cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
188 cls->ptr()->token_pos_ = d->ReadTokenPosition();
189 cls->ptr()->state_bits_ = d->Read<uint16_t>();
siva 2016/06/30 00:06:08 This piece of code is repeated why not make a help
190 }
191
192 for (intptr_t id = start_index_; id < stop_index_; id++) {
193 RawClass* cls = reinterpret_cast<RawClass*>(d->Ref(id));
194 Deserializer::InitializeHeader(cls, kClassCid, Class::InstanceSize(),
195 is_vm_object);
196 RawObject** from = cls->from();
197 RawObject** to_snapshot = cls->to_snapshot(kind);
198 RawObject** to = cls->to();
199 for (RawObject** p = from; p <= to_snapshot; p++) {
200 *p = d->ReadRef();
201 }
202 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
203 *p = Object::null();
204 }
205
206 intptr_t class_id = d->ReadCid();
207
208 ASSERT(class_id >= kNumPredefinedCids);
209 Instance fake;
210 cls->ptr()->handle_vtable_ = fake.vtable();
211
212 cls->ptr()->id_ = class_id;
213 cls->ptr()->instance_size_in_words_ = d->Read<int32_t>();
214 cls->ptr()->next_field_offset_in_words_ = d->Read<int32_t>();
215 cls->ptr()->type_arguments_field_offset_in_words_ = d->Read<int32_t>();
216 cls->ptr()->num_type_arguments_ = d->Read<uint16_t>();
217 cls->ptr()->num_own_type_arguments_ = d->Read<uint16_t>();
218 cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
219 cls->ptr()->token_pos_ = d->ReadTokenPosition();
220 cls->ptr()->state_bits_ = d->Read<uint16_t>();
221
222 table->AllocateIndex(class_id);
223 table->SetAt(class_id, cls);
224 }
225 }
226
227 void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
228 NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
229 Timeline::GetIsolateStream(), "PostLoadClass"));
230
231 Class& cls = Class::Handle(zone);
232 for (intptr_t i = predefined_start_index_;
233 i < predefined_stop_index_;
234 i++) {
235 cls ^= refs.At(i);
236 cls.RehashConstants(zone);
237 }
238 for (intptr_t i = start_index_; i < stop_index_; i++) {
239 cls ^= refs.At(i);
240 cls.RehashConstants(zone);
241 }
242 }
243
244 private:
245 intptr_t predefined_start_index_;
246 intptr_t predefined_stop_index_;
247 };
248
249 class UnresolvedClassSerializationCluster : public SerializationCluster {
250 public:
251 UnresolvedClassSerializationCluster() { }
252 virtual ~UnresolvedClassSerializationCluster() { }
253
254 void Trace(Serializer* s, RawObject* object) {
255 RawUnresolvedClass* cls = UnresolvedClass::RawCast(object);
256 objects_.Add(cls);
257
258 RawObject** from = cls->from();
259 RawObject** to = cls->to();
260 for (RawObject** p = from; p <= to; p++) {
261 s->Push(*p);
262 }
263 }
264
265 void WriteAlloc(Serializer* s) {
266 s->WriteCid(kUnresolvedClassCid);
267 intptr_t count = objects_.length();
268 s->Write<intptr_t>(count);
269 for (intptr_t i = 0; i < count; i++) {
270 RawUnresolvedClass* cls = objects_[i];
271 s->AssignRef(cls);
272 }
273 }
274
275 void WriteFill(Serializer* s) {
276 intptr_t count = objects_.length();
277 s->Write<intptr_t>(count);
278 for (intptr_t i = 0; i < count; i++) {
279 RawUnresolvedClass* cls = objects_[i];
280 RawObject** from = cls->from();
281 RawObject** to = cls->to();
282 for (RawObject** p = from; p <= to; p++) {
283 s->WriteRef(*p);
284 }
285 s->WriteTokenPosition(cls->ptr()->token_pos_);
286 }
287 }
288
289 private:
290 GrowableArray<RawUnresolvedClass*> objects_;
291 };
292
293 class UnresolvedClassDeserializationCluster : public DeserializationCluster {
294 public:
295 UnresolvedClassDeserializationCluster() { }
296 virtual ~UnresolvedClassDeserializationCluster() { }
297
298 void ReadAlloc(Deserializer* d) {
299 start_index_ = d->next_index();
300 PageSpace* old_space = d->heap()->old_space();
301 intptr_t count = d->Read<intptr_t>();
302 for (intptr_t i = 0; i < count; i++) {
303 d->AssignRef(AllocateUninitialized(old_space,
304 UnresolvedClass::InstanceSize()));
305 }
306 stop_index_ = d->next_index();
307 }
308
309 void ReadFill(Deserializer* d) {
310 bool is_vm_object = d->isolate() == Dart::vm_isolate();
311
312 for (intptr_t id = start_index_; id < stop_index_; id++) {
313 RawUnresolvedClass* cls =
314 reinterpret_cast<RawUnresolvedClass*>(d->Ref(id));
315 Deserializer::InitializeHeader(cls, kUnresolvedClassCid,
316 UnresolvedClass::InstanceSize(),
317 is_vm_object);
318 RawObject** from = cls->from();
319 RawObject** to = cls->to();
320 for (RawObject** p = from; p <= to; p++) {
321 *p = d->ReadRef();
322 }
323 cls->ptr()->token_pos_ = d->ReadTokenPosition();
324 }
325 }
326 };
327
328 class TypeArgumentsSerializationCluster : public SerializationCluster {
329 public:
330 TypeArgumentsSerializationCluster() { }
331 virtual ~TypeArgumentsSerializationCluster() { }
332
333 void Trace(Serializer* s, RawObject* object) {
334 RawTypeArguments* type_args = TypeArguments::RawCast(object);
335 objects_.Add(type_args);
336
337 s->Push(type_args->ptr()->instantiations_);
338 intptr_t length = Smi::Value(type_args->ptr()->length_);
339 for (intptr_t i = 0; i < length; i++) {
340 s->Push(type_args->ptr()->types()[i]);
341 }
342 }
343
344 void WriteAlloc(Serializer* s) {
345 s->WriteCid(kTypeArgumentsCid);
346 intptr_t count = objects_.length();
347 s->Write<intptr_t>(count);
348 for (intptr_t i = 0; i < count; i++) {
349 RawTypeArguments* type_args = objects_[i];
350 intptr_t length = Smi::Value(type_args->ptr()->length_);
351 s->Write<intptr_t>(length);
352 s->AssignRef(type_args);
353 }
354 }
355
356 void WriteFill(Serializer* s) {
357 intptr_t count = objects_.length();
358 for (intptr_t i = 0; i < count; i++) {
359 RawTypeArguments* type_args = objects_[i];
360 intptr_t length = Smi::Value(type_args->ptr()->length_);
361 s->Write<intptr_t>(length);
362 s->Write<bool>(type_args->IsCanonical());
363 intptr_t hash = Smi::Value(type_args->ptr()->hash_);
364 s->Write<int32_t>(hash);
365 s->WriteRef(type_args->ptr()->instantiations_);
366 for (intptr_t j = 0; j < length; j++) {
367 s->WriteRef(type_args->ptr()->types()[j]);
368 }
369 }
370 }
371
372 private:
373 GrowableArray<RawTypeArguments*> objects_;
374 };
375
376
377 class TypeArgumentsDeserializationCluster : public DeserializationCluster {
378 public:
379 TypeArgumentsDeserializationCluster() { }
380 virtual ~TypeArgumentsDeserializationCluster() { }
381
382 void ReadAlloc(Deserializer* d) {
383 start_index_ = d->next_index();
384 PageSpace* old_space = d->heap()->old_space();
385 intptr_t count = d->Read<intptr_t>();
386 for (intptr_t i = 0; i < count; i++) {
387 intptr_t length = d->Read<intptr_t>();
388 d->AssignRef(AllocateUninitialized(old_space,
389 TypeArguments::InstanceSize(length)));
390 }
391 stop_index_ = d->next_index();
392 }
393
394 void ReadFill(Deserializer* d) {
395 bool is_vm_object = d->isolate() == Dart::vm_isolate();
396
397 for (intptr_t id = start_index_; id < stop_index_; id++) {
398 RawTypeArguments* type_args =
399 reinterpret_cast<RawTypeArguments*>(d->Ref(id));
400 intptr_t length = d->Read<intptr_t>();
401 bool is_canonical = d->Read<bool>();
402 Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
403 TypeArguments::InstanceSize(length),
404 is_vm_object, is_canonical);
405 type_args->ptr()->length_ = Smi::New(length);
406 type_args->ptr()->hash_ = Smi::New(d->Read<int32_t>());
407 type_args->ptr()->instantiations_ =
408 reinterpret_cast<RawArray*>(d->ReadRef());
409 for (intptr_t j = 0; j < length; j++) {
410 type_args->ptr()->types()[j] =
411 reinterpret_cast<RawAbstractType*>(d->ReadRef());
412 }
413 }
414 }
415 };
416
417
418 class PatchClassSerializationCluster : public SerializationCluster {
419 public:
420 PatchClassSerializationCluster() { }
421 virtual ~PatchClassSerializationCluster() { }
422
423 void Trace(Serializer* s, RawObject* object) {
424 RawPatchClass* cls = PatchClass::RawCast(object);
425 objects_.Add(cls);
426
427 RawObject** from = cls->from();
428 RawObject** to = cls->to();
429 for (RawObject** p = from; p <= to; p++) {
430 s->Push(*p);
431 }
432 }
433
434 void WriteAlloc(Serializer* s) {
435 s->WriteCid(kPatchClassCid);
436 intptr_t count = objects_.length();
437 s->Write<intptr_t>(count);
438 for (intptr_t i = 0; i < count; i++) {
439 RawPatchClass* cls = objects_[i];
440 s->AssignRef(cls);
441 }
442 }
siva 2016/06/30 00:06:08 The WriteAlloc function seems similar in each of t
443
444 void WriteFill(Serializer* s) {
445 intptr_t count = objects_.length();
446 for (intptr_t i = 0; i < count; i++) {
447 RawPatchClass* cls = objects_[i];
448 RawObject** from = cls->from();
449 RawObject** to = cls->to();
450 for (RawObject** p = from; p <= to; p++) {
451 s->WriteRef(*p);
452 }
453 }
454 }
455
456 private:
457 GrowableArray<RawPatchClass*> objects_;
458 };
459
460 class PatchClassDeserializationCluster : public DeserializationCluster {
461 public:
462 PatchClassDeserializationCluster() { }
463 virtual ~PatchClassDeserializationCluster() { }
464
465 void ReadAlloc(Deserializer* d) {
466 start_index_ = d->next_index();
467 PageSpace* old_space = d->heap()->old_space();
468 intptr_t count = d->Read<intptr_t>();
469 for (intptr_t i = 0; i < count; i++) {
470 d->AssignRef(AllocateUninitialized(old_space,
471 PatchClass::InstanceSize()));
472 }
473 stop_index_ = d->next_index();
474 }
siva 2016/06/30 00:06:07 The ReadAlloc function seems similar in each of th
475
476 void ReadFill(Deserializer* d) {
477 bool is_vm_object = d->isolate() == Dart::vm_isolate();
478
479 for (intptr_t id = start_index_; id < stop_index_; id++) {
480 RawPatchClass* cls = reinterpret_cast<RawPatchClass*>(d->Ref(id));
481 Deserializer::InitializeHeader(cls, kPatchClassCid,
482 PatchClass::InstanceSize(), is_vm_object);
483 RawObject** from = cls->from();
484 RawObject** to = cls->to();
485 for (RawObject** p = from; p <= to; p++) {
486 *p = d->ReadRef();
487 }
488 }
489 }
490 };
491
492 class FunctionSerializationCluster : public SerializationCluster {
493 public:
494 FunctionSerializationCluster() { }
495 virtual ~FunctionSerializationCluster() { }
496
497 void Trace(Serializer* s, RawObject* object) {
498 RawFunction* func = Function::RawCast(object);
499 objects_.Add(func);
500
501 RawObject** from = func->from();
502 RawObject** to = func->to_snapshot();
503 for (RawObject** p = from; p <= to; p++) {
504 s->Push(*p);
505 }
506 if (s->kind() == Snapshot::kAppNoJIT) {
507 s->Push(func->ptr()->code_);
508 } else if (s->kind() == Snapshot::kAppWithJIT) {
509 s->Push(func->ptr()->unoptimized_code_);
510 s->Push(func->ptr()->ic_data_array_);
511 }
512 }
513
514 void WriteAlloc(Serializer* s) {
515 s->WriteCid(kFunctionCid);
516 intptr_t count = objects_.length();
517 s->Write<intptr_t>(count);
518 for (intptr_t i = 0; i < count; i++) {
519 RawFunction* func = objects_[i];
520 s->AssignRef(func);
521 }
522 }
523
524 void WriteFill(Serializer* s) {
525 Snapshot::Kind kind = s->kind();
526 intptr_t count = objects_.length();
527 for (intptr_t i = 0; i < count; i++) {
528 RawFunction* func = objects_[i];
529 RawObject** from = func->from();
530 RawObject** to = func->to_snapshot();
531 for (RawObject** p = from; p <= to; p++) {
532 s->WriteRef(*p);
533 }
534 if (kind == Snapshot::kAppNoJIT) {
535 s->WriteRef(func->ptr()->code_);
536 } else if (s->kind() == Snapshot::kAppWithJIT) {
537 s->WriteRef(func->ptr()->unoptimized_code_);
538 s->WriteRef(func->ptr()->ic_data_array_);
539 }
540
541 s->WriteTokenPosition(func->ptr()->token_pos_);
542 s->WriteTokenPosition(func->ptr()->end_token_pos_);
543 s->Write<int16_t>(func->ptr()->num_fixed_parameters_);
544 s->Write<int16_t>(func->ptr()->num_optional_parameters_);
545 s->Write<uint32_t>(func->ptr()->kind_tag_);
546 if (kind == Snapshot::kAppNoJIT) {
547 // Omit fields used to support de/reoptimization.
548 } else {
549 bool is_optimized = Code::IsOptimized(func->ptr()->code_);
550 if (is_optimized) {
551 s->Write<int32_t>(FLAG_optimization_counter_threshold);
552 } else {
553 s->Write<int32_t>(0);
554 }
555 s->Write<int8_t>(func->ptr()->deoptimization_counter_);
556 s->Write<uint16_t>(func->ptr()->optimized_instruction_count_);
557 s->Write<uint16_t>(func->ptr()->optimized_call_site_count_);
558 }
559 }
560 }
561
562 private:
563 GrowableArray<RawFunction*> objects_;
564 };
565
566 class FunctionDeserializationCluster : public DeserializationCluster {
567 public:
568 FunctionDeserializationCluster() { }
569 virtual ~FunctionDeserializationCluster() { }
570
571 void ReadAlloc(Deserializer* d) {
572 start_index_ = d->next_index();
573 PageSpace* old_space = d->heap()->old_space();
574 intptr_t count = d->Read<intptr_t>();
575 for (intptr_t i = 0; i < count; i++) {
576 d->AssignRef(AllocateUninitialized(old_space,
577 Function::InstanceSize()));
578 }
579 stop_index_ = d->next_index();
580 }
581
582 void ReadFill(Deserializer* d) {
583 Snapshot::Kind kind = d->kind();
584 bool is_vm_object = d->isolate() == Dart::vm_isolate();
585
586 for (intptr_t id = start_index_; id < stop_index_; id++) {
587 RawFunction* func = reinterpret_cast<RawFunction*>(d->Ref(id));
588 Deserializer::InitializeHeader(func, kFunctionCid,
589 Function::InstanceSize(), is_vm_object);
590 RawObject** from = func->from();
591 RawObject** to_snapshot = func->to_snapshot();
592 RawObject** to = func->to();
593 for (RawObject** p = from; p <= to_snapshot; p++) {
594 *p = d->ReadRef();
595 }
596 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
597 *p = Object::null();
598 }
599 if (kind == Snapshot::kAppNoJIT) {
600 func->ptr()->code_ = reinterpret_cast<RawCode*>(d->ReadRef());
601 } else if (kind == Snapshot::kAppWithJIT) {
602 func->ptr()->unoptimized_code_ =
603 reinterpret_cast<RawCode*>(d->ReadRef());
604 func->ptr()->ic_data_array_ = reinterpret_cast<RawArray*>(d->ReadRef());
605 }
606
607 #if defined(DEBUG)
608 func->ptr()->entry_point_ = 0;
609 #endif
610
611 func->ptr()->token_pos_ = d->ReadTokenPosition();
612 func->ptr()->end_token_pos_ = d->ReadTokenPosition();
613 func->ptr()->num_fixed_parameters_ = d->Read<int16_t>();
614 func->ptr()->num_optional_parameters_ = d->Read<int16_t>();
615 func->ptr()->kind_tag_ = d->Read<uint32_t>();
616 if (kind == Snapshot::kAppNoJIT) {
617 // Omit fields used to support de/reoptimization.
618 } else {
619 func->ptr()->usage_counter_ = d->Read<int32_t>();
620 func->ptr()->deoptimization_counter_ = d->Read<int8_t>();
621 func->ptr()->optimized_instruction_count_ = d->Read<uint16_t>();
622 func->ptr()->optimized_call_site_count_ = d->Read<uint16_t>();
623 }
624 }
625 }
626
627 void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
628 NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
629 Timeline::GetIsolateStream(), "PostLoadFunction"));
630
631 if (kind == Snapshot::kAppNoJIT) {
632 Function& func = Function::Handle(zone);
633 for (intptr_t i = start_index_; i < stop_index_; i++) {
634 func ^= refs.At(i);
635 ASSERT(func.raw()->ptr()->code_->IsCode());
636 uword entry_point = func.raw()->ptr()->code_->ptr()->entry_point_;
637 ASSERT(entry_point != 0);
638 func.raw()->ptr()->entry_point_ = entry_point;
639 }
640 } else if (kind == Snapshot::kAppWithJIT) {
641 Function& func = Function::Handle(zone);
642 Code& code = Code::Handle(zone);
643 for (intptr_t i = start_index_; i < stop_index_; i++) {
644 func ^= refs.At(i);
645 code ^= func.unoptimized_code();
646 if (!code.IsNull()) {
647 func.SetInstructions(code);
648 func.set_was_compiled(true);
649 } else {
650 func.ClearCode();
651 func.set_was_compiled(false);
652 }
653 }
654 } else {
655 Function& func = Function::Handle(zone);
656 for (intptr_t i = start_index_; i < stop_index_; i++) {
657 func ^= refs.At(i);
658 func.ClearICDataArray();
659 func.ClearCode();
660 func.set_was_compiled(false);
661 }
662 }
663 }
664 };
665
666 class ClosureDataSerializationCluster : public SerializationCluster {
667 public:
668 ClosureDataSerializationCluster() { }
669 virtual ~ClosureDataSerializationCluster() { }
670
671 void Trace(Serializer* s, RawObject* object) {
672 RawClosureData* data = ClosureData::RawCast(object);
673 objects_.Add(data);
674
675 RawObject** from = data->from();
676 RawObject** to = data->to();
677 for (RawObject** p = from; p <= to; p++) {
678 s->Push(*p);
679 }
680 }
681
682 void WriteAlloc(Serializer* s) {
683 s->WriteCid(kClosureDataCid);
684 intptr_t count = objects_.length();
685 s->Write<intptr_t>(count);
686 for (intptr_t i = 0; i < count; i++) {
687 RawClosureData* data = objects_[i];
688 s->AssignRef(data);
689 }
690 }
691
692 void WriteFill(Serializer* s) {
693 intptr_t count = objects_.length();
694 for (intptr_t i = 0; i < count; i++) {
695 RawClosureData* data = objects_[i];
696 RawObject** from = data->from();
697 RawObject** to = data->to();
698 for (RawObject** p = from; p <= to; p++) {
699 s->WriteRef(*p);
700 }
701 }
702 }
703
704 private:
705 GrowableArray<RawClosureData*> objects_;
706 };
707
708 class ClosureDataDeserializationCluster : public DeserializationCluster {
709 public:
710 ClosureDataDeserializationCluster() { }
711 virtual ~ClosureDataDeserializationCluster() { }
712
713 void ReadAlloc(Deserializer* d) {
714 start_index_ = d->next_index();
715 PageSpace* old_space = d->heap()->old_space();
716 intptr_t count = d->Read<intptr_t>();
717 for (intptr_t i = 0; i < count; i++) {
718 d->AssignRef(AllocateUninitialized(old_space,
719 ClosureData::InstanceSize()));
720 }
721 stop_index_ = d->next_index();
722 }
723
724 void ReadFill(Deserializer* d) {
725 bool is_vm_object = d->isolate() == Dart::vm_isolate();
726
727 for (intptr_t id = start_index_; id < stop_index_; id++) {
728 RawClosureData* data = reinterpret_cast<RawClosureData*>(d->Ref(id));
729 Deserializer::InitializeHeader(data, kClosureDataCid,
730 ClosureData::InstanceSize(), is_vm_object);
731 RawObject** from = data->from();
732 RawObject** to = data->to();
733 for (RawObject** p = from; p <= to; p++) {
734 *p = d->ReadRef();
735 }
736 }
737 }
738 };
739
740 class RedirectionDataSerializationCluster : public SerializationCluster {
741 public:
742 RedirectionDataSerializationCluster() { }
743 virtual ~RedirectionDataSerializationCluster() { }
744
745 void Trace(Serializer* s, RawObject* object) {
746 RawRedirectionData* data = RedirectionData::RawCast(object);
747 objects_.Add(data);
748
749 RawObject** from = data->from();
750 RawObject** to = data->to();
751 for (RawObject** p = from; p <= to; p++) {
752 s->Push(*p);
753 }
754 }
755
756 void WriteAlloc(Serializer* s) {
757 s->WriteCid(kRedirectionDataCid);
758 intptr_t count = objects_.length();
759 s->Write<intptr_t>(count);
760 for (intptr_t i = 0; i < count; i++) {
761 RawRedirectionData* data = objects_[i];
762 s->AssignRef(data);
763 }
764 }
765
766 void WriteFill(Serializer* s) {
767 intptr_t count = objects_.length();
768 for (intptr_t i = 0; i < count; i++) {
769 RawRedirectionData* data = objects_[i];
770 RawObject** from = data->from();
771 RawObject** to = data->to();
772 for (RawObject** p = from; p <= to; p++) {
773 s->WriteRef(*p);
774 }
775 }
776 }
777
778 private:
779 GrowableArray<RawRedirectionData*> objects_;
780 };
781
782 class RedirectionDataDeserializationCluster : public DeserializationCluster {
783 public:
784 RedirectionDataDeserializationCluster() { }
785 virtual ~RedirectionDataDeserializationCluster() { }
786
787 void ReadAlloc(Deserializer* d) {
788 start_index_ = d->next_index();
789 PageSpace* old_space = d->heap()->old_space();
790 intptr_t count = d->Read<intptr_t>();
791 for (intptr_t i = 0; i < count; i++) {
792 d->AssignRef(AllocateUninitialized(old_space,
793 RedirectionData::InstanceSize()));
794 }
795 stop_index_ = d->next_index();
796 }
797
798 void ReadFill(Deserializer* d) {
799 bool is_vm_object = d->isolate() == Dart::vm_isolate();
800
801 for (intptr_t id = start_index_; id < stop_index_; id++) {
802 RawRedirectionData* data =
803 reinterpret_cast<RawRedirectionData*>(d->Ref(id));
804 Deserializer::InitializeHeader(data, kRedirectionDataCid,
805 RedirectionData::InstanceSize(),
806 is_vm_object);
807 RawObject** from = data->from();
808 RawObject** to = data->to();
809 for (RawObject** p = from; p <= to; p++) {
810 *p = d->ReadRef();
811 }
812 }
813 }
814 };
815
816 class FieldSerializationCluster : public SerializationCluster {
817 public:
818 FieldSerializationCluster() { }
819 virtual ~FieldSerializationCluster() { }
820
821 void Trace(Serializer* s, RawObject* object) {
822 RawField* field = Field::RawCast(object);
823 objects_.Add(field);
824
825 Snapshot::Kind kind = s->kind();
826
827 s->Push(field->ptr()->name_);
828 s->Push(field->ptr()->owner_);
829 s->Push(field->ptr()->type_);
830 // Write out the initial static value or field offset.
831 if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
832 if (kind == Snapshot::kAppNoJIT) {
833 // For precompiled static fields, the value was already reset and
834 // initializer_ now contains a Function.
835 s->Push(field->ptr()->value_.static_value_);
836 } else if (Field::ConstBit::decode(field->ptr()->kind_bits_)) {
837 // Do not reset const fields.
838 s->Push(field->ptr()->value_.static_value_);
839 } else {
840 // Otherwise, for static fields we write out the initial static value.
841 s->Push(field->ptr()->initializer_.saved_value_);
842 }
843 } else {
844 s->Push(field->ptr()->value_.offset_);
845 }
846 // Write out the initializer function or saved initial value.
847 if (kind == Snapshot::kAppNoJIT) {
848 s->Push(field->ptr()->initializer_.precompiled_);
849 } else {
850 s->Push(field->ptr()->initializer_.saved_value_);
851 }
852 if (kind != Snapshot::kAppNoJIT) {
853 // Write out the guarded list length.
854 s->Push(field->ptr()->guarded_list_length_);
855 }
856 }
857
858 void WriteAlloc(Serializer* s) {
859 s->WriteCid(kFieldCid);
860 intptr_t count = objects_.length();
861 s->Write<intptr_t>(count);
862 for (intptr_t i = 0; i < count; i++) {
863 RawField* field = objects_[i];
864 s->AssignRef(field);
865 }
866 }
867
868 void WriteFill(Serializer* s) {
869 Snapshot::Kind kind = s->kind();
870 intptr_t count = objects_.length();
871 for (intptr_t i = 0; i < count; i++) {
872 RawField* field = objects_[i];
873
874 s->WriteRef(field->ptr()->name_);
875 s->WriteRef(field->ptr()->owner_);
876 s->WriteRef(field->ptr()->type_);
877 // Write out the initial static value or field offset.
878 if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
879 if (kind == Snapshot::kAppNoJIT) {
880 // For precompiled static fields, the value was already reset and
881 // initializer_ now contains a Function.
882 s->WriteRef(field->ptr()->value_.static_value_);
883 } else if (Field::ConstBit::decode(field->ptr()->kind_bits_)) {
884 // Do not reset const fields.
885 s->WriteRef(field->ptr()->value_.static_value_);
886 } else {
887 // Otherwise, for static fields we write out the initial static value.
888 s->WriteRef(field->ptr()->initializer_.saved_value_);
889 }
890 } else {
891 s->WriteRef(field->ptr()->value_.offset_);
892 }
893 // Write out the initializer function or saved initial value.
894 if (kind == Snapshot::kAppNoJIT) {
895 s->WriteRef(field->ptr()->initializer_.precompiled_);
896 } else {
897 s->WriteRef(field->ptr()->initializer_.saved_value_);
898 }
899 if (kind != Snapshot::kAppNoJIT) {
900 // Write out the guarded list length.
901 s->WriteRef(field->ptr()->guarded_list_length_);
902 }
903
904 if (kind != Snapshot::kAppNoJIT) {
905 s->WriteTokenPosition(field->ptr()->token_pos_);
906 s->WriteCid(field->ptr()->guarded_cid_);
907 s->WriteCid(field->ptr()->is_nullable_);
908 }
909 s->Write<uint8_t>(field->ptr()->kind_bits_);
910 }
911 }
912
913 private:
914 GrowableArray<RawField*> objects_;
915 };
siva 2016/06/30 00:06:08 two blank lines between all these classes in this
rmacnak 2016/06/30 01:39:21 Done.
916
917 class FieldDeserializationCluster : public DeserializationCluster {
918 public:
919 FieldDeserializationCluster() { }
920 virtual ~FieldDeserializationCluster() { }
921
922 void ReadAlloc(Deserializer* d) {
923 start_index_ = d->next_index();
924 PageSpace* old_space = d->heap()->old_space();
925 intptr_t count = d->Read<intptr_t>();
926 for (intptr_t i = 0; i < count; i++) {
927 d->AssignRef(AllocateUninitialized(old_space, Field::InstanceSize()));
928 }
929 stop_index_ = d->next_index();
930 }
931
932 void ReadFill(Deserializer* d) {
933 Snapshot::Kind kind = d->kind();
934 bool is_vm_object = d->isolate() == Dart::vm_isolate();
935
936 for (intptr_t id = start_index_; id < stop_index_; id++) {
937 RawField* field = reinterpret_cast<RawField*>(d->Ref(id));
938 Deserializer::InitializeHeader(field, kFieldCid,
939 Field::InstanceSize(), is_vm_object);
940 RawObject** from = field->from();
941 RawObject** to_snapshot = field->to_snapshot(kind);
942 RawObject** to = field->to();
943 for (RawObject** p = from; p <= to_snapshot; p++) {
944 *p = d->ReadRef();
945 }
946 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
947 *p = Object::null();
948 }
949
950 if (kind != Snapshot::kAppNoJIT) {
951 field->ptr()->token_pos_ = d->ReadTokenPosition();
952 field->ptr()->guarded_cid_ = d->ReadCid();
953 field->ptr()->is_nullable_ = d->ReadCid();
954 }
955 field->ptr()->kind_bits_ = d->Read<uint8_t>();
956 }
957 }
958
959 void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
960 NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
961 Timeline::GetIsolateStream(), "PostLoadField"));
962
963 Field& field = Field::Handle(zone);
964 if (!FLAG_use_field_guards) {
965 for (intptr_t i = start_index_; i < stop_index_; i++) {
966 field ^= refs.At(i);
967 field.set_guarded_cid(kDynamicCid);
968 field.set_is_nullable(true);
969 field.set_guarded_list_length(Field::kNoFixedLength);
970 field.set_guarded_list_length_in_object_offset(
971 Field::kUnknownLengthOffset);
972 }
973 } else {
974 for (intptr_t i = start_index_; i < stop_index_; i++) {
975 field ^= refs.At(i);
976 field.InitializeGuardedListLengthInObjectOffset();
977 }
978 }
979 }
980 };
981
982 class LiteralTokenSerializationCluster : public SerializationCluster {
983 public:
984 LiteralTokenSerializationCluster() { }
985 virtual ~LiteralTokenSerializationCluster() { }
986
987 void Trace(Serializer* s, RawObject* object) {
988 RawLiteralToken* token = LiteralToken::RawCast(object);
989 objects_.Add(token);
990
991 RawObject** from = token->from();
992 RawObject** to = token->to();
993 for (RawObject** p = from; p <= to; p++) {
994 s->Push(*p);
995 }
996 }
997
998 void WriteAlloc(Serializer* s) {
999 s->WriteCid(kLiteralTokenCid);
1000 intptr_t count = objects_.length();
1001 s->Write<intptr_t>(count);
1002 for (intptr_t i = 0; i < count; i++) {
1003 RawLiteralToken* token = objects_[i];
1004 s->AssignRef(token);
1005 }
1006 }
1007
1008 void WriteFill(Serializer* s) {
1009 intptr_t count = objects_.length();
1010 for (intptr_t i = 0; i < count; i++) {
1011 RawLiteralToken* token = objects_[i];
1012 RawObject** from = token->from();
1013 RawObject** to = token->to();
1014 for (RawObject** p = from; p <= to; p++) {
1015 s->WriteRef(*p);
1016 }
1017 s->Write<int32_t>(token->ptr()->kind_);
1018 }
1019 }
1020
1021 private:
1022 GrowableArray<RawLiteralToken*> objects_;
1023 };
1024
1025 class LiteralTokenDeserializationCluster : public DeserializationCluster {
1026 public:
1027 LiteralTokenDeserializationCluster() { }
1028 virtual ~LiteralTokenDeserializationCluster() { }
1029
1030 void ReadAlloc(Deserializer* d) {
1031 start_index_ = d->next_index();
1032 PageSpace* old_space = d->heap()->old_space();
1033 intptr_t count = d->Read<intptr_t>();
1034 for (intptr_t i = 0; i < count; i++) {
1035 d->AssignRef(AllocateUninitialized(old_space,
1036 LiteralToken::InstanceSize()));
1037 }
1038 stop_index_ = d->next_index();
1039 }
1040
1041 void ReadFill(Deserializer* d) {
1042 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1043
1044 for (intptr_t id = start_index_; id < stop_index_; id++) {
1045 RawLiteralToken* token = reinterpret_cast<RawLiteralToken*>(d->Ref(id));
1046 Deserializer::InitializeHeader(token, kLiteralTokenCid,
1047 LiteralToken::InstanceSize(),
1048 is_vm_object);
1049 RawObject** from = token->from();
1050 RawObject** to = token->to();
1051 for (RawObject** p = from; p <= to; p++) {
1052 *p = d->ReadRef();
1053 }
1054 token->ptr()->kind_ = static_cast<Token::Kind>(d->Read<int32_t>());
1055 }
1056 }
1057 };
1058
1059 class TokenStreamSerializationCluster : public SerializationCluster {
1060 public:
1061 TokenStreamSerializationCluster() { }
1062 virtual ~TokenStreamSerializationCluster() { }
1063
1064 void Trace(Serializer* s, RawObject* object) {
1065 RawTokenStream* stream = TokenStream::RawCast(object);
1066 objects_.Add(stream);
1067
1068 RawObject** from = stream->from();
1069 RawObject** to = stream->to();
1070 for (RawObject** p = from; p <= to; p++) {
1071 s->Push(*p);
1072 }
1073 }
1074
1075 void WriteAlloc(Serializer* s) {
1076 s->WriteCid(kTokenStreamCid);
1077 intptr_t count = objects_.length();
1078 s->Write<intptr_t>(count);
1079 for (intptr_t i = 0; i < count; i++) {
1080 RawTokenStream* stream = objects_[i];
1081 s->AssignRef(stream);
1082 }
1083 }
1084
1085 void WriteFill(Serializer* s) {
1086 intptr_t count = objects_.length();
1087 for (intptr_t i = 0; i < count; i++) {
1088 RawTokenStream* stream = objects_[i];
1089 RawObject** from = stream->from();
1090 RawObject** to = stream->to();
1091 for (RawObject** p = from; p <= to; p++) {
1092 s->WriteRef(*p);
1093 }
1094 }
1095 }
1096
1097 private:
1098 GrowableArray<RawTokenStream*> objects_;
1099 };
1100
1101 class TokenStreamDeserializationCluster : public DeserializationCluster {
1102 public:
1103 TokenStreamDeserializationCluster() { }
1104 virtual ~TokenStreamDeserializationCluster() { }
1105
1106 void ReadAlloc(Deserializer* d) {
1107 start_index_ = d->next_index();
1108 PageSpace* old_space = d->heap()->old_space();
1109 intptr_t count = d->Read<intptr_t>();
1110 for (intptr_t i = 0; i < count; i++) {
1111 d->AssignRef(AllocateUninitialized(old_space,
1112 TokenStream::InstanceSize()));
1113 }
1114 stop_index_ = d->next_index();
1115 }
1116
1117 void ReadFill(Deserializer* d) {
1118 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1119
1120 for (intptr_t id = start_index_; id < stop_index_; id++) {
1121 RawTokenStream* stream = reinterpret_cast<RawTokenStream*>(d->Ref(id));
1122 Deserializer::InitializeHeader(stream, kTokenStreamCid,
1123 TokenStream::InstanceSize(), is_vm_object);
1124 RawObject** from = stream->from();
1125 RawObject** to = stream->to();
1126 for (RawObject** p = from; p <= to; p++) {
1127 *p = d->ReadRef();
1128 }
1129 }
1130 }
1131 };
1132
1133 class ScriptSerializationCluster : public SerializationCluster {
1134 public:
1135 ScriptSerializationCluster() { }
1136 virtual ~ScriptSerializationCluster() { }
1137
1138 void Trace(Serializer* s, RawObject* object) {
1139 RawScript* script = Script::RawCast(object);
1140 objects_.Add(script);
1141
1142 RawObject** from = script->from();
1143 RawObject** to = script->to_snapshot(s->kind());
1144 for (RawObject** p = from; p <= to; p++) {
1145 s->Push(*p);
1146 }
1147 }
1148
1149 void WriteAlloc(Serializer* s) {
1150 s->WriteCid(kScriptCid);
1151 intptr_t count = objects_.length();
1152 s->Write<intptr_t>(count);
1153 for (intptr_t i = 0; i < count; i++) {
1154 RawScript* script = objects_[i];
1155 s->AssignRef(script);
1156 }
1157 }
1158
1159 void WriteFill(Serializer* s) {
1160 Snapshot::Kind kind = s->kind();
1161 intptr_t count = objects_.length();
1162 for (intptr_t i = 0; i < count; i++) {
1163 RawScript* script = objects_[i];
1164 RawObject** from = script->from();
1165 RawObject** to = script->to_snapshot(kind);
1166 for (RawObject** p = from; p <= to; p++) {
1167 s->WriteRef(*p);
1168 }
1169
1170 s->Write<int32_t>(script->ptr()->line_offset_);
1171 s->Write<int32_t>(script->ptr()->col_offset_);
1172 s->Write<int8_t>(script->ptr()->kind_);
1173 }
1174 }
1175
1176 private:
1177 GrowableArray<RawScript*> objects_;
1178 };
1179
1180
1181 class ScriptDeserializationCluster : public DeserializationCluster {
1182 public:
1183 ScriptDeserializationCluster() { }
1184 virtual ~ScriptDeserializationCluster() { }
1185
1186 void ReadAlloc(Deserializer* d) {
1187 start_index_ = d->next_index();
1188 PageSpace* old_space = d->heap()->old_space();
1189 intptr_t count = d->Read<intptr_t>();
1190 for (intptr_t i = 0; i < count; i++) {
1191 d->AssignRef(AllocateUninitialized(old_space, Script::InstanceSize()));
1192 }
1193 stop_index_ = d->next_index();
1194 }
1195
1196 void ReadFill(Deserializer* d) {
1197 Snapshot::Kind kind = d->kind();
1198 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1199
1200 for (intptr_t id = start_index_; id < stop_index_; id++) {
1201 RawScript* script = reinterpret_cast<RawScript*>(d->Ref(id));
1202 Deserializer::InitializeHeader(script, kScriptCid,
1203 Script::InstanceSize(), is_vm_object);
1204 RawObject** from = script->from();
1205 RawObject** to_snapshot = script->to_snapshot(kind);
1206 RawObject** to = script->to();
1207 for (RawObject** p = from; p <= to_snapshot; p++) {
1208 *p = d->ReadRef();
1209 }
1210 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
1211 *p = Object::null();
1212 }
1213
1214 script->ptr()->line_offset_ = d->Read<int32_t>();
1215 script->ptr()->col_offset_ = d->Read<int32_t>();
1216 script->ptr()->kind_ = d->Read<int8_t>();
1217 script->ptr()->load_timestamp_ = 0;
1218 }
1219 }
1220 };
1221
1222
1223 class LibrarySerializationCluster : public SerializationCluster {
1224 public:
1225 LibrarySerializationCluster() { }
1226 virtual ~LibrarySerializationCluster() { }
1227
1228 void Trace(Serializer* s, RawObject* object) {
1229 RawLibrary* lib = Library::RawCast(object);
1230 objects_.Add(lib);
1231
1232 RawObject** from = lib->from();
1233 RawObject** to = lib->to_snapshot();
1234 for (RawObject** p = from; p <= to; p++) {
1235 s->Push(*p);
1236 }
1237 }
1238
1239 void WriteAlloc(Serializer* s) {
1240 s->WriteCid(kLibraryCid);
1241 intptr_t count = objects_.length();
1242 s->Write<intptr_t>(count);
1243 for (intptr_t i = 0; i < count; i++) {
1244 RawLibrary* lib = objects_[i];
1245 s->AssignRef(lib);
1246 }
1247 }
1248
1249 void WriteFill(Serializer* s) {
1250 intptr_t count = objects_.length();
1251 for (intptr_t i = 0; i < count; i++) {
1252 RawLibrary* lib = objects_[i];
1253 RawObject** from = lib->from();
1254 RawObject** to = lib->to_snapshot();
1255 for (RawObject** p = from; p <= to; p++) {
1256 s->WriteRef(*p);
1257 }
1258
1259 s->Write<int32_t>(lib->ptr()->index_);
1260 s->Write<uint16_t>(lib->ptr()->num_imports_);
1261 s->Write<int8_t>(lib->ptr()->load_state_);
1262 s->Write<bool>(lib->ptr()->corelib_imported_);
1263 s->Write<bool>(lib->ptr()->is_dart_scheme_);
1264 s->Write<bool>(lib->ptr()->debuggable_);
1265 }
1266 }
1267
1268 private:
1269 GrowableArray<RawLibrary*> objects_;
1270 };
1271
1272 class LibraryDeserializationCluster : public DeserializationCluster {
1273 public:
1274 LibraryDeserializationCluster() { }
1275 virtual ~LibraryDeserializationCluster() { }
1276
1277 void ReadAlloc(Deserializer* d) {
1278 start_index_ = d->next_index();
1279 PageSpace* old_space = d->heap()->old_space();
1280 intptr_t count = d->Read<intptr_t>();
1281 for (intptr_t i = 0; i < count; i++) {
1282 d->AssignRef(AllocateUninitialized(old_space, Library::InstanceSize()));
1283 }
1284 stop_index_ = d->next_index();
1285 }
1286
1287 void ReadFill(Deserializer* d) {
1288 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1289
1290 for (intptr_t id = start_index_; id < stop_index_; id++) {
1291 RawLibrary* lib = reinterpret_cast<RawLibrary*>(d->Ref(id));
1292 Deserializer::InitializeHeader(lib, kLibraryCid,
1293 Library::InstanceSize(), is_vm_object);
1294 RawObject** from = lib->from();
1295 RawObject** to_snapshot = lib->to_snapshot();
1296 RawObject** to = lib->to();
1297 for (RawObject** p = from; p <= to_snapshot; p++) {
1298 *p = d->ReadRef();
1299 }
1300 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
1301 *p = Object::null();
1302 }
1303
1304 lib->ptr()->native_entry_resolver_ = NULL;
1305 lib->ptr()->native_entry_symbol_resolver_ = NULL;
1306 lib->ptr()->index_ = d->Read<int32_t>();
1307 lib->ptr()->num_imports_ = d->Read<uint16_t>();
1308 lib->ptr()->load_state_ = d->Read<int8_t>();
1309 lib->ptr()->corelib_imported_ = d->Read<bool>();
1310 lib->ptr()->is_dart_scheme_ = d->Read<bool>();
1311 lib->ptr()->debuggable_ = d->Read<bool>();
1312 lib->ptr()->is_in_fullsnapshot_ = true;
1313 }
1314 }
1315
1316 void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
1317 // TODO(rmacnak): This is surprisingly slow, roughly 20% of deserialization
1318 // time for the JIT. Maybe make the lookups happy with a null?
1319
1320 NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
1321 Timeline::GetIsolateStream(), "PostLoadLibrary"));
1322
1323 Library& lib = Library::Handle(zone);
1324 for (intptr_t i = start_index_; i < stop_index_; i++) {
1325 lib ^= refs.At(i);
1326 const intptr_t kInitialNameCacheSize = 64;
1327 lib.InitResolvedNamesCache(kInitialNameCacheSize);
1328 }
1329 }
1330 };
1331
1332 class NamespaceSerializationCluster : public SerializationCluster {
1333 public:
1334 NamespaceSerializationCluster() { }
1335 virtual ~NamespaceSerializationCluster() { }
1336
1337 void Trace(Serializer* s, RawObject* object) {
1338 RawNamespace* ns = Namespace::RawCast(object);
1339 objects_.Add(ns);
1340
1341 RawObject** from = ns->from();
1342 RawObject** to = ns->to();
1343 for (RawObject** p = from; p <= to; p++) {
1344 s->Push(*p);
1345 }
1346 }
1347
1348 void WriteAlloc(Serializer* s) {
1349 s->WriteCid(kNamespaceCid);
1350 intptr_t count = objects_.length();
1351 s->Write<intptr_t>(count);
1352 for (intptr_t i = 0; i < count; i++) {
1353 RawNamespace* ns = objects_[i];
1354 s->AssignRef(ns);
1355 }
1356 }
1357
1358 void WriteFill(Serializer* s) {
1359 intptr_t count = objects_.length();
1360 for (intptr_t i = 0; i < count; i++) {
1361 RawNamespace* ns = objects_[i];
1362 RawObject** from = ns->from();
1363 RawObject** to = ns->to();
1364 for (RawObject** p = from; p <= to; p++) {
1365 s->WriteRef(*p);
1366 }
1367 }
1368 }
1369
1370 private:
1371 GrowableArray<RawNamespace*> objects_;
1372 };
1373
1374 class NamespaceDeserializationCluster : public DeserializationCluster {
1375 public:
1376 NamespaceDeserializationCluster() { }
1377 virtual ~NamespaceDeserializationCluster() { }
1378
1379 void ReadAlloc(Deserializer* d) {
1380 start_index_ = d->next_index();
1381 PageSpace* old_space = d->heap()->old_space();
1382 intptr_t count = d->Read<intptr_t>();
1383 for (intptr_t i = 0; i < count; i++) {
1384 d->AssignRef(AllocateUninitialized(old_space, Namespace::InstanceSize()));
1385 }
1386 stop_index_ = d->next_index();
1387 }
1388
1389 void ReadFill(Deserializer* d) {
1390 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1391
1392 for (intptr_t id = start_index_; id < stop_index_; id++) {
1393 RawNamespace* ns = reinterpret_cast<RawNamespace*>(d->Ref(id));
1394 Deserializer::InitializeHeader(ns, kNamespaceCid,
1395 Namespace::InstanceSize(), is_vm_object);
1396 RawObject** from = ns->from();
1397 RawObject** to = ns->to();
1398 for (RawObject** p = from; p <= to; p++) {
1399 *p = d->ReadRef();
1400 }
1401 }
1402 }
1403 };
1404
1405 class CodeSerializationCluster : public SerializationCluster {
1406 public:
1407 CodeSerializationCluster() { }
1408 virtual ~CodeSerializationCluster() { }
1409
1410 void Trace(Serializer* s, RawObject* object) {
1411 RawCode* code = Code::RawCast(object);
1412 objects_.Add(code);
1413
1414 s->Push(code->ptr()->object_pool_);
1415 s->Push(code->ptr()->owner_);
1416 s->Push(code->ptr()->exception_handlers_);
1417 s->Push(code->ptr()->pc_descriptors_);
1418 s->Push(code->ptr()->stackmaps_);
1419 }
1420
1421 void WriteAlloc(Serializer* s) {
1422 s->WriteCid(kCodeCid);
1423 intptr_t count = objects_.length();
1424 s->Write<intptr_t>(count);
1425 for (intptr_t i = 0; i < count; i++) {
1426 RawCode* code = objects_[i];
1427 s->AssignRef(code);
1428 }
1429 }
1430
1431 void WriteFill(Serializer* s) {
1432 Snapshot::Kind kind = s->kind();
1433 intptr_t count = objects_.length();
1434 for (intptr_t i = 0; i < count; i++) {
1435 RawCode* code = objects_[i];
1436
1437 intptr_t pointer_offsets_length =
1438 Code::PtrOffBits::decode(code->ptr()->state_bits_);
1439 if (pointer_offsets_length != 0) {
1440 FATAL("Cannot serialize code with embedded pointers");
1441 }
1442 if (kind == Snapshot::kAppNoJIT) {
1443 // No disabled code in precompilation.
1444 ASSERT(code->ptr()->instructions_ == code->ptr()->active_instructions_);
1445 } else {
1446 ASSERT(kind == Snapshot::kAppWithJIT);
1447 // We never include optimized code in JIT precompilation. Deoptimization
1448 // requires code patching and we cannot patch code that is shared
1449 // between isolates and should not mutate memory allocated by the
1450 // embedder.
1451 bool is_optimized = Code::PtrOffBits::decode(code->ptr()->state_bits_);
1452 if (is_optimized) {
1453 FATAL("Cannot include optimized code in a JIT snapshot");
1454 }
1455 }
1456
1457 RawInstructions* instr = code->ptr()->instructions_;
1458 int32_t text_offset = s->GetTextOffset(instr, code);
1459 s->Write<int32_t>(text_offset);
1460
1461 s->WriteRef(code->ptr()->object_pool_);
1462 s->WriteRef(code->ptr()->owner_);
1463 s->WriteRef(code->ptr()->exception_handlers_);
1464 s->WriteRef(code->ptr()->pc_descriptors_);
1465 s->WriteRef(code->ptr()->stackmaps_);
1466
1467 s->Write<int32_t>(code->ptr()->state_bits_);
1468 }
1469 }
1470
1471 private:
1472 GrowableArray<RawCode*> objects_;
1473 };
1474
1475 class CodeDeserializationCluster : public DeserializationCluster {
1476 public:
1477 CodeDeserializationCluster() { }
1478 virtual ~CodeDeserializationCluster() { }
1479
1480 void ReadAlloc(Deserializer* d) {
1481 start_index_ = d->next_index();
1482 PageSpace* old_space = d->heap()->old_space();
1483 intptr_t count = d->Read<intptr_t>();
1484 for (intptr_t i = 0; i < count; i++) {
1485 d->AssignRef(AllocateUninitialized(old_space, Code::InstanceSize(0)));
1486 }
1487 stop_index_ = d->next_index();
1488 }
1489
1490 void ReadFill(Deserializer* d) {
1491 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1492
1493 for (intptr_t id = start_index_; id < stop_index_; id++) {
1494 RawCode* code = reinterpret_cast<RawCode*>(d->Ref(id));
1495 Deserializer::InitializeHeader(code, kCodeCid,
1496 Code::InstanceSize(0), is_vm_object);
1497
1498 int32_t text_offset = d->Read<int32_t>();
1499 RawInstructions* instr = reinterpret_cast<RawInstructions*>(
1500 d->GetInstructionsAt(text_offset) + kHeapObjectTag);
1501 uword entry_point = Instructions::EntryPoint(instr);
1502
1503 code->ptr()->entry_point_ = entry_point;
1504 code->ptr()->active_instructions_ = instr;
1505 code->ptr()->instructions_ = instr;
1506 code->ptr()->object_pool_ =
1507 reinterpret_cast<RawObjectPool*>(d->ReadRef());
1508 code->ptr()->owner_ = d->ReadRef();
1509 code->ptr()->exception_handlers_ =
1510 reinterpret_cast<RawExceptionHandlers*>(d->ReadRef());
1511 code->ptr()->pc_descriptors_ =
1512 reinterpret_cast<RawPcDescriptors*>(d->ReadRef());
1513 code->ptr()->stackmaps_ =
1514 reinterpret_cast<RawArray*>(d->ReadRef());
1515
1516 code->ptr()->deopt_info_array_ = Array::null();
1517 code->ptr()->static_calls_target_table_ = Array::null();
1518 code->ptr()->var_descriptors_ = LocalVarDescriptors::null();
1519 code->ptr()->inlined_metadata_ = Array::null();
1520 code->ptr()->code_source_map_ = CodeSourceMap::null();
1521 code->ptr()->comments_ = Array::null();
1522 code->ptr()->return_address_metadata_ = Object::null();
1523
1524 code->ptr()->compile_timestamp_ = 0;
1525 code->ptr()->state_bits_ = d->Read<int32_t>();
1526 code->ptr()->lazy_deopt_pc_offset_ = -1;
1527 }
1528 }
1529 };
1530
1531 class ObjectPoolSerializationCluster : public SerializationCluster {
1532 public:
1533 ObjectPoolSerializationCluster() { }
1534 virtual ~ObjectPoolSerializationCluster() { }
1535
1536 void Trace(Serializer* s, RawObject* object) {
1537 RawObjectPool* pool = ObjectPool::RawCast(object);
1538 objects_.Add(pool);
1539
1540 intptr_t length = pool->ptr()->length_;
1541 RawTypedData* info_array = pool->ptr()->info_array_;
1542
1543 for (intptr_t i = 0; i < length; i++) {
1544 ObjectPool::EntryType entry_type =
1545 static_cast<ObjectPool::EntryType>(info_array->ptr()->data()[i]);
1546 if (entry_type == ObjectPool::kTaggedObject) {
1547 s->Push(pool->ptr()->data()[i].raw_obj_);
1548 }
1549 }
1550
1551 // We are going to allocate the object pool and its info array together,
1552 // so steal a slot in the refs array to hold it between alloc and fill.
1553 // s->NoteUntracedRef();
siva 2016/06/30 00:06:08 Code commented out, can it be deleted?
rmacnak 2016/06/30 01:39:21 -> TODO
1554 }
1555
1556 void WriteAlloc(Serializer* s) {
1557 s->WriteCid(kObjectPoolCid);
1558 intptr_t count = objects_.length();
1559 s->Write<intptr_t>(count);
1560 for (intptr_t i = 0; i < count; i++) {
1561 RawObjectPool* pool = objects_[i];
1562 /// RawTypedData* info_array = pool->ptr()->info_array_;
1563 intptr_t length = pool->ptr()->length_;
1564 s->Write<intptr_t>(length);
1565 /// s->AssignRefNotTraced(info_array);
1566 s->AssignRef(pool);
1567 }
1568 }
1569
1570 void WriteFill(Serializer* s) {
1571 intptr_t count = objects_.length();
1572 for (intptr_t i = 0; i < count; i++) {
1573 RawObjectPool* pool = objects_[i];
1574 RawTypedData* info_array = pool->ptr()->info_array_;
1575 intptr_t length = pool->ptr()->length_;
1576 s->Write<intptr_t>(length);
1577 for (intptr_t j = 0; j < length; j++) {
1578 ObjectPool::EntryType entry_type =
1579 static_cast<ObjectPool::EntryType>(info_array->ptr()->data()[j]);
1580 s->Write<int8_t>(entry_type);
1581 RawObjectPool::Entry& entry = pool->ptr()->data()[j];
1582 switch (entry_type) {
1583 case ObjectPool::kTaggedObject: {
1584 #if !defined(TARGET_ARCH_DBC)
1585 if (entry.raw_obj_ ==
1586 StubCode::CallNativeCFunction_entry()->code()) {
1587 // Natives can run while precompiling, becoming linked and
1588 // switching their stub. Reset to the initial stub used for
1589 // lazy-linking.
1590 s->WriteRef(StubCode::CallBootstrapCFunction_entry()->code());
1591 break;
1592 }
1593 #endif
1594 s->WriteRef(entry.raw_obj_);
1595 break;
1596 }
1597 case ObjectPool::kImmediate: {
1598 s->Write<intptr_t>(entry.raw_value_);
1599 break;
1600 }
1601 case ObjectPool::kNativeEntry: {
1602 // Write nothing. Will initialize with the lazy link entry.
1603 #if defined(TARGET_ARCH_DBC)
1604 UNREACHABLE(); // DBC does not support lazy native call linking.
1605 #endif
1606 break;
1607 }
1608 default:
1609 UNREACHABLE();
1610 }
1611 }
1612 }
1613 }
1614
1615 private:
1616 GrowableArray<RawObjectPool*> objects_;
1617 };
1618
1619
1620 class ObjectPoolDeserializationCluster : public DeserializationCluster {
1621 public:
1622 ObjectPoolDeserializationCluster() { }
1623 virtual ~ObjectPoolDeserializationCluster() { }
1624
1625 void ReadAlloc(Deserializer* d) {
1626 start_index_ = d->next_index();
1627 PageSpace* old_space = d->heap()->old_space();
1628 intptr_t count = d->Read<intptr_t>();
1629 for (intptr_t i = 0; i < count; i++) {
1630 intptr_t length = d->Read<intptr_t>();
1631 /// d->AssignRef(AllocateUninitialized(old_space,
1632 /// TypedData::InstanceSize(length)));
1633 d->AssignRef(AllocateUninitialized(old_space,
1634 ObjectPool::InstanceSize(length)));
1635 }
1636 stop_index_ = d->next_index();
1637 }
1638
1639 void ReadFill(Deserializer* d) {
1640 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1641 PageSpace* old_space = d->heap()->old_space();
1642 for (intptr_t id = start_index_; id < stop_index_; id += 1) {
1643 intptr_t length = d->Read<intptr_t>();
1644 /// RawTypedData* info_array =
1645 /// reinterpret_cast<RawTypedData*>(d->Ref(id));
1646 RawTypedData* info_array = reinterpret_cast<RawTypedData*>(
1647 AllocateUninitialized(old_space, TypedData::InstanceSize(length)));
1648 Deserializer::InitializeHeader(info_array, kTypedDataUint8ArrayCid,
1649 TypedData::InstanceSize(length),
1650 is_vm_object);
1651 info_array->ptr()->length_ = Smi::New(length);
1652 RawObjectPool* pool = reinterpret_cast<RawObjectPool*>(d->Ref(id + 0));
1653 Deserializer::InitializeHeader(pool, kObjectPoolCid,
1654 ObjectPool::InstanceSize(length),
1655 is_vm_object);
1656 pool->ptr()->length_ = length;
1657 pool->ptr()->info_array_ = info_array;
1658 for (intptr_t j = 0; j < length; j++) {
1659 ObjectPool::EntryType entry_type =
1660 static_cast<ObjectPool::EntryType>(d->Read<int8_t>());
1661 info_array->ptr()->data()[j] = entry_type;
1662 RawObjectPool::Entry& entry = pool->ptr()->data()[j];
1663 switch (entry_type) {
1664 case ObjectPool::kTaggedObject:
1665 entry.raw_obj_ = d->ReadRef();
1666 break;
1667 case ObjectPool::kImmediate:
1668 entry.raw_value_ = d->Read<intptr_t>();
1669 break;
1670 case ObjectPool::kNativeEntry: {
1671 #if !defined(TARGET_ARCH_DBC)
1672 // Read nothing. Initialize with the lazy link entry.
1673 uword new_entry = NativeEntry::LinkNativeCallEntry();
1674 entry.raw_value_ = static_cast<intptr_t>(new_entry);
1675 #else
1676 UNREACHABLE(); // DBC does not support lazy native call linking.
1677 #endif
1678 break;
1679 }
1680 default:
1681 UNREACHABLE();
1682 }
1683 }
1684 }
1685 }
1686 };
1687
1688
1689 // PcDescriptor, Stackmap, OneByteString, TwoByteString
1690 class RODataSerializationCluster : public SerializationCluster {
1691 public:
1692 explicit RODataSerializationCluster(intptr_t cid) : cid_(cid) { }
1693 virtual ~RODataSerializationCluster() { }
1694
1695 void Trace(Serializer* s, RawObject* object) {
1696 objects_.Add(object);
1697
1698 // A string's hash must already be computed when we write it because it
1699 // will be loaded into read-only memory.
1700 if (cid_ == kOneByteStringCid) {
1701 RawOneByteString* str = static_cast<RawOneByteString*>(object);
1702 if (str->ptr()->hash_ == Smi::New(0)) {
1703 intptr_t hash = String::Hash(str->ptr()->data(),
1704 Smi::Value(str->ptr()->length_));
1705 str->ptr()->hash_ = Smi::New(hash);
1706 }
1707 ASSERT(str->ptr()->hash_ != Smi::New(0));
1708 } else if (cid_ == kTwoByteStringCid) {
1709 RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
1710 if (str->ptr()->hash_ == Smi::New(0)) {
1711 intptr_t hash = String::Hash(str->ptr()->data(),
1712 Smi::Value(str->ptr()->length_) * 2);
1713 str->ptr()->hash_ = Smi::New(hash);
1714 }
1715 ASSERT(str->ptr()->hash_ != Smi::New(0));
1716 }
1717 }
1718
1719 void WriteAlloc(Serializer* s) {
1720 s->WriteCid(cid_);
1721 intptr_t count = objects_.length();
1722 s->Write<intptr_t>(count);
1723 for (intptr_t i = 0; i < count; i++) {
1724 RawObject* object = objects_[i];
1725 int32_t rodata_offset = s->GetRODataOffset(object);
1726 s->Write<int32_t>(rodata_offset);
1727 s->AssignRef(object);
1728 }
1729 }
1730
1731 void WriteFill(Serializer* s) {
1732 // No-op.
1733 }
1734
1735 private:
1736 const intptr_t cid_;
1737 GrowableArray<RawObject*> objects_;
1738 };
1739
1740
1741 class RODataDeserializationCluster : public DeserializationCluster {
1742 public:
1743 RODataDeserializationCluster() { }
1744 virtual ~RODataDeserializationCluster() { }
1745
1746 void ReadAlloc(Deserializer* d) {
1747 intptr_t count = d->Read<intptr_t>();
1748 for (intptr_t i = 0; i < count; i++) {
1749 int32_t rodata_offset = d->Read<int32_t>();
1750 d->AssignRef(d->GetObjectAt(rodata_offset));
1751 }
1752 }
1753
1754 void ReadFill(Deserializer* d) {
1755 // No-op.
1756 }
1757 };
1758
1759
1760 class LocalVarDescriptorsSerializationCluster : public SerializationCluster {
1761 public:
1762 LocalVarDescriptorsSerializationCluster() { }
1763 virtual ~LocalVarDescriptorsSerializationCluster() { }
1764
1765 void Trace(Serializer* s, RawObject* object) { UNIMPLEMENTED(); }
1766 void WriteAlloc(Serializer* s) {}
1767 void WriteFill(Serializer* s) {}
1768
1769 private:
1770 GrowableArray<RawClass*> objects_;
1771 };
1772
1773
1774 class ExceptionHandlersSerializationCluster : public SerializationCluster {
1775 public:
1776 ExceptionHandlersSerializationCluster() { }
1777 virtual ~ExceptionHandlersSerializationCluster() { }
1778
1779 void Trace(Serializer* s, RawObject* object) {
1780 RawExceptionHandlers* handlers = ExceptionHandlers::RawCast(object);
1781 objects_.Add(handlers);
1782
1783 s->Push(handlers->ptr()->handled_types_data_);
1784 }
1785
1786 void WriteAlloc(Serializer* s) {
1787 s->WriteCid(kExceptionHandlersCid);
1788 intptr_t count = objects_.length();
1789 s->Write<intptr_t>(count);
1790 for (intptr_t i = 0; i < count; i++) {
1791 RawExceptionHandlers* handlers = objects_[i];
1792 intptr_t length = handlers->ptr()->num_entries_;
1793 s->Write<intptr_t>(length);
1794 s->AssignRef(handlers);
1795 }
1796 }
1797
1798 void WriteFill(Serializer* s) {
1799 intptr_t count = objects_.length();
1800 for (intptr_t i = 0; i < count; i++) {
1801 RawExceptionHandlers* handlers = objects_[i];
1802 intptr_t length = handlers->ptr()->num_entries_;
1803 s->Write<intptr_t>(length);
1804 s->WriteRef(handlers->ptr()->handled_types_data_);
1805
1806 uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
1807 intptr_t length_in_bytes =
1808 length * sizeof(RawExceptionHandlers::HandlerInfo);
1809 s->WriteBytes(data, length_in_bytes);
1810 }
1811 }
1812
1813 private:
1814 GrowableArray<RawExceptionHandlers*> objects_;
1815 };
1816
1817 class ExceptionHandlersDeserializationCluster : public DeserializationCluster {
1818 public:
1819 ExceptionHandlersDeserializationCluster() { }
1820 virtual ~ExceptionHandlersDeserializationCluster() { }
1821
1822 void ReadAlloc(Deserializer* d) {
1823 start_index_ = d->next_index();
1824 PageSpace* old_space = d->heap()->old_space();
1825 intptr_t count = d->Read<intptr_t>();
1826 for (intptr_t i = 0; i < count; i++) {
1827 intptr_t length = d->Read<intptr_t>();
1828 d->AssignRef(AllocateUninitialized(old_space,
1829 ExceptionHandlers::InstanceSize(length)));
1830 }
1831 stop_index_ = d->next_index();
1832 }
1833
1834 void ReadFill(Deserializer* d) {
1835 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1836
1837 for (intptr_t id = start_index_; id < stop_index_; id++) {
1838 RawExceptionHandlers* handlers =
1839 reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
1840 intptr_t length = d->Read<intptr_t>();
1841 Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
1842 ExceptionHandlers::InstanceSize(length),
1843 is_vm_object);
1844 handlers->ptr()->num_entries_ = length;
1845 handlers->ptr()->handled_types_data_ =
1846 reinterpret_cast<RawArray*>(d->ReadRef());
1847
1848 uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
1849 intptr_t length_in_bytes =
1850 length * sizeof(RawExceptionHandlers::HandlerInfo);
1851 d->ReadBytes(data, length_in_bytes);
1852 }
1853 }
1854 };
1855
1856 class ContextSerializationCluster : public SerializationCluster {
1857 public:
1858 ContextSerializationCluster() { }
1859 virtual ~ContextSerializationCluster() { }
1860
1861 void Trace(Serializer* s, RawObject* object) {
1862 RawContext* context = Context::RawCast(object);
1863 objects_.Add(context);
1864
1865 s->Push(context->ptr()->parent_);
1866 intptr_t length = context->ptr()->num_variables_;
1867 for (intptr_t i = 0; i < length; i++) {
1868 s->Push(context->ptr()->data()[i]);
1869 }
1870 }
1871
1872 void WriteAlloc(Serializer* s) {
1873 s->WriteCid(kContextCid);
1874 intptr_t count = objects_.length();
1875 s->Write<intptr_t>(count);
1876 for (intptr_t i = 0; i < count; i++) {
1877 RawContext* context = objects_[i];
1878 intptr_t length = context->ptr()->num_variables_;
1879 s->Write<intptr_t>(length);
1880 s->AssignRef(context);
1881 }
1882 }
1883
1884 void WriteFill(Serializer* s) {
1885 intptr_t count = objects_.length();
1886 for (intptr_t i = 0; i < count; i++) {
1887 RawContext* context = objects_[i];
1888 intptr_t length = context->ptr()->num_variables_;
1889 s->Write<intptr_t>(length);
1890 s->WriteRef(context->ptr()->parent_);
1891 for (intptr_t j = 0; j < length; j++) {
1892 s->WriteRef(context->ptr()->data()[j]);
1893 }
1894 }
1895 }
1896
1897 private:
1898 GrowableArray<RawContext*> objects_;
1899 };
1900
1901 class ContextDeserializationCluster : public DeserializationCluster {
1902 public:
1903 ContextDeserializationCluster() { }
1904 virtual ~ContextDeserializationCluster() { }
1905
1906 void ReadAlloc(Deserializer* d) {
1907 start_index_ = d->next_index();
1908 PageSpace* old_space = d->heap()->old_space();
1909 intptr_t count = d->Read<intptr_t>();
1910 for (intptr_t i = 0; i < count; i++) {
1911 intptr_t length = d->Read<intptr_t>();
1912 d->AssignRef(AllocateUninitialized(old_space,
1913 Context::InstanceSize(length)));
1914 }
1915 stop_index_ = d->next_index();
1916 }
1917
1918 void ReadFill(Deserializer* d) {
1919 bool is_vm_object = d->isolate() == Dart::vm_isolate();
1920
1921 for (intptr_t id = start_index_; id < stop_index_; id++) {
1922 RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
1923 intptr_t length = d->Read<intptr_t>();
1924 Deserializer::InitializeHeader(context, kContextCid,
1925 Context::InstanceSize(length),
1926 is_vm_object);
1927 context->ptr()->num_variables_ = length;
1928 context->ptr()->parent_ = reinterpret_cast<RawContext*>(d->ReadRef());
1929 for (intptr_t j = 0; j < length; j++) {
1930 context->ptr()->data()[j] = d->ReadRef();
1931 }
1932 }
1933 }
1934 };
1935
1936 class ContextScopeSerializationCluster : public SerializationCluster {
1937 public:
1938 ContextScopeSerializationCluster() { }
1939 virtual ~ContextScopeSerializationCluster() { }
1940
1941 void Trace(Serializer* s, RawObject* object) {
1942 RawContextScope* scope = ContextScope::RawCast(object);
1943 objects_.Add(scope);
1944
1945 intptr_t length = scope->ptr()->num_variables_;
1946 RawObject** from = scope->from();
1947 RawObject** to = scope->to(length);
1948 for (RawObject** p = from; p <= to; p++) {
1949 s->Push(*p);
1950 }
1951 }
1952
1953 void WriteAlloc(Serializer* s) {
1954 s->WriteCid(kContextScopeCid);
1955 intptr_t count = objects_.length();
1956 s->Write<intptr_t>(count);
1957 for (intptr_t i = 0; i < count; i++) {
1958 RawContextScope* scope = objects_[i];
1959 intptr_t length = scope->ptr()->num_variables_;
1960 s->Write<intptr_t>(length);
1961 s->AssignRef(scope);
1962 }
1963 }
1964
1965 void WriteFill(Serializer* s) {
1966 intptr_t count = objects_.length();
1967 for (intptr_t i = 0; i < count; i++) {
1968 RawContextScope* scope = objects_[i];
1969 intptr_t length = scope->ptr()->num_variables_;
1970 s->Write<intptr_t>(length);
1971 s->Write<bool>(scope->ptr()->is_implicit_);
1972 RawObject** from = scope->from();
1973 RawObject** to = scope->to(length);
1974 for (RawObject** p = from; p <= to; p++) {
1975 s->WriteRef(*p);
1976 }
1977 }
1978 }
1979
1980 private:
1981 GrowableArray<RawContextScope*> objects_;
1982 };
1983
1984 class ContextScopeDeserializationCluster : public DeserializationCluster {
1985 public:
1986 ContextScopeDeserializationCluster() { }
1987 virtual ~ContextScopeDeserializationCluster() { }
1988
1989 void ReadAlloc(Deserializer* d) {
1990 start_index_ = d->next_index();
1991 PageSpace* old_space = d->heap()->old_space();
1992 intptr_t count = d->Read<intptr_t>();
1993 for (intptr_t i = 0; i < count; i++) {
1994 intptr_t length = d->Read<intptr_t>();
1995 d->AssignRef(AllocateUninitialized(old_space,
1996 ContextScope::InstanceSize(length)));
1997 }
1998 stop_index_ = d->next_index();
1999 }
2000
2001 void ReadFill(Deserializer* d) {
2002 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2003
2004 for (intptr_t id = start_index_; id < stop_index_; id++) {
2005 RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
2006 intptr_t length = d->Read<intptr_t>();
2007 Deserializer::InitializeHeader(scope, kContextScopeCid,
2008 ContextScope::InstanceSize(length),
2009 is_vm_object);
2010 scope->ptr()->num_variables_ = length;
2011 scope->ptr()->is_implicit_ = d->Read<bool>();
2012 RawObject** from = scope->from();
2013 RawObject** to = scope->to(length);
2014 for (RawObject** p = from; p <= to; p++) {
2015 *p = d->ReadRef();
2016 }
2017 }
2018 }
2019 };
2020
2021
2022 class ICDataSerializationCluster : public SerializationCluster {
2023 public:
2024 ICDataSerializationCluster() { }
2025 virtual ~ICDataSerializationCluster() { }
2026
2027 void Trace(Serializer* s, RawObject* object) {
2028 RawICData* ic = ICData::RawCast(object);
2029 objects_.Add(ic);
2030
2031 RawObject** from = ic->from();
2032 RawObject** to = ic->to_snapshot(s->kind());
2033 for (RawObject** p = from; p <= to; p++) {
2034 s->Push(*p);
2035 }
2036 }
2037
2038 void WriteAlloc(Serializer* s) {
2039 s->WriteCid(kICDataCid);
2040 intptr_t count = objects_.length();
2041 s->Write<intptr_t>(count);
2042 for (intptr_t i = 0; i < count; i++) {
2043 RawICData* ic = objects_[i];
2044 s->AssignRef(ic);
2045 }
2046 }
2047
2048 void WriteFill(Serializer* s) {
2049 Snapshot::Kind kind = s->kind();
2050 intptr_t count = objects_.length();
2051 for (intptr_t i = 0; i < count; i++) {
2052 RawICData* ic = objects_[i];
2053 RawObject** from = ic->from();
2054 RawObject** to = ic->to_snapshot(kind);
2055 for (RawObject** p = from; p <= to; p++) {
2056 s->WriteRef(*p);
2057 }
2058 s->Write<int32_t>(ic->ptr()->deopt_id_);
2059 s->Write<uint32_t>(ic->ptr()->state_bits_);
2060 #if defined(TAG_IC_DATA)
2061 s->Write<intptr_t>(ic->ptr()->tag_);
2062 #endif
2063 }
2064 }
2065
2066 private:
2067 GrowableArray<RawICData*> objects_;
2068 };
2069
2070 class ICDataDeserializationCluster : public DeserializationCluster {
2071 public:
2072 ICDataDeserializationCluster() { }
2073 virtual ~ICDataDeserializationCluster() { }
2074
2075 void ReadAlloc(Deserializer* d) {
2076 start_index_ = d->next_index();
2077 PageSpace* old_space = d->heap()->old_space();
2078 intptr_t count = d->Read<intptr_t>();
2079 for (intptr_t i = 0; i < count; i++) {
2080 d->AssignRef(AllocateUninitialized(old_space, ICData::InstanceSize()));
2081 }
2082 stop_index_ = d->next_index();
2083 }
2084
2085 void ReadFill(Deserializer* d) {
2086 Snapshot::Kind kind = d->kind();
2087 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2088
2089 for (intptr_t id = start_index_; id < stop_index_; id++) {
2090 RawICData* ic = reinterpret_cast<RawICData*>(d->Ref(id));
2091 Deserializer::InitializeHeader(ic, kICDataCid,
2092 ICData::InstanceSize(), is_vm_object);
2093 RawObject** from = ic->from();
2094 RawObject** to_snapshot = ic->to_snapshot(kind);
2095 RawObject** to = ic->to();
2096 for (RawObject** p = from; p <= to_snapshot; p++) {
2097 *p = d->ReadRef();
2098 }
2099 for (RawObject** p = to_snapshot + 1; p <= to; p++) {
2100 *p = Object::null();
2101 }
2102 ic->ptr()->deopt_id_ = d->Read<int32_t>();
2103 ic->ptr()->state_bits_ = d->Read<int32_t>();
2104 #if defined(TAG_IC_DATA)
2105 ic->ptr()->tag_ = d->Read<intptr_t>();
2106 #endif
2107 }
2108 }
2109
2110 void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
2111 NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
2112 Timeline::GetIsolateStream(), "PostLoadICData"));
2113
2114 if (kind == Snapshot::kAppNoJIT) {
2115 ICData& ic = ICData::Handle(zone);
2116 Object& funcOrCode = Object::Handle(zone);
2117 Code& code = Code::Handle(zone);
2118 Smi& entry_point = Smi::Handle(zone);
2119 for (intptr_t i = start_index_; i < stop_index_; i++) {
2120 ic ^= refs.At(i);
2121 for (intptr_t j = 0; j < ic.NumberOfChecks(); j++) {
2122 funcOrCode = ic.GetTargetOrCodeAt(j);
2123 if (funcOrCode.IsCode()) {
2124 code ^= funcOrCode.raw();
2125 entry_point = Smi::FromAlignedAddress(code.EntryPoint());
2126 ic.SetEntryPointAt(j, entry_point);
2127 }
2128 }
2129 }
2130 }
2131 }
2132 };
2133
2134 class MegamorphicCacheSerializationCluster : public SerializationCluster {
2135 public:
2136 MegamorphicCacheSerializationCluster() { }
2137 virtual ~MegamorphicCacheSerializationCluster() { }
2138
2139 void Trace(Serializer* s, RawObject* object) {
2140 RawMegamorphicCache* cache = MegamorphicCache::RawCast(object);
2141 objects_.Add(cache);
2142
2143 RawObject** from = cache->from();
2144 RawObject** to = cache->to();
2145 for (RawObject** p = from; p <= to; p++) {
2146 s->Push(*p);
2147 }
2148 }
2149
2150 void WriteAlloc(Serializer* s) {
2151 s->WriteCid(kMegamorphicCacheCid);
2152 intptr_t count = objects_.length();
2153 s->Write<intptr_t>(count);
2154 for (intptr_t i = 0; i < count; i++) {
2155 RawMegamorphicCache* cache = objects_[i];
2156 s->AssignRef(cache);
2157 }
2158 }
2159
2160 void WriteFill(Serializer* s) {
2161 intptr_t count = objects_.length();
2162 for (intptr_t i = 0; i < count; i++) {
2163 RawMegamorphicCache* cache = objects_[i];
2164 RawObject** from = cache->from();
2165 RawObject** to = cache->to();
2166 for (RawObject** p = from; p <= to; p++) {
2167 s->WriteRef(*p);
2168 }
2169 s->Write<int32_t>(cache->ptr()->filled_entry_count_);
2170 }
2171 }
2172
2173 private:
2174 GrowableArray<RawMegamorphicCache*> objects_;
2175 };
2176
2177
2178 class MegamorphicCacheDeserializationCluster : public DeserializationCluster {
2179 public:
2180 MegamorphicCacheDeserializationCluster() { }
2181 virtual ~MegamorphicCacheDeserializationCluster() { }
2182
2183 void ReadAlloc(Deserializer* d) {
2184 start_index_ = d->next_index();
2185 PageSpace* old_space = d->heap()->old_space();
2186 intptr_t count = d->Read<intptr_t>();
2187 for (intptr_t i = 0; i < count; i++) {
2188 d->AssignRef(AllocateUninitialized(old_space,
2189 MegamorphicCache::InstanceSize()));
2190 }
2191 stop_index_ = d->next_index();
2192 }
2193
2194 void ReadFill(Deserializer* d) {
2195 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2196
2197 for (intptr_t id = start_index_; id < stop_index_; id++) {
2198 RawMegamorphicCache* cache =
2199 reinterpret_cast<RawMegamorphicCache*>(d->Ref(id));
2200 Deserializer::InitializeHeader(cache, kMegamorphicCacheCid,
2201 MegamorphicCache::InstanceSize(),
2202 is_vm_object);
2203 RawObject** from = cache->from();
2204 RawObject** to = cache->to();
2205 for (RawObject** p = from; p <= to; p++) {
2206 *p = d->ReadRef();
2207 }
2208 cache->ptr()->filled_entry_count_ = d->Read<int32_t>();
2209 }
2210 }
2211 };
2212
2213
2214 class SubtypeTestCacheSerializationCluster : public SerializationCluster {
2215 public:
2216 SubtypeTestCacheSerializationCluster() { }
2217 virtual ~SubtypeTestCacheSerializationCluster() { }
2218
2219 void Trace(Serializer* s, RawObject* object) {
2220 RawSubtypeTestCache* cache = SubtypeTestCache::RawCast(object);
2221 objects_.Add(cache);
2222 s->Push(cache->ptr()->cache_);
2223 }
2224
2225 void WriteAlloc(Serializer* s) {
2226 s->WriteCid(kSubtypeTestCacheCid);
2227 intptr_t count = objects_.length();
2228 s->Write<intptr_t>(count);
2229 for (intptr_t i = 0; i < count; i++) {
2230 RawSubtypeTestCache* cache = objects_[i];
2231 s->AssignRef(cache);
2232 }
2233 }
2234
2235 void WriteFill(Serializer* s) {
2236 intptr_t count = objects_.length();
2237 for (intptr_t i = 0; i < count; i++) {
2238 RawSubtypeTestCache* cache = objects_[i];
2239 s->WriteRef(cache->ptr()->cache_);
2240 }
2241 }
2242
2243 private:
2244 GrowableArray<RawSubtypeTestCache*> objects_;
2245 };
2246
2247 class SubtypeTestCacheDeserializationCluster : public DeserializationCluster {
2248 public:
2249 SubtypeTestCacheDeserializationCluster() { }
2250 virtual ~SubtypeTestCacheDeserializationCluster() { }
2251
2252 void ReadAlloc(Deserializer* d) {
2253 start_index_ = d->next_index();
2254 PageSpace* old_space = d->heap()->old_space();
2255 intptr_t count = d->Read<intptr_t>();
2256 for (intptr_t i = 0; i < count; i++) {
2257 d->AssignRef(AllocateUninitialized(old_space,
2258 SubtypeTestCache::InstanceSize()));
2259 }
2260 stop_index_ = d->next_index();
2261 }
2262
2263 void ReadFill(Deserializer* d) {
2264 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2265
2266 for (intptr_t id = start_index_; id < stop_index_; id++) {
2267 RawSubtypeTestCache* cache =
2268 reinterpret_cast<RawSubtypeTestCache*>(d->Ref(id));
2269 Deserializer::InitializeHeader(cache, kSubtypeTestCacheCid,
2270 SubtypeTestCache::InstanceSize(),
2271 is_vm_object);
2272 cache->ptr()->cache_ = reinterpret_cast<RawArray*>(d->ReadRef());
2273 }
2274 }
2275 };
2276
2277 class LanguageErrorSerializationCluster : public SerializationCluster {
2278 public:
2279 LanguageErrorSerializationCluster() { }
2280 virtual ~LanguageErrorSerializationCluster() { }
2281
2282 void Trace(Serializer* s, RawObject* object) {
2283 RawLanguageError* error = LanguageError::RawCast(object);
2284 objects_.Add(error);
2285
2286 RawObject** from = error->from();
2287 RawObject** to = error->to();
2288 for (RawObject** p = from; p <= to; p++) {
2289 s->Push(*p);
2290 }
2291 }
2292
2293 void WriteAlloc(Serializer* s) {
2294 s->WriteCid(kLanguageErrorCid);
2295 intptr_t count = objects_.length();
2296 s->Write<intptr_t>(count);
2297 for (intptr_t i = 0; i < count; i++) {
2298 RawLanguageError* error = objects_[i];
2299 s->AssignRef(error);
2300 }
2301 }
2302
2303 void WriteFill(Serializer* s) {
2304 intptr_t count = objects_.length();
2305 for (intptr_t i = 0; i < count; i++) {
2306 RawLanguageError* error = objects_[i];
2307 RawObject** from = error->from();
2308 RawObject** to = error->to();
2309 for (RawObject** p = from; p <= to; p++) {
2310 s->WriteRef(*p);
2311 }
2312 s->WriteTokenPosition(error->ptr()->token_pos_);
2313 s->Write<bool>(error->ptr()->report_after_token_);
2314 s->Write<int8_t>(error->ptr()->kind_);
2315 }
2316 }
2317
2318 private:
2319 GrowableArray<RawLanguageError*> objects_;
2320 };
2321
2322 class LanguageErrorDeserializationCluster : public DeserializationCluster {
2323 public:
2324 LanguageErrorDeserializationCluster() { }
2325 virtual ~LanguageErrorDeserializationCluster() { }
2326
2327 void ReadAlloc(Deserializer* d) {
2328 start_index_ = d->next_index();
2329 PageSpace* old_space = d->heap()->old_space();
2330 intptr_t count = d->Read<intptr_t>();
2331 for (intptr_t i = 0; i < count; i++) {
2332 d->AssignRef(AllocateUninitialized(old_space,
2333 LanguageError::InstanceSize()));
2334 }
2335 stop_index_ = d->next_index();
2336 }
2337
2338 void ReadFill(Deserializer* d) {
2339 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2340
2341 for (intptr_t id = start_index_; id < stop_index_; id++) {
2342 RawLanguageError* error = reinterpret_cast<RawLanguageError*>(d->Ref(id));
2343 Deserializer::InitializeHeader(error, kLanguageErrorCid,
2344 LanguageError::InstanceSize(),
2345 is_vm_object);
2346 RawObject** from = error->from();
2347 RawObject** to = error->to();
2348 for (RawObject** p = from; p <= to; p++) {
2349 *p = d->ReadRef();
2350 }
2351 error->ptr()->token_pos_ = d->ReadTokenPosition();
2352 error->ptr()->report_after_token_ = d->Read<bool>();
2353 error->ptr()->kind_ = d->Read<int8_t>();
2354 }
2355 }
2356 };
2357
2358 class UnhandledExceptionSerializationCluster : public SerializationCluster {
2359 public:
2360 UnhandledExceptionSerializationCluster() { }
2361 virtual ~UnhandledExceptionSerializationCluster() { }
2362
2363 void Trace(Serializer* s, RawObject* object) {
2364 RawUnhandledException* exception = UnhandledException::RawCast(object);
2365 objects_.Add(exception);
2366
2367 RawObject** from = exception->from();
2368 RawObject** to = exception->to();
2369 for (RawObject** p = from; p <= to; p++) {
2370 s->Push(*p);
2371 }
2372 }
2373
2374 void WriteAlloc(Serializer* s) {
2375 s->WriteCid(kUnhandledExceptionCid);
2376 intptr_t count = objects_.length();
2377 s->Write<intptr_t>(count);
2378 for (intptr_t i = 0; i < count; i++) {
2379 RawUnhandledException* exception = objects_[i];
2380 s->AssignRef(exception);
2381 }
2382 }
2383
2384 void WriteFill(Serializer* s) {
2385 intptr_t count = objects_.length();
2386 for (intptr_t i = 0; i < count; i++) {
2387 RawUnhandledException* exception = objects_[i];
2388 RawObject** from = exception->from();
2389 RawObject** to = exception->to();
2390 for (RawObject** p = from; p <= to; p++) {
2391 s->WriteRef(*p);
2392 }
2393 }
2394 }
2395
2396 private:
2397 GrowableArray<RawUnhandledException*> objects_;
2398 };
2399
2400 class UnhandledExceptionDeserializationCluster : public DeserializationCluster {
2401 public:
2402 UnhandledExceptionDeserializationCluster() { }
2403 virtual ~UnhandledExceptionDeserializationCluster() { }
2404
2405 void ReadAlloc(Deserializer* d) {
2406 start_index_ = d->next_index();
2407 PageSpace* old_space = d->heap()->old_space();
2408 intptr_t count = d->Read<intptr_t>();
2409 for (intptr_t i = 0; i < count; i++) {
2410 d->AssignRef(AllocateUninitialized(old_space,
2411 UnhandledException::InstanceSize()));
2412 }
2413 stop_index_ = d->next_index();
2414 }
2415
2416 void ReadFill(Deserializer* d) {
2417 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2418
2419 for (intptr_t id = start_index_; id < stop_index_; id++) {
2420 RawUnhandledException* exception =
2421 reinterpret_cast<RawUnhandledException*>(d->Ref(id));
2422 Deserializer::InitializeHeader(exception, kUnhandledExceptionCid,
2423 UnhandledException::InstanceSize(),
2424 is_vm_object);
2425 RawObject** from = exception->from();
2426 RawObject** to = exception->to();
2427 for (RawObject** p = from; p <= to; p++) {
2428 *p = d->ReadRef();
2429 }
2430 }
2431 }
2432 };
2433
2434 class InstanceSerializationCluster : public SerializationCluster {
2435 public:
2436 explicit InstanceSerializationCluster(intptr_t cid) : cid_(cid) {
2437 RawClass* cls = Isolate::Current()->class_table()->At(cid);
2438 next_field_offset_ =
2439 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2;
2440 instance_size_in_words_ = cls->ptr()->instance_size_in_words_;
2441 ASSERT(next_field_offset_ > 0);
2442 ASSERT(instance_size_in_words_ > 0);
2443 }
2444 virtual ~InstanceSerializationCluster() { }
2445
2446 void Trace(Serializer* s, RawObject* object) {
2447 RawInstance* instance = Instance::RawCast(object);
2448 objects_.Add(instance);
2449
2450 intptr_t offset = Instance::NextFieldOffset();
2451 while (offset < next_field_offset_) {
2452 RawObject* raw_obj = *reinterpret_cast<RawObject**>(
2453 reinterpret_cast<uword>(instance->ptr()) + offset);
2454 s->Push(raw_obj);
2455 offset += kWordSize;
2456 }
2457 }
2458
2459 void WriteAlloc(Serializer* s) {
2460 s->Write<intptr_t>(cid_);
2461 intptr_t count = objects_.length();
2462 s->Write<intptr_t>(count);
2463
2464 s->Write<intptr_t>(next_field_offset_);
2465 s->Write<intptr_t>(instance_size_in_words_);
2466
2467 for (intptr_t i = 0; i < count; i++) {
2468 RawInstance* instance = objects_[i];
2469 s->AssignRef(instance);
2470 }
2471 }
2472
2473 void WriteFill(Serializer* s) {
2474 intptr_t count = objects_.length();
2475 for (intptr_t i = 0; i < count; i++) {
2476 RawInstance* instance = objects_[i];
2477 s->Write<bool>(instance->IsCanonical());
2478 intptr_t offset = Instance::NextFieldOffset();
2479 while (offset < next_field_offset_) {
2480 RawObject* raw_obj = *reinterpret_cast<RawObject**>(
2481 reinterpret_cast<uword>(instance->ptr()) + offset);
2482 s->WriteRef(raw_obj);
2483 offset += kWordSize;
2484 }
2485 }
2486 }
2487
2488 private:
2489 const intptr_t cid_;
2490 intptr_t next_field_offset_;
2491 intptr_t instance_size_in_words_;
2492 GrowableArray<RawInstance*> objects_;
2493 };
2494
2495 class InstanceDeserializationCluster : public DeserializationCluster {
2496 public:
2497 explicit InstanceDeserializationCluster(intptr_t cid) : cid_(cid) { }
2498 virtual ~InstanceDeserializationCluster() { }
2499
2500 void ReadAlloc(Deserializer* d) {
2501 start_index_ = d->next_index();
2502 PageSpace* old_space = d->heap()->old_space();
2503 intptr_t count = d->Read<intptr_t>();
2504 next_field_offset_ = d->Read<intptr_t>();
2505 instance_size_in_words_ = d->Read<intptr_t>();
2506 intptr_t instance_size =
2507 Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
2508 for (intptr_t i = 0; i < count; i++) {
2509 d->AssignRef(AllocateUninitialized(old_space, instance_size));
2510 }
2511 stop_index_ = d->next_index();
2512 }
2513
2514 void ReadFill(Deserializer* d) {
2515 intptr_t instance_size =
2516 Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
2517 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2518
2519 for (intptr_t id = start_index_; id < stop_index_; id++) {
2520 RawInstance* instance = reinterpret_cast<RawInstance*>(d->Ref(id));
2521 bool is_canonical = d->Read<bool>();
2522 Deserializer::InitializeHeader(instance, cid_,
2523 instance_size,
2524 is_vm_object, is_canonical);
2525 intptr_t offset = Instance::NextFieldOffset();
2526 while (offset < next_field_offset_) {
2527 RawObject** p = reinterpret_cast<RawObject**>(
2528 reinterpret_cast<uword>(instance->ptr()) + offset);
2529 *p = d->ReadRef();
2530 offset += kWordSize;
2531 }
2532 if (offset < instance_size) {
2533 RawObject** p = reinterpret_cast<RawObject**>(
2534 reinterpret_cast<uword>(instance->ptr()) + offset);
2535 *p = Object::null();
2536 offset += kWordSize;
2537 }
2538 ASSERT(offset == instance_size);
2539 }
2540 }
2541
2542 private:
2543 const intptr_t cid_;
2544 intptr_t next_field_offset_;
2545 intptr_t instance_size_in_words_;
2546 };
2547
2548 class LibraryPrefixSerializationCluster : public SerializationCluster {
2549 public:
2550 LibraryPrefixSerializationCluster() { }
2551 virtual ~LibraryPrefixSerializationCluster() { }
2552
2553 void Trace(Serializer* s, RawObject* object) {
2554 RawLibraryPrefix* prefix = LibraryPrefix::RawCast(object);
2555 objects_.Add(prefix);
2556
2557 RawObject** from = prefix->from();
2558 RawObject** to = prefix->to();
2559 for (RawObject** p = from; p <= to; p++) {
2560 s->Push(*p);
2561 }
2562 }
2563
2564 void WriteAlloc(Serializer* s) {
2565 s->WriteCid(kLibraryPrefixCid);
2566 intptr_t count = objects_.length();
2567 s->Write<intptr_t>(count);
2568 for (intptr_t i = 0; i < count; i++) {
2569 RawLibraryPrefix* prefix = objects_[i];
2570 s->AssignRef(prefix);
2571 }
2572 }
2573
2574 void WriteFill(Serializer* s) {
2575 intptr_t count = objects_.length();
2576 for (intptr_t i = 0; i < count; i++) {
2577 RawLibraryPrefix* prefix = objects_[i];
2578 RawObject** from = prefix->from();
2579 RawObject** to = prefix->to();
2580 for (RawObject** p = from; p <= to; p++) {
2581 s->WriteRef(*p);
2582 }
2583 s->Write<uint16_t>(prefix->ptr()->num_imports_);
2584 s->Write<bool>(prefix->ptr()->is_deferred_load_);
2585 s->Write<bool>(prefix->ptr()->is_loaded_);
2586 }
2587 }
2588
2589 private:
2590 GrowableArray<RawLibraryPrefix*> objects_;
2591 };
2592
2593 class LibraryPrefixDeserializationCluster : public DeserializationCluster {
2594 public:
2595 LibraryPrefixDeserializationCluster() { }
2596 virtual ~LibraryPrefixDeserializationCluster() { }
2597
2598 void ReadAlloc(Deserializer* d) {
2599 start_index_ = d->next_index();
2600 PageSpace* old_space = d->heap()->old_space();
2601 intptr_t count = d->Read<intptr_t>();
2602 for (intptr_t i = 0; i < count; i++) {
2603 d->AssignRef(AllocateUninitialized(old_space,
2604 LibraryPrefix::InstanceSize()));
2605 }
2606 stop_index_ = d->next_index();
2607 }
2608
2609 void ReadFill(Deserializer* d) {
2610 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2611
2612 for (intptr_t id = start_index_; id < stop_index_; id++) {
2613 RawLibraryPrefix* prefix =
2614 reinterpret_cast<RawLibraryPrefix*>(d->Ref(id));
2615 Deserializer::InitializeHeader(prefix, kLibraryPrefixCid,
2616 LibraryPrefix::InstanceSize(),
2617 is_vm_object);
2618 RawObject** from = prefix->from();
2619 RawObject** to = prefix->to();
2620 for (RawObject** p = from; p <= to; p++) {
2621 *p = d->ReadRef();
2622 }
2623 prefix->ptr()->num_imports_ = d->Read<uint16_t>();
2624 prefix->ptr()->is_deferred_load_ = d->Read<bool>();
2625 prefix->ptr()->is_loaded_ = d->Read<bool>();
2626 }
2627 }
2628 };
2629
2630 class TypeSerializationCluster : public SerializationCluster {
2631 public:
2632 TypeSerializationCluster() { }
2633 virtual ~TypeSerializationCluster() { }
2634
2635 void Trace(Serializer* s, RawObject* object) {
2636 RawType* type = Type::RawCast(object);
2637 if (type->IsCanonical()) {
2638 canonical_objects_.Add(type);
2639 } else {
2640 objects_.Add(type);
2641 }
2642
2643 RawObject** from = type->from();
2644 RawObject** to = type->to();
2645 for (RawObject** p = from; p <= to; p++) {
2646 s->Push(*p);
2647 }
2648
2649 RawSmi* raw_type_class_id = Smi::RawCast(type->ptr()->type_class_id_);
2650 RawClass* type_class =
2651 s->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
2652 s->Push(type_class);
2653 }
2654
2655 void WriteAlloc(Serializer* s) {
2656 s->WriteCid(kTypeCid);
2657 intptr_t count = canonical_objects_.length();
2658 s->Write<intptr_t>(count);
2659 for (intptr_t i = 0; i < count; i++) {
2660 RawType* type = canonical_objects_[i];
2661 s->AssignRef(type);
2662 }
2663 count = objects_.length();
2664 s->Write<intptr_t>(count);
2665 for (intptr_t i = 0; i < count; i++) {
2666 RawType* type = objects_[i];
2667 s->AssignRef(type);
2668 }
2669 }
2670
2671 void WriteFill(Serializer* s) {
2672 intptr_t count = canonical_objects_.length();
2673 for (intptr_t i = 0; i < count; i++) {
2674 RawType* type = canonical_objects_[i];
2675 RawObject** from = type->from();
2676 RawObject** to = type->to();
2677 for (RawObject** p = from; p <= to; p++) {
2678 s->WriteRef(*p);
2679 }
2680 s->WriteTokenPosition(type->ptr()->token_pos_);
2681 s->Write<int8_t>(type->ptr()->type_state_);
2682 }
2683 count = objects_.length();
2684 for (intptr_t i = 0; i < count; i++) {
2685 RawType* type = objects_[i];
2686 RawObject** from = type->from();
2687 RawObject** to = type->to();
2688 for (RawObject** p = from; p <= to; p++) {
2689 s->WriteRef(*p);
2690 }
2691 s->WriteTokenPosition(type->ptr()->token_pos_);
2692 s->Write<int8_t>(type->ptr()->type_state_);
2693 }
2694 }
2695
2696 private:
2697 GrowableArray<RawType*> canonical_objects_;
2698 GrowableArray<RawType*> objects_;
2699 };
2700
2701 class TypeDeserializationCluster : public DeserializationCluster {
2702 public:
2703 TypeDeserializationCluster() { }
2704 virtual ~TypeDeserializationCluster() { }
2705
2706 void ReadAlloc(Deserializer* d) {
2707 canonical_start_index_ = d->next_index();
2708 PageSpace* old_space = d->heap()->old_space();
2709 intptr_t count = d->Read<intptr_t>();
2710 for (intptr_t i = 0; i < count; i++) {
2711 d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
2712 }
2713 canonical_stop_index_ = d->next_index();
2714
2715 start_index_ = d->next_index();
2716 count = d->Read<intptr_t>();
2717 for (intptr_t i = 0; i < count; i++) {
2718 d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
2719 }
2720 stop_index_ = d->next_index();
2721 }
2722
2723 void ReadFill(Deserializer* d) {
2724 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2725
2726 for (intptr_t id = canonical_start_index_;
2727 id < canonical_stop_index_;
2728 id++) {
2729 RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
2730 Deserializer::InitializeHeader(type, kTypeCid,
2731 Type::InstanceSize(), is_vm_object, true);
2732 RawObject** from = type->from();
2733 RawObject** to = type->to();
2734 for (RawObject** p = from; p <= to; p++) {
2735 *p = d->ReadRef();
2736 }
2737 type->ptr()->token_pos_ = d->ReadTokenPosition();
2738 type->ptr()->type_state_ = d->Read<int8_t>();
2739 }
2740
2741 for (intptr_t id = start_index_; id < stop_index_; id++) {
2742 RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
2743 Deserializer::InitializeHeader(type, kTypeCid,
2744 Type::InstanceSize(), is_vm_object);
2745 RawObject** from = type->from();
2746 RawObject** to = type->to();
2747 for (RawObject** p = from; p <= to; p++) {
2748 *p = d->ReadRef();
2749 }
2750 type->ptr()->token_pos_ = d->ReadTokenPosition();
2751 type->ptr()->type_state_ = d->Read<int8_t>();
2752 }
2753 }
2754
2755 private:
2756 intptr_t canonical_start_index_;
2757 intptr_t canonical_stop_index_;
2758 };
2759
2760 class TypeRefSerializationCluster : public SerializationCluster {
2761 public:
2762 TypeRefSerializationCluster() { }
2763 virtual ~TypeRefSerializationCluster() { }
2764
2765 void Trace(Serializer* s, RawObject* object) {
2766 RawTypeRef* type = TypeRef::RawCast(object);
2767 objects_.Add(type);
2768
2769 RawObject** from = type->from();
2770 RawObject** to = type->to();
2771 for (RawObject** p = from; p <= to; p++) {
2772 s->Push(*p);
2773 }
2774 }
2775
2776 void WriteAlloc(Serializer* s) {
2777 s->WriteCid(kTypeRefCid);
2778 intptr_t count = objects_.length();
2779 s->Write<intptr_t>(count);
2780 for (intptr_t i = 0; i < count; i++) {
2781 RawTypeRef* type = objects_[i];
2782 s->AssignRef(type);
2783 }
2784 }
2785
2786 void WriteFill(Serializer* s) {
2787 intptr_t count = objects_.length();
2788 for (intptr_t i = 0; i < count; i++) {
2789 RawTypeRef* type = objects_[i];
2790 RawObject** from = type->from();
2791 RawObject** to = type->to();
2792 for (RawObject** p = from; p <= to; p++) {
2793 s->WriteRef(*p);
2794 }
2795 }
2796 }
2797
2798 private:
2799 GrowableArray<RawTypeRef*> objects_;
2800 };
2801
2802 class TypeRefDeserializationCluster : public DeserializationCluster {
2803 public:
2804 TypeRefDeserializationCluster() { }
2805 virtual ~TypeRefDeserializationCluster() { }
2806
2807 void ReadAlloc(Deserializer* d) {
2808 start_index_ = d->next_index();
2809 PageSpace* old_space = d->heap()->old_space();
2810 intptr_t count = d->Read<intptr_t>();
2811 for (intptr_t i = 0; i < count; i++) {
2812 d->AssignRef(AllocateUninitialized(old_space, TypeRef::InstanceSize()));
2813 }
2814 stop_index_ = d->next_index();
2815 }
2816
2817 void ReadFill(Deserializer* d) {
2818 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2819
2820 for (intptr_t id = start_index_; id < stop_index_; id++) {
2821 RawTypeRef* type = reinterpret_cast<RawTypeRef*>(d->Ref(id));
2822 Deserializer::InitializeHeader(type, kTypeRefCid,
2823 TypeRef::InstanceSize(), is_vm_object);
2824 RawObject** from = type->from();
2825 RawObject** to = type->to();
2826 for (RawObject** p = from; p <= to; p++) {
2827 *p = d->ReadRef();
2828 }
2829 }
2830 }
2831 };
2832
2833 class TypeParameterSerializationCluster : public SerializationCluster {
2834 public:
2835 TypeParameterSerializationCluster() { }
2836 virtual ~TypeParameterSerializationCluster() { }
2837
2838 void Trace(Serializer* s, RawObject* object) {
2839 RawTypeParameter* type = TypeParameter::RawCast(object);
2840 objects_.Add(type);
2841 ASSERT(!type->IsCanonical());
2842
2843 RawObject** from = type->from();
2844 RawObject** to = type->to();
2845 for (RawObject** p = from; p <= to; p++) {
2846 s->Push(*p);
2847 }
2848 }
2849
2850 void WriteAlloc(Serializer* s) {
2851 s->WriteCid(kTypeParameterCid);
2852 intptr_t count = objects_.length();
2853 s->Write<intptr_t>(count);
2854 for (intptr_t i = 0; i < count; i++) {
2855 RawTypeParameter* type = objects_[i];
2856 s->AssignRef(type);
2857 }
2858 }
2859
2860 void WriteFill(Serializer* s) {
2861 intptr_t count = objects_.length();
2862 for (intptr_t i = 0; i < count; i++) {
2863 RawTypeParameter* type = objects_[i];
2864 RawObject** from = type->from();
2865 RawObject** to = type->to();
2866 for (RawObject** p = from; p <= to; p++) {
2867 s->WriteRef(*p);
2868 }
2869 s->Write<intptr_t>(type->ptr()->parameterized_class_id_);
2870 s->WriteTokenPosition(type->ptr()->token_pos_);
2871 s->Write<int16_t>(type->ptr()->index_);
2872 s->Write<int8_t>(type->ptr()->type_state_);
2873 }
2874 }
2875
2876 private:
2877 GrowableArray<RawTypeParameter*> objects_;
2878 };
2879
2880
2881 class TypeParameterDeserializationCluster : public DeserializationCluster {
2882 public:
2883 TypeParameterDeserializationCluster() { }
2884 virtual ~TypeParameterDeserializationCluster() { }
2885
2886 void ReadAlloc(Deserializer* d) {
2887 start_index_ = d->next_index();
2888 PageSpace* old_space = d->heap()->old_space();
2889 intptr_t count = d->Read<intptr_t>();
2890 for (intptr_t i = 0; i < count; i++) {
2891 d->AssignRef(AllocateUninitialized(old_space,
2892 TypeParameter::InstanceSize()));
2893 }
2894 stop_index_ = d->next_index();
2895 }
2896
2897 void ReadFill(Deserializer* d) {
2898 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2899
2900 for (intptr_t id = start_index_; id < stop_index_; id++) {
2901 RawTypeParameter* type = reinterpret_cast<RawTypeParameter*>(d->Ref(id));
2902 Deserializer::InitializeHeader(type, kTypeParameterCid,
2903 TypeParameter::InstanceSize(),
2904 is_vm_object);
2905 RawObject** from = type->from();
2906 RawObject** to = type->to();
2907 for (RawObject** p = from; p <= to; p++) {
2908 *p = d->ReadRef();
2909 }
2910 type->ptr()->parameterized_class_id_ = d->Read<intptr_t>();
2911 type->ptr()->token_pos_ = d->ReadTokenPosition();
2912 type->ptr()->index_ = d->Read<int16_t>();
2913 type->ptr()->type_state_ = d->Read<int8_t>();
2914 }
2915 }
2916 };
2917
2918 class BoundedTypeSerializationCluster : public SerializationCluster {
2919 public:
2920 BoundedTypeSerializationCluster() { }
2921 virtual ~BoundedTypeSerializationCluster() { }
2922
2923 void Trace(Serializer* s, RawObject* object) {
2924 RawBoundedType* type = BoundedType::RawCast(object);
2925 objects_.Add(type);
2926
2927 RawObject** from = type->from();
2928 RawObject** to = type->to();
2929 for (RawObject** p = from; p <= to; p++) {
2930 s->Push(*p);
2931 }
2932 }
2933
2934 void WriteAlloc(Serializer* s) {
2935 s->WriteCid(kBoundedTypeCid);
2936 intptr_t count = objects_.length();
2937 s->Write<intptr_t>(count);
2938 for (intptr_t i = 0; i < count; i++) {
2939 RawBoundedType* type = objects_[i];
2940 s->AssignRef(type);
2941 }
2942 }
2943
2944 void WriteFill(Serializer* s) {
2945 intptr_t count = objects_.length();
2946 for (intptr_t i = 0; i < count; i++) {
2947 RawBoundedType* type = objects_[i];
2948 RawObject** from = type->from();
2949 RawObject** to = type->to();
2950 for (RawObject** p = from; p <= to; p++) {
2951 s->WriteRef(*p);
2952 }
2953 }
2954 }
2955
2956 private:
2957 GrowableArray<RawBoundedType*> objects_;
2958 };
2959
2960 class BoundedTypeDeserializationCluster : public DeserializationCluster {
2961 public:
2962 BoundedTypeDeserializationCluster() { }
2963 virtual ~BoundedTypeDeserializationCluster() { }
2964
2965 void ReadAlloc(Deserializer* d) {
2966 start_index_ = d->next_index();
2967 PageSpace* old_space = d->heap()->old_space();
2968 intptr_t count = d->Read<intptr_t>();
2969 for (intptr_t i = 0; i < count; i++) {
2970 d->AssignRef(AllocateUninitialized(old_space,
2971 BoundedType::InstanceSize()));
2972 }
2973 stop_index_ = d->next_index();
2974 }
2975
2976 void ReadFill(Deserializer* d) {
2977 bool is_vm_object = d->isolate() == Dart::vm_isolate();
2978
2979 for (intptr_t id = start_index_; id < stop_index_; id++) {
2980 RawBoundedType* type = reinterpret_cast<RawBoundedType*>(d->Ref(id));
2981 Deserializer::InitializeHeader(type, kBoundedTypeCid,
2982 BoundedType::InstanceSize(), is_vm_object);
2983 RawObject** from = type->from();
2984 RawObject** to = type->to();
2985 for (RawObject** p = from; p <= to; p++) {
2986 *p = d->ReadRef();
2987 }
2988 }
2989 }
2990 };
2991
2992 class ClosureSerializationCluster : public SerializationCluster {
2993 public:
2994 ClosureSerializationCluster() { }
2995 virtual ~ClosureSerializationCluster() { }
2996
2997 void Trace(Serializer* s, RawObject* object) {
2998 RawClosure* closure = Closure::RawCast(object);
2999 objects_.Add(closure);
3000
3001 RawObject** from = closure->from();
3002 RawObject** to = closure->to();
3003 for (RawObject** p = from; p <= to; p++) {
3004 s->Push(*p);
3005 }
3006 }
3007
3008 void WriteAlloc(Serializer* s) {
3009 s->WriteCid(kClosureCid);
3010 intptr_t count = objects_.length();
3011 s->Write<intptr_t>(count);
3012 for (intptr_t i = 0; i < count; i++) {
3013 RawClosure* closure = objects_[i];
3014 s->AssignRef(closure);
3015 }
3016 }
3017
3018 void WriteFill(Serializer* s) {
3019 intptr_t count = objects_.length();
3020 for (intptr_t i = 0; i < count; i++) {
3021 RawClosure* closure = objects_[i];
3022 s->Write<bool>(closure->IsCanonical());
3023 RawObject** from = closure->from();
3024 RawObject** to = closure->to();
3025 for (RawObject** p = from; p <= to; p++) {
3026 s->WriteRef(*p);
3027 }
3028 }
3029 }
3030
3031 private:
3032 GrowableArray<RawClosure*> objects_;
3033 };
3034
3035
3036 class ClosureDeserializationCluster : public DeserializationCluster {
3037 public:
3038 ClosureDeserializationCluster() { }
3039 virtual ~ClosureDeserializationCluster() { }
3040
3041 void ReadAlloc(Deserializer* d) {
3042 start_index_ = d->next_index();
3043 PageSpace* old_space = d->heap()->old_space();
3044 intptr_t count = d->Read<intptr_t>();
3045 for (intptr_t i = 0; i < count; i++) {
3046 d->AssignRef(AllocateUninitialized(old_space, Closure::InstanceSize()));
3047 }
3048 stop_index_ = d->next_index();
3049 }
3050
3051 void ReadFill(Deserializer* d) {
3052 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3053
3054 for (intptr_t id = start_index_; id < stop_index_; id++) {
3055 RawClosure* closure = reinterpret_cast<RawClosure*>(d->Ref(id));
3056 bool is_canonical = d->Read<bool>();
3057 Deserializer::InitializeHeader(closure, kClosureCid,
3058 Closure::InstanceSize(),
3059 is_vm_object, is_canonical);
3060 RawObject** from = closure->from();
3061 RawObject** to = closure->to();
3062 for (RawObject** p = from; p <= to; p++) {
3063 *p = d->ReadRef();
3064 }
3065 }
3066 }
3067 };
3068
3069
3070 class MintSerializationCluster : public SerializationCluster {
3071 public:
3072 MintSerializationCluster() { }
3073 virtual ~MintSerializationCluster() { }
3074
3075 void Trace(Serializer* s, RawObject* object) {
3076 RawMint* mint = Mint::RawCast(object);
3077 objects_.Add(mint);
3078 }
3079
3080 void WriteAlloc(Serializer* s) {
3081 s->WriteCid(kMintCid);
3082 intptr_t count = objects_.length();
3083 s->Write<intptr_t>(count);
3084 for (intptr_t i = 0; i < count; i++) {
3085 RawMint* mint = objects_[i];
3086 s->AssignRef(mint);
3087 }
3088 }
3089
3090 void WriteFill(Serializer* s) {
3091 intptr_t count = objects_.length();
3092 for (intptr_t i = 0; i < count; i++) {
3093 RawMint* mint = objects_[i];
3094 s->Write<bool>(mint->IsCanonical());
3095 s->Write<int64_t>(mint->ptr()->value_);
3096 }
3097 }
3098
3099 private:
3100 GrowableArray<RawMint*> objects_;
3101 };
3102
3103 class MintDeserializationCluster : public DeserializationCluster {
3104 public:
3105 MintDeserializationCluster() { }
3106 virtual ~MintDeserializationCluster() { }
3107
3108 void ReadAlloc(Deserializer* d) {
3109 start_index_ = d->next_index();
3110 PageSpace* old_space = d->heap()->old_space();
3111 intptr_t count = d->Read<intptr_t>();
3112 for (intptr_t i = 0; i < count; i++) {
3113 d->AssignRef(AllocateUninitialized(old_space, Mint::InstanceSize()));
3114 }
3115 stop_index_ = d->next_index();
3116 }
3117
3118 void ReadFill(Deserializer* d) {
3119 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3120
3121 for (intptr_t id = start_index_; id < stop_index_; id++) {
3122 RawMint* mint = reinterpret_cast<RawMint*>(d->Ref(id));
3123 bool is_canonical = d->Read<bool>();
3124 Deserializer::InitializeHeader(mint, kMintCid,
3125 Mint::InstanceSize(),
3126 is_vm_object, is_canonical);
3127 mint->ptr()->value_ = d->Read<int64_t>();
3128 }
3129 }
3130 };
3131
3132 class BigintSerializationCluster : public SerializationCluster {
3133 public:
3134 BigintSerializationCluster() { }
3135 virtual ~BigintSerializationCluster() { }
3136
3137 void Trace(Serializer* s, RawObject* object) {
3138 RawBigint* bigint = Bigint::RawCast(object);
3139 objects_.Add(bigint);
3140
3141 RawObject** from = bigint->from();
3142 RawObject** to = bigint->to();
3143 for (RawObject** p = from; p <= to; p++) {
3144 s->Push(*p);
3145 }
3146 }
3147
3148 void WriteAlloc(Serializer* s) {
3149 s->WriteCid(kBigintCid);
3150 intptr_t count = objects_.length();
3151 s->Write<intptr_t>(count);
3152 for (intptr_t i = 0; i < count; i++) {
3153 RawBigint* bigint = objects_[i];
3154 s->AssignRef(bigint);
3155 }
3156 }
3157
3158 void WriteFill(Serializer* s) {
3159 intptr_t count = objects_.length();
3160 for (intptr_t i = 0; i < count; i++) {
3161 RawBigint* bigint = objects_[i];
3162 s->Write<bool>(bigint->IsCanonical());
3163 RawObject** from = bigint->from();
3164 RawObject** to = bigint->to();
3165 for (RawObject** p = from; p <= to; p++) {
3166 s->WriteRef(*p);
3167 }
3168 }
3169 }
3170
3171 private:
3172 GrowableArray<RawBigint*> objects_;
3173 };
3174
3175 class BigintDeserializationCluster : public DeserializationCluster {
3176 public:
3177 BigintDeserializationCluster() { }
3178 virtual ~BigintDeserializationCluster() { }
3179
3180 void ReadAlloc(Deserializer* d) {
3181 start_index_ = d->next_index();
3182 PageSpace* old_space = d->heap()->old_space();
3183 intptr_t count = d->Read<intptr_t>();
3184 for (intptr_t i = 0; i < count; i++) {
3185 d->AssignRef(AllocateUninitialized(old_space, Bigint::InstanceSize()));
3186 }
3187 stop_index_ = d->next_index();
3188 }
3189
3190 void ReadFill(Deserializer* d) {
3191 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3192
3193 for (intptr_t id = start_index_; id < stop_index_; id++) {
3194 RawBigint* bigint = reinterpret_cast<RawBigint*>(d->Ref(id));
3195 bool is_canonical = d->Read<bool>();
3196 Deserializer::InitializeHeader(bigint, kBigintCid,
3197 Bigint::InstanceSize(),
3198 is_vm_object, is_canonical);
3199 RawObject** from = bigint->from();
3200 RawObject** to = bigint->to();
3201 for (RawObject** p = from; p <= to; p++) {
3202 *p = d->ReadRef();
3203 }
3204 }
3205 }
3206 };
3207
3208 class DoubleSerializationCluster : public SerializationCluster {
3209 public:
3210 DoubleSerializationCluster() { }
3211 virtual ~DoubleSerializationCluster() { }
3212
3213 void Trace(Serializer* s, RawObject* object) {
3214 RawDouble* dbl = Double::RawCast(object);
3215 objects_.Add(dbl);
3216 }
3217
3218 void WriteAlloc(Serializer* s) {
3219 s->WriteCid(kDoubleCid);
3220 intptr_t count = objects_.length();
3221 s->Write<intptr_t>(count);
3222 for (intptr_t i = 0; i < count; i++) {
3223 RawDouble* dbl = objects_[i];
3224 s->AssignRef(dbl);
3225 }
3226 }
3227
3228 void WriteFill(Serializer* s) {
3229 intptr_t count = objects_.length();
3230 for (intptr_t i = 0; i < count; i++) {
3231 RawDouble* dbl = objects_[i];
3232 s->Write<bool>(dbl->IsCanonical());
3233 s->Write<double>(dbl->ptr()->value_);
3234 }
3235 }
3236
3237 private:
3238 GrowableArray<RawDouble*> objects_;
3239 };
3240
3241 class DoubleDeserializationCluster : public DeserializationCluster {
3242 public:
3243 DoubleDeserializationCluster() { }
3244 virtual ~DoubleDeserializationCluster() { }
3245
3246 void ReadAlloc(Deserializer* d) {
3247 start_index_ = d->next_index();
3248 PageSpace* old_space = d->heap()->old_space();
3249 intptr_t count = d->Read<intptr_t>();
3250 for (intptr_t i = 0; i < count; i++) {
3251 d->AssignRef(AllocateUninitialized(old_space, Double::InstanceSize()));
3252 }
3253 stop_index_ = d->next_index();
3254 }
3255
3256 void ReadFill(Deserializer* d) {
3257 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3258
3259 for (intptr_t id = start_index_; id < stop_index_; id++) {
3260 RawDouble* dbl = reinterpret_cast<RawDouble*>(d->Ref(id));
3261 bool is_canonical = d->Read<bool>();
3262 Deserializer::InitializeHeader(dbl, kDoubleCid,
3263 Double::InstanceSize(),
3264 is_vm_object, is_canonical);
3265 dbl->ptr()->value_ = d->Read<double>();
3266 }
3267 }
3268 };
3269
3270
3271 class GrowableObjectArraySerializationCluster : public SerializationCluster {
3272 public:
3273 GrowableObjectArraySerializationCluster() { }
3274 virtual ~GrowableObjectArraySerializationCluster() { }
3275
3276 void Trace(Serializer* s, RawObject* object) {
3277 RawGrowableObjectArray* array = GrowableObjectArray::RawCast(object);
3278 objects_.Add(array);
3279
3280 RawObject** from = array->from();
3281 RawObject** to = array->to();
3282 for (RawObject** p = from; p <= to; p++) {
3283 s->Push(*p);
3284 }
3285 }
3286
3287 void WriteAlloc(Serializer* s) {
3288 s->WriteCid(kGrowableObjectArrayCid);
3289 intptr_t count = objects_.length();
3290 s->Write<intptr_t>(count);
3291 for (intptr_t i = 0; i < count; i++) {
3292 RawGrowableObjectArray* array = objects_[i];
3293 s->AssignRef(array);
3294 }
3295 }
3296
3297 void WriteFill(Serializer* s) {
3298 intptr_t count = objects_.length();
3299 for (intptr_t i = 0; i < count; i++) {
3300 RawGrowableObjectArray* array = objects_[i];
3301 s->Write<bool>(array->IsCanonical());
3302 RawObject** from = array->from();
3303 RawObject** to = array->to();
3304 for (RawObject** p = from; p <= to; p++) {
3305 s->WriteRef(*p);
3306 }
3307 }
3308 }
3309
3310 private:
3311 GrowableArray<RawGrowableObjectArray*> objects_;
3312 };
3313
3314 class GrowableObjectArrayDeserializationCluster
3315 : public DeserializationCluster {
3316 public:
3317 GrowableObjectArrayDeserializationCluster() { }
3318 virtual ~GrowableObjectArrayDeserializationCluster() { }
3319
3320 void ReadAlloc(Deserializer* d) {
3321 start_index_ = d->next_index();
3322 PageSpace* old_space = d->heap()->old_space();
3323 intptr_t count = d->Read<intptr_t>();
3324 for (intptr_t i = 0; i < count; i++) {
3325 d->AssignRef(AllocateUninitialized(old_space,
3326 GrowableObjectArray::InstanceSize()));
3327 }
3328 stop_index_ = d->next_index();
3329 }
3330
3331 void ReadFill(Deserializer* d) {
3332 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3333
3334 for (intptr_t id = start_index_; id < stop_index_; id++) {
3335 RawGrowableObjectArray* list =
3336 reinterpret_cast<RawGrowableObjectArray*>(d->Ref(id));
3337 bool is_canonical = d->Read<bool>();
3338 Deserializer::InitializeHeader(list, kGrowableObjectArrayCid,
3339 GrowableObjectArray::InstanceSize(),
3340 is_vm_object, is_canonical);
3341 RawObject** from = list->from();
3342 RawObject** to = list->to();
3343 for (RawObject** p = from; p <= to; p++) {
3344 *p = d->ReadRef();
3345 }
3346 }
3347 }
3348 };
3349
3350 class TypedDataSerializationCluster : public SerializationCluster {
3351 public:
3352 explicit TypedDataSerializationCluster(intptr_t cid) : cid_(cid) { }
3353 virtual ~TypedDataSerializationCluster() { }
3354
3355 void Trace(Serializer* s, RawObject* object) {
3356 RawTypedData* data = TypedData::RawCast(object);
3357 objects_.Add(data);
3358 }
3359
3360 void WriteAlloc(Serializer* s) {
3361 s->Write<intptr_t>(cid_);
3362 intptr_t count = objects_.length();
3363 s->Write<intptr_t>(count);
3364 for (intptr_t i = 0; i < count; i++) {
3365 RawTypedData* data = objects_[i];
3366 intptr_t length = Smi::Value(data->ptr()->length_);
3367 s->Write<intptr_t>(length);
3368 s->AssignRef(data);
3369 }
3370 }
3371
3372 void WriteFill(Serializer* s) {
3373 intptr_t count = objects_.length();
3374 intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
3375 for (intptr_t i = 0; i < count; i++) {
3376 RawTypedData* data = objects_[i];
3377 intptr_t length = Smi::Value(data->ptr()->length_);
3378 s->Write<intptr_t>(length);
3379 s->Write<bool>(data->IsCanonical());
3380 uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
3381 s->WriteBytes(cdata, length * element_size);
3382 }
3383 }
3384
3385 private:
3386 const intptr_t cid_;
3387 GrowableArray<RawTypedData*> objects_;
3388 };
3389
3390
3391 class TypedDataDeserializationCluster : public DeserializationCluster {
3392 public:
3393 explicit TypedDataDeserializationCluster(intptr_t cid) : cid_(cid) { }
3394 virtual ~TypedDataDeserializationCluster() { }
3395
3396 void ReadAlloc(Deserializer* d) {
3397 start_index_ = d->next_index();
3398 PageSpace* old_space = d->heap()->old_space();
3399 intptr_t count = d->Read<intptr_t>();
3400 intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
3401 for (intptr_t i = 0; i < count; i++) {
3402 intptr_t length = d->Read<intptr_t>();
3403 d->AssignRef(AllocateUninitialized(old_space,
3404 TypedData::InstanceSize(length * element_size)));
3405 }
3406 stop_index_ = d->next_index();
3407 }
3408
3409 void ReadFill(Deserializer* d) {
3410 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3411 intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
3412
3413 for (intptr_t id = start_index_; id < stop_index_; id++) {
3414 RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
3415 intptr_t length = d->Read<intptr_t>();
3416 bool is_canonical = d->Read<bool>();
3417 intptr_t length_in_bytes = length * element_size;
3418 Deserializer::InitializeHeader(data, cid_,
3419 TypedData::InstanceSize(length_in_bytes),
3420 is_vm_object, is_canonical);
3421 data->ptr()->length_ = Smi::New(length);
3422 uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
3423 d->ReadBytes(cdata, length_in_bytes);
3424 }
3425 }
3426
3427 private:
3428 const intptr_t cid_;
3429 };
3430
3431
3432 class ExternalTypedDataSerializationCluster : public SerializationCluster {
3433 public:
3434 explicit ExternalTypedDataSerializationCluster(intptr_t cid) : cid_(cid) { }
3435 virtual ~ExternalTypedDataSerializationCluster() { }
3436
3437 void Trace(Serializer* s, RawObject* object) {
3438 RawExternalTypedData* data = ExternalTypedData::RawCast(object);
3439 objects_.Add(data);
3440 ASSERT(!data->IsCanonical());
3441 }
3442
3443 void WriteAlloc(Serializer* s) {
3444 s->Write<intptr_t>(cid_);
3445 intptr_t count = objects_.length();
3446 s->Write<intptr_t>(count);
3447 for (intptr_t i = 0; i < count; i++) {
3448 RawExternalTypedData* data = objects_[i];
3449 s->AssignRef(data);
3450 }
3451 }
3452
3453 void WriteFill(Serializer* s) {
3454 intptr_t count = objects_.length();
3455 intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
3456 for (intptr_t i = 0; i < count; i++) {
3457 RawExternalTypedData* data = objects_[i];
3458 intptr_t length = Smi::Value(data->ptr()->length_);
3459 s->Write<intptr_t>(length);
3460 uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data_);
3461 s->WriteBytes(cdata, length * element_size);
3462 }
3463 }
3464
3465 private:
3466 const intptr_t cid_;
3467 GrowableArray<RawExternalTypedData*> objects_;
3468 };
3469
3470
3471 class ExternalTypedDataDeserializationCluster : public DeserializationCluster {
3472 public:
3473 explicit ExternalTypedDataDeserializationCluster(intptr_t cid) : cid_(cid) { }
3474 virtual ~ExternalTypedDataDeserializationCluster() { }
3475
3476 void ReadAlloc(Deserializer* d) {
3477 start_index_ = d->next_index();
3478 PageSpace* old_space = d->heap()->old_space();
3479 intptr_t count = d->Read<intptr_t>();
3480 for (intptr_t i = 0; i < count; i++) {
3481 d->AssignRef(AllocateUninitialized(old_space,
3482 ExternalTypedData::InstanceSize()));
3483 }
3484 stop_index_ = d->next_index();
3485 }
3486
3487 void ReadFill(Deserializer* d) {
3488 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3489 intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
3490
3491 for (intptr_t id = start_index_; id < stop_index_; id++) {
3492 RawExternalTypedData* data =
3493 reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
3494 intptr_t length = d->Read<intptr_t>();
3495 Deserializer::InitializeHeader(data, cid_,
3496 ExternalTypedData::InstanceSize(),
3497 is_vm_object);
3498 data->ptr()->length_ = Smi::New(length);
3499 data->ptr()->data_ = const_cast<uint8_t*>(d->CurrentBufferAddress());
3500 d->Advance(length * element_size);
3501 }
3502 }
3503
3504 private:
3505 const intptr_t cid_;
3506 };
3507
3508 class StacktraceSerializationCluster : public SerializationCluster {
3509 public:
3510 StacktraceSerializationCluster() { }
3511 virtual ~StacktraceSerializationCluster() { }
3512
3513 void Trace(Serializer* s, RawObject* object) {
3514 RawStacktrace* trace = Stacktrace::RawCast(object);
3515 objects_.Add(trace);
3516
3517 RawObject** from = trace->from();
3518 RawObject** to = trace->to();
3519 for (RawObject** p = from; p <= to; p++) {
3520 s->Push(*p);
3521 }
3522 }
3523
3524 void WriteAlloc(Serializer* s) {
3525 s->WriteCid(kStacktraceCid);
3526 intptr_t count = objects_.length();
3527 s->Write<intptr_t>(count);
3528 for (intptr_t i = 0; i < count; i++) {
3529 RawStacktrace* trace = objects_[i];
3530 s->AssignRef(trace);
3531 }
3532 }
3533
3534 void WriteFill(Serializer* s) {
3535 intptr_t count = objects_.length();
3536 for (intptr_t i = 0; i < count; i++) {
3537 RawStacktrace* trace = objects_[i];
3538 RawObject** from = trace->from();
3539 RawObject** to = trace->to();
3540 for (RawObject** p = from; p <= to; p++) {
3541 s->WriteRef(*p);
3542 }
3543 }
3544 }
3545
3546 private:
3547 GrowableArray<RawStacktrace*> objects_;
3548 };
3549
3550 class StacktraceDeserializationCluster : public DeserializationCluster {
3551 public:
3552 StacktraceDeserializationCluster() { }
3553 virtual ~StacktraceDeserializationCluster() { }
3554
3555 void ReadAlloc(Deserializer* d) {
3556 start_index_ = d->next_index();
3557 PageSpace* old_space = d->heap()->old_space();
3558 intptr_t count = d->Read<intptr_t>();
3559 for (intptr_t i = 0; i < count; i++) {
3560 d->AssignRef(AllocateUninitialized(old_space,
3561 Stacktrace::InstanceSize()));
3562 }
3563 stop_index_ = d->next_index();
3564 }
3565
3566 void ReadFill(Deserializer* d) {
3567 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3568
3569 for (intptr_t id = start_index_; id < stop_index_; id++) {
3570 RawStacktrace* trace = reinterpret_cast<RawStacktrace*>(d->Ref(id));
3571 Deserializer::InitializeHeader(trace, kStacktraceCid,
3572 Stacktrace::InstanceSize(), is_vm_object);
3573 RawObject** from = trace->from();
3574 RawObject** to = trace->to();
3575 for (RawObject** p = from; p <= to; p++) {
3576 *p = d->ReadRef();
3577 }
3578 }
3579 }
3580 };
3581
3582 class RegExpSerializationCluster : public SerializationCluster {
3583 public:
3584 RegExpSerializationCluster() { }
3585 virtual ~RegExpSerializationCluster() { }
3586
3587 void Trace(Serializer* s, RawObject* object) {
3588 RawRegExp* regexp = RegExp::RawCast(object);
3589 objects_.Add(regexp);
3590
3591 RawObject** from = regexp->from();
3592 RawObject** to = regexp->to();
3593 for (RawObject** p = from; p <= to; p++) {
3594 s->Push(*p);
3595 }
3596 }
3597
3598 void WriteAlloc(Serializer* s) {
3599 s->WriteCid(kRegExpCid);
3600 intptr_t count = objects_.length();
3601 s->Write<intptr_t>(count);
3602 for (intptr_t i = 0; i < count; i++) {
3603 RawRegExp* regexp = objects_[i];
3604 s->AssignRef(regexp);
3605 }
3606 }
3607
3608 void WriteFill(Serializer* s) {
3609 intptr_t count = objects_.length();
3610 for (intptr_t i = 0; i < count; i++) {
3611 RawRegExp* regexp = objects_[i];
3612 RawObject** from = regexp->from();
3613 RawObject** to = regexp->to();
3614 for (RawObject** p = from; p <= to; p++) {
3615 s->WriteRef(*p);
3616 }
3617
3618 s->Write<intptr_t>(regexp->ptr()->num_registers_);
3619 s->Write<int8_t>(regexp->ptr()->type_flags_);
3620 }
3621 }
3622
3623 private:
3624 GrowableArray<RawRegExp*> objects_;
3625 };
3626
3627 class RegExpDeserializationCluster : public DeserializationCluster {
3628 public:
3629 RegExpDeserializationCluster() { }
3630 virtual ~RegExpDeserializationCluster() { }
3631
3632 void ReadAlloc(Deserializer* d) {
3633 start_index_ = d->next_index();
3634 PageSpace* old_space = d->heap()->old_space();
3635 intptr_t count = d->Read<intptr_t>();
3636 for (intptr_t i = 0; i < count; i++) {
3637 d->AssignRef(AllocateUninitialized(old_space,
3638 RegExp::InstanceSize()));
3639 }
3640 stop_index_ = d->next_index();
3641 }
3642
3643 void ReadFill(Deserializer* d) {
3644 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3645
3646 for (intptr_t id = start_index_; id < stop_index_; id++) {
3647 RawRegExp* regexp = reinterpret_cast<RawRegExp*>(d->Ref(id));
3648 Deserializer::InitializeHeader(regexp, kRegExpCid,
3649 RegExp::InstanceSize(), is_vm_object);
3650 RawObject** from = regexp->from();
3651 RawObject** to = regexp->to();
3652 for (RawObject** p = from; p <= to; p++) {
3653 *p = d->ReadRef();
3654 }
3655
3656 regexp->ptr()->num_registers_ = d->Read<intptr_t>();
3657 regexp->ptr()->type_flags_ = d->Read<int8_t>();
3658 }
3659 }
3660 };
3661
3662 class LinkedHashMapSerializationCluster : public SerializationCluster {
3663 public:
3664 LinkedHashMapSerializationCluster() { }
3665 virtual ~LinkedHashMapSerializationCluster() { }
3666
3667 void Trace(Serializer* s, RawObject* object) {
3668 RawLinkedHashMap* map = LinkedHashMap::RawCast(object);
3669 objects_.Add(map);
3670
3671 s->Push(map->ptr()->type_arguments_);
3672
3673 intptr_t used_data = Smi::Value(map->ptr()->used_data_);
3674 RawArray* data_array = map->ptr()->data_;
3675 RawObject** data_elements = data_array->ptr()->data();
3676 for (intptr_t i = 0; i < used_data; i += 2) {
3677 RawObject* key = data_elements[i];
3678 if (key != data_array) {
3679 RawObject* value = data_elements[i + 1];
3680 s->Push(key);
3681 s->Push(value);
3682 }
3683 }
3684 }
3685
3686 void WriteAlloc(Serializer* s) {
3687 s->WriteCid(kLinkedHashMapCid);
3688 intptr_t count = objects_.length();
3689 s->Write<intptr_t>(count);
3690 for (intptr_t i = 0; i < count; i++) {
3691 RawLinkedHashMap* map = objects_[i];
3692 s->AssignRef(map);
3693 }
3694 }
3695
3696 void WriteFill(Serializer* s) {
3697 intptr_t count = objects_.length();
3698 for (intptr_t i = 0; i < count; i++) {
3699 RawLinkedHashMap* map = objects_[i];
3700 s->Write<bool>(map->IsCanonical());
3701
3702 s->WriteRef(map->ptr()->type_arguments_);
3703
3704 const intptr_t used_data = Smi::Value(map->ptr()->used_data_);
3705 ASSERT((used_data & 1) == 0); // Keys + values, so must be even.
3706 const intptr_t deleted_keys = Smi::Value(map->ptr()->deleted_keys_);
3707
3708 // Write out the number of (not deleted) key/value pairs that will follow.
3709 s->Write<intptr_t>((used_data >> 1) - deleted_keys);
3710
3711 RawArray* data_array = map->ptr()->data_;
3712 RawObject** data_elements = data_array->ptr()->data();
3713 for (intptr_t i = 0; i < used_data; i += 2) {
3714 RawObject* key = data_elements[i];
3715 if (key != data_array) {
3716 RawObject* value = data_elements[i + 1];
3717 s->WriteRef(key);
3718 s->WriteRef(value);
3719 }
3720 }
3721 }
3722 }
3723
3724 private:
3725 GrowableArray<RawLinkedHashMap*> objects_;
3726 };
3727
3728 class LinkedHashMapDeserializationCluster : public DeserializationCluster {
3729 public:
3730 LinkedHashMapDeserializationCluster() { }
3731 virtual ~LinkedHashMapDeserializationCluster() { }
3732
3733 void ReadAlloc(Deserializer* d) {
3734 start_index_ = d->next_index();
3735 PageSpace* old_space = d->heap()->old_space();
3736 intptr_t count = d->Read<intptr_t>();
3737 for (intptr_t i = 0; i < count; i++) {
3738 d->AssignRef(AllocateUninitialized(old_space,
3739 LinkedHashMap::InstanceSize()));
3740 }
3741 stop_index_ = d->next_index();
3742 }
3743
3744 void ReadFill(Deserializer* d) {
3745 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3746 PageSpace* old_space = d->heap()->old_space();
3747
3748 for (intptr_t id = start_index_; id < stop_index_; id++) {
3749 RawLinkedHashMap* map = reinterpret_cast<RawLinkedHashMap*>(d->Ref(id));
3750 bool is_canonical = d->Read<bool>();
3751 Deserializer::InitializeHeader(map, kLinkedHashMapCid,
3752 LinkedHashMap::InstanceSize(),
3753 is_vm_object, is_canonical);
3754
3755 map->ptr()->type_arguments_ =
3756 reinterpret_cast<RawTypeArguments*>(d->ReadRef());
3757
3758 // TODO(rmacnak): Reserve ref ids and co-allocate in ReadAlloc.
3759 intptr_t pairs = d->Read<intptr_t>();
3760 intptr_t used_data = pairs << 1;
3761 intptr_t data_size = Utils::Maximum(
3762 Utils::RoundUpToPowerOfTwo(used_data),
3763 static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
3764
3765 RawArray* data = reinterpret_cast<RawArray*>(
3766 AllocateUninitialized(old_space, Array::InstanceSize(data_size)));
3767 data->ptr()->type_arguments_ = TypeArguments::null();
3768 data->ptr()->length_ = Smi::New(data_size);
3769 intptr_t i;
3770 for (i = 0; i < used_data; i++) {
3771 data->ptr()->data()[i] = d->ReadRef();
3772 }
3773 for (; i < data_size; i++) {
3774 data->ptr()->data()[i] = Object::null();
3775 }
3776
3777 map->ptr()->index_ = TypedData::null();
3778 map->ptr()->hash_mask_ = Smi::New(0);
3779 map->ptr()->data_ = data;
3780 map->ptr()->used_data_ = Smi::New(used_data);
3781 map->ptr()->deleted_keys_ = Smi::New(0);
3782 }
3783 }
3784 };
3785
3786 class ArraySerializationCluster : public SerializationCluster {
3787 public:
3788 explicit ArraySerializationCluster(intptr_t cid) : cid_(cid) { }
3789 virtual ~ArraySerializationCluster() { }
3790
3791 void Trace(Serializer* s, RawObject* object) {
3792 RawArray* array = Array::RawCast(object);
3793 objects_.Add(array);
3794
3795 s->Push(array->ptr()->type_arguments_);
3796 intptr_t length = Smi::Value(array->ptr()->length_);
3797 for (intptr_t i = 0; i < length; i++) {
3798 s->Push(array->ptr()->data()[i]);
3799 }
3800 }
3801
3802 void WriteAlloc(Serializer* s) {
3803 s->WriteCid(cid_);
3804 intptr_t count = objects_.length();
3805 s->Write<intptr_t>(count);
3806 for (intptr_t i = 0; i < count; i++) {
3807 RawArray* array = objects_[i];
3808 intptr_t length = Smi::Value(array->ptr()->length_);
3809 s->Write<intptr_t>(length);
3810 s->AssignRef(array);
3811 }
3812 }
3813
3814 void WriteFill(Serializer* s) {
3815 intptr_t count = objects_.length();
3816 for (intptr_t i = 0; i < count; i++) {
3817 RawArray* array = objects_[i];
3818 intptr_t length = Smi::Value(array->ptr()->length_);
3819 s->Write<intptr_t>(length);
3820 s->Write<bool>(array->IsCanonical());
3821 s->WriteRef(array->ptr()->type_arguments_);
3822 for (intptr_t j = 0; j < length; j++) {
3823 s->WriteRef(array->ptr()->data()[j]);
3824 }
3825 }
3826 }
3827
3828 private:
3829 intptr_t cid_;
3830 GrowableArray<RawArray*> objects_;
3831 };
3832
3833 class ArrayDeserializationCluster : public DeserializationCluster {
3834 public:
3835 explicit ArrayDeserializationCluster(intptr_t cid) : cid_(cid) { }
3836 virtual ~ArrayDeserializationCluster() { }
3837
3838 void ReadAlloc(Deserializer* d) {
3839 start_index_ = d->next_index();
3840 PageSpace* old_space = d->heap()->old_space();
3841 intptr_t count = d->Read<intptr_t>();
3842 for (intptr_t i = 0; i < count; i++) {
3843 intptr_t length = d->Read<intptr_t>();
3844 d->AssignRef(AllocateUninitialized(old_space,
3845 Array::InstanceSize(length)));
3846 }
3847 stop_index_ = d->next_index();
3848 }
3849
3850 void ReadFill(Deserializer* d) {
3851 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3852
3853 for (intptr_t id = start_index_; id < stop_index_; id++) {
3854 RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
3855 intptr_t length = d->Read<intptr_t>();
3856 bool is_canonical = d->Read<bool>();
3857 Deserializer::InitializeHeader(array, cid_,
3858 Array::InstanceSize(length),
3859 is_vm_object, is_canonical);
3860 array->ptr()->type_arguments_ =
3861 reinterpret_cast<RawTypeArguments*>(d->ReadRef());
3862 array->ptr()->length_ = Smi::New(length);
3863 for (intptr_t j = 0; j < length; j++) {
3864 array->ptr()->data()[j] = d->ReadRef();
3865 }
3866 }
3867 }
3868
3869 private:
3870 const intptr_t cid_;
3871 };
3872
3873 class OneByteStringSerializationCluster : public SerializationCluster {
3874 public:
3875 OneByteStringSerializationCluster() { }
3876 virtual ~OneByteStringSerializationCluster() { }
3877
3878 void Trace(Serializer* s, RawObject* object) {
3879 RawOneByteString* str = reinterpret_cast<RawOneByteString*>(object);
3880 objects_.Add(str);
3881 }
3882
3883 void WriteAlloc(Serializer* s) {
3884 s->WriteCid(kOneByteStringCid);
3885 intptr_t count = objects_.length();
3886 s->Write<intptr_t>(count);
3887 for (intptr_t i = 0; i < count; i++) {
3888 RawOneByteString* str = objects_[i];
3889 intptr_t length = Smi::Value(str->ptr()->length_);
3890 s->Write<intptr_t>(length);
3891 s->AssignRef(str);
3892 }
3893 }
3894
3895 void WriteFill(Serializer* s) {
3896 intptr_t count = objects_.length();
3897 for (intptr_t i = 0; i < count; i++) {
3898 RawOneByteString* str = objects_[i];
3899 intptr_t length = Smi::Value(str->ptr()->length_);
3900 s->Write<intptr_t>(length);
3901 s->Write<bool>(str->IsCanonical());
3902 intptr_t hash = Smi::Value(str->ptr()->hash_);
3903 s->Write<int32_t>(hash);
3904 s->WriteBytes(str->ptr()->data(), length);
3905 }
3906 }
3907
3908 private:
3909 GrowableArray<RawOneByteString*> objects_;
3910 };
3911
3912 class OneByteStringDeserializationCluster : public DeserializationCluster {
3913 public:
3914 OneByteStringDeserializationCluster() { }
3915 virtual ~OneByteStringDeserializationCluster() { }
3916
3917 void ReadAlloc(Deserializer* d) {
3918 start_index_ = d->next_index();
3919 PageSpace* old_space = d->heap()->old_space();
3920 intptr_t count = d->Read<intptr_t>();
3921 for (intptr_t i = 0; i < count; i++) {
3922 intptr_t length = d->Read<intptr_t>();
3923 d->AssignRef(AllocateUninitialized(old_space,
3924 OneByteString::InstanceSize(length)));
3925 }
3926 stop_index_ = d->next_index();
3927 }
3928
3929 void ReadFill(Deserializer* d) {
3930 bool is_vm_object = d->isolate() == Dart::vm_isolate();
3931
3932 for (intptr_t id = start_index_; id < stop_index_; id++) {
3933 RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
3934 intptr_t length = d->Read<intptr_t>();
3935 bool is_canonical = d->Read<bool>();
3936 Deserializer::InitializeHeader(str, kOneByteStringCid,
3937 OneByteString::InstanceSize(length),
3938 is_vm_object, is_canonical);
3939 str->ptr()->length_ = Smi::New(length);
3940 str->ptr()->hash_ = Smi::New(d->Read<intptr_t>());
3941 for (intptr_t j = 0; j < length; j++) {
3942 str->ptr()->data()[j] = d->Read<uint8_t>();
3943 }
3944 }
3945 }
3946 };
3947
3948 class TwoByteStringSerializationCluster : public SerializationCluster {
3949 public:
3950 TwoByteStringSerializationCluster() { }
3951 virtual ~TwoByteStringSerializationCluster() { }
3952
3953 void Trace(Serializer* s, RawObject* object) {
3954 RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(object);
3955 objects_.Add(str);
3956 }
3957
3958 void WriteAlloc(Serializer* s) {
3959 s->WriteCid(kTwoByteStringCid);
3960 intptr_t count = objects_.length();
3961 s->Write<intptr_t>(count);
3962 for (intptr_t i = 0; i < count; i++) {
3963 RawTwoByteString* str = objects_[i];
3964 intptr_t length = Smi::Value(str->ptr()->length_);
3965 s->Write<intptr_t>(length);
3966 s->AssignRef(str);
3967 }
3968 }
3969
3970 void WriteFill(Serializer* s) {
3971 intptr_t count = objects_.length();
3972 for (intptr_t i = 0; i < count; i++) {
3973 RawTwoByteString* str = objects_[i];
3974 intptr_t length = Smi::Value(str->ptr()->length_);
3975 s->Write<intptr_t>(length);
3976 s->Write<bool>(str->IsCanonical());
3977 intptr_t hash = Smi::Value(str->ptr()->hash_);
3978 s->Write<int32_t>(hash);
3979 s->WriteBytes(reinterpret_cast<uint8_t*>(str->ptr()->data()), length * 2);
3980 }
3981 }
3982
3983 private:
3984 GrowableArray<RawTwoByteString*> objects_;
3985 };
3986
3987 class TwoByteStringDeserializationCluster : public DeserializationCluster {
3988 public:
3989 TwoByteStringDeserializationCluster() { }
3990 virtual ~TwoByteStringDeserializationCluster() { }
3991
3992 void ReadAlloc(Deserializer* d) {
3993 start_index_ = d->next_index();
3994 PageSpace* old_space = d->heap()->old_space();
3995 intptr_t count = d->Read<intptr_t>();
3996 for (intptr_t i = 0; i < count; i++) {
3997 intptr_t length = d->Read<intptr_t>();
3998 d->AssignRef(AllocateUninitialized(old_space,
3999 TwoByteString::InstanceSize(length)));
4000 }
4001 stop_index_ = d->next_index();
4002 }
4003
4004 void ReadFill(Deserializer* d) {
4005 bool is_vm_object = d->isolate() == Dart::vm_isolate();
4006
4007 for (intptr_t id = start_index_; id < stop_index_; id++) {
4008 RawTwoByteString* str =
4009 reinterpret_cast<RawTwoByteString*>(d->Ref(id));
4010 intptr_t length = d->Read<intptr_t>();
4011 bool is_canonical = d->Read<bool>();
4012 Deserializer::InitializeHeader(str, kTwoByteStringCid,
4013 TwoByteString::InstanceSize(length),
4014 is_vm_object, is_canonical);
4015 str->ptr()->length_ = Smi::New(length);
4016 str->ptr()->hash_ = Smi::New(d->Read<int32_t>());
4017 uint8_t* cdata = reinterpret_cast<uint8_t*>(str->ptr()->data());
4018 d->ReadBytes(cdata, length * 2);
4019 }
4020 }
4021 };
4022
4023
4024 Serializer::Serializer(Thread* thread,
4025 Snapshot::Kind kind,
4026 uint8_t** buffer,
4027 ReAlloc alloc,
4028 intptr_t initial_size,
4029 InstructionsWriter* instructions_writer)
4030 : StackResource(thread),
4031 heap_(thread->isolate()->heap()),
4032 zone_(thread->zone()),
4033 kind_(kind),
4034 stream_(buffer, alloc, initial_size),
4035 instructions_writer_(instructions_writer),
4036 clusters_by_cid_(NULL),
4037 stack_(),
4038 num_cids_(0),
4039 num_base_objects_(0),
4040 num_written_objects_(0),
4041 next_ref_index_(1) {
4042 num_cids_ = thread->isolate()->class_table()->NumCids();
4043 clusters_by_cid_ = new SerializationCluster*[num_cids_];
4044 for (intptr_t i = 0; i < num_cids_; i++) {
4045 clusters_by_cid_[i] = NULL;
siva 2016/06/30 00:06:07 why not just call NewClusterForClass(i) here inste
rmacnak 2016/06/30 01:39:21 We only create a cluster if there are instances of
4046 }
4047 }
4048
4049
4050 Serializer::~Serializer() {
4051 delete[] clusters_by_cid_;
4052 }
4053
4054
4055 SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
4056 Zone* Z = zone_;
4057 if ((cid > kNumPredefinedCids) ||
4058 (cid == kInstanceCid) ||
4059 RawObject::IsTypedDataViewClassId(cid)) {
4060 Push(isolate()->class_table()->At(cid));
4061 return new (Z) InstanceSerializationCluster(cid);
4062 }
4063 if (RawObject::IsExternalTypedDataClassId(cid)) {
4064 return new (Z) ExternalTypedDataSerializationCluster(cid);
4065 }
4066 if (RawObject::IsTypedDataClassId(cid)) {
4067 return new (Z) TypedDataSerializationCluster(cid);
4068 }
4069
4070 switch (cid) {
4071 case kClassCid: return new (Z) ClassSerializationCluster();
4072 case kUnresolvedClassCid:
4073 return new (Z) UnresolvedClassSerializationCluster();
4074 case kTypeArgumentsCid: return new (Z) TypeArgumentsSerializationCluster();
4075 case kPatchClassCid: return new (Z) PatchClassSerializationCluster();
4076 case kFunctionCid: return new (Z) FunctionSerializationCluster();
4077 case kClosureDataCid: return new (Z) ClosureDataSerializationCluster();
4078 case kRedirectionDataCid:
4079 return new (Z) RedirectionDataSerializationCluster();
4080 case kFieldCid: return new (Z) FieldSerializationCluster();
4081 case kLiteralTokenCid: return new (Z) LiteralTokenSerializationCluster();
4082 case kTokenStreamCid: return new (Z) TokenStreamSerializationCluster();
4083 case kScriptCid: return new (Z) ScriptSerializationCluster();
4084 case kLibraryCid: return new (Z) LibrarySerializationCluster();
4085 case kNamespaceCid: return new (Z) NamespaceSerializationCluster();
4086 case kCodeCid: return new (Z) CodeSerializationCluster();
4087 case kObjectPoolCid: return new (Z) ObjectPoolSerializationCluster();
4088 case kPcDescriptorsCid:
4089 return new (Z) RODataSerializationCluster(kPcDescriptorsCid);
4090 case kStackmapCid:
4091 return new (Z) RODataSerializationCluster(kStackmapCid);
4092 case kExceptionHandlersCid:
4093 return new (Z) ExceptionHandlersSerializationCluster();
4094 case kContextCid: return new (Z) ContextSerializationCluster();
4095 case kContextScopeCid: return new (Z) ContextScopeSerializationCluster();
4096 case kICDataCid: return new (Z) ICDataSerializationCluster();
4097 case kMegamorphicCacheCid:
4098 return new (Z) MegamorphicCacheSerializationCluster();
4099 case kSubtypeTestCacheCid:
4100 return new (Z) SubtypeTestCacheSerializationCluster();
4101 case kLanguageErrorCid:
4102 return new (Z) LanguageErrorSerializationCluster();
4103 case kUnhandledExceptionCid:
4104 return new (Z) UnhandledExceptionSerializationCluster();
4105 case kLibraryPrefixCid: return new (Z) LibraryPrefixSerializationCluster();
4106 case kTypeCid: return new (Z) TypeSerializationCluster();
4107 case kTypeRefCid: return new (Z) TypeRefSerializationCluster();
4108 case kTypeParameterCid: return new (Z) TypeParameterSerializationCluster();
4109 case kBoundedTypeCid: return new (Z) BoundedTypeSerializationCluster();
4110 case kClosureCid: return new (Z) ClosureSerializationCluster();
4111 case kMintCid: return new (Z) MintSerializationCluster();
4112 case kBigintCid: return new (Z) BigintSerializationCluster();
4113 case kDoubleCid: return new (Z) DoubleSerializationCluster();
4114 case kGrowableObjectArrayCid:
4115 return new (Z) GrowableObjectArraySerializationCluster();
4116 case kStacktraceCid: return new (Z) StacktraceSerializationCluster();
4117 case kRegExpCid: return new (Z) RegExpSerializationCluster();
4118 case kLinkedHashMapCid: return new (Z) LinkedHashMapSerializationCluster();
4119 case kArrayCid:
4120 return new (Z) ArraySerializationCluster(kArrayCid);
4121 case kImmutableArrayCid:
4122 return new (Z) ArraySerializationCluster(kImmutableArrayCid);
4123 case kOneByteStringCid: {
4124 if (Snapshot::IncludesCode(kind_)) {
4125 return new (Z) RODataSerializationCluster(kOneByteStringCid);
4126 } else {
4127 return new (Z) OneByteStringSerializationCluster();
4128 }
4129 }
4130 case kTwoByteStringCid: {
4131 if (Snapshot::IncludesCode(kind_)) {
4132 return new (Z) RODataSerializationCluster(kTwoByteStringCid);
4133 } else {
4134 return new (Z) TwoByteStringSerializationCluster();
4135 }
4136 }
4137 default: break;
4138 }
4139
4140 FATAL1("No cluster defined for cid %" Pd, cid);
4141 return NULL;
4142 }
4143
4144
4145 void Serializer::Trace(RawObject* object) {
4146 intptr_t cid;
4147 if (!object->IsHeapObject()) {
4148 cid = kSmiCid;
4149 } else {
4150 cid = object->GetClassId();
4151 }
4152
4153 SerializationCluster* cluster = clusters_by_cid_[cid];
4154 if (cluster == NULL) {
4155 cluster = NewClusterForClass(cid);
4156 clusters_by_cid_[cid] = cluster;
4157 }
4158 ASSERT(cluster != NULL);
4159 cluster->Trace(this, object);
4160 }
4161
4162
4163 void Serializer::WriteVersionAndFeatures() {
4164 const char* expected_version = Version::SnapshotString();
4165 ASSERT(expected_version != NULL);
4166 const intptr_t version_len = strlen(expected_version);
4167 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
4168
4169 const char* expected_features = Dart::FeaturesString(kind_);
4170 ASSERT(expected_features != NULL);
4171 const intptr_t features_len = strlen(expected_features);
4172 WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
4173 features_len + 1);
4174 free(const_cast<char*>(expected_features));
4175 }
4176
4177
4178 #if defined(DEBUG)
4179 static const intptr_t kSectionMarker = 0xABAB;
4180 #endif
4181
4182 void Serializer::Serialize() {
4183 while (stack_.length() > 0) {
4184 Trace(stack_.RemoveLast());
4185 }
4186
4187 intptr_t num_clusters = 0;
4188 for (intptr_t cid = 1; cid < num_cids_; cid++) {
4189 SerializationCluster* cluster = clusters_by_cid_[cid];
4190 if (cluster != NULL) {
4191 num_clusters++;
4192 }
4193 }
4194
4195 intptr_t num_objects = num_base_objects_ + num_written_objects_;
4196
4197 Write<int32_t>(num_objects);
4198 Write<int32_t>(num_clusters);
4199
4200 for (intptr_t cid = 1; cid < num_cids_; cid++) {
4201 SerializationCluster* cluster = clusters_by_cid_[cid];
4202 if (cluster != NULL) {
4203 cluster->WriteAlloc(this);
4204 #if defined(DEBUG)
4205 Write<intptr_t>(next_ref_index_);
4206 #endif
4207 }
4208 }
4209
4210 // We should have assigned a ref to every object we pushed.
4211 ASSERT((next_ref_index_ - 1) == num_objects);
4212
4213 for (intptr_t cid = 1; cid < num_cids_; cid++) {
4214 SerializationCluster* cluster = clusters_by_cid_[cid];
4215 if (cluster != NULL) {
4216 cluster->WriteFill(this);
4217 #if defined(DEBUG)
4218 Write<intptr_t>(kSectionMarker);
4219 #endif
4220 }
4221 }
4222 }
4223
4224
4225 void Serializer::AddVMIsolateBaseObjects() {
4226 // These objects are always allocated by Object::InitOnce, so they are not
4227 // written into the snapshot.
4228
4229 AddBaseObject(Object::null());
4230 AddBaseObject(Object::sentinel().raw());
4231 AddBaseObject(Object::transition_sentinel().raw());
4232 AddBaseObject(Object::empty_array().raw());
4233 AddBaseObject(Object::zero_array().raw());
4234 AddBaseObject(Object::dynamic_type().raw());
4235 AddBaseObject(Object::void_type().raw());
4236 AddBaseObject(Bool::True().raw());
4237 AddBaseObject(Bool::False().raw());
4238 AddBaseObject(Object::extractor_parameter_types().raw());
4239 AddBaseObject(Object::extractor_parameter_names().raw());
4240 AddBaseObject(Object::empty_context_scope().raw());
4241 AddBaseObject(Object::empty_descriptors().raw());
4242 AddBaseObject(Object::empty_var_descriptors().raw());
4243 AddBaseObject(Object::empty_exception_handlers().raw());
4244
4245 for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
4246 AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
4247 }
4248 for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
4249 AddBaseObject(ICData::cached_icdata_arrays_[i]);
4250 }
4251
4252 ClassTable* table = isolate()->class_table();
4253 for (intptr_t cid = kClassCid; cid <= kUnwindErrorCid; cid++) {
4254 // Error has no class object.
4255 if (cid != kErrorCid) {
4256 ASSERT(table->HasValidClassAt(cid));
4257 AddBaseObject(table->At(cid));
4258 }
4259 }
4260 AddBaseObject(table->At(kDynamicCid));
4261 AddBaseObject(table->At(kVoidCid));
4262 }
4263
4264
4265 intptr_t Serializer::WriteVMSnapshot(const Array& symbols,
4266 const Array& scripts) {
4267 NoSafepointScope no_safepoint;
4268
4269 AddVMIsolateBaseObjects();
4270
4271 // Push roots.
4272 Push(symbols.raw());
4273 Push(scripts.raw());
4274 if (Snapshot::IncludesCode(kind_)) {
4275 StubCode::Push(this);
4276 }
4277
4278 Serialize();
4279
4280 // Write roots.
4281 WriteRef(symbols.raw());
4282 WriteRef(scripts.raw());
4283 if (Snapshot::IncludesCode(kind_)) {
4284 StubCode::WriteRef(this);
4285 }
4286
4287 #if defined(DEBUG)
4288 Write<intptr_t>(kSectionMarker);
4289 #endif
4290
4291 // Note we are not clearing the object id table. The full ref table
4292 // of the vm isolate snapshot serves as the base objects for the
4293 // regular isolate snapshot.
4294
4295 // Return the number of objects, -1 accounts for unused ref 0.
4296 return next_ref_index_ - 1;
4297 }
4298
4299
4300 void Serializer::WriteFullSnapshot(intptr_t num_base_objects,
4301 ObjectStore* object_store) {
4302 NoSafepointScope no_safepoint;
4303
4304 if (num_base_objects == 0) {
4305 // Units tests not writing a new vm isolate.
4306 const Array& base_objects = Object::vm_isolate_snapshot_object_table();
4307 for (intptr_t i = 1; i < base_objects.Length(); i++) {
4308 AddBaseObject(base_objects.At(i));
4309 }
4310 } else {
4311 // Base objects carried over from WriteVMIsolateSnapshot.
4312 num_base_objects_ += num_base_objects;
4313 next_ref_index_ += num_base_objects;
4314 }
4315
4316 // Push roots.
4317 RawObject** from = object_store->from();
4318 RawObject** to = object_store->to_snapshot(kind_);
4319 for (RawObject** p = from; p <= to; p++) {
4320 Push(*p);
4321 }
4322
4323 Serialize();
4324
4325 // Write roots.
4326 for (RawObject** p = from; p <= to; p++) {
4327 WriteRef(*p);
4328 }
4329
4330 #if defined(DEBUG)
4331 Write<intptr_t>(kSectionMarker);
4332 #endif
4333
4334 heap_->ResetObjectIdTable();
4335 }
4336
4337
4338 Deserializer::Deserializer(Thread* thread,
4339 Snapshot::Kind kind,
4340 const uint8_t* buffer,
4341 intptr_t size,
4342 const uint8_t* instructions_buffer,
4343 const uint8_t* data_buffer)
4344 : StackResource(thread),
4345 heap_(thread->isolate()->heap()),
4346 zone_(thread->zone()),
4347 kind_(kind),
4348 stream_(buffer, size),
4349 instructions_reader_(NULL),
4350 refs_(NULL),
4351 next_ref_index_(1),
4352 clusters_(NULL) {
4353 if (Snapshot::IncludesCode(kind)) {
4354 ASSERT(instructions_buffer != NULL);
4355 }
4356 if (instructions_buffer != NULL) {
4357 instructions_reader_ =
4358 new (zone_) InstructionsReader(instructions_buffer, data_buffer);
4359 }
4360 }
4361
4362
4363 Deserializer::~Deserializer() {
4364 delete[] clusters_;
4365 }
4366
4367
4368 DeserializationCluster* Deserializer::ReadCluster() {
4369 intptr_t cid = ReadCid();
4370
4371 Zone* Z = zone_;
4372 if ((cid > kNumPredefinedCids) ||
4373 (cid == kInstanceCid) ||
4374 RawObject::IsTypedDataViewClassId(cid)) {
4375 return new (Z) InstanceDeserializationCluster(cid);
4376 }
4377 if (RawObject::IsExternalTypedDataClassId(cid)) {
4378 return new (Z) ExternalTypedDataDeserializationCluster(cid);
4379 }
4380 if (RawObject::IsTypedDataClassId(cid)) {
4381 return new (Z) TypedDataDeserializationCluster(cid);
4382 }
4383
4384 switch (cid) {
4385 case kClassCid: return new (Z) ClassDeserializationCluster();
4386 case kUnresolvedClassCid:
4387 return new (Z) UnresolvedClassDeserializationCluster();
4388 case kTypeArgumentsCid:
4389 return new (Z) TypeArgumentsDeserializationCluster();
4390 case kPatchClassCid: return new (Z) PatchClassDeserializationCluster();
4391 case kFunctionCid: return new (Z) FunctionDeserializationCluster();
4392 case kClosureDataCid: return new (Z) ClosureDataDeserializationCluster();
4393 case kRedirectionDataCid:
4394 return new (Z) RedirectionDataDeserializationCluster();
4395 case kFieldCid: return new (Z) FieldDeserializationCluster();
4396 case kLiteralTokenCid: return new (Z) LiteralTokenDeserializationCluster();
4397 case kTokenStreamCid: return new (Z) TokenStreamDeserializationCluster();
4398 case kScriptCid: return new (Z) ScriptDeserializationCluster();
4399 case kLibraryCid: return new (Z) LibraryDeserializationCluster();
4400 case kNamespaceCid: return new (Z) NamespaceDeserializationCluster();
4401 case kCodeCid: return new (Z) CodeDeserializationCluster();
4402 case kObjectPoolCid: return new (Z) ObjectPoolDeserializationCluster();
4403 case kPcDescriptorsCid:
4404 case kStackmapCid:
4405 return new (Z) RODataDeserializationCluster();
4406 case kExceptionHandlersCid:
4407 return new (Z) ExceptionHandlersDeserializationCluster();
4408 case kContextCid: return new (Z) ContextDeserializationCluster();
4409 case kContextScopeCid: return new (Z) ContextScopeDeserializationCluster();
4410 case kICDataCid: return new (Z) ICDataDeserializationCluster();
4411 case kMegamorphicCacheCid:
4412 return new (Z) MegamorphicCacheDeserializationCluster();
4413 case kSubtypeTestCacheCid:
4414 return new (Z) SubtypeTestCacheDeserializationCluster();
4415 case kLanguageErrorCid:
4416 return new (Z) LanguageErrorDeserializationCluster();
4417 case kUnhandledExceptionCid:
4418 return new (Z) UnhandledExceptionDeserializationCluster();
4419 case kLibraryPrefixCid:
4420 return new (Z) LibraryPrefixDeserializationCluster();
4421 case kTypeCid: return new (Z) TypeDeserializationCluster();
4422 case kTypeRefCid: return new (Z) TypeRefDeserializationCluster();
4423 case kTypeParameterCid:
4424 return new (Z) TypeParameterDeserializationCluster();
4425 case kBoundedTypeCid: return new (Z) BoundedTypeDeserializationCluster();
4426 case kClosureCid: return new (Z) ClosureDeserializationCluster();
4427 case kMintCid: return new (Z) MintDeserializationCluster();
4428 case kBigintCid: return new (Z) BigintDeserializationCluster();
4429 case kDoubleCid: return new (Z) DoubleDeserializationCluster();
4430 case kGrowableObjectArrayCid:
4431 return new (Z) GrowableObjectArrayDeserializationCluster();
4432 case kStacktraceCid: return new (Z) StacktraceDeserializationCluster();
4433 case kRegExpCid: return new (Z) RegExpDeserializationCluster();
4434 case kLinkedHashMapCid:
4435 return new (Z) LinkedHashMapDeserializationCluster();
4436 case kArrayCid:
4437 return new (Z) ArrayDeserializationCluster(kArrayCid);
4438 case kImmutableArrayCid:
4439 return new (Z) ArrayDeserializationCluster(kImmutableArrayCid);
4440 case kOneByteStringCid: {
4441 if (Snapshot::IncludesCode(kind_)) {
4442 return new (Z) RODataDeserializationCluster();
4443 } else {
4444 return new (Z) OneByteStringDeserializationCluster();
4445 }
4446 }
4447 case kTwoByteStringCid: {
4448 if (Snapshot::IncludesCode(kind_)) {
4449 return new (Z) RODataDeserializationCluster();
4450 } else {
4451 return new (Z) TwoByteStringDeserializationCluster();
4452 }
4453 }
4454 default: break;
4455 }
4456 FATAL1("No cluster defined for cid %" Pd, cid);
4457 return NULL;
4458 }
4459
4460
4461 RawApiError* Deserializer::VerifyVersionAndFeatures() {
4462 // If the version string doesn't match, return an error.
4463 // Note: New things are allocated only if we're going to return an error.
4464
4465 const char* expected_version = Version::SnapshotString();
4466 ASSERT(expected_version != NULL);
4467 const intptr_t version_len = strlen(expected_version);
4468 if (PendingBytes() < version_len) {
4469 const intptr_t kMessageBufferSize = 128;
4470 char message_buffer[kMessageBufferSize];
4471 OS::SNPrint(message_buffer,
4472 kMessageBufferSize,
4473 "No full snapshot version found, expected '%s'",
4474 expected_version);
4475 // This can also fail while bringing up the VM isolate, so make sure to
4476 // allocate the error message in old space.
4477 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
4478 return ApiError::New(msg, Heap::kOld);
4479 }
4480
4481 const char* version = reinterpret_cast<const char*>(CurrentBufferAddress());
4482 ASSERT(version != NULL);
4483 if (strncmp(version, expected_version, version_len)) {
4484 const intptr_t kMessageBufferSize = 256;
4485 char message_buffer[kMessageBufferSize];
4486 char* actual_version = OS::StrNDup(version, version_len);
4487 OS::SNPrint(message_buffer,
4488 kMessageBufferSize,
4489 "Wrong %s snapshot version, expected '%s' found '%s'",
4490 (Snapshot::IsFull(kind_)) ? "full" : "script",
4491 expected_version,
4492 actual_version);
4493 free(actual_version);
4494 // This can also fail while bringing up the VM isolate, so make sure to
4495 // allocate the error message in old space.
4496 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
4497 return ApiError::New(msg, Heap::kOld);
4498 }
4499 Advance(version_len);
4500
4501 const char* expected_features = Dart::FeaturesString(kind_);
4502 ASSERT(expected_features != NULL);
4503 const intptr_t expected_len = strlen(expected_features);
4504
4505 const char* features = reinterpret_cast<const char*>(CurrentBufferAddress());
4506 ASSERT(features != NULL);
4507 intptr_t buffer_len = OS::StrNLen(features, PendingBytes());
4508 if ((buffer_len != expected_len) ||
4509 strncmp(features, expected_features, expected_len)) {
4510 const intptr_t kMessageBufferSize = 256;
4511 char message_buffer[kMessageBufferSize];
4512 char* actual_features = OS::StrNDup(features, buffer_len < 128 ? buffer_len
4513 : 128);
4514 OS::SNPrint(message_buffer,
4515 kMessageBufferSize,
4516 "Wrong features in snapshot, expected '%s' found '%s'",
4517 expected_features,
4518 actual_features);
4519 free(const_cast<char*>(expected_features));
4520 free(actual_features);
4521 // This can also fail while bringing up the VM isolate, so make sure to
4522 // allocate the error message in old space.
4523 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
4524 return ApiError::New(msg, Heap::kOld);
4525 }
4526 free(const_cast<char*>(expected_features));
4527 Advance(expected_len + 1);
4528 return ApiError::null();
4529 }
4530
4531
4532 void Deserializer::Prepare() {
4533 num_objects_ = Read<int32_t>();
4534 num_clusters_ = Read<int32_t>();
4535
4536 clusters_ = new DeserializationCluster*[num_clusters_];
4537 refs_ = Array::New(num_objects_ + 1, Heap::kOld);
4538 }
4539
4540
4541 void Deserializer::Deserialize() {
4542 // TODO(rmacnak): Verify num of base objects.
4543
4544 {
4545 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
4546 Timeline::GetIsolateStream(), "ReadAlloc"));
4547 for (intptr_t i = 0; i < num_clusters_; i++) {
4548 clusters_[i] = ReadCluster();
4549 clusters_[i]->ReadAlloc(this);
4550 #if defined(DEBUG)
4551 intptr_t serializers_next_ref_index_ = Read<intptr_t>();
4552 ASSERT(serializers_next_ref_index_ == next_ref_index_);
4553 #endif
4554 }
4555 }
4556
4557 // We should have completely filled the ref array.
4558 ASSERT((next_ref_index_ - 1) == num_objects_);
4559
4560 {
4561 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
4562 Timeline::GetIsolateStream(), "ReadFill"));
4563 for (intptr_t i = 0; i < num_clusters_; i++) {
4564 clusters_[i]->ReadFill(this);
4565 #if defined(DEBUG)
4566 intptr_t section_marker = Read<intptr_t>();
4567 ASSERT(section_marker == kSectionMarker);
4568 #endif
4569 }
4570 }
4571 }
4572
4573 class HeapLocker : public StackResource {
4574 public:
4575 HeapLocker(Thread* thread, PageSpace* page_space)
4576 : StackResource(thread), page_space_(page_space) {
4577 page_space_->AcquireDataLock();
4578 }
4579 ~HeapLocker() {
4580 page_space_->ReleaseDataLock();
4581 }
4582
4583 private:
4584 PageSpace* page_space_;
4585 };
4586
4587
4588 void Deserializer::AddVMIsolateBaseObjects() {
4589 // These objects are always allocated by Object::InitOnce, so they are not
4590 // written into the snapshot.
4591
4592 AddBaseObject(Object::null());
4593 AddBaseObject(Object::sentinel().raw());
4594 AddBaseObject(Object::transition_sentinel().raw());
4595 AddBaseObject(Object::empty_array().raw());
4596 AddBaseObject(Object::zero_array().raw());
4597 AddBaseObject(Object::dynamic_type().raw());
4598 AddBaseObject(Object::void_type().raw());
4599 AddBaseObject(Bool::True().raw());
4600 AddBaseObject(Bool::False().raw());
4601 AddBaseObject(Object::extractor_parameter_types().raw());
4602 AddBaseObject(Object::extractor_parameter_names().raw());
4603 AddBaseObject(Object::empty_context_scope().raw());
4604 AddBaseObject(Object::empty_descriptors().raw());
4605 AddBaseObject(Object::empty_var_descriptors().raw());
4606 AddBaseObject(Object::empty_exception_handlers().raw());
4607
4608 for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
4609 AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
4610 }
4611 for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
4612 AddBaseObject(ICData::cached_icdata_arrays_[i]);
4613 }
4614
4615 ClassTable* table = isolate()->class_table();
4616 for (intptr_t cid = kClassCid; cid <= kUnwindErrorCid; cid++) {
4617 // Error has no class object.
4618 if (cid != kErrorCid) {
4619 ASSERT(table->HasValidClassAt(cid));
4620 AddBaseObject(table->At(cid));
4621 }
4622 }
4623 AddBaseObject(table->At(kDynamicCid));
4624 AddBaseObject(table->At(kVoidCid));
4625 }
4626
4627
4628 void Deserializer::ReadVMSnapshot() {
4629 Array& symbol_table = Array::Handle(zone_);
4630 Array& refs = Array::Handle(zone_);
4631 Prepare();
4632
4633 {
4634 NoSafepointScope no_safepoint;
4635 HeapLocker hl(thread(), heap_->old_space());
siva 2016/06/30 00:06:07 Why do you need to lock the heap pages, no other t
rmacnak 2016/06/30 01:39:21 Comes from the old full snapshot reading code. Rem
4636
4637 AddVMIsolateBaseObjects();
4638
4639 Deserialize();
4640
4641 // Read roots.
4642 symbol_table ^= ReadRef();
4643 isolate()->object_store()->set_symbol_table(symbol_table);
4644 ReadRef(); // Script list.
4645 if (Snapshot::IncludesCode(kind_)) {
4646 StubCode::ReadRef(this);
4647 }
4648
4649 #if defined(DEBUG)
4650 intptr_t section_marker = Read<intptr_t>();
4651 ASSERT(section_marker == kSectionMarker);
4652 #endif
4653
4654 refs = refs_;
4655 refs_ = NULL;
4656 }
4657
4658 Symbols::InitOnceFromSnapshot(isolate());
4659
4660 Object::set_vm_isolate_snapshot_object_table(refs);
4661
4662 #if defined(DEBUG)
4663 isolate()->ValidateClassTable();
4664 #endif
4665 }
4666
4667 void Deserializer::ReadFullSnapshot(ObjectStore* object_store) {
4668 Array& refs = Array::Handle();
4669 Prepare();
4670
4671 {
4672 NoSafepointScope no_safepoint;
4673 HeapLocker hl(thread(), heap_->old_space());
4674
4675 // N.B.: Skipping index 0 because ref 0 is illegal.
4676 const Array& base_objects = Object::vm_isolate_snapshot_object_table();
4677 for (intptr_t i = 1; i < base_objects.Length(); i++) {
4678 AddBaseObject(base_objects.At(i));
4679 }
4680
4681 Deserialize();
4682
4683 // Read roots.
4684 RawObject** from = object_store->from();
4685 RawObject** to = object_store->to_snapshot(kind_);
4686 for (RawObject** p = from; p <= to; p++) {
4687 *p = ReadRef();
4688 }
4689
4690 #if defined(DEBUG)
4691 intptr_t section_marker = Read<intptr_t>();
4692 ASSERT(section_marker == kSectionMarker);
4693 #endif
4694
4695 refs = refs_;
4696 refs_ = NULL;
4697 }
4698
4699 #if defined(DEBUG)
4700 Isolate* isolate = thread()->isolate();
4701 isolate->ValidateClassTable();
4702 isolate->heap()->Verify();
4703 #endif
4704
4705 {
4706 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
4707 Timeline::GetIsolateStream(), "PostLoad"));
4708 for (intptr_t i = 0; i < num_clusters_; i++) {
4709 clusters_[i]->PostLoad(refs, kind_, zone_);
4710 }
4711 }
4712
4713 // Setup native resolver for bootstrap impl.
4714 Bootstrap::SetupNativeResolver();
4715 }
4716
4717
4718 // An object visitor which will iterate over all the script objects in the heap
4719 // and either count them or collect them into an array. This is used during
4720 // full snapshot generation of the VM isolate to write out all script
4721 // objects and their accompanying token streams.
4722 class ScriptVisitor : public ObjectVisitor {
4723 public:
4724 explicit ScriptVisitor(Thread* thread) :
4725 objHandle_(Object::Handle(thread->zone())),
4726 count_(0),
4727 scripts_(NULL) {}
4728
4729 ScriptVisitor(Thread* thread, const Array* scripts) :
4730 objHandle_(Object::Handle(thread->zone())),
4731 count_(0),
4732 scripts_(scripts) {}
4733
4734 void VisitObject(RawObject* obj) {
4735 if (obj->IsScript()) {
4736 if (scripts_ != NULL) {
4737 objHandle_ = obj;
4738 scripts_->SetAt(count_, objHandle_);
4739 }
4740 count_ += 1;
4741 }
4742 }
4743
4744 intptr_t count() const { return count_; }
4745
4746 private:
4747 Object& objHandle_;
4748 intptr_t count_;
4749 const Array* scripts_;
4750 };
4751
4752
4753
4754 FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
4755 uint8_t** vm_isolate_snapshot_buffer,
4756 uint8_t** isolate_snapshot_buffer,
4757 ReAlloc alloc,
4758 InstructionsWriter* instructions_writer)
4759 : thread_(Thread::Current()),
4760 kind_(kind),
4761 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
4762 isolate_snapshot_buffer_(isolate_snapshot_buffer),
4763 alloc_(alloc),
4764 vm_isolate_snapshot_size_(0),
4765 isolate_snapshot_size_(0),
4766 instructions_writer_(instructions_writer),
4767 scripts_(Array::Handle(zone())),
4768 saved_symbol_table_(Array::Handle(zone())),
4769 new_vm_symbol_table_(Array::Handle(zone())) {
4770 ASSERT(isolate_snapshot_buffer_ != NULL);
4771 ASSERT(alloc_ != NULL);
4772 ASSERT(isolate() != NULL);
4773 ASSERT(ClassFinalizer::AllClassesFinalized());
4774 ASSERT(isolate() != NULL);
4775 ASSERT(heap() != NULL);
4776 ObjectStore* object_store = isolate()->object_store();
4777 ASSERT(object_store != NULL);
4778
4779 #if defined(DEBUG)
4780 // Ensure the class table is valid.
4781 isolate()->ValidateClassTable();
4782 #endif
4783 // Can't have any mutation happening while we're serializing.
4784 ASSERT(isolate()->background_compiler() == NULL);
4785
4786 if (vm_isolate_snapshot_buffer != NULL) {
4787 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
4788 Timeline::GetIsolateStream(), "PrepareNewVMIsolate"));
4789
4790 // Collect all the script objects and their accompanying token stream
4791 // objects into an array so that we can write it out as part of the VM
4792 // isolate snapshot. We first count the number of script objects, allocate
4793 // an array and then fill it up with the script objects.
4794 ScriptVisitor scripts_counter(thread());
4795 heap()->IterateOldObjects(&scripts_counter);
4796 Dart::vm_isolate()->heap()->IterateOldObjects(&scripts_counter);
4797 intptr_t count = scripts_counter.count();
4798 scripts_ = Array::New(count, Heap::kOld);
4799 ScriptVisitor script_visitor(thread(), &scripts_);
4800 heap()->IterateOldObjects(&script_visitor);
4801 Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor);
4802 ASSERT(script_visitor.count() == count);
4803
4804 // Tuck away the current symbol table.
4805 saved_symbol_table_ = object_store->symbol_table();
4806
4807 // Create a unified symbol table that will be written as the vm isolate's
4808 // symbol table.
4809 new_vm_symbol_table_ = Symbols::UnifiedSymbolTable();
4810
4811 // Create an empty symbol table that will be written as the isolate's symbol
4812 // table.
4813 Symbols::SetupSymbolTable(isolate());
4814 } else {
4815 // Reuse the current vm isolate.
siva 2016/06/30 00:06:08 Why have this empty block here?
rmacnak 2016/06/30 01:39:21 Scoping the comment.
4816 }
4817 }
4818
4819 FullSnapshotWriter::~FullSnapshotWriter() {
4820 // We may run Dart code afterwards, restore the symbol table if needed.
4821 if (!saved_symbol_table_.IsNull()) {
4822 isolate()->object_store()->set_symbol_table(saved_symbol_table_);
4823 saved_symbol_table_ = Array::null();
4824 }
4825 new_vm_symbol_table_ = Array::null();
4826 scripts_ = Array::null();
4827 }
4828
4829
4830 intptr_t FullSnapshotWriter::WriteVmIsolateSnapshot() {
4831 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
4832 Timeline::GetIsolateStream(), "WriteVmIsolateSnapshot"));
4833
4834 ASSERT(vm_isolate_snapshot_buffer_ != NULL);
4835 Serializer serializer(thread(),
4836 kind_,
4837 vm_isolate_snapshot_buffer_,
4838 alloc_,
4839 kInitialSize,
4840 instructions_writer_);
4841
4842 serializer.ReserveHeader();
4843 serializer.WriteVersionAndFeatures();
4844 /*
4845 * Now Write out the following
4846 * - the symbol table
4847 * - all the scripts and token streams for these scripts
4848 * - the stub code (precompiled snapshots only)
4849 **/
4850 intptr_t num_objects = serializer.WriteVMSnapshot(new_vm_symbol_table_,
4851 scripts_);
4852 serializer.FillHeader(serializer.kind());
4853
4854 vm_isolate_snapshot_size_ = serializer.bytes_written();
4855 return num_objects;
4856 }
4857
4858
4859 void FullSnapshotWriter::WriteIsolateFullSnapshot(
4860 intptr_t num_base_objects) {
4861 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
4862 Timeline::GetIsolateStream(), "WriteIsolateFullSnapshot"));
4863
4864 Serializer serializer(thread(),
4865 kind_,
4866 isolate_snapshot_buffer_,
4867 alloc_,
4868 kInitialSize,
4869 instructions_writer_);
4870 ObjectStore* object_store = isolate()->object_store();
4871 ASSERT(object_store != NULL);
4872
4873 serializer.ReserveHeader();
4874 serializer.WriteVersionAndFeatures();
4875 serializer.WriteFullSnapshot(num_base_objects, object_store);
4876 serializer.FillHeader(serializer.kind());
4877
4878 isolate_snapshot_size_ = serializer.bytes_written();
4879 }
4880
4881
4882 void FullSnapshotWriter::WriteFullSnapshot() {
4883 intptr_t num_base_objects;
4884 if (vm_isolate_snapshot_buffer() != NULL) {
4885 num_base_objects = WriteVmIsolateSnapshot();
4886 ASSERT(num_base_objects != 0);
4887 } else {
4888 num_base_objects = 0;
4889 }
4890
4891 WriteIsolateFullSnapshot(num_base_objects);
4892
4893 if (Snapshot::IncludesCode(kind_)) {
4894 instructions_writer_->Write();
4895
4896 OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize());
4897 OS::Print("Isolate(CodeSize): %" Pd "\n", IsolateSnapshotSize());
4898 OS::Print("Instructions(CodeSize): %" Pd "\n",
4899 instructions_writer_->binary_size());
4900 intptr_t total = VmIsolateSnapshotSize() +
4901 IsolateSnapshotSize() +
4902 instructions_writer_->binary_size();
4903 OS::Print("Total(CodeSize): %" Pd "\n", total);
4904 }
4905 }
4906
4907
4908 RawApiError* IsolateSnapshotReader::ReadFullSnapshot() {
4909 Deserializer deserializer(thread_,
4910 kind_,
4911 buffer_,
4912 size_,
4913 instructions_buffer_,
4914 data_buffer_);
4915
4916 RawApiError* error = deserializer.VerifyVersionAndFeatures();
4917 if (error != ApiError::null()) {
4918 return error;
4919 }
4920
4921 deserializer.ReadFullSnapshot(thread_->isolate()->object_store());
4922
4923 return ApiError::null();
4924 }
4925
4926
4927 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() {
4928 Deserializer deserializer(thread_,
4929 kind_,
4930 buffer_,
4931 size_,
4932 instructions_buffer_,
4933 data_buffer_);
4934
4935 RawApiError* error = deserializer.VerifyVersionAndFeatures();
4936 if (error != ApiError::null()) {
4937 return error;
4938 }
4939
4940 deserializer.ReadVMSnapshot();
4941
4942 Dart::set_instructions_snapshot_buffer(instructions_buffer_);
4943 Dart::set_data_snapshot_buffer(data_buffer_);
4944
4945 return ApiError::null();
4946 }
4947
4948 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698