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

Unified Diff: runtime/vm/snapshot.cc

Issue 9235063: Implementation of message reader for converting a message snapshot into a C structure (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 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: runtime/vm/snapshot.cc
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 8cb504591ee37fe0acab86dcdcf4f1efd995302f..edd9e7ba9a41ed4f9f1718b9047117081bf6c460 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -55,8 +55,20 @@ const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) {
}
+RawSmi* BaseReader::ReadAsSmi() {
+ intptr_t value = ReadIntptrValue();
+ ASSERT((value & kSmiTagMask) == 0);
+ return reinterpret_cast<RawSmi*>(value);
+}
+
+
+intptr_t BaseReader::ReadSmiValue() {
+ return Smi::Value(ReadAsSmi());
+}
+
+
SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate)
- : stream_(snapshot->content(), snapshot->length()),
+ : BaseReader(snapshot->content(), snapshot->length()),
kind_(snapshot->kind()),
isolate_(isolate),
cls_(Class::Handle()),
@@ -425,6 +437,176 @@ RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) {
}
+MessageReader::MessageReader(const uint8_t* buffer, intptr_t length)
+ : BaseReader(buffer, length) {
+}
+
+
+intptr_t MessageReader::LookupInternalClass(intptr_t class_header) {
+ SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header);
+ ASSERT(header_type == kObjectId);
+ intptr_t header_value = SerializedHeaderData::decode(class_header);
+ return header_value;
+}
+
+
+Dart_Value* MessageReader::AllocateDartValue(Dart_Value::Type type) {
+ Dart_Value* value = reinterpret_cast<Dart_Value*>(malloc(sizeof(Dart_Value)));
siva 2012/01/27 01:56:52 Instead of using regular malloc should we accept a
Søren Gjesse 2012/01/27 14:40:03 Done.
+ memset(value, 0, sizeof(*value));
siva 2012/01/27 01:56:52 Is this init needed as we are about to deserialize
Søren Gjesse 2012/01/27 14:40:03 Not really - removed.
+ value->type = type;
+ return value;
+}
+
+
+Dart_Value* MessageReader::AllocateDartValueNull() {
+ return AllocateDartValue(Dart_Value::kNull);
+}
+
+
+Dart_Value* MessageReader::AllocateDartValueBool(bool val) {
+ Dart_Value* value = AllocateDartValue(Dart_Value::kBool);
+ value->data.bl = val;
+ return value;
+}
+
+
+Dart_Value* MessageReader::AllocateDartValueInt32(int32_t val) {
+ Dart_Value* value = AllocateDartValue(Dart_Value::kInt32);
+ value->data.int32 = val;
+ return value;
+}
+
+
+Dart_Value* MessageReader::AllocateDartValueDouble(double val) {
+ Dart_Value* value = AllocateDartValue(Dart_Value::kDouble);
+ value->data.dbl = val;
+ return value;
+}
+
+
+Dart_Value* MessageReader::AllocateDartValueString(intptr_t length) {
+ Dart_Value* value =
+ reinterpret_cast<Dart_Value*>(malloc(sizeof(Dart_Value) + length + 1));
+ memset(value, 0, sizeof(*value));
+ reinterpret_cast<char*>(value)[sizeof(*value)] = '\0';
+ value->data.str = reinterpret_cast<char*>(value) + sizeof(*value);
+ value->type = Dart_Value::kString;
+ return value;
+}
+
+
+Dart_Value* MessageReader::AllocateDartValueArray(intptr_t length) {
+ // Allocate a Dart_Value structure followed by an array of pointers
+ // to Dart_Value structures.
+ Dart_Value* value =
+ reinterpret_cast<Dart_Value*>(
+ malloc(sizeof(Dart_Value) + length * sizeof(value)));
+ memset(value, 0, sizeof(*value));
+ value->type = Dart_Value::kArray;
+ value->data.array.len = length;
+ value->data.array.values = reinterpret_cast<Dart_Value**>(value + 1);
siva 2012/01/27 01:56:52 If the passed in 'length' is 0 which happens if we
Søren Gjesse 2012/01/27 14:40:03 Set values to NULL for empty arrays. Added test wi
+ return value;
+}
+
+
+Dart_Value* MessageReader::ReadInlinedObject(intptr_t object_id) {
+ // Read the class header information and lookup the class.
+ intptr_t class_header = ReadIntptrValue();
+ intptr_t tags = ReadIntptrValue();
+ USE(tags);
+ intptr_t class_id;
+
+ // Reading of regular dart instances is not supported.
+ if (SerializedHeaderData::decode(class_header) == kInstanceId) {
+ return NULL;
+ }
+
+ ASSERT((class_header & kSmiTagMask) != 0);
+ class_id = LookupInternalClass(class_header);
+ switch (class_id) {
+ case ObjectStore::kArrayClass: {
+ intptr_t len = ReadSmiValue();
+ // Skip type arguments.
+ Dart_Value* type_arguments = ReadObject();
+ if (type_arguments == NULL || type_arguments->type != Dart_Value::kNull) {
+ return NULL;
siva 2012/01/27 01:56:52 This condition may not be true when you are receiv
Søren Gjesse 2012/01/27 14:40:03 I have added a test for processing objects from Da
+ }
+ Dart_Value* value = AllocateDartValueArray(len);
+ for (int i = 0; i < len; i++) {
+ value->data.array.values[i] = ReadObject();
+ }
+ return value;
+ break;
+ }
+ case ObjectStore::kDoubleClass: {
+ // Read the double value for the object.
+ return AllocateDartValueDouble(Read<double>());
+ break;
+ }
+ case ObjectStore::kOneByteStringClass: {
+ intptr_t len = ReadSmiValue();
+ intptr_t hash = ReadSmiValue();
+ USE(hash);
+ Dart_Value* value = AllocateDartValueString(len);
+ char* p = value->data.str;
+ for (intptr_t i = 0; i < len; i++) {
+ *p = Read<uint8_t>();
+ p++;
+ }
+ *p = '\0';
+ return value;
+ break;
+ }
+ case ObjectStore::kTwoByteStringClass:
+ // Two byte strings not supported.
+ return NULL;
+ break;
+ case ObjectStore::kFourByteStringClass:
+ // Four byte strings not supported.
+ return NULL;
+ break;
+ default:
+ // Everything else not supported.
+ return NULL;
+ }
+}
+
+
+Dart_Value* MessageReader::ReadIndexedObject(intptr_t object_id) {
+ if (object_id == Object::kNullObject) {
+ return AllocateDartValueNull();
+ } else if (object_id == ObjectStore::kTrueValue) {
+ return AllocateDartValueBool(true);
+ } else if (object_id == ObjectStore::kFalseValue) {
+ return AllocateDartValueBool(false);
+ }
siva 2012/01/27 01:56:52 should we have: else { UNREACHABLE(); } because
Søren Gjesse 2012/01/27 14:40:03 We should definately be able to handle back-refere
+ return NULL;
+}
+
+
+Dart_Value* MessageReader::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);
+ }
+ ASSERT(header_type == kInlined);
+ return ReadInlinedObject(header_value);
+}
+
+
+Dart_Value* MessageReader::ReadObject() {
+ int64_t value = Read<int64_t>();
+ if ((value & kSmiTagMask) == 0) {
+ Dart_Value* dart_value = AllocateDartValueInt32(value >> kSmiTagShift);
+ return dart_value;
+ }
+ ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
+ return ReadObjectImpl(value);
+}
+
+
void MessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) {
// Write out the serialization header value for this object.
WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds);

Powered by Google App Engine
This is Rietveld 408576698