Chromium Code Reviews| 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); |