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

Unified Diff: runtime/vm/raw_object_snapshot.cc

Issue 1151013005: Serialize maps without hashes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: _getIndexSize and name constant Created 5 years, 7 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 | « runtime/vm/raw_object.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/raw_object_snapshot.cc
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 27ec70df7f8bf49e65ec7b0e3f029a72bf6df90a..fcb7b0a47669edeeab5055c027d7529d6bab092d 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -2204,9 +2204,9 @@ void RawGrowableObjectArray::WriteTo(SnapshotWriter* writer,
RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind) {
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind) {
ASSERT(reader != NULL);
LinkedHashMap& map = LinkedHashMap::ZoneHandle(
@@ -2222,20 +2222,46 @@ RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader,
reader->AddBackRef(object_id, &map, kIsDeserialized);
// Set the object tags.
map.set_tags(tags);
- // Read and set the fields.
- intptr_t num_flds = (map.raw()->to() - map.raw()->from());
- for (intptr_t i = 0; i <= num_flds; i++) {
- (*reader->PassiveObjectHandle()) = reader->ReadObjectRef();
- map.StorePointer((map.raw()->from() + i),
- reader->PassiveObjectHandle()->raw());
+
+ // Read the type arguments.
+ *reader->TypeArgumentsHandle() ^= reader->ReadObjectImpl();
+ map.SetTypeArguments(*reader->TypeArgumentsHandle());
+
+ // Read the number of key/value pairs.
+ intptr_t len = reader->ReadSmiValue();
+ intptr_t used_data = (len << 1);
+ map.SetUsedData(used_data);
+
+ // Allocate the data array.
+ intptr_t data_size = Utils::Maximum(
+ Utils::RoundUpToPowerOfTwo(used_data),
+ static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
+ Array& data = Array::ZoneHandle(reader->zone(),
+ Array::New(data_size, HEAP_SPACE(kind)));
+ map.SetData(data);
+ map.SetDeletedKeys(0);
+
+ // The index and hashMask is regenerated by the maps themselves on demand.
+ // Thus, the index will probably be allocated in new space (unless it's huge).
+ // TODO(koda): Eagerly rehash here when no keys have user-defined '==', and
+ // in particular, if/when (const) maps are needed in the VM isolate snapshot.
+ ASSERT(reader->isolate() != Dart::vm_isolate());
+ map.SetHashMask(0); // Prefer sentinel 0 over null for better type feedback.
+
+ // Read the keys and values.
+ bool is_canonical = RawObject::IsCanonical(tags);
+ for (intptr_t i = 0; i < used_data; i++) {
+ *reader->PassiveObjectHandle() =
+ is_canonical ? reader->ReadObjectImpl() : reader->ReadObjectRef();
+ data.SetAt(i, *reader->PassiveObjectHandle());
}
return map.raw();
}
void RawLinkedHashMap::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind) {
+ intptr_t object_id,
+ Snapshot::Kind kind) {
if (kind == Snapshot::kFull || kind == Snapshot::kScript) {
// The immutable maps that seed map literals are not yet VM-internal, so
// we don't reach this.
@@ -2248,14 +2274,45 @@ void RawLinkedHashMap::WriteTo(SnapshotWriter* writer,
// Write out the class and tags information.
writer->WriteIndexedObject(kLinkedHashMapCid);
- writer->WriteTags(writer->GetObjectTags(this));
+ const uword tags = writer->GetObjectTags(this);
+ writer->WriteTags(tags);
- // Write out all the object pointer fields.
- // TODO(koda): Serialize only used parts of data_ (after compaction), to
- // reduce space and support per-isolate salted hash codes. All allowed keys
- // have types for which we can rehash without running Dart code.
- SnapshotWriterVisitor visitor(writer);
- visitor.VisitPointers(from(), to());
+ // Write out the type arguments.
+ writer->WriteObjectImpl(ptr()->type_arguments_);
+
+ const intptr_t used_data = Smi::Value(ptr()->used_data_);
+ ASSERT((used_data & 1) == 0); // Keys + values, so must be even.
+ const intptr_t deleted_keys = Smi::Value(ptr()->deleted_keys_);
+
+ // Write out the number of (not deleted) key/value pairs that will follow.
+ writer->Write<RawObject*>(Smi::New((used_data >> 1) - deleted_keys));
+
+ // Write out the keys and values.
+ const bool is_canonical = RawObject::IsCanonical(tags);
+ RawArray* data_array = ptr()->data_;
+ RawObject** data_elements = data_array->ptr()->data();
+ ASSERT(used_data <= Smi::Value(data_array->ptr()->length_));
+#if defined(DEBUG)
+ intptr_t deleted_keys_found = 0;
+#endif // DEBUG
+ for (intptr_t i = 0; i < used_data; i += 2) {
+ RawObject* key = data_elements[i];
+ if (key == data_array) {
+#if defined(DEBUG)
+ ++deleted_keys_found;
+#endif // DEBUG
+ continue;
+ }
+ RawObject* value = data_elements[i + 1];
+ if (is_canonical) {
+ writer->WriteObjectImpl(key);
+ writer->WriteObjectImpl(value);
+ } else {
+ writer->WriteObjectRef(key);
+ writer->WriteObjectRef(value);
+ }
+ }
+ DEBUG_ASSERT(deleted_keys_found == deleted_keys);
}
« no previous file with comments | « runtime/vm/raw_object.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698