Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, 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 "vm/assert.h" | 7 #include "vm/assert.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/exceptions.h" | |
| 9 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| 10 #include "vm/object.h" | 11 #include "vm/object.h" |
| 11 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 12 | 13 |
| 13 namespace dart { | 14 namespace dart { |
| 14 | 15 |
| 15 enum { | 16 enum { |
| 16 kInstanceId = ObjectStore::kMaxId, | 17 kInstanceId = ObjectStore::kMaxId, |
| 17 kMaxPredefinedObjectIds, | 18 kMaxPredefinedObjectIds, |
| 18 }; | 19 }; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate) | 56 SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate) |
| 56 : stream_(snapshot->content(), snapshot->length()), | 57 : stream_(snapshot->content(), snapshot->length()), |
| 57 kind_(snapshot->kind()), | 58 kind_(snapshot->kind()), |
| 58 isolate_(isolate), | 59 isolate_(isolate), |
| 59 cls_(Class::Handle()), | 60 cls_(Class::Handle()), |
| 60 obj_(Object::Handle()), | 61 obj_(Object::Handle()), |
| 61 str_(String::Handle()), | 62 str_(String::Handle()), |
| 62 library_(Library::Handle()), | 63 library_(Library::Handle()), |
| 63 type_(AbstractType::Handle()), | 64 type_(AbstractType::Handle()), |
| 64 type_arguments_(AbstractTypeArguments::Handle()), | 65 type_arguments_(AbstractTypeArguments::Handle()), |
| 65 backward_references_() { | 66 backward_references_((snapshot->kind() == Snapshot::kFull) ? 1024 : 4) { |
|
Ivan Posva
2012/01/16 19:30:33
1024 and 4 seem like magic numbers. What do we nee
siva
2012/01/18 00:00:24
Added two constants one for the full snapshot case
| |
| 66 } | 67 } |
| 67 | 68 |
| 68 | 69 |
| 69 RawObject* SnapshotReader::ReadObject() { | 70 RawObject* SnapshotReader::ReadObject() { |
| 70 int64_t value = Read<int64_t>(); | 71 int64_t value = Read<int64_t>(); |
| 71 if ((value & kSmiTagMask) == 0) { | 72 if ((value & kSmiTagMask) == 0) { |
| 72 return Integer::New((value >> kSmiTagShift)); | 73 return Integer::New((value >> kSmiTagShift)); |
| 73 } | 74 } |
| 74 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 75 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
| 75 return ReadObjectImpl(value); | 76 return ReadObjectImpl(value); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 102 backward_references_.Add(obj); | 103 backward_references_.Add(obj); |
| 103 } | 104 } |
| 104 | 105 |
| 105 | 106 |
| 106 void SnapshotReader::ReadFullSnapshot() { | 107 void SnapshotReader::ReadFullSnapshot() { |
| 107 ASSERT(kind_ == Snapshot::kFull); | 108 ASSERT(kind_ == Snapshot::kFull); |
| 108 Isolate* isolate = Isolate::Current(); | 109 Isolate* isolate = Isolate::Current(); |
| 109 ASSERT(isolate != NULL); | 110 ASSERT(isolate != NULL); |
| 110 ObjectStore* object_store = isolate->object_store(); | 111 ObjectStore* object_store = isolate->object_store(); |
| 111 ASSERT(object_store != NULL); | 112 ASSERT(object_store != NULL); |
| 113 NoGCScope no_gc; | |
| 114 | |
| 115 // TODO(asiva): Add a check here to ensure we have the right heap | |
| 116 // size for the full snapshot being read. | |
| 112 | 117 |
| 113 // Read in all the objects stored in the object store. | 118 // Read in all the objects stored in the object store. |
| 114 intptr_t num_flds = (object_store->to() - object_store->from()); | 119 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 115 for (intptr_t i = 0; i <= num_flds; i++) { | 120 for (intptr_t i = 0; i <= num_flds; i++) { |
| 116 *(object_store->from() + i) = ReadObject(); | 121 *(object_store->from() + i) = ReadObject(); |
| 117 } | 122 } |
| 118 | 123 |
| 119 // Setup native resolver for bootstrap impl. | 124 // Setup native resolver for bootstrap impl. |
| 120 Bootstrap::SetupNativeResolver(); | 125 Bootstrap::SetupNativeResolver(); |
| 121 } | 126 } |
| 122 | 127 |
| 123 | 128 |
| 129 #define ALLOC_NEW_OBJECT_WITH_LEN(type, obj, class_obj, length) \ | |
| 130 ASSERT(kind_ == Snapshot::kFull); \ | |
| 131 ASSERT(isolate()->no_gc_scope_depth() != 0); \ | |
| 132 cls_ = class_obj; \ | |
| 133 *obj = reinterpret_cast<Raw##type*>( \ | |
| 134 AllocateUninitialized(cls_, type::InstanceSize(length))); \ | |
| 135 obj->SetLength(length); \ | |
| 136 | |
| 137 | |
| 138 void SnapshotReader::NewArray(Array* array, intptr_t len) { | |
| 139 ALLOC_NEW_OBJECT_WITH_LEN(Array, array, object_store()->array_class(), len); | |
| 140 } | |
| 141 | |
| 142 | |
| 143 void SnapshotReader::NewImmutableArray(ImmutableArray* array, intptr_t len) { | |
| 144 ALLOC_NEW_OBJECT_WITH_LEN(ImmutableArray, | |
| 145 array, | |
| 146 object_store()->immutable_array_class(), | |
| 147 len); | |
| 148 } | |
| 149 | |
| 150 | |
| 151 void SnapshotReader::NewOneByteString(OneByteString* str_obj, intptr_t len) { | |
| 152 ALLOC_NEW_OBJECT_WITH_LEN(OneByteString, | |
| 153 str_obj, | |
| 154 object_store()->one_byte_string_class(), | |
| 155 len); | |
| 156 } | |
| 157 | |
| 158 | |
| 159 void SnapshotReader::NewTwoByteString(TwoByteString* str_obj, intptr_t len) { | |
| 160 ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, | |
| 161 str_obj, | |
| 162 object_store()->two_byte_string_class(), | |
| 163 len); | |
| 164 } | |
| 165 | |
| 166 | |
| 167 void SnapshotReader::NewFourByteString(FourByteString* str_obj, intptr_t len) { | |
| 168 ALLOC_NEW_OBJECT_WITH_LEN(FourByteString, | |
| 169 str_obj, | |
| 170 object_store()->four_byte_string_class(), | |
| 171 len); | |
| 172 } | |
| 173 | |
| 174 | |
| 175 void SnapshotReader::NewTypeArguments(TypeArguments* obj, intptr_t len) { | |
| 176 ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, | |
| 177 obj, | |
| 178 Object::type_arguments_class(), | |
| 179 len); | |
| 180 } | |
| 181 | |
| 182 | |
| 183 void SnapshotReader::NewTokenStream(TokenStream* obj, intptr_t len) { | |
| 184 ALLOC_NEW_OBJECT_WITH_LEN(TokenStream, | |
| 185 obj, | |
| 186 Object::token_stream_class(), | |
| 187 len); | |
| 188 } | |
| 189 | |
| 190 | |
| 191 void SnapshotReader::NewContext(Context* obj, intptr_t num_variables) { | |
| 192 ASSERT(kind_ == Snapshot::kFull); | |
| 193 cls_ = Object::context_class(); | |
| 194 *obj = reinterpret_cast<RawContext*>( | |
| 195 AllocateUninitialized(cls_, Context::InstanceSize(num_variables))); | |
| 196 obj->set_num_variables(num_variables); | |
| 197 } | |
| 198 | |
| 199 | |
| 200 void SnapshotReader::NewClass(Class* obj, int value) { | |
| 201 ASSERT(kind_ == Snapshot::kFull); | |
| 202 ObjectKind object_kind = static_cast<ObjectKind>(value); | |
| 203 if ((object_kind == kInstance || object_kind == kClosure)) { | |
| 204 cls_ = Object::class_class(); | |
| 205 *obj = reinterpret_cast<RawClass*>( | |
| 206 AllocateUninitialized(cls_, Class::InstanceSize())); | |
| 207 obj->set_instance_kind(object_kind); | |
| 208 if (object_kind == kInstance) { | |
| 209 Instance fake; | |
| 210 obj->set_handle_vtable(fake.vtable()); | |
| 211 } else { | |
| 212 Closure fake; | |
| 213 obj->set_handle_vtable(fake.vtable()); | |
| 214 } | |
| 215 } else { | |
| 216 *obj = Class::GetClass(object_kind); | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 | |
| 221 void SnapshotReader::NewMint(Mint* obj, int64_t value) { | |
| 222 ASSERT(kind_ == Snapshot::kFull); | |
| 223 cls_ = object_store()->mint_class(); | |
| 224 *obj = reinterpret_cast<RawMint*>( | |
| 225 AllocateUninitialized(cls_, Mint::InstanceSize())); | |
| 226 obj->set_value(value); | |
| 227 } | |
| 228 | |
| 229 | |
| 230 void SnapshotReader::NewDouble(Double* obj, double value) { | |
| 231 ASSERT(kind_ == Snapshot::kFull); | |
| 232 cls_ = object_store()->double_class(); | |
| 233 *obj = reinterpret_cast<RawDouble*>( | |
| 234 AllocateUninitialized(cls_, Double::InstanceSize())); | |
| 235 obj->set_value(value); | |
| 236 } | |
| 237 | |
| 238 | |
| 239 #define ALLOC_NEW_OBJECT(type, class_obj) \ | |
| 240 ASSERT(kind_ == Snapshot::kFull); \ | |
| 241 ASSERT(isolate()->no_gc_scope_depth() != 0); \ | |
| 242 cls_ = class_obj; \ | |
| 243 return reinterpret_cast<Raw##type*>( \ | |
| 244 AllocateUninitialized(cls_, type::InstanceSize())); \ | |
| 245 | |
| 246 | |
| 247 RawUnresolvedClass* SnapshotReader::NewUnresolvedClass() { | |
| 248 ALLOC_NEW_OBJECT(UnresolvedClass, Object::unresolved_class_class()); | |
| 249 } | |
| 250 | |
| 251 | |
| 252 RawType* SnapshotReader::NewType() { | |
| 253 ALLOC_NEW_OBJECT(Type, Object::type_class()); | |
| 254 } | |
| 255 | |
| 256 | |
| 257 RawTypeParameter* SnapshotReader::NewTypeParameter() { | |
| 258 ALLOC_NEW_OBJECT(TypeParameter, Object::type_parameter_class()); | |
| 259 } | |
| 260 | |
| 261 | |
| 262 RawFunction* SnapshotReader::NewFunction() { | |
| 263 ALLOC_NEW_OBJECT(Function, Object::function_class()); | |
| 264 } | |
| 265 | |
| 266 | |
| 267 RawField* SnapshotReader::NewField() { | |
| 268 ALLOC_NEW_OBJECT(Field, Object::field_class()); | |
| 269 } | |
| 270 | |
| 271 | |
| 272 RawLibrary* SnapshotReader::NewLibrary() { | |
| 273 ALLOC_NEW_OBJECT(Library, Object::library_class()); | |
| 274 } | |
| 275 | |
| 276 | |
| 277 RawLibraryPrefix* SnapshotReader::NewLibraryPrefix() { | |
| 278 ALLOC_NEW_OBJECT(LibraryPrefix, Object::library_prefix_class()); | |
| 279 } | |
| 280 | |
| 281 | |
| 282 RawScript* SnapshotReader::NewScript() { | |
| 283 ALLOC_NEW_OBJECT(Script, Object::script_class()); | |
| 284 } | |
| 285 | |
| 286 | |
| 124 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { | 287 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| 125 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); | 288 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); |
| 126 | 289 |
| 127 // If the header is an object Id, lookup singleton VM classes or classes | 290 // If the header is an object Id, lookup singleton VM classes or classes |
| 128 // stored in the object store. | 291 // stored in the object store. |
| 129 if (header_type == kObjectId) { | 292 if (header_type == kObjectId) { |
| 130 intptr_t header_value = SerializedHeaderData::decode(class_header); | 293 intptr_t header_value = SerializedHeaderData::decode(class_header); |
| 131 if (IsSingletonClassId(header_value)) { | 294 if (IsObjectStoreClassId(header_value)) { |
| 295 return object_store()->GetClass(header_value); | |
| 296 } else if (IsSingletonClassId(header_value)) { | |
| 132 return Object::GetSingletonClass(header_value); // return the singleton. | 297 return Object::GetSingletonClass(header_value); // return the singleton. |
| 133 } else if (IsObjectStoreClassId(header_value)) { | |
| 134 return object_store()->GetClass(header_value); | |
| 135 } | 298 } |
| 136 } | 299 } |
| 137 return Class::null(); | 300 return Class::null(); |
| 138 } | 301 } |
| 139 | 302 |
| 140 | 303 |
| 304 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, | |
| 305 intptr_t size) { | |
| 306 ASSERT(isolate()->no_gc_scope_depth() != 0); | |
| 307 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | |
| 308 Heap* heap = isolate()->heap(); | |
| 309 | |
| 310 uword address = heap->TryAllocate(size, Heap::kOld); | |
| 311 if (address == 0) { | |
| 312 // Use the preallocated out of memory exception to avoid calling | |
| 313 // into dart code or allocating any code. | |
| 314 const Instance& exception = | |
| 315 Instance::Handle(object_store()->out_of_memory()); | |
| 316 Exceptions::Throw(exception); | |
| 317 UNREACHABLE(); | |
| 318 } | |
| 319 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | |
| 320 raw_obj->ptr()->class_ = cls.raw(); | |
| 321 uword tags = 0; | |
| 322 tags = RawObject::SizeTag::update(size, tags); | |
| 323 raw_obj->ptr()->tags_ = tags; | |
| 324 return raw_obj; | |
| 325 } | |
| 326 | |
| 327 | |
| 141 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header) { | 328 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header) { |
| 142 SerializedHeaderType header_type = SerializedHeaderTag::decode(header); | 329 SerializedHeaderType header_type = SerializedHeaderTag::decode(header); |
| 143 intptr_t header_value = SerializedHeaderData::decode(header); | 330 intptr_t header_value = SerializedHeaderData::decode(header); |
| 144 | 331 |
| 145 if (header_type == kObjectId) { | 332 if (header_type == kObjectId) { |
| 146 return ReadIndexedObject(header_value); | 333 return ReadIndexedObject(header_value); |
| 147 } | 334 } |
| 148 ASSERT(header_type == kInlined); | 335 ASSERT(header_type == kInlined); |
| 149 return ReadInlinedObject(header_value); | 336 return ReadInlinedObject(header_value); |
| 150 } | 337 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 if (SerializedHeaderData::decode(class_header) == kInstanceId) { | 373 if (SerializedHeaderData::decode(class_header) == kInstanceId) { |
| 187 // Object is regular dart instance. | 374 // Object is regular dart instance. |
| 188 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); | 375 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); |
| 189 AddBackwardReference(object_id, &result); | 376 AddBackwardReference(object_id, &result); |
| 190 | 377 |
| 191 cls_ ^= ReadObject(); | 378 cls_ ^= ReadObject(); |
| 192 ASSERT(!cls_.IsNull()); | 379 ASSERT(!cls_.IsNull()); |
| 193 intptr_t instance_size = cls_.instance_size(); | 380 intptr_t instance_size = cls_.instance_size(); |
| 194 ASSERT(instance_size > 0); | 381 ASSERT(instance_size > 0); |
| 195 // Allocate the instance and read in all the fields for the object. | 382 // Allocate the instance and read in all the fields for the object. |
| 196 RawObject* raw = Instance::New(cls_, Heap::kNew); | 383 if (kind_ == Snapshot::kFull) { |
| 197 result ^= raw; | 384 result ^= AllocateUninitialized(cls_, instance_size); |
| 385 } else { | |
| 386 result ^= Object::Allocate(cls_, instance_size, Heap::kNew); | |
| 387 } | |
| 198 intptr_t offset = Object::InstanceSize(); | 388 intptr_t offset = Object::InstanceSize(); |
| 199 while (offset < instance_size) { | 389 while (offset < instance_size) { |
| 200 obj_ = ReadObject(); | 390 obj_ = ReadObject(); |
| 201 result.SetFieldAtOffset(offset, obj_); | 391 result.SetFieldAtOffset(offset, obj_); |
| 202 offset += kWordSize; | 392 offset += kWordSize; |
| 203 } | 393 } |
| 204 if (kind_ == Snapshot::kFull) { | 394 if (kind_ == Snapshot::kFull) { |
| 205 result.SetCreatedFromSnapshot(); | 395 result.SetCreatedFromSnapshot(); |
| 206 } else if (result.IsCanonical()) { | 396 } else if (result.IsCanonical()) { |
| 207 result = result.Canonicalize(); | 397 result = result.Canonicalize(); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 | 644 |
| 455 | 645 |
| 456 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 646 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 457 for (RawObject** current = first; current <= last; current++) { | 647 for (RawObject** current = first; current <= last; current++) { |
| 458 RawObject* raw_obj = *current; | 648 RawObject* raw_obj = *current; |
| 459 writer_->WriteObject(raw_obj); | 649 writer_->WriteObject(raw_obj); |
| 460 } | 650 } |
| 461 } | 651 } |
| 462 | 652 |
| 463 } // namespace dart | 653 } // namespace dart |
| OLD | NEW |