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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « vm/snapshot.h ('k') | vm/snapshot_ids.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: vm/snapshot.cc
===================================================================
--- vm/snapshot.cc (revision 10409)
+++ vm/snapshot.cc (working copy)
@@ -11,37 +11,100 @@
#include "vm/heap.h"
#include "vm/object.h"
#include "vm/object_store.h"
+#include "vm/snapshot_ids.h"
#include "vm/symbols.h"
namespace dart {
-enum {
- kInstanceId = ObjectStore::kMaxId,
- kMaxPredefinedObjectIds,
-};
static const int kNumInitialReferencesInFullSnapshot = 160 * KB;
static const int kNumInitialReferences = 4;
-static bool IsSingletonClassId(intptr_t index) {
+static bool IsSingletonClassId(intptr_t class_id) {
// Check if this is a singleton object class which is shared by all isolates.
- return (index >= Object::kClassClass && index < Object::kMaxId);
+ return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) ||
+ (class_id >= kNullCid && class_id <= kVoidCid));
}
-static bool IsObjectStoreClassId(intptr_t index) {
+static bool IsObjectStoreClassId(intptr_t class_id) {
// Check if this is a class which is stored in the object store.
- return (index >= ObjectStore::kObjectClass && index < ObjectStore::kMaxId);
+ return (class_id == kObjectCid ||
+ (class_id >= kInstanceCid && class_id <= kJSRegExpCid));
}
static bool IsObjectStoreTypeId(intptr_t index) {
// Check if this is a type which is stored in the object store.
- return (index >= ObjectStore::kObjectType &&
- index <= ObjectStore::kListInterface);
+ return (index >= kObjectType && index <= kByteArrayInterface);
}
+static intptr_t ClassIdFromObjectId(intptr_t object_id) {
+ ASSERT(object_id > kClassIdsOffset);
+ intptr_t class_id = (object_id - kClassIdsOffset);
+ return class_id;
+}
+
+
+static intptr_t ObjectIdFromClassId(intptr_t class_id) {
+ ASSERT(class_id > kIllegalCid && class_id < kNumPredefinedCids);
+ return (class_id + kClassIdsOffset);
+}
+
+
+static RawType* GetType(ObjectStore* object_store, int index) {
+ switch (index) {
+ case kObjectType: return object_store->object_type();
+ case kNullType: return object_store->null_type();
+ case kDynamicType: return object_store->dynamic_type();
+ case kVoidType: return object_store->void_type();
+ case kFunctionInterface: return object_store->function_interface();
+ case kNumberInterface: return object_store->number_interface();
+ case kDoubleInterface: return object_store->double_interface();
+ case kIntInterface: return object_store->int_interface();
+ case kBoolInterface: return object_store->bool_interface();
+ case kStringInterface: return object_store->string_interface();
+ case kListInterface: return object_store->list_interface();
+ case kByteArrayInterface: return object_store->byte_array_interface();
+ default: break;
+ }
+ UNREACHABLE();
+ return Type::null();
+}
+
+
+static int GetTypeIndex(ObjectStore* object_store, const RawType* raw_type) {
+ ASSERT(raw_type->IsHeapObject());
+ if (raw_type == object_store->object_type()) {
+ return kObjectType;
+ } else if (raw_type == object_store->null_type()) {
+ return kNullType;
+ } else if (raw_type == object_store->dynamic_type()) {
+ return kDynamicType;
+ } else if (raw_type == object_store->void_type()) {
+ return kVoidType;
+ } else if (raw_type == object_store->function_interface()) {
+ return kFunctionInterface;
+ } else if (raw_type == object_store->number_interface()) {
+ return kNumberInterface;
+ } else if (raw_type == object_store->double_interface()) {
+ return kDoubleInterface;
+ } else if (raw_type == object_store->int_interface()) {
+ return kIntInterface;
+ } else if (raw_type == object_store->bool_interface()) {
+ return kBoolInterface;
+ } else if (raw_type == object_store->string_interface()) {
+ return kStringInterface;
+ } else if (raw_type == object_store->list_interface()) {
+ return kListInterface;
+ } else if (raw_type == object_store->byte_array_interface()) {
+ return kByteArrayInterface;
+ }
+ return kInvalidIndex;
+}
+
+
// TODO(5411462): Temporary setup of snapshot for testing purposes,
// the actual creation of a snapshot maybe done differently.
const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) {
@@ -167,7 +230,7 @@
// Since we are only reading an object reference, If it is an instance kind
// then we only need to figure out the class of the object and allocate an
// instance of it. The individual fields will be read later.
- if (SerializedHeaderData::decode(class_header) == kInstanceId) {
+ if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
Instance& result = Instance::ZoneHandle(isolate(), Instance::null());
AddBackRef(object_id, &result, kIsNotDeserialized);
@@ -181,16 +244,15 @@
result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew);
}
return result.raw();
- } else {
- ASSERT((class_header & kSmiTagMask) != 0);
- cls_ = LookupInternalClass(class_header);
- ASSERT(!cls_.IsNull());
}
+ ASSERT((class_header & kSmiTagMask) != 0);
+ cls_ = LookupInternalClass(class_header);
+ ASSERT(!cls_.IsNull());
// Similarly Array and ImmutableArray objects are also similarly only
// allocated here, the individual array elements are read later.
- ObjectKind obj_kind = cls_.instance_kind();
- if (obj_kind == Array::kInstanceKind) {
+ intptr_t class_id = cls_.id();
+ if (class_id == kArrayCid) {
// Read the length and allocate an object based on the len.
intptr_t len = ReadSmiValue();
Array& array = Array::ZoneHandle(
@@ -200,7 +262,7 @@
return array.raw();
}
- if (obj_kind == ImmutableArray::kInstanceKind) {
+ if (class_id == kImmutableArrayCid) {
// Read the length and allocate an object based on the len.
intptr_t len = ReadSmiValue();
ImmutableArray& array = ImmutableArray::ZoneHandle(
@@ -214,9 +276,9 @@
// For all other internal VM classes we read the object inline.
intptr_t tags = ReadIntptrValue();
- switch (obj_kind) {
+ switch (class_id) {
#define SNAPSHOT_READ(clazz) \
- case clazz::kInstanceKind: { \
+ case clazz::kClassId: { \
obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \
break; \
}
@@ -348,28 +410,26 @@
}
-RawClass* SnapshotReader::NewClass(int value) {
+RawClass* SnapshotReader::NewClass(intptr_t class_id, bool is_signature_class) {
ASSERT(kind_ == Snapshot::kFull);
ASSERT(isolate()->no_gc_scope_depth() != 0);
- ObjectKind object_kind = static_cast<ObjectKind>(value);
- if ((object_kind == kInstance || object_kind == kClosure)) {
- cls_ = Object::class_class();
- RawClass* obj = reinterpret_cast<RawClass*>(
- AllocateUninitialized(cls_, Class::InstanceSize()));
- if (object_kind == kInstance) {
- Instance fake;
- obj->ptr()->handle_vtable_ = fake.vtable();
- } else {
- Closure fake;
- obj->ptr()->handle_vtable_ = fake.vtable();
- }
- cls_ = obj;
- cls_.set_instance_kind(object_kind);
- cls_.set_id(kIllegalObjectKind);
- isolate()->class_table()->Register(cls_);
- return cls_.raw();
+ if (class_id < kNumPredefinedCids) {
+ return Class::GetClass(class_id, is_signature_class);
}
- return Class::GetClass(object_kind);
+ cls_ = Object::class_class();
+ RawClass* obj = reinterpret_cast<RawClass*>(
+ AllocateUninitialized(cls_, Class::InstanceSize()));
+ if (is_signature_class) {
+ Closure fake;
+ obj->ptr()->handle_vtable_ = fake.vtable();
+ } else {
+ Instance fake;
+ obj->ptr()->handle_vtable_ = fake.vtable();
+ }
+ cls_ = obj;
+ cls_.set_id(kIllegalCid);
+ isolate()->class_table()->Register(cls_);
+ return cls_.raw();
}
@@ -474,12 +534,12 @@
if (IsVMIsolateObject(class_header)) {
intptr_t class_id = GetVMIsolateObjectId(class_header);
if (IsSingletonClassId(class_id)) {
- return Object::GetSingletonClass(class_id); // return singleton.
+ return isolate()->class_table()->At(class_id); // get singleton class.
}
} else if (SerializedHeaderTag::decode(class_header) == kObjectId) {
- intptr_t header_value = SerializedHeaderData::decode(class_header);
- if (IsObjectStoreClassId(header_value)) {
- return object_store()->GetClass(header_value);
+ intptr_t class_id = SerializedHeaderData::decode(class_header);
+ if (IsObjectStoreClassId(class_id)) {
+ return isolate()->class_table()->At(class_id); // get singleton class.
}
}
return Class::null();
@@ -504,7 +564,7 @@
RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
uword tags = 0;
intptr_t index = cls.id();
- ASSERT(index != kIllegalObjectKind);
+ ASSERT(index != kIllegalCid);
tags = RawObject::ClassIdTag::update(index, tags);
tags = RawObject::SizeTag::update(size, tags);
raw_obj->ptr()->tags_ = tags;
@@ -514,36 +574,41 @@
RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
intptr_t object_id = GetVMIsolateObjectId(header_value);
- if (object_id == Object::kNullObject) {
+ if (object_id == kNullObject) {
// This is a singleton null object, return it.
return Object::null();
}
- if (object_id == Object::kSentinelObject) {
+ if (object_id == kSentinelObject) {
return Object::sentinel();
}
- if (IsSingletonClassId(object_id)) {
- return Object::GetSingletonClass(object_id); // return singleton object.
+ intptr_t class_id = ClassIdFromObjectId(object_id);
+ if (IsSingletonClassId(class_id)) {
+ return isolate()->class_table()->At(class_id); // get singleton class.
} else {
ASSERT(Symbols::IsVMSymbolId(object_id));
return Symbols::GetVMSymbol(object_id); // return VM symbol.
}
UNREACHABLE();
+ return Object::null();
}
RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) {
- if (IsObjectStoreClassId(object_id)) {
- return object_store()->GetClass(object_id);
- } else if (object_id == ObjectStore::kTrueValue) {
+ if (object_id == kTrueValue) {
return object_store()->true_value();
- } else if (object_id == ObjectStore::kFalseValue) {
+ }
+ if (object_id == kFalseValue) {
return object_store()->false_value();
- } else if (kind_ != Snapshot::kFull) {
+ }
+ intptr_t class_id = ClassIdFromObjectId(object_id);
+ if (IsObjectStoreClassId(class_id)) {
+ return isolate()->class_table()->At(class_id); // get singleton class.
+ }
+ if (kind_ != Snapshot::kFull) {
if (IsObjectStoreTypeId(object_id)) {
- return object_store()->GetType(object_id); // return type object.
+ return GetType(object_store(), object_id); // return type obj.
}
}
-
Object* object = GetBackRef(object_id);
return object->raw();
}
@@ -553,7 +618,7 @@
// Read the class header information and lookup the class.
intptr_t class_header = ReadIntptrValue();
intptr_t tags = ReadIntptrValue();
- if (SerializedHeaderData::decode(class_header) == kInstanceId) {
+ if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
// Object is regular dart instance.
Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
intptr_t instance_size = 0;
@@ -587,14 +652,13 @@
*result = result->Canonicalize();
}
return result->raw();
- } else {
- ASSERT((class_header & kSmiTagMask) != 0);
- cls_ = LookupInternalClass(class_header);
- ASSERT(!cls_.IsNull());
}
- switch (cls_.instance_kind()) {
+ ASSERT((class_header & kSmiTagMask) != 0);
+ cls_ = LookupInternalClass(class_header);
+ ASSERT(!cls_.IsNull());
+ switch (cls_.id()) {
#define SNAPSHOT_READ(clazz) \
- case clazz::kInstanceKind: { \
+ case clazz::kClassId: { \
obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \
break; \
}
@@ -635,28 +699,33 @@
void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
// Check if it is a singleton null object.
if (rawobj == Object::null()) {
- WriteVMIsolateObject(Object::kNullObject);
+ WriteVMIsolateObject(kNullObject);
return;
}
// Check if it is a singleton sentinel object.
if (rawobj == Object::sentinel()) {
- WriteVMIsolateObject(Object::kSentinelObject);
+ WriteVMIsolateObject(kSentinelObject);
return;
}
- // Check if it is a singleton class object.
- RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
- intptr_t index = Object::GetSingletonClassIndex(raw_class);
- if (index != Object::kInvalidIndex) {
- WriteVMIsolateObject(index);
- return;
+ // Check if it is a singleton class object which is shared by
+ // all isolates.
+ intptr_t id = rawobj->GetClassId();
+ if (id == kClassCid) {
+ RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
+ intptr_t class_id = raw_class->ptr()->id_;
+ if (IsSingletonClassId(class_id)) {
+ intptr_t object_id = ObjectIdFromClassId(class_id);
+ WriteVMIsolateObject(object_id);
+ return;
+ }
}
- // Check it is a predefined symbol.
- index = Symbols::LookupVMSymbol(rawobj);
- if (index != Object::kInvalidIndex) {
- WriteVMIsolateObject(index);
+ // Check it is a predefined symbol in the VM isolate.
+ id = Symbols::LookupVMSymbol(rawobj);
+ if (id != kInvalidIndex) {
+ WriteVMIsolateObject(id);
return;
}
@@ -669,20 +738,13 @@
if (CheckAndWritePredefinedObject(raw)) {
return;
}
- // Check if object has already been serialized, in that
- // case just write the object id out.
- uword tags = raw->ptr()->tags_;
- if (SerializedHeaderTag::decode(tags) == kObjectId) {
- intptr_t id = SerializedHeaderData::decode(tags);
- WriteIndexedObject(id);
- return;
- }
NoGCScope no_gc;
- RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
-
- ObjectKind obj_kind = cls->ptr()->instance_kind_;
- if (obj_kind == Instance::kInstanceKind) {
+ RawClass* cls = class_table_->At(raw->GetClassId());
+ intptr_t class_id = cls->ptr()->id_;
+ ASSERT(class_id == raw->GetClassId());
+ if (class_id >= kNumPredefinedCids) {
+ ASSERT(!Class::IsSignatureClass(cls));
// Object is being referenced, add it to the forward ref list and mark
// it so that future references to this object in the snapshot will use
// this object id. Mark it as not having been serialized yet so that we
@@ -693,14 +755,14 @@
WriteInlinedObjectHeader(object_id);
// Indicate this is an instance object.
- WriteIntptrValue(SerializedHeaderData::encode(kInstanceId));
+ WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId));
// Write out the class information for this object.
WriteObjectImpl(cls);
return;
}
- if (obj_kind == Array::kInstanceKind) {
+ if (class_id == kArrayCid) {
// Object is being referenced, add it to the forward ref list and mark
// it so that future references to this object in the snapshot will use
// this object id. Mark it as not having been serialized yet so that we
@@ -713,14 +775,14 @@
WriteInlinedObjectHeader(object_id);
// Write out the class information.
- WriteIndexedObject(ObjectStore::kArrayClass);
+ WriteIndexedObject(kArrayCid);
// Write out the length field.
Write<RawObject*>(rawarray->ptr()->length_);
return;
}
- if (obj_kind == ImmutableArray::kInstanceKind) {
+ if (class_id == kImmutableArrayCid) {
// Object is being referenced, add it to the forward ref list and mark
// it so that future references to this object in the snapshot will use
// this object id. Mark it as not having been serialized yet so that we
@@ -733,7 +795,7 @@
WriteInlinedObjectHeader(object_id);
// Write out the class information.
- WriteIndexedObject(ObjectStore::kImmutableArrayClass);
+ WriteIndexedObject(kImmutableArrayCid);
// Write out the length field.
Write<RawObject*>(rawarray->ptr()->length_);
@@ -745,9 +807,9 @@
// this object id. Mark it as not having been serialized yet so that we
// will serialize the object when we go through the forward list.
intptr_t object_id = MarkObject(raw, kIsSerialized);
- switch (obj_kind) {
+ switch (class_id) {
#define SNAPSHOT_WRITE(clazz) \
- case clazz::kInstanceKind: { \
+ case clazz::kClassId: { \
Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
raw_obj->WriteTo(this, object_id, kind_); \
return; \
@@ -850,28 +912,28 @@
// Check if it is a singleton boolean true value.
if (rawobj == object_store()->true_value()) {
- WriteIndexedObject(ObjectStore::kTrueValue);
+ WriteIndexedObject(kTrueValue);
return true;
}
// Check if it is a singleton boolean false value.
if (rawobj == object_store()->false_value()) {
- WriteIndexedObject(ObjectStore::kFalseValue);
+ WriteIndexedObject(kFalseValue);
return true;
}
// Check if it is a code object in that case just write a Null object
// as we do not want code objects in the snapshot.
- if (rawobj->GetClassId() == kCode) {
- WriteVMIsolateObject(Object::kNullObject);
+ if (rawobj->GetClassId() == kCodeCid) {
+ WriteVMIsolateObject(kNullObject);
return true;
}
// Check if classes are not being serialized and it is preinitialized type.
if (kind_ != Snapshot::kFull) {
RawType* raw_type = reinterpret_cast<RawType*>(rawobj);
- intptr_t index = object_store()->GetTypeIndex(raw_type);
- if (index != ObjectStore::kInvalidIndex) {
+ intptr_t index = GetTypeIndex(object_store(), raw_type);
+ if (index != kInvalidIndex) {
WriteIndexedObject(index);
return true;
}
@@ -908,9 +970,10 @@
intptr_t object_id = SerializedHeaderData::decode(tags);
tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags();
RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
- ObjectKind kind = cls->ptr()->instance_kind_;
+ intptr_t class_id = cls->ptr()->id_;
- if (kind == Instance::kInstanceKind) {
+ if (class_id >= kNumPredefinedCids) {
+ ASSERT(!Class::IsSignatureClass(cls));
// Object is regular dart instance.
// TODO(5411462): figure out what we need to do if an object with native
// fields is serialized (throw exception or serialize a null object).
@@ -922,7 +985,7 @@
WriteInlinedObjectHeader(object_id);
// Indicate this is an instance object.
- WriteIntptrValue(SerializedHeaderData::encode(kInstanceId));
+ WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId));
// Write out the tags.
WriteIntptrValue(tags);
@@ -939,9 +1002,9 @@
}
return;
}
- switch (kind) {
+ switch (class_id) {
#define SNAPSHOT_WRITE(clazz) \
- case clazz::kInstanceKind: { \
+ case clazz::kClassId: { \
Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
raw_obj->WriteTo(this, object_id, kind_); \
return; \
@@ -976,16 +1039,18 @@
void SnapshotWriter::WriteClassId(RawClass* cls) {
ASSERT(kind_ != Snapshot::kFull);
- int id = object_store()->GetClassIndex(cls);
- if (IsSingletonClassId(id)) {
- WriteVMIsolateObject(id);
- } else if (IsObjectStoreClassId(id)) {
- WriteIndexedObject(id);
+ int class_id = cls->ptr()->id_;
+ if (IsSingletonClassId(class_id)) {
+ intptr_t object_id = ObjectIdFromClassId(class_id);
+ WriteVMIsolateObject(object_id);
+ } else if (IsObjectStoreClassId(class_id)) {
+ intptr_t object_id = ObjectIdFromClassId(class_id);
+ WriteIndexedObject(object_id);
} else {
// TODO(5411462): Should restrict this to only core-lib classes in this
// case.
// Write out the class and tags information.
- WriteVMIsolateObject(Object::kClassClass);
+ WriteVMIsolateObject(kClassCid);
WriteIntptrValue(GetObjectTags(cls));
// Write out the library url and class name.
« 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