Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/snapshot.h" | 5 #include "vm/snapshot.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
| 10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 ASSERT(kLengthIndex == length_offset()); | 48 ASSERT(kLengthIndex == length_offset()); |
| 49 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset()); | 49 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset()); |
| 50 ASSERT((kHeapObjectTag & kInlined)); | 50 ASSERT((kHeapObjectTag & kInlined)); |
| 51 ASSERT((kHeapObjectTag & kObjectId)); | 51 ASSERT((kHeapObjectTag & kObjectId)); |
| 52 ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId); | 52 ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId); |
| 53 const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory); | 53 const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory); |
| 54 return snapshot; | 54 return snapshot; |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 RawSmi* BaseReader::ReadAsSmi() { | |
| 59 intptr_t value = ReadIntptrValue(); | |
| 60 ASSERT((value & kSmiTagMask) == 0); | |
| 61 return reinterpret_cast<RawSmi*>(value); | |
| 62 } | |
| 63 | |
| 64 | |
| 65 intptr_t BaseReader::ReadSmiValue() { | |
| 66 return Smi::Value(ReadAsSmi()); | |
| 67 } | |
| 68 | |
| 69 | |
| 58 SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate) | 70 SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate) |
| 59 : stream_(snapshot->content(), snapshot->length()), | 71 : BaseReader(snapshot->content(), snapshot->length()), |
| 60 kind_(snapshot->kind()), | 72 kind_(snapshot->kind()), |
| 61 isolate_(isolate), | 73 isolate_(isolate), |
| 62 cls_(Class::Handle()), | 74 cls_(Class::Handle()), |
| 63 obj_(Object::Handle()), | 75 obj_(Object::Handle()), |
| 64 str_(String::Handle()), | 76 str_(String::Handle()), |
| 65 library_(Library::Handle()), | 77 library_(Library::Handle()), |
| 66 type_(AbstractType::Handle()), | 78 type_(AbstractType::Handle()), |
| 67 type_arguments_(AbstractTypeArguments::Handle()), | 79 type_arguments_(AbstractTypeArguments::Handle()), |
| 68 backward_references_((snapshot->kind() == Snapshot::kFull) ? | 80 backward_references_((snapshot->kind() == Snapshot::kFull) ? |
| 69 kNumInitialReferencesInFullSnapshot : | 81 kNumInitialReferencesInFullSnapshot : |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 418 #undef SNAPSHOT_READ | 430 #undef SNAPSHOT_READ |
| 419 default: UNREACHABLE(); break; | 431 default: UNREACHABLE(); break; |
| 420 } | 432 } |
| 421 if (kind_ == Snapshot::kFull) { | 433 if (kind_ == Snapshot::kFull) { |
| 422 obj_.SetCreatedFromSnapshot(); | 434 obj_.SetCreatedFromSnapshot(); |
| 423 } | 435 } |
| 424 return obj_.raw(); | 436 return obj_.raw(); |
| 425 } | 437 } |
| 426 | 438 |
| 427 | 439 |
| 440 MessageReader::MessageReader(const uint8_t* buffer, intptr_t length) | |
| 441 : BaseReader(buffer, length) { | |
| 442 } | |
| 443 | |
| 444 | |
| 445 intptr_t MessageReader::LookupInternalClass(intptr_t class_header) { | |
| 446 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); | |
| 447 ASSERT(header_type == kObjectId); | |
| 448 intptr_t header_value = SerializedHeaderData::decode(class_header); | |
| 449 return header_value; | |
| 450 } | |
| 451 | |
| 452 | |
| 453 Dart_Value* MessageReader::AllocateDartValue(Dart_Value::Type type) { | |
| 454 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.
| |
| 455 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.
| |
| 456 value->type = type; | |
| 457 return value; | |
| 458 } | |
| 459 | |
| 460 | |
| 461 Dart_Value* MessageReader::AllocateDartValueNull() { | |
| 462 return AllocateDartValue(Dart_Value::kNull); | |
| 463 } | |
| 464 | |
| 465 | |
| 466 Dart_Value* MessageReader::AllocateDartValueBool(bool val) { | |
| 467 Dart_Value* value = AllocateDartValue(Dart_Value::kBool); | |
| 468 value->data.bl = val; | |
| 469 return value; | |
| 470 } | |
| 471 | |
| 472 | |
| 473 Dart_Value* MessageReader::AllocateDartValueInt32(int32_t val) { | |
| 474 Dart_Value* value = AllocateDartValue(Dart_Value::kInt32); | |
| 475 value->data.int32 = val; | |
| 476 return value; | |
| 477 } | |
| 478 | |
| 479 | |
| 480 Dart_Value* MessageReader::AllocateDartValueDouble(double val) { | |
| 481 Dart_Value* value = AllocateDartValue(Dart_Value::kDouble); | |
| 482 value->data.dbl = val; | |
| 483 return value; | |
| 484 } | |
| 485 | |
| 486 | |
| 487 Dart_Value* MessageReader::AllocateDartValueString(intptr_t length) { | |
| 488 Dart_Value* value = | |
| 489 reinterpret_cast<Dart_Value*>(malloc(sizeof(Dart_Value) + length + 1)); | |
| 490 memset(value, 0, sizeof(*value)); | |
| 491 reinterpret_cast<char*>(value)[sizeof(*value)] = '\0'; | |
| 492 value->data.str = reinterpret_cast<char*>(value) + sizeof(*value); | |
| 493 value->type = Dart_Value::kString; | |
| 494 return value; | |
| 495 } | |
| 496 | |
| 497 | |
| 498 Dart_Value* MessageReader::AllocateDartValueArray(intptr_t length) { | |
| 499 // Allocate a Dart_Value structure followed by an array of pointers | |
| 500 // to Dart_Value structures. | |
| 501 Dart_Value* value = | |
| 502 reinterpret_cast<Dart_Value*>( | |
| 503 malloc(sizeof(Dart_Value) + length * sizeof(value))); | |
| 504 memset(value, 0, sizeof(*value)); | |
| 505 value->type = Dart_Value::kArray; | |
| 506 value->data.array.len = length; | |
| 507 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
| |
| 508 return value; | |
| 509 } | |
| 510 | |
| 511 | |
| 512 Dart_Value* MessageReader::ReadInlinedObject(intptr_t object_id) { | |
| 513 // Read the class header information and lookup the class. | |
| 514 intptr_t class_header = ReadIntptrValue(); | |
| 515 intptr_t tags = ReadIntptrValue(); | |
| 516 USE(tags); | |
| 517 intptr_t class_id; | |
| 518 | |
| 519 // Reading of regular dart instances is not supported. | |
| 520 if (SerializedHeaderData::decode(class_header) == kInstanceId) { | |
| 521 return NULL; | |
| 522 } | |
| 523 | |
| 524 ASSERT((class_header & kSmiTagMask) != 0); | |
| 525 class_id = LookupInternalClass(class_header); | |
| 526 switch (class_id) { | |
| 527 case ObjectStore::kArrayClass: { | |
| 528 intptr_t len = ReadSmiValue(); | |
| 529 // Skip type arguments. | |
| 530 Dart_Value* type_arguments = ReadObject(); | |
| 531 if (type_arguments == NULL || type_arguments->type != Dart_Value::kNull) { | |
| 532 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
| |
| 533 } | |
| 534 Dart_Value* value = AllocateDartValueArray(len); | |
| 535 for (int i = 0; i < len; i++) { | |
| 536 value->data.array.values[i] = ReadObject(); | |
| 537 } | |
| 538 return value; | |
| 539 break; | |
| 540 } | |
| 541 case ObjectStore::kDoubleClass: { | |
| 542 // Read the double value for the object. | |
| 543 return AllocateDartValueDouble(Read<double>()); | |
| 544 break; | |
| 545 } | |
| 546 case ObjectStore::kOneByteStringClass: { | |
| 547 intptr_t len = ReadSmiValue(); | |
| 548 intptr_t hash = ReadSmiValue(); | |
| 549 USE(hash); | |
| 550 Dart_Value* value = AllocateDartValueString(len); | |
| 551 char* p = value->data.str; | |
| 552 for (intptr_t i = 0; i < len; i++) { | |
| 553 *p = Read<uint8_t>(); | |
| 554 p++; | |
| 555 } | |
| 556 *p = '\0'; | |
| 557 return value; | |
| 558 break; | |
| 559 } | |
| 560 case ObjectStore::kTwoByteStringClass: | |
| 561 // Two byte strings not supported. | |
| 562 return NULL; | |
| 563 break; | |
| 564 case ObjectStore::kFourByteStringClass: | |
| 565 // Four byte strings not supported. | |
| 566 return NULL; | |
| 567 break; | |
| 568 default: | |
| 569 // Everything else not supported. | |
| 570 return NULL; | |
| 571 } | |
| 572 } | |
| 573 | |
| 574 | |
| 575 Dart_Value* MessageReader::ReadIndexedObject(intptr_t object_id) { | |
| 576 if (object_id == Object::kNullObject) { | |
| 577 return AllocateDartValueNull(); | |
| 578 } else if (object_id == ObjectStore::kTrueValue) { | |
| 579 return AllocateDartValueBool(true); | |
| 580 } else if (object_id == ObjectStore::kFalseValue) { | |
| 581 return AllocateDartValueBool(false); | |
| 582 } | |
|
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
| |
| 583 return NULL; | |
| 584 } | |
| 585 | |
| 586 | |
| 587 Dart_Value* MessageReader::ReadObjectImpl(intptr_t header) { | |
| 588 SerializedHeaderType header_type = SerializedHeaderTag::decode(header); | |
| 589 intptr_t header_value = SerializedHeaderData::decode(header); | |
| 590 | |
| 591 if (header_type == kObjectId) { | |
| 592 return ReadIndexedObject(header_value); | |
| 593 } | |
| 594 ASSERT(header_type == kInlined); | |
| 595 return ReadInlinedObject(header_value); | |
| 596 } | |
| 597 | |
| 598 | |
| 599 Dart_Value* MessageReader::ReadObject() { | |
| 600 int64_t value = Read<int64_t>(); | |
| 601 if ((value & kSmiTagMask) == 0) { | |
| 602 Dart_Value* dart_value = AllocateDartValueInt32(value >> kSmiTagShift); | |
| 603 return dart_value; | |
| 604 } | |
| 605 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | |
| 606 return ReadObjectImpl(value); | |
| 607 } | |
| 608 | |
| 609 | |
| 428 void MessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) { | 610 void MessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) { |
| 429 // Write out the serialization header value for this object. | 611 // Write out the serialization header value for this object. |
| 430 WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds); | 612 WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds); |
| 431 | 613 |
| 432 // Write out the class and tags information. | 614 // Write out the class and tags information. |
| 433 WriteObjectHeader(ObjectStore::kArrayClass, 0); | 615 WriteObjectHeader(ObjectStore::kArrayClass, 0); |
| 434 | 616 |
| 435 // Write out the length field. | 617 // Write out the length field. |
| 436 Write<RawObject*>(Smi::New(field_count)); | 618 Write<RawObject*>(Smi::New(field_count)); |
| 437 | 619 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 650 | 832 |
| 651 | 833 |
| 652 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 834 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 653 for (RawObject** current = first; current <= last; current++) { | 835 for (RawObject** current = first; current <= last; current++) { |
| 654 RawObject* raw_obj = *current; | 836 RawObject* raw_obj = *current; |
| 655 writer_->WriteObject(raw_obj); | 837 writer_->WriteObject(raw_obj); |
| 656 } | 838 } |
| 657 } | 839 } |
| 658 | 840 |
| 659 } // namespace dart | 841 } // namespace dart |
| OLD | NEW |