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

Side by Side Diff: vm/snapshot.cc

Issue 10827209: Unify class ids and snapshot object ids list so that we don't have disparate and sometimes confusin… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « vm/snapshot.h ('k') | vm/snapshot_ids.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/snapshot.h" 5 #include "vm/snapshot.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/exceptions.h" 10 #include "vm/exceptions.h"
11 #include "vm/heap.h" 11 #include "vm/heap.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/snapshot_ids.h"
14 #include "vm/symbols.h" 15 #include "vm/symbols.h"
15 16
16 namespace dart { 17 namespace dart {
17 18
18 enum {
19 kInstanceId = ObjectStore::kMaxId,
20 kMaxPredefinedObjectIds,
21 };
22 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; 19 static const int kNumInitialReferencesInFullSnapshot = 160 * KB;
23 static const int kNumInitialReferences = 4; 20 static const int kNumInitialReferences = 4;
24 21
25 22
26 static bool IsSingletonClassId(intptr_t index) { 23 static bool IsSingletonClassId(intptr_t class_id) {
27 // Check if this is a singleton object class which is shared by all isolates. 24 // Check if this is a singleton object class which is shared by all isolates.
28 return (index >= Object::kClassClass && index < Object::kMaxId); 25 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) ||
26 (class_id >= kNullCid && class_id <= kVoidCid));
29 } 27 }
30 28
31 29
32 static bool IsObjectStoreClassId(intptr_t index) { 30 static bool IsObjectStoreClassId(intptr_t class_id) {
33 // Check if this is a class which is stored in the object store. 31 // Check if this is a class which is stored in the object store.
34 return (index >= ObjectStore::kObjectClass && index < ObjectStore::kMaxId); 32 return (class_id == kObjectCid ||
33 (class_id >= kInstanceCid && class_id <= kJSRegExpCid));
35 } 34 }
36 35
37 36
38 static bool IsObjectStoreTypeId(intptr_t index) { 37 static bool IsObjectStoreTypeId(intptr_t index) {
39 // Check if this is a type which is stored in the object store. 38 // Check if this is a type which is stored in the object store.
40 return (index >= ObjectStore::kObjectType && 39 return (index >= kObjectType && index <= kByteArrayInterface);
41 index <= ObjectStore::kListInterface); 40 }
41
42
43 static intptr_t ClassIdFromObjectId(intptr_t object_id) {
44 ASSERT(object_id > kClassIdsOffset);
45 intptr_t class_id = (object_id - kClassIdsOffset);
46 return class_id;
47 }
48
49
50 static intptr_t ObjectIdFromClassId(intptr_t class_id) {
51 ASSERT(class_id > kIllegalCid && class_id < kNumPredefinedCids);
52 return (class_id + kClassIdsOffset);
53 }
54
55
56 static RawType* GetType(ObjectStore* object_store, int index) {
57 switch (index) {
58 case kObjectType: return object_store->object_type();
59 case kNullType: return object_store->null_type();
60 case kDynamicType: return object_store->dynamic_type();
61 case kVoidType: return object_store->void_type();
62 case kFunctionInterface: return object_store->function_interface();
63 case kNumberInterface: return object_store->number_interface();
64 case kDoubleInterface: return object_store->double_interface();
65 case kIntInterface: return object_store->int_interface();
66 case kBoolInterface: return object_store->bool_interface();
67 case kStringInterface: return object_store->string_interface();
68 case kListInterface: return object_store->list_interface();
69 case kByteArrayInterface: return object_store->byte_array_interface();
70 default: break;
71 }
72 UNREACHABLE();
73 return Type::null();
74 }
75
76
77 static int GetTypeIndex(ObjectStore* object_store, const RawType* raw_type) {
78 ASSERT(raw_type->IsHeapObject());
79 if (raw_type == object_store->object_type()) {
80 return kObjectType;
81 } else if (raw_type == object_store->null_type()) {
82 return kNullType;
83 } else if (raw_type == object_store->dynamic_type()) {
84 return kDynamicType;
85 } else if (raw_type == object_store->void_type()) {
86 return kVoidType;
87 } else if (raw_type == object_store->function_interface()) {
88 return kFunctionInterface;
89 } else if (raw_type == object_store->number_interface()) {
90 return kNumberInterface;
91 } else if (raw_type == object_store->double_interface()) {
92 return kDoubleInterface;
93 } else if (raw_type == object_store->int_interface()) {
94 return kIntInterface;
95 } else if (raw_type == object_store->bool_interface()) {
96 return kBoolInterface;
97 } else if (raw_type == object_store->string_interface()) {
98 return kStringInterface;
99 } else if (raw_type == object_store->list_interface()) {
100 return kListInterface;
101 } else if (raw_type == object_store->byte_array_interface()) {
102 return kByteArrayInterface;
103 }
104 return kInvalidIndex;
42 } 105 }
43 106
44 107
45 // TODO(5411462): Temporary setup of snapshot for testing purposes, 108 // TODO(5411462): Temporary setup of snapshot for testing purposes,
46 // the actual creation of a snapshot maybe done differently. 109 // the actual creation of a snapshot maybe done differently.
47 const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) { 110 const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) {
48 ASSERT(raw_memory != NULL); 111 ASSERT(raw_memory != NULL);
49 ASSERT(kHeaderSize == sizeof(Snapshot)); 112 ASSERT(kHeaderSize == sizeof(Snapshot));
50 ASSERT(kLengthIndex == length_offset()); 113 ASSERT(kLengthIndex == length_offset());
51 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset()); 114 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); 223 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
161 intptr_t object_id = SerializedHeaderData::decode(header_value); 224 intptr_t object_id = SerializedHeaderData::decode(header_value);
162 ASSERT(GetBackRef(object_id) == NULL); 225 ASSERT(GetBackRef(object_id) == NULL);
163 226
164 // Read the class header information and lookup the class. 227 // Read the class header information and lookup the class.
165 intptr_t class_header = ReadIntptrValue(); 228 intptr_t class_header = ReadIntptrValue();
166 229
167 // Since we are only reading an object reference, If it is an instance kind 230 // Since we are only reading an object reference, If it is an instance kind
168 // then we only need to figure out the class of the object and allocate an 231 // then we only need to figure out the class of the object and allocate an
169 // instance of it. The individual fields will be read later. 232 // instance of it. The individual fields will be read later.
170 if (SerializedHeaderData::decode(class_header) == kInstanceId) { 233 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
171 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); 234 Instance& result = Instance::ZoneHandle(isolate(), Instance::null());
172 AddBackRef(object_id, &result, kIsNotDeserialized); 235 AddBackRef(object_id, &result, kIsNotDeserialized);
173 236
174 cls_ ^= ReadObjectImpl(); // Read class information. 237 cls_ ^= ReadObjectImpl(); // Read class information.
175 ASSERT(!cls_.IsNull()); 238 ASSERT(!cls_.IsNull());
176 intptr_t instance_size = cls_.instance_size(); 239 intptr_t instance_size = cls_.instance_size();
177 ASSERT(instance_size > 0); 240 ASSERT(instance_size > 0);
178 if (kind_ == Snapshot::kFull) { 241 if (kind_ == Snapshot::kFull) {
179 result ^= AllocateUninitialized(cls_, instance_size); 242 result ^= AllocateUninitialized(cls_, instance_size);
180 } else { 243 } else {
181 result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew); 244 result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew);
182 } 245 }
183 return result.raw(); 246 return result.raw();
184 } else {
185 ASSERT((class_header & kSmiTagMask) != 0);
186 cls_ = LookupInternalClass(class_header);
187 ASSERT(!cls_.IsNull());
188 } 247 }
248 ASSERT((class_header & kSmiTagMask) != 0);
249 cls_ = LookupInternalClass(class_header);
250 ASSERT(!cls_.IsNull());
189 251
190 // Similarly Array and ImmutableArray objects are also similarly only 252 // Similarly Array and ImmutableArray objects are also similarly only
191 // allocated here, the individual array elements are read later. 253 // allocated here, the individual array elements are read later.
192 ObjectKind obj_kind = cls_.instance_kind(); 254 intptr_t class_id = cls_.id();
193 if (obj_kind == Array::kInstanceKind) { 255 if (class_id == kArrayCid) {
194 // Read the length and allocate an object based on the len. 256 // Read the length and allocate an object based on the len.
195 intptr_t len = ReadSmiValue(); 257 intptr_t len = ReadSmiValue();
196 Array& array = Array::ZoneHandle( 258 Array& array = Array::ZoneHandle(
197 isolate(), 259 isolate(),
198 (kind_ == Snapshot::kFull) ? NewArray(len) : Array::New(len)); 260 (kind_ == Snapshot::kFull) ? NewArray(len) : Array::New(len));
199 AddBackRef(object_id, &array, kIsNotDeserialized); 261 AddBackRef(object_id, &array, kIsNotDeserialized);
200 262
201 return array.raw(); 263 return array.raw();
202 } 264 }
203 if (obj_kind == ImmutableArray::kInstanceKind) { 265 if (class_id == kImmutableArrayCid) {
204 // Read the length and allocate an object based on the len. 266 // Read the length and allocate an object based on the len.
205 intptr_t len = ReadSmiValue(); 267 intptr_t len = ReadSmiValue();
206 ImmutableArray& array = ImmutableArray::ZoneHandle( 268 ImmutableArray& array = ImmutableArray::ZoneHandle(
207 isolate(), 269 isolate(),
208 (kind_ == Snapshot::kFull) ? 270 (kind_ == Snapshot::kFull) ?
209 NewImmutableArray(len) : ImmutableArray::New(len)); 271 NewImmutableArray(len) : ImmutableArray::New(len));
210 AddBackRef(object_id, &array, kIsNotDeserialized); 272 AddBackRef(object_id, &array, kIsNotDeserialized);
211 273
212 return array.raw(); 274 return array.raw();
213 } 275 }
214 276
215 // For all other internal VM classes we read the object inline. 277 // For all other internal VM classes we read the object inline.
216 intptr_t tags = ReadIntptrValue(); 278 intptr_t tags = ReadIntptrValue();
217 switch (obj_kind) { 279 switch (class_id) {
218 #define SNAPSHOT_READ(clazz) \ 280 #define SNAPSHOT_READ(clazz) \
219 case clazz::kInstanceKind: { \ 281 case clazz::kClassId: { \
220 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ 282 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \
221 break; \ 283 break; \
222 } 284 }
223 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) 285 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
224 #undef SNAPSHOT_READ 286 #undef SNAPSHOT_READ
225 default: UNREACHABLE(); break; 287 default: UNREACHABLE(); break;
226 } 288 }
227 if (kind_ == Snapshot::kFull) { 289 if (kind_ == Snapshot::kFull) {
228 obj_.SetCreatedFromSnapshot(); 290 obj_.SetCreatedFromSnapshot();
229 } 291 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 ASSERT(kind_ == Snapshot::kFull); 403 ASSERT(kind_ == Snapshot::kFull);
342 ASSERT(isolate()->no_gc_scope_depth() != 0); 404 ASSERT(isolate()->no_gc_scope_depth() != 0);
343 cls_ = Object::context_class(); 405 cls_ = Object::context_class();
344 RawContext* obj = reinterpret_cast<RawContext*>( 406 RawContext* obj = reinterpret_cast<RawContext*>(
345 AllocateUninitialized(cls_, Context::InstanceSize(num_variables))); 407 AllocateUninitialized(cls_, Context::InstanceSize(num_variables)));
346 obj->ptr()->num_variables_ = num_variables; 408 obj->ptr()->num_variables_ = num_variables;
347 return obj; 409 return obj;
348 } 410 }
349 411
350 412
351 RawClass* SnapshotReader::NewClass(int value) { 413 RawClass* SnapshotReader::NewClass(intptr_t class_id, bool is_signature_class) {
352 ASSERT(kind_ == Snapshot::kFull); 414 ASSERT(kind_ == Snapshot::kFull);
353 ASSERT(isolate()->no_gc_scope_depth() != 0); 415 ASSERT(isolate()->no_gc_scope_depth() != 0);
354 ObjectKind object_kind = static_cast<ObjectKind>(value); 416 if (class_id < kNumPredefinedCids) {
355 if ((object_kind == kInstance || object_kind == kClosure)) { 417 return Class::GetClass(class_id, is_signature_class);
356 cls_ = Object::class_class();
357 RawClass* obj = reinterpret_cast<RawClass*>(
358 AllocateUninitialized(cls_, Class::InstanceSize()));
359 if (object_kind == kInstance) {
360 Instance fake;
361 obj->ptr()->handle_vtable_ = fake.vtable();
362 } else {
363 Closure fake;
364 obj->ptr()->handle_vtable_ = fake.vtable();
365 }
366 cls_ = obj;
367 cls_.set_instance_kind(object_kind);
368 cls_.set_id(kIllegalObjectKind);
369 isolate()->class_table()->Register(cls_);
370 return cls_.raw();
371 } 418 }
372 return Class::GetClass(object_kind); 419 cls_ = Object::class_class();
420 RawClass* obj = reinterpret_cast<RawClass*>(
421 AllocateUninitialized(cls_, Class::InstanceSize()));
422 if (is_signature_class) {
423 Closure fake;
424 obj->ptr()->handle_vtable_ = fake.vtable();
425 } else {
426 Instance fake;
427 obj->ptr()->handle_vtable_ = fake.vtable();
428 }
429 cls_ = obj;
430 cls_.set_id(kIllegalCid);
431 isolate()->class_table()->Register(cls_);
432 return cls_.raw();
373 } 433 }
374 434
375 435
376 RawMint* SnapshotReader::NewMint(int64_t value) { 436 RawMint* SnapshotReader::NewMint(int64_t value) {
377 ASSERT(kind_ == Snapshot::kFull); 437 ASSERT(kind_ == Snapshot::kFull);
378 ASSERT(isolate()->no_gc_scope_depth() != 0); 438 ASSERT(isolate()->no_gc_scope_depth() != 0);
379 cls_ = object_store()->mint_class(); 439 cls_ = object_store()->mint_class();
380 RawMint* obj = reinterpret_cast<RawMint*>( 440 RawMint* obj = reinterpret_cast<RawMint*>(
381 AllocateUninitialized(cls_, Mint::InstanceSize())); 441 AllocateUninitialized(cls_, Mint::InstanceSize()));
382 obj->ptr()->value_ = value; 442 obj->ptr()->value_ = value;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 object_store()->growable_object_array_class()); 527 object_store()->growable_object_array_class());
468 } 528 }
469 529
470 530
471 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { 531 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) {
472 // If the header is an object Id, lookup singleton VM classes or classes 532 // If the header is an object Id, lookup singleton VM classes or classes
473 // stored in the object store. 533 // stored in the object store.
474 if (IsVMIsolateObject(class_header)) { 534 if (IsVMIsolateObject(class_header)) {
475 intptr_t class_id = GetVMIsolateObjectId(class_header); 535 intptr_t class_id = GetVMIsolateObjectId(class_header);
476 if (IsSingletonClassId(class_id)) { 536 if (IsSingletonClassId(class_id)) {
477 return Object::GetSingletonClass(class_id); // return singleton. 537 return isolate()->class_table()->At(class_id); // get singleton class.
478 } 538 }
479 } else if (SerializedHeaderTag::decode(class_header) == kObjectId) { 539 } else if (SerializedHeaderTag::decode(class_header) == kObjectId) {
480 intptr_t header_value = SerializedHeaderData::decode(class_header); 540 intptr_t class_id = SerializedHeaderData::decode(class_header);
481 if (IsObjectStoreClassId(header_value)) { 541 if (IsObjectStoreClassId(class_id)) {
482 return object_store()->GetClass(header_value); 542 return isolate()->class_table()->At(class_id); // get singleton class.
483 } 543 }
484 } 544 }
485 return Class::null(); 545 return Class::null();
486 } 546 }
487 547
488 548
489 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, 549 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls,
490 intptr_t size) { 550 intptr_t size) {
491 ASSERT(isolate()->no_gc_scope_depth() != 0); 551 ASSERT(isolate()->no_gc_scope_depth() != 0);
492 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 552 ASSERT(Utils::IsAligned(size, kObjectAlignment));
493 Heap* heap = isolate()->heap(); 553 Heap* heap = isolate()->heap();
494 554
495 uword address = heap->TryAllocate(size, Heap::kOld); 555 uword address = heap->TryAllocate(size, Heap::kOld);
496 if (address == 0) { 556 if (address == 0) {
497 // Use the preallocated out of memory exception to avoid calling 557 // Use the preallocated out of memory exception to avoid calling
498 // into dart code or allocating any code. 558 // into dart code or allocating any code.
499 const Instance& exception = 559 const Instance& exception =
500 Instance::Handle(object_store()->out_of_memory()); 560 Instance::Handle(object_store()->out_of_memory());
501 Exceptions::Throw(exception); 561 Exceptions::Throw(exception);
502 UNREACHABLE(); 562 UNREACHABLE();
503 } 563 }
504 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); 564 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
505 uword tags = 0; 565 uword tags = 0;
506 intptr_t index = cls.id(); 566 intptr_t index = cls.id();
507 ASSERT(index != kIllegalObjectKind); 567 ASSERT(index != kIllegalCid);
508 tags = RawObject::ClassIdTag::update(index, tags); 568 tags = RawObject::ClassIdTag::update(index, tags);
509 tags = RawObject::SizeTag::update(size, tags); 569 tags = RawObject::SizeTag::update(size, tags);
510 raw_obj->ptr()->tags_ = tags; 570 raw_obj->ptr()->tags_ = tags;
511 return raw_obj; 571 return raw_obj;
512 } 572 }
513 573
514 574
515 RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) { 575 RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
516 intptr_t object_id = GetVMIsolateObjectId(header_value); 576 intptr_t object_id = GetVMIsolateObjectId(header_value);
517 if (object_id == Object::kNullObject) { 577 if (object_id == kNullObject) {
518 // This is a singleton null object, return it. 578 // This is a singleton null object, return it.
519 return Object::null(); 579 return Object::null();
520 } 580 }
521 if (object_id == Object::kSentinelObject) { 581 if (object_id == kSentinelObject) {
522 return Object::sentinel(); 582 return Object::sentinel();
523 } 583 }
524 if (IsSingletonClassId(object_id)) { 584 intptr_t class_id = ClassIdFromObjectId(object_id);
525 return Object::GetSingletonClass(object_id); // return singleton object. 585 if (IsSingletonClassId(class_id)) {
586 return isolate()->class_table()->At(class_id); // get singleton class.
526 } else { 587 } else {
527 ASSERT(Symbols::IsVMSymbolId(object_id)); 588 ASSERT(Symbols::IsVMSymbolId(object_id));
528 return Symbols::GetVMSymbol(object_id); // return VM symbol. 589 return Symbols::GetVMSymbol(object_id); // return VM symbol.
529 } 590 }
530 UNREACHABLE(); 591 UNREACHABLE();
592 return Object::null();
531 } 593 }
532 594
533 595
534 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { 596 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) {
535 if (IsObjectStoreClassId(object_id)) { 597 if (object_id == kTrueValue) {
536 return object_store()->GetClass(object_id);
537 } else if (object_id == ObjectStore::kTrueValue) {
538 return object_store()->true_value(); 598 return object_store()->true_value();
539 } else if (object_id == ObjectStore::kFalseValue) { 599 }
600 if (object_id == kFalseValue) {
540 return object_store()->false_value(); 601 return object_store()->false_value();
541 } else if (kind_ != Snapshot::kFull) { 602 }
603 intptr_t class_id = ClassIdFromObjectId(object_id);
604 if (IsObjectStoreClassId(class_id)) {
605 return isolate()->class_table()->At(class_id); // get singleton class.
606 }
607 if (kind_ != Snapshot::kFull) {
542 if (IsObjectStoreTypeId(object_id)) { 608 if (IsObjectStoreTypeId(object_id)) {
543 return object_store()->GetType(object_id); // return type object. 609 return GetType(object_store(), object_id); // return type obj.
544 } 610 }
545 } 611 }
546
547 Object* object = GetBackRef(object_id); 612 Object* object = GetBackRef(object_id);
548 return object->raw(); 613 return object->raw();
549 } 614 }
550 615
551 616
552 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { 617 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) {
553 // Read the class header information and lookup the class. 618 // Read the class header information and lookup the class.
554 intptr_t class_header = ReadIntptrValue(); 619 intptr_t class_header = ReadIntptrValue();
555 intptr_t tags = ReadIntptrValue(); 620 intptr_t tags = ReadIntptrValue();
556 if (SerializedHeaderData::decode(class_header) == kInstanceId) { 621 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
557 // Object is regular dart instance. 622 // Object is regular dart instance.
558 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); 623 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
559 intptr_t instance_size = 0; 624 intptr_t instance_size = 0;
560 if (result == NULL) { 625 if (result == NULL) {
561 result = &(Instance::ZoneHandle(isolate(), Instance::null())); 626 result = &(Instance::ZoneHandle(isolate(), Instance::null()));
562 AddBackRef(object_id, result, kIsDeserialized); 627 AddBackRef(object_id, result, kIsDeserialized);
563 cls_ ^= ReadObjectImpl(); 628 cls_ ^= ReadObjectImpl();
564 ASSERT(!cls_.IsNull()); 629 ASSERT(!cls_.IsNull());
565 instance_size = cls_.instance_size(); 630 instance_size = cls_.instance_size();
566 ASSERT(instance_size > 0); 631 ASSERT(instance_size > 0);
(...skipping 13 matching lines...) Expand all
580 obj_ = ReadObjectRef(); 645 obj_ = ReadObjectRef();
581 result->SetFieldAtOffset(offset, obj_); 646 result->SetFieldAtOffset(offset, obj_);
582 offset += kWordSize; 647 offset += kWordSize;
583 } 648 }
584 if (kind_ == Snapshot::kFull) { 649 if (kind_ == Snapshot::kFull) {
585 result->SetCreatedFromSnapshot(); 650 result->SetCreatedFromSnapshot();
586 } else if (result->IsCanonical()) { 651 } else if (result->IsCanonical()) {
587 *result = result->Canonicalize(); 652 *result = result->Canonicalize();
588 } 653 }
589 return result->raw(); 654 return result->raw();
590 } else {
591 ASSERT((class_header & kSmiTagMask) != 0);
592 cls_ = LookupInternalClass(class_header);
593 ASSERT(!cls_.IsNull());
594 } 655 }
595 switch (cls_.instance_kind()) { 656 ASSERT((class_header & kSmiTagMask) != 0);
657 cls_ = LookupInternalClass(class_header);
658 ASSERT(!cls_.IsNull());
659 switch (cls_.id()) {
596 #define SNAPSHOT_READ(clazz) \ 660 #define SNAPSHOT_READ(clazz) \
597 case clazz::kInstanceKind: { \ 661 case clazz::kClassId: { \
598 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ 662 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \
599 break; \ 663 break; \
600 } 664 }
601 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) 665 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
602 #undef SNAPSHOT_READ 666 #undef SNAPSHOT_READ
603 default: UNREACHABLE(); break; 667 default: UNREACHABLE(); break;
604 } 668 }
605 if (kind_ == Snapshot::kFull) { 669 if (kind_ == Snapshot::kFull) {
606 obj_.SetCreatedFromSnapshot(); 670 obj_.SetCreatedFromSnapshot();
607 } 671 }
(...skipping 20 matching lines...) Expand all
628 692
629 void SnapshotWriter::WriteObject(RawObject* rawobj) { 693 void SnapshotWriter::WriteObject(RawObject* rawobj) {
630 WriteObjectImpl(rawobj); 694 WriteObjectImpl(rawobj);
631 WriteForwardedObjects(); 695 WriteForwardedObjects();
632 } 696 }
633 697
634 698
635 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { 699 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
636 // Check if it is a singleton null object. 700 // Check if it is a singleton null object.
637 if (rawobj == Object::null()) { 701 if (rawobj == Object::null()) {
638 WriteVMIsolateObject(Object::kNullObject); 702 WriteVMIsolateObject(kNullObject);
639 return; 703 return;
640 } 704 }
641 705
642 // Check if it is a singleton sentinel object. 706 // Check if it is a singleton sentinel object.
643 if (rawobj == Object::sentinel()) { 707 if (rawobj == Object::sentinel()) {
644 WriteVMIsolateObject(Object::kSentinelObject); 708 WriteVMIsolateObject(kSentinelObject);
645 return; 709 return;
646 } 710 }
647 711
648 // Check if it is a singleton class object. 712 // Check if it is a singleton class object which is shared by
649 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); 713 // all isolates.
650 intptr_t index = Object::GetSingletonClassIndex(raw_class); 714 intptr_t id = rawobj->GetClassId();
651 if (index != Object::kInvalidIndex) { 715 if (id == kClassCid) {
652 WriteVMIsolateObject(index); 716 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
717 intptr_t class_id = raw_class->ptr()->id_;
718 if (IsSingletonClassId(class_id)) {
719 intptr_t object_id = ObjectIdFromClassId(class_id);
720 WriteVMIsolateObject(object_id);
721 return;
722 }
723 }
724
725 // Check it is a predefined symbol in the VM isolate.
726 id = Symbols::LookupVMSymbol(rawobj);
727 if (id != kInvalidIndex) {
728 WriteVMIsolateObject(id);
653 return; 729 return;
654 } 730 }
655 731
656 // Check it is a predefined symbol.
657 index = Symbols::LookupVMSymbol(rawobj);
658 if (index != Object::kInvalidIndex) {
659 WriteVMIsolateObject(index);
660 return;
661 }
662
663 UNREACHABLE(); 732 UNREACHABLE();
664 } 733 }
665 734
666 735
667 void SnapshotWriter::WriteObjectRef(RawObject* raw) { 736 void SnapshotWriter::WriteObjectRef(RawObject* raw) {
668 // First check if object can be written as a simple predefined type. 737 // First check if object can be written as a simple predefined type.
669 if (CheckAndWritePredefinedObject(raw)) { 738 if (CheckAndWritePredefinedObject(raw)) {
670 return; 739 return;
671 } 740 }
672 // Check if object has already been serialized, in that
673 // case just write the object id out.
674 uword tags = raw->ptr()->tags_;
675 if (SerializedHeaderTag::decode(tags) == kObjectId) {
676 intptr_t id = SerializedHeaderData::decode(tags);
677 WriteIndexedObject(id);
678 return;
679 }
680 741
681 NoGCScope no_gc; 742 NoGCScope no_gc;
682 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); 743 RawClass* cls = class_table_->At(raw->GetClassId());
683 744 intptr_t class_id = cls->ptr()->id_;
684 ObjectKind obj_kind = cls->ptr()->instance_kind_; 745 ASSERT(class_id == raw->GetClassId());
685 if (obj_kind == Instance::kInstanceKind) { 746 if (class_id >= kNumPredefinedCids) {
747 ASSERT(!Class::IsSignatureClass(cls));
686 // Object is being referenced, add it to the forward ref list and mark 748 // Object is being referenced, add it to the forward ref list and mark
687 // it so that future references to this object in the snapshot will use 749 // it so that future references to this object in the snapshot will use
688 // this object id. Mark it as not having been serialized yet so that we 750 // this object id. Mark it as not having been serialized yet so that we
689 // will serialize the object when we go through the forward list. 751 // will serialize the object when we go through the forward list.
690 intptr_t object_id = MarkObject(raw, kIsNotSerialized); 752 intptr_t object_id = MarkObject(raw, kIsNotSerialized);
691 753
692 // Write out the serialization header value for this object. 754 // Write out the serialization header value for this object.
693 WriteInlinedObjectHeader(object_id); 755 WriteInlinedObjectHeader(object_id);
694 756
695 // Indicate this is an instance object. 757 // Indicate this is an instance object.
696 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); 758 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId));
697 759
698 // Write out the class information for this object. 760 // Write out the class information for this object.
699 WriteObjectImpl(cls); 761 WriteObjectImpl(cls);
700 762
701 return; 763 return;
702 } 764 }
703 if (obj_kind == Array::kInstanceKind) { 765 if (class_id == kArrayCid) {
704 // Object is being referenced, add it to the forward ref list and mark 766 // Object is being referenced, add it to the forward ref list and mark
705 // it so that future references to this object in the snapshot will use 767 // it so that future references to this object in the snapshot will use
706 // this object id. Mark it as not having been serialized yet so that we 768 // this object id. Mark it as not having been serialized yet so that we
707 // will serialize the object when we go through the forward list. 769 // will serialize the object when we go through the forward list.
708 intptr_t object_id = MarkObject(raw, kIsNotSerialized); 770 intptr_t object_id = MarkObject(raw, kIsNotSerialized);
709 771
710 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); 772 RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
711 773
712 // Write out the serialization header value for this object. 774 // Write out the serialization header value for this object.
713 WriteInlinedObjectHeader(object_id); 775 WriteInlinedObjectHeader(object_id);
714 776
715 // Write out the class information. 777 // Write out the class information.
716 WriteIndexedObject(ObjectStore::kArrayClass); 778 WriteIndexedObject(kArrayCid);
717 779
718 // Write out the length field. 780 // Write out the length field.
719 Write<RawObject*>(rawarray->ptr()->length_); 781 Write<RawObject*>(rawarray->ptr()->length_);
720 782
721 return; 783 return;
722 } 784 }
723 if (obj_kind == ImmutableArray::kInstanceKind) { 785 if (class_id == kImmutableArrayCid) {
724 // Object is being referenced, add it to the forward ref list and mark 786 // Object is being referenced, add it to the forward ref list and mark
725 // it so that future references to this object in the snapshot will use 787 // it so that future references to this object in the snapshot will use
726 // this object id. Mark it as not having been serialized yet so that we 788 // this object id. Mark it as not having been serialized yet so that we
727 // will serialize the object when we go through the forward list. 789 // will serialize the object when we go through the forward list.
728 intptr_t object_id = MarkObject(raw, kIsNotSerialized); 790 intptr_t object_id = MarkObject(raw, kIsNotSerialized);
729 791
730 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); 792 RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
731 793
732 // Write out the serialization header value for this object. 794 // Write out the serialization header value for this object.
733 WriteInlinedObjectHeader(object_id); 795 WriteInlinedObjectHeader(object_id);
734 796
735 // Write out the class information. 797 // Write out the class information.
736 WriteIndexedObject(ObjectStore::kImmutableArrayClass); 798 WriteIndexedObject(kImmutableArrayCid);
737 799
738 // Write out the length field. 800 // Write out the length field.
739 Write<RawObject*>(rawarray->ptr()->length_); 801 Write<RawObject*>(rawarray->ptr()->length_);
740 802
741 return; 803 return;
742 } 804 }
743 // Object is being referenced, add it to the forward ref list and mark 805 // Object is being referenced, add it to the forward ref list and mark
744 // it so that future references to this object in the snapshot will use 806 // it so that future references to this object in the snapshot will use
745 // this object id. Mark it as not having been serialized yet so that we 807 // this object id. Mark it as not having been serialized yet so that we
746 // will serialize the object when we go through the forward list. 808 // will serialize the object when we go through the forward list.
747 intptr_t object_id = MarkObject(raw, kIsSerialized); 809 intptr_t object_id = MarkObject(raw, kIsSerialized);
748 switch (obj_kind) { 810 switch (class_id) {
749 #define SNAPSHOT_WRITE(clazz) \ 811 #define SNAPSHOT_WRITE(clazz) \
750 case clazz::kInstanceKind: { \ 812 case clazz::kClassId: { \
751 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ 813 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
752 raw_obj->WriteTo(this, object_id, kind_); \ 814 raw_obj->WriteTo(this, object_id, kind_); \
753 return; \ 815 return; \
754 } \ 816 } \
755 817
756 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) 818 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
757 #undef SNAPSHOT_WRITE 819 #undef SNAPSHOT_WRITE
758 default: break; 820 default: break;
759 } 821 }
760 UNREACHABLE(); 822 UNREACHABLE();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 // Now check if it is an object from the VM isolate (NOTE: premarked objects 905 // Now check if it is an object from the VM isolate (NOTE: premarked objects
844 // are considered to be objects in the VM isolate). These objects are shared 906 // are considered to be objects in the VM isolate). These objects are shared
845 // by all isolates. 907 // by all isolates.
846 if (rawobj->IsMarked()) { 908 if (rawobj->IsMarked()) {
847 HandleVMIsolateObject(rawobj); 909 HandleVMIsolateObject(rawobj);
848 return true; 910 return true;
849 } 911 }
850 912
851 // Check if it is a singleton boolean true value. 913 // Check if it is a singleton boolean true value.
852 if (rawobj == object_store()->true_value()) { 914 if (rawobj == object_store()->true_value()) {
853 WriteIndexedObject(ObjectStore::kTrueValue); 915 WriteIndexedObject(kTrueValue);
854 return true; 916 return true;
855 } 917 }
856 918
857 // Check if it is a singleton boolean false value. 919 // Check if it is a singleton boolean false value.
858 if (rawobj == object_store()->false_value()) { 920 if (rawobj == object_store()->false_value()) {
859 WriteIndexedObject(ObjectStore::kFalseValue); 921 WriteIndexedObject(kFalseValue);
860 return true; 922 return true;
861 } 923 }
862 924
863 // Check if it is a code object in that case just write a Null object 925 // Check if it is a code object in that case just write a Null object
864 // as we do not want code objects in the snapshot. 926 // as we do not want code objects in the snapshot.
865 if (rawobj->GetClassId() == kCode) { 927 if (rawobj->GetClassId() == kCodeCid) {
866 WriteVMIsolateObject(Object::kNullObject); 928 WriteVMIsolateObject(kNullObject);
867 return true; 929 return true;
868 } 930 }
869 931
870 // Check if classes are not being serialized and it is preinitialized type. 932 // Check if classes are not being serialized and it is preinitialized type.
871 if (kind_ != Snapshot::kFull) { 933 if (kind_ != Snapshot::kFull) {
872 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); 934 RawType* raw_type = reinterpret_cast<RawType*>(rawobj);
873 intptr_t index = object_store()->GetTypeIndex(raw_type); 935 intptr_t index = GetTypeIndex(object_store(), raw_type);
874 if (index != ObjectStore::kInvalidIndex) { 936 if (index != kInvalidIndex) {
875 WriteIndexedObject(index); 937 WriteIndexedObject(index);
876 return true; 938 return true;
877 } 939 }
878 } 940 }
879 941
880 return false; 942 return false;
881 } 943 }
882 944
883 945
884 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { 946 void SnapshotWriter::WriteObjectImpl(RawObject* raw) {
(...skipping 16 matching lines...) Expand all
901 // - Object is seen for the first time (inlined as follows): 963 // - Object is seen for the first time (inlined as follows):
902 // (object size in multiples of kObjectAlignment | 0x1) 964 // (object size in multiples of kObjectAlignment | 0x1)
903 // serialized fields of the object 965 // serialized fields of the object
904 // ...... 966 // ......
905 NoGCScope no_gc; 967 NoGCScope no_gc;
906 uword tags = raw->ptr()->tags_; 968 uword tags = raw->ptr()->tags_;
907 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); 969 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
908 intptr_t object_id = SerializedHeaderData::decode(tags); 970 intptr_t object_id = SerializedHeaderData::decode(tags);
909 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); 971 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags();
910 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); 972 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
911 ObjectKind kind = cls->ptr()->instance_kind_; 973 intptr_t class_id = cls->ptr()->id_;
912 974
913 if (kind == Instance::kInstanceKind) { 975 if (class_id >= kNumPredefinedCids) {
976 ASSERT(!Class::IsSignatureClass(cls));
914 // Object is regular dart instance. 977 // Object is regular dart instance.
915 // TODO(5411462): figure out what we need to do if an object with native 978 // TODO(5411462): figure out what we need to do if an object with native
916 // fields is serialized (throw exception or serialize a null object). 979 // fields is serialized (throw exception or serialize a null object).
917 ASSERT(cls->ptr()->num_native_fields_ == 0); 980 ASSERT(cls->ptr()->num_native_fields_ == 0);
918 intptr_t instance_size = cls->ptr()->instance_size_; 981 intptr_t instance_size = cls->ptr()->instance_size_;
919 ASSERT(instance_size != 0); 982 ASSERT(instance_size != 0);
920 983
921 // Write out the serialization header value for this object. 984 // Write out the serialization header value for this object.
922 WriteInlinedObjectHeader(object_id); 985 WriteInlinedObjectHeader(object_id);
923 986
924 // Indicate this is an instance object. 987 // Indicate this is an instance object.
925 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); 988 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId));
926 989
927 // Write out the tags. 990 // Write out the tags.
928 WriteIntptrValue(tags); 991 WriteIntptrValue(tags);
929 992
930 // Write out the class information for this object. 993 // Write out the class information for this object.
931 WriteObjectImpl(cls); 994 WriteObjectImpl(cls);
932 995
933 // Write out all the fields for the object. 996 // Write out all the fields for the object.
934 intptr_t offset = Object::InstanceSize(); 997 intptr_t offset = Object::InstanceSize();
935 while (offset < instance_size) { 998 while (offset < instance_size) {
936 WriteObjectRef(*reinterpret_cast<RawObject**>( 999 WriteObjectRef(*reinterpret_cast<RawObject**>(
937 reinterpret_cast<uword>(raw->ptr()) + offset)); 1000 reinterpret_cast<uword>(raw->ptr()) + offset));
938 offset += kWordSize; 1001 offset += kWordSize;
939 } 1002 }
940 return; 1003 return;
941 } 1004 }
942 switch (kind) { 1005 switch (class_id) {
943 #define SNAPSHOT_WRITE(clazz) \ 1006 #define SNAPSHOT_WRITE(clazz) \
944 case clazz::kInstanceKind: { \ 1007 case clazz::kClassId: { \
945 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ 1008 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
946 raw_obj->WriteTo(this, object_id, kind_); \ 1009 raw_obj->WriteTo(this, object_id, kind_); \
947 return; \ 1010 return; \
948 } \ 1011 } \
949 1012
950 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) 1013 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
951 #undef SNAPSHOT_WRITE 1014 #undef SNAPSHOT_WRITE
952 default: break; 1015 default: break;
953 } 1016 }
954 UNREACHABLE(); 1017 UNREACHABLE();
(...skipping 14 matching lines...) Expand all
969 1032
970 // Mark object as serialized. 1033 // Mark object as serialized.
971 forward_list_[i]->set_state(kIsSerialized); 1034 forward_list_[i]->set_state(kIsSerialized);
972 } 1035 }
973 } 1036 }
974 } 1037 }
975 1038
976 1039
977 void SnapshotWriter::WriteClassId(RawClass* cls) { 1040 void SnapshotWriter::WriteClassId(RawClass* cls) {
978 ASSERT(kind_ != Snapshot::kFull); 1041 ASSERT(kind_ != Snapshot::kFull);
979 int id = object_store()->GetClassIndex(cls); 1042 int class_id = cls->ptr()->id_;
980 if (IsSingletonClassId(id)) { 1043 if (IsSingletonClassId(class_id)) {
981 WriteVMIsolateObject(id); 1044 intptr_t object_id = ObjectIdFromClassId(class_id);
982 } else if (IsObjectStoreClassId(id)) { 1045 WriteVMIsolateObject(object_id);
983 WriteIndexedObject(id); 1046 } else if (IsObjectStoreClassId(class_id)) {
1047 intptr_t object_id = ObjectIdFromClassId(class_id);
1048 WriteIndexedObject(object_id);
984 } else { 1049 } else {
985 // TODO(5411462): Should restrict this to only core-lib classes in this 1050 // TODO(5411462): Should restrict this to only core-lib classes in this
986 // case. 1051 // case.
987 // Write out the class and tags information. 1052 // Write out the class and tags information.
988 WriteVMIsolateObject(Object::kClassClass); 1053 WriteVMIsolateObject(kClassCid);
989 WriteIntptrValue(GetObjectTags(cls)); 1054 WriteIntptrValue(GetObjectTags(cls));
990 1055
991 // Write out the library url and class name. 1056 // Write out the library url and class name.
992 RawLibrary* library = cls->ptr()->library_; 1057 RawLibrary* library = cls->ptr()->library_;
993 ASSERT(library != Library::null()); 1058 ASSERT(library != Library::null());
994 WriteObjectImpl(library->ptr()->url_); 1059 WriteObjectImpl(library->ptr()->url_);
995 WriteObjectImpl(cls->ptr()->name_); 1060 WriteObjectImpl(cls->ptr()->name_);
996 } 1061 }
997 } 1062 }
998 1063
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 RawObject* raw_obj = *current; 1106 RawObject* raw_obj = *current;
1042 if (as_references_) { 1107 if (as_references_) {
1043 writer_->WriteObjectRef(raw_obj); 1108 writer_->WriteObjectRef(raw_obj);
1044 } else { 1109 } else {
1045 writer_->WriteObjectImpl(raw_obj); 1110 writer_->WriteObjectImpl(raw_obj);
1046 } 1111 }
1047 } 1112 }
1048 } 1113 }
1049 1114
1050 } // namespace dart 1115 } // namespace dart
OLDNEW
« no previous file with comments | « vm/snapshot.h ('k') | vm/snapshot_ids.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698