Chromium Code Reviews| Index: vm/snapshot.cc |
| =================================================================== |
| --- vm/snapshot.cc (revision 3329) |
| +++ vm/snapshot.cc (working copy) |
| @@ -1,4 +1,4 @@ |
| -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| @@ -6,6 +6,7 @@ |
| #include "vm/assert.h" |
| #include "vm/bootstrap.h" |
| +#include "vm/exceptions.h" |
| #include "vm/heap.h" |
| #include "vm/object.h" |
| #include "vm/object_store.h" |
| @@ -62,7 +63,7 @@ |
| library_(Library::Handle()), |
| type_(AbstractType::Handle()), |
| type_arguments_(AbstractTypeArguments::Handle()), |
| - backward_references_() { |
| + 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
|
| } |
| @@ -109,7 +110,11 @@ |
| ASSERT(isolate != NULL); |
| ObjectStore* object_store = isolate->object_store(); |
| ASSERT(object_store != NULL); |
| + NoGCScope no_gc; |
| + // TODO(asiva): Add a check here to ensure we have the right heap |
| + // size for the full snapshot being read. |
| + |
| // Read in all the objects stored in the object store. |
| intptr_t num_flds = (object_store->to() - object_store->from()); |
| for (intptr_t i = 0; i <= num_flds; i++) { |
| @@ -121,6 +126,164 @@ |
| } |
| +#define ALLOC_NEW_OBJECT_WITH_LEN(type, obj, class_obj, length) \ |
| + ASSERT(kind_ == Snapshot::kFull); \ |
| + ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
| + cls_ = class_obj; \ |
| + *obj = reinterpret_cast<Raw##type*>( \ |
| + AllocateUninitialized(cls_, type::InstanceSize(length))); \ |
| + obj->SetLength(length); \ |
| + |
| + |
| +void SnapshotReader::NewArray(Array* array, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(Array, array, object_store()->array_class(), len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewImmutableArray(ImmutableArray* array, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(ImmutableArray, |
| + array, |
| + object_store()->immutable_array_class(), |
| + len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewOneByteString(OneByteString* str_obj, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(OneByteString, |
| + str_obj, |
| + object_store()->one_byte_string_class(), |
| + len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewTwoByteString(TwoByteString* str_obj, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, |
| + str_obj, |
| + object_store()->two_byte_string_class(), |
| + len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewFourByteString(FourByteString* str_obj, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(FourByteString, |
| + str_obj, |
| + object_store()->four_byte_string_class(), |
| + len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewTypeArguments(TypeArguments* obj, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, |
| + obj, |
| + Object::type_arguments_class(), |
| + len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewTokenStream(TokenStream* obj, intptr_t len) { |
| + ALLOC_NEW_OBJECT_WITH_LEN(TokenStream, |
| + obj, |
| + Object::token_stream_class(), |
| + len); |
| +} |
| + |
| + |
| +void SnapshotReader::NewContext(Context* obj, intptr_t num_variables) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + cls_ = Object::context_class(); |
| + *obj = reinterpret_cast<RawContext*>( |
| + AllocateUninitialized(cls_, Context::InstanceSize(num_variables))); |
| + obj->set_num_variables(num_variables); |
| +} |
| + |
| + |
| +void SnapshotReader::NewClass(Class* obj, int value) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ObjectKind object_kind = static_cast<ObjectKind>(value); |
| + if ((object_kind == kInstance || object_kind == kClosure)) { |
| + cls_ = Object::class_class(); |
| + *obj = reinterpret_cast<RawClass*>( |
| + AllocateUninitialized(cls_, Class::InstanceSize())); |
| + obj->set_instance_kind(object_kind); |
| + if (object_kind == kInstance) { |
| + Instance fake; |
| + obj->set_handle_vtable(fake.vtable()); |
| + } else { |
| + Closure fake; |
| + obj->set_handle_vtable(fake.vtable()); |
| + } |
| + } else { |
| + *obj = Class::GetClass(object_kind); |
| + } |
| +} |
| + |
| + |
| +void SnapshotReader::NewMint(Mint* obj, int64_t value) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + cls_ = object_store()->mint_class(); |
| + *obj = reinterpret_cast<RawMint*>( |
| + AllocateUninitialized(cls_, Mint::InstanceSize())); |
| + obj->set_value(value); |
| +} |
| + |
| + |
| +void SnapshotReader::NewDouble(Double* obj, double value) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + cls_ = object_store()->double_class(); |
| + *obj = reinterpret_cast<RawDouble*>( |
| + AllocateUninitialized(cls_, Double::InstanceSize())); |
| + obj->set_value(value); |
| +} |
| + |
| + |
| +#define ALLOC_NEW_OBJECT(type, class_obj) \ |
| + ASSERT(kind_ == Snapshot::kFull); \ |
| + ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
| + cls_ = class_obj; \ |
| + return reinterpret_cast<Raw##type*>( \ |
| + AllocateUninitialized(cls_, type::InstanceSize())); \ |
| + |
| + |
| +RawUnresolvedClass* SnapshotReader::NewUnresolvedClass() { |
| + ALLOC_NEW_OBJECT(UnresolvedClass, Object::unresolved_class_class()); |
| +} |
| + |
| + |
| +RawType* SnapshotReader::NewType() { |
| + ALLOC_NEW_OBJECT(Type, Object::type_class()); |
| +} |
| + |
| + |
| +RawTypeParameter* SnapshotReader::NewTypeParameter() { |
| + ALLOC_NEW_OBJECT(TypeParameter, Object::type_parameter_class()); |
| +} |
| + |
| + |
| +RawFunction* SnapshotReader::NewFunction() { |
| + ALLOC_NEW_OBJECT(Function, Object::function_class()); |
| +} |
| + |
| + |
| +RawField* SnapshotReader::NewField() { |
| + ALLOC_NEW_OBJECT(Field, Object::field_class()); |
| +} |
| + |
| + |
| +RawLibrary* SnapshotReader::NewLibrary() { |
| + ALLOC_NEW_OBJECT(Library, Object::library_class()); |
| +} |
| + |
| + |
| +RawLibraryPrefix* SnapshotReader::NewLibraryPrefix() { |
| + ALLOC_NEW_OBJECT(LibraryPrefix, Object::library_prefix_class()); |
| +} |
| + |
| + |
| +RawScript* SnapshotReader::NewScript() { |
| + ALLOC_NEW_OBJECT(Script, Object::script_class()); |
| +} |
| + |
| + |
| RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); |
| @@ -128,16 +291,40 @@ |
| // stored in the object store. |
| if (header_type == kObjectId) { |
| intptr_t header_value = SerializedHeaderData::decode(class_header); |
| - if (IsSingletonClassId(header_value)) { |
| + if (IsObjectStoreClassId(header_value)) { |
| + return object_store()->GetClass(header_value); |
| + } else if (IsSingletonClassId(header_value)) { |
| return Object::GetSingletonClass(header_value); // return the singleton. |
| - } else if (IsObjectStoreClassId(header_value)) { |
| - return object_store()->GetClass(header_value); |
| } |
| } |
| return Class::null(); |
| } |
| +RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, |
| + intptr_t size) { |
| + ASSERT(isolate()->no_gc_scope_depth() != 0); |
| + ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| + Heap* heap = isolate()->heap(); |
| + |
| + uword address = heap->TryAllocate(size, Heap::kOld); |
| + if (address == 0) { |
| + // Use the preallocated out of memory exception to avoid calling |
| + // into dart code or allocating any code. |
| + const Instance& exception = |
| + Instance::Handle(object_store()->out_of_memory()); |
| + Exceptions::Throw(exception); |
| + UNREACHABLE(); |
| + } |
| + RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| + raw_obj->ptr()->class_ = cls.raw(); |
| + uword tags = 0; |
| + tags = RawObject::SizeTag::update(size, tags); |
| + raw_obj->ptr()->tags_ = tags; |
| + return raw_obj; |
| +} |
| + |
| + |
| RawObject* SnapshotReader::ReadObjectImpl(intptr_t header) { |
| SerializedHeaderType header_type = SerializedHeaderTag::decode(header); |
| intptr_t header_value = SerializedHeaderData::decode(header); |
| @@ -193,8 +380,11 @@ |
| intptr_t instance_size = cls_.instance_size(); |
| ASSERT(instance_size > 0); |
| // Allocate the instance and read in all the fields for the object. |
| - RawObject* raw = Instance::New(cls_, Heap::kNew); |
| - result ^= raw; |
| + if (kind_ == Snapshot::kFull) { |
| + result ^= AllocateUninitialized(cls_, instance_size); |
| + } else { |
| + result ^= Object::Allocate(cls_, instance_size, Heap::kNew); |
| + } |
| intptr_t offset = Object::InstanceSize(); |
| while (offset < instance_size) { |
| obj_ = ReadObject(); |