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

Unified Diff: vm/dart_api_message.cc

Issue 10535066: 1. Remove recursion during snapshot writing and reading (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
Index: vm/dart_api_message.cc
===================================================================
--- vm/dart_api_message.cc (revision 8411)
+++ vm/dart_api_message.cc (working copy)
@@ -166,6 +166,18 @@
}
+ApiMessageReader::BackwardReferenceNode*
+ApiMessageReader::AllocateBackwardReferenceNode(
+ Dart_CObject* reference, bool is_deserialized) {
+ BackwardReferenceNode* value =
+ reinterpret_cast<BackwardReferenceNode*>(
+ alloc_(NULL, 0, sizeof(BackwardReferenceNode)));
+ value->set_reference(reference);
+ value->set_is_deserialized(is_deserialized);
+ return value;
+}
+
+
Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) {
// Read the class header information and lookup the class.
intptr_t class_header = ReadIntptrValue();
@@ -180,6 +192,77 @@
ASSERT((class_header & kSmiTagMask) != 0);
class_id = LookupInternalClass(class_header);
+ if (class_id == ObjectStore::kArrayClass ||
+ class_id == ObjectStore::kImmutableArrayClass) {
+ intptr_t len = ReadSmiValue();
+ Dart_CObject* value = GetBackwardReference(object_id);
+ if (value == NULL) {
+ value = AllocateDartCObjectArray(len);
+ AddBackwardReference(object_id, value, true);
+ }
+ // Skip type arguments.
+ // TODO(sjesse): Remove this when message serialization format is
+ // updated (currently type_arguments is leaked).
+ Dart_CObject* type_arguments = ReadObjectImpl();
+ if (type_arguments != &type_arguments_marker &&
+ type_arguments->type != Dart_CObject::kNull) {
+ return AllocateDartCObjectUnsupported();
+ }
+ for (int i = 0; i < len; i++) {
+ value->value.as_array.values[i] = ReadObjectRef();
+ }
+ return value;
+ }
+
+ return ReadInternalVMObject(class_id, object_id);
+}
+
+
+Dart_CObject* ApiMessageReader::ReadObjectRef() {
+ int64_t value = Read<int64_t>();
+ if ((value & kSmiTagMask) == 0) {
+ int64_t untagged_value = value >> kSmiTagShift;
+ if (kMinInt32 <= untagged_value && untagged_value <= kMaxInt32) {
+ return AllocateDartCObjectInt32(untagged_value);
+ } else {
+ return AllocateDartCObjectInt64(untagged_value);
+ }
+ }
+ ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
+ SerializedHeaderType header_type = SerializedHeaderTag::decode(value);
+ intptr_t header_value = SerializedHeaderData::decode(value);
+
+ if (header_type == kObjectId) {
+ return ReadIndexedObject(header_value);
+ }
+ ASSERT(header_type == kInlined);
+ // Read the class header information and lookup the class.
+ intptr_t class_header = ReadIntptrValue();
+
+ // Reading of regular dart instances is not supported.
+ if (SerializedHeaderData::decode(class_header) == kInstanceId) {
+ return AllocateDartCObjectUnsupported();
+ }
+ ASSERT((class_header & kSmiTagMask) != 0);
+ intptr_t object_id = header_value;
+ intptr_t class_id = LookupInternalClass(class_header);
+ if (class_id == ObjectStore::kArrayClass ||
+ class_id == ObjectStore::kImmutableArrayClass) {
+ ASSERT(GetBackwardReference(object_id) == NULL);
+ intptr_t len = ReadSmiValue();
+ Dart_CObject* value = AllocateDartCObjectArray(len);
+ AddBackwardReference(object_id, value, false);
+ return value;
+ }
+ intptr_t tags = ReadIntptrValue();
+ USE(tags);
+
+ return ReadInternalVMObject(class_id, object_id);
+}
+
+
+Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id,
+ intptr_t object_id) {
switch (class_id) {
case Object::kClassClass: {
return AllocateDartCObjectUnsupported();
@@ -188,11 +271,11 @@
// TODO(sjesse): Remove this when message serialization format is
// updated (currently length is leaked).
Dart_CObject* value = &type_arguments_marker;
- AddBackwardReference(object_id, value);
- Dart_CObject* length = ReadObject();
+ AddBackwardReference(object_id, value, true);
+ Dart_CObject* length = ReadObjectImpl();
ASSERT(length->type == Dart_CObject::kInt32);
for (int i = 0; i < length->value.as_int32; i++) {
- Dart_CObject* type = ReadObject();
+ Dart_CObject* type = ReadObjectImpl();
if (type != &dynamic_type_marker) {
return AllocateDartCObjectUnsupported();
}
@@ -202,37 +285,20 @@
case Object::kTypeParameterClass: {
// TODO(sgjesse): Fix this workaround ignoring the type parameter.
Dart_CObject* value = &dynamic_type_marker;
- AddBackwardReference(object_id, value);
+ AddBackwardReference(object_id, value, true);
intptr_t index = ReadIntptrValue();
USE(index);
intptr_t token_index = ReadIntptrValue();
USE(token_index);
int8_t type_state = Read<int8_t>();
USE(type_state);
- Dart_CObject* parameterized_class = ReadObject();
+ Dart_CObject* parameterized_class = ReadObjectImpl();
// The type parameter is finalized, therefore parameterized_class is null.
ASSERT(parameterized_class->type == Dart_CObject::kNull);
- Dart_CObject* name = ReadObject();
+ Dart_CObject* name = ReadObjectImpl();
ASSERT(name->type == Dart_CObject::kString);
return value;
}
- case ObjectStore::kArrayClass: {
- intptr_t len = ReadSmiValue();
- Dart_CObject* value = AllocateDartCObjectArray(len);
- AddBackwardReference(object_id, value);
- // Skip type arguments.
- // TODO(sjesse): Remove this when message serialization format is
- // updated (currently type_arguments is leaked).
- Dart_CObject* type_arguments = ReadObject();
- if (type_arguments != &type_arguments_marker &&
- type_arguments->type != Dart_CObject::kNull) {
- return AllocateDartCObjectUnsupported();
- }
- for (int i = 0; i < len; i++) {
- value->value.as_array.values[i] = ReadObject();
- }
- return value;
- }
case ObjectStore::kMintClass: {
int64_t value = Read<int64_t>();
Dart_CObject* object;
@@ -241,14 +307,14 @@
} else {
object = AllocateDartCObjectInt64(value);
}
- AddBackwardReference(object_id, object);
+ AddBackwardReference(object_id, object, true);
return object;
}
case ObjectStore::kBigintClass: {
// Read in the hex string representation of the bigint.
intptr_t len = ReadIntptrValue();
Dart_CObject* object = AllocateDartCObjectBigint(len);
- AddBackwardReference(object_id, object);
+ AddBackwardReference(object_id, object, true);
char* p = object->value.as_bigint;
for (intptr_t i = 0; i < len; i++) {
p[i] = Read<uint8_t>();
@@ -259,7 +325,7 @@
case ObjectStore::kDoubleClass: {
// Read the double value for the object.
Dart_CObject* object = AllocateDartCObjectDouble(Read<double>());
- AddBackwardReference(object_id, object);
+ AddBackwardReference(object_id, object, true);
return object;
}
case ObjectStore::kOneByteStringClass: {
@@ -267,7 +333,7 @@
intptr_t hash = ReadSmiValue();
USE(hash);
Dart_CObject* object = AllocateDartCObjectString(len);
- AddBackwardReference(object_id, object);
+ AddBackwardReference(object_id, object, true);
char* p = object->value.as_string;
for (intptr_t i = 0; i < len; i++) {
p[i] = Read<uint8_t>();
@@ -284,7 +350,7 @@
case ObjectStore::kUint8ArrayClass: {
intptr_t len = ReadSmiValue();
Dart_CObject* object = AllocateDartCObjectUint8Array(len);
- AddBackwardReference(object_id, object);
+ AddBackwardReference(object_id, object, true);
if (len > 0) {
uint8_t* p = object->value.as_byte_array.values;
for (intptr_t i = 0; i < len; i++) {
@@ -320,24 +386,24 @@
}
intptr_t index = object_id - kMaxPredefinedObjectIds;
ASSERT((0 <= index) && (index < backward_references_.length()));
- ASSERT(backward_references_[index] != NULL);
- return backward_references_[index];
+ ASSERT(backward_references_[index]->reference() != NULL);
+ return backward_references_[index]->reference();
}
-Dart_CObject* ApiMessageReader::ReadObjectImpl(intptr_t header) {
- SerializedHeaderType header_type = SerializedHeaderTag::decode(header);
- intptr_t header_value = SerializedHeaderData::decode(header);
-
- if (header_type == kObjectId) {
- return ReadIndexedObject(header_value);
+Dart_CObject* ApiMessageReader::ReadObject() {
+ Dart_CObject* value = ReadObjectImpl();
+ for (intptr_t i = 0; i < backward_references_.length(); i++) {
+ if (!backward_references_[i]->is_deserialized()) {
+ ReadObjectImpl();
+ backward_references_[i]->set_is_deserialized(true);
+ }
}
- ASSERT(header_type == kInlined);
- return ReadInlinedObject(header_value);
+ return value;
}
-Dart_CObject* ApiMessageReader::ReadObject() {
+Dart_CObject* ApiMessageReader::ReadObjectImpl() {
int64_t value = Read<int64_t>();
if ((value & kSmiTagMask) == 0) {
int64_t untagged_value = value >> kSmiTagShift;
@@ -348,15 +414,39 @@
}
}
ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
- return ReadObjectImpl(value);
+ SerializedHeaderType header_type = SerializedHeaderTag::decode(value);
+ intptr_t header_value = SerializedHeaderData::decode(value);
+
+ if (header_type == kObjectId) {
+ return ReadIndexedObject(header_value);
+ }
+ ASSERT(header_type == kInlined);
+ return ReadInlinedObject(header_value);
}
-void ApiMessageReader::AddBackwardReference(intptr_t id, Dart_CObject* obj) {
- ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length());
- backward_references_.Add(obj);
+void ApiMessageReader::AddBackwardReference(intptr_t id,
+ Dart_CObject* obj,
+ bool is_deserialized) {
+ intptr_t index = (id - kMaxPredefinedObjectIds);
+ ASSERT(index == backward_references_.length());
+ BackwardReferenceNode* node = AllocateBackwardReferenceNode(obj,
+ is_deserialized);
+ ASSERT(node != NULL);
+ backward_references_.Add(node);
}
+
+Dart_CObject* ApiMessageReader::GetBackwardReference(intptr_t id) {
+ ASSERT(id >= kMaxPredefinedObjectIds);
+ intptr_t index = (id - kMaxPredefinedObjectIds);
+ if (index < backward_references_.length()) {
+ return backward_references_[index]->reference();
+ }
+ return NULL;
+}
+
+
void ApiMessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) {
// Write out the serialization header value for this object.
WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds);
@@ -404,7 +494,8 @@
intptr_t ApiMessageWriter::GetMarkedCObjectMark(Dart_CObject* object) {
ASSERT(IsCObjectMarked(object));
- intptr_t mark_value = ((object->type & kDartCObjectMarkMask) >> 3);
+ intptr_t mark_value =
+ ((object->type & kDartCObjectMarkMask) >> kDartCObjectTypeBits);
// An offset was added to object id for making marking object id 0 possible.
return mark_value - kDartCObjectMarkOffset;
}
@@ -422,6 +513,18 @@
}
+void ApiMessageWriter::AddToForwardList(Dart_CObject* object) {
+ if (forward_id_ >= forward_list_length_) {
+ intptr_t new_size = (forward_list_length_ * sizeof(object)) * 2;
+ void* new_list = ::realloc(forward_list_, new_size);
+ ASSERT(new_list != NULL);
+ forward_list_ = reinterpret_cast<Dart_CObject**>(new_list);
+ }
+ forward_list_[forward_id_] = object;
+ forward_id_ += 1;
+}
+
+
void ApiMessageWriter::WriteSmi(int64_t value) {
ASSERT(Smi::IsValid64(value));
Write<RawObject*>(Smi::New(value));
@@ -476,7 +579,72 @@
return;
}
- switch (object->type) {
+ Dart_CObject::Type type = object->type;
+ if (type == Dart_CObject::kArray) {
+ // Write out the serialization header value for this object.
+ WriteInlinedHeader(object);
+ // Write out the class and tags information.
+ WriteObjectHeader(ObjectStore::kArrayClass, 0);
+ WriteSmi(object->value.as_array.length);
+ // Write out the type arguments.
+ WriteIndexedObject(Object::kNullObject);
+ // Write out array elements.
+ for (int i = 0; i < object->value.as_array.length; i++) {
+ WriteCObjectRef(object->value.as_array.values[i]);
+ }
+ return;
+ }
+ return WriteCObjectInlined(object, type);
+}
+
+
+void ApiMessageWriter::WriteCObjectRef(Dart_CObject* object) {
+ if (IsCObjectMarked(object)) {
+ intptr_t object_id = GetMarkedCObjectMark(object);
+ WriteIndexedObject(kMaxPredefinedObjectIds + object_id);
+ return;
+ }
+
+ Dart_CObject::Type type = object->type;
+ if (type == Dart_CObject::kArray) {
+ // Write out the serialization header value for this object.
+ WriteInlinedHeader(object);
+ // Write out the class information.
+ WriteIndexedObject(ObjectStore::kArrayClass);
+ // Write out the length information.
+ WriteSmi(object->value.as_array.length);
+ // Add object to forward list so that this object is serialized later.
+ AddToForwardList(object);
+ return;
+ }
+ return WriteCObjectInlined(object, type);
+}
+
+
+void ApiMessageWriter::WriteForwardedCObject(Dart_CObject* object) {
+ ASSERT(IsCObjectMarked(object));
+ Dart_CObject::Type type =
+ static_cast<Dart_CObject::Type>(object->type & kDartCObjectTypeMask);
+ ASSERT(type == Dart_CObject::kArray);
+
+ // Write out the serialization header value for this object.
+ intptr_t object_id = GetMarkedCObjectMark(object);
+ WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds + object_id);
+ // Write out the class and tags information.
+ WriteObjectHeader(ObjectStore::kArrayClass, 0);
+ WriteSmi(object->value.as_array.length);
+ // Write out the type arguments.
+ WriteIndexedObject(Object::kNullObject);
+ // Write out array elements.
+ for (int i = 0; i < object->value.as_array.length; i++) {
+ WriteCObjectRef(object->value.as_array.values[i]);
+ }
+}
+
+
+void ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object,
+ Dart_CObject::Type type) {
+ switch (type) {
case Dart_CObject::kNull:
WriteIndexedObject(Object::kNullObject);
break;
@@ -530,20 +698,6 @@
}
break;
}
- case Dart_CObject::kArray: {
- // Write out the serialization header value for this object.
- WriteInlinedHeader(object);
- // Write out the class and tags information.
- WriteObjectHeader(ObjectStore::kArrayClass, 0);
- WriteSmi(object->value.as_array.length);
- // Write out the type arguments.
- WriteIndexedObject(Object::kNullObject);
- // Write out array elements.
- for (int i = 0; i < object->value.as_array.length; i++) {
- WriteCObject(object->value.as_array.values[i]);
- }
- break;
- }
case Dart_CObject::kUint8Array: {
// Write out the serialization header value for this object.
WriteInlinedHeader(object);
@@ -565,6 +719,11 @@
void ApiMessageWriter::WriteCMessage(Dart_CObject* object) {
WriteCObject(object);
+ // Write out all objects that were added to the forward list and have
+ // not been serialized yet. These would typically be fields of arrays.
Søren Gjesse 2012/06/08 08:12:12 Maybe extend comment here to mention that the forw
siva 2012/06/11 20:49:06 Done.
+ for (intptr_t i = 0; i < forward_id_; i++) {
+ WriteForwardedCObject(forward_list_[i]);
+ }
UnmarkAllCObjects(object);
FinalizeBuffer();
}

Powered by Google App Engine
This is Rietveld 408576698