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/object.h" | 5 #include "vm/object.h" |
6 #include "vm/object_store.h" | 6 #include "vm/object_store.h" |
7 #include "vm/snapshot.h" | 7 #include "vm/snapshot.h" |
8 #include "vm/stub_code.h" | 8 #include "vm/stub_code.h" |
9 #include "vm/symbols.h" | 9 #include "vm/symbols.h" |
10 #include "vm/visitor.h" | 10 #include "vm/visitor.h" |
(...skipping 2186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2197 | 2197 |
2198 // Write out the used length field. | 2198 // Write out the used length field. |
2199 writer->Write<RawObject*>(ptr()->length_); | 2199 writer->Write<RawObject*>(ptr()->length_); |
2200 | 2200 |
2201 // Write out the Array object. | 2201 // Write out the Array object. |
2202 writer->WriteObjectImpl(ptr()->data_); | 2202 writer->WriteObjectImpl(ptr()->data_); |
2203 } | 2203 } |
2204 | 2204 |
2205 | 2205 |
2206 RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader, | 2206 RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader, |
2207 intptr_t object_id, | 2207 intptr_t object_id, |
2208 intptr_t tags, | 2208 intptr_t tags, |
2209 Snapshot::Kind kind) { | 2209 Snapshot::Kind kind) { |
2210 ASSERT(reader != NULL); | 2210 ASSERT(reader != NULL); |
2211 | 2211 |
2212 LinkedHashMap& map = LinkedHashMap::ZoneHandle( | 2212 LinkedHashMap& map = LinkedHashMap::ZoneHandle( |
2213 reader->zone(), LinkedHashMap::null()); | 2213 reader->zone(), LinkedHashMap::null()); |
2214 if (kind == Snapshot::kFull || kind == Snapshot::kScript) { | 2214 if (kind == Snapshot::kFull || kind == Snapshot::kScript) { |
2215 // The immutable maps that seed map literals are not yet VM-internal, so | 2215 // The immutable maps that seed map literals are not yet VM-internal, so |
2216 // we don't reach this. | 2216 // we don't reach this. |
2217 UNREACHABLE(); | 2217 UNREACHABLE(); |
2218 } else { | 2218 } else { |
2219 // Since the map might contain itself as a key or value, allocate first. | 2219 // Since the map might contain itself as a key or value, allocate first. |
2220 map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind)); | 2220 map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind)); |
2221 } | 2221 } |
2222 reader->AddBackRef(object_id, &map, kIsDeserialized); | 2222 reader->AddBackRef(object_id, &map, kIsDeserialized); |
2223 // Set the object tags. | 2223 // Set the object tags. |
2224 map.set_tags(tags); | 2224 map.set_tags(tags); |
2225 // Read and set the fields. | 2225 |
2226 intptr_t num_flds = (map.raw()->to() - map.raw()->from()); | 2226 // Read the type arguments. |
2227 for (intptr_t i = 0; i <= num_flds; i++) { | 2227 *reader->TypeArgumentsHandle() ^= reader->ReadObjectImpl(); |
2228 (*reader->PassiveObjectHandle()) = reader->ReadObjectRef(); | 2228 map.SetTypeArguments(*reader->TypeArgumentsHandle()); |
2229 map.StorePointer((map.raw()->from() + i), | 2229 |
2230 reader->PassiveObjectHandle()->raw()); | 2230 // Read the number of key/value pairs. |
| 2231 intptr_t len = reader->ReadSmiValue(); |
| 2232 intptr_t used_data = (len << 1); |
| 2233 map.SetUsedData(used_data); |
| 2234 |
| 2235 // Allocate the data array. |
| 2236 intptr_t data_size = Utils::Maximum( |
| 2237 Utils::RoundUpToPowerOfTwo(used_data), |
| 2238 static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize)); |
| 2239 Array& data = Array::ZoneHandle(reader->zone(), |
| 2240 Array::New(data_size, HEAP_SPACE(kind))); |
| 2241 map.SetData(data); |
| 2242 map.SetDeletedKeys(0); |
| 2243 |
| 2244 // The index and hashMask is regenerated by the maps themselves on demand. |
| 2245 // Thus, the index will probably be allocated in new space (unless it's huge). |
| 2246 // TODO(koda): Eagerly rehash here when no keys have user-defined '==', and |
| 2247 // in particular, if/when (const) maps are needed in the VM isolate snapshot. |
| 2248 ASSERT(reader->isolate() != Dart::vm_isolate()); |
| 2249 map.SetHashMask(0); // Prefer sentinel 0 over null for better type feedback. |
| 2250 |
| 2251 // Read the keys and values. |
| 2252 bool is_canonical = RawObject::IsCanonical(tags); |
| 2253 for (intptr_t i = 0; i < used_data; i++) { |
| 2254 *reader->PassiveObjectHandle() = |
| 2255 is_canonical ? reader->ReadObjectImpl() : reader->ReadObjectRef(); |
| 2256 data.SetAt(i, *reader->PassiveObjectHandle()); |
2231 } | 2257 } |
2232 return map.raw(); | 2258 return map.raw(); |
2233 } | 2259 } |
2234 | 2260 |
2235 | 2261 |
2236 void RawLinkedHashMap::WriteTo(SnapshotWriter* writer, | 2262 void RawLinkedHashMap::WriteTo(SnapshotWriter* writer, |
2237 intptr_t object_id, | 2263 intptr_t object_id, |
2238 Snapshot::Kind kind) { | 2264 Snapshot::Kind kind) { |
2239 if (kind == Snapshot::kFull || kind == Snapshot::kScript) { | 2265 if (kind == Snapshot::kFull || kind == Snapshot::kScript) { |
2240 // The immutable maps that seed map literals are not yet VM-internal, so | 2266 // The immutable maps that seed map literals are not yet VM-internal, so |
2241 // we don't reach this. | 2267 // we don't reach this. |
2242 UNREACHABLE(); | 2268 UNREACHABLE(); |
2243 } | 2269 } |
2244 ASSERT(writer != NULL); | 2270 ASSERT(writer != NULL); |
2245 | 2271 |
2246 // Write out the serialization header value for this object. | 2272 // Write out the serialization header value for this object. |
2247 writer->WriteInlinedObjectHeader(object_id); | 2273 writer->WriteInlinedObjectHeader(object_id); |
2248 | 2274 |
2249 // Write out the class and tags information. | 2275 // Write out the class and tags information. |
2250 writer->WriteIndexedObject(kLinkedHashMapCid); | 2276 writer->WriteIndexedObject(kLinkedHashMapCid); |
2251 writer->WriteTags(writer->GetObjectTags(this)); | 2277 const uword tags = writer->GetObjectTags(this); |
| 2278 writer->WriteTags(tags); |
2252 | 2279 |
2253 // Write out all the object pointer fields. | 2280 // Write out the type arguments. |
2254 // TODO(koda): Serialize only used parts of data_ (after compaction), to | 2281 writer->WriteObjectImpl(ptr()->type_arguments_); |
2255 // reduce space and support per-isolate salted hash codes. All allowed keys | 2282 |
2256 // have types for which we can rehash without running Dart code. | 2283 const intptr_t used_data = Smi::Value(ptr()->used_data_); |
2257 SnapshotWriterVisitor visitor(writer); | 2284 ASSERT((used_data & 1) == 0); // Keys + values, so must be even. |
2258 visitor.VisitPointers(from(), to()); | 2285 const intptr_t deleted_keys = Smi::Value(ptr()->deleted_keys_); |
| 2286 |
| 2287 // Write out the number of (not deleted) key/value pairs that will follow. |
| 2288 writer->Write<RawObject*>(Smi::New((used_data >> 1) - deleted_keys)); |
| 2289 |
| 2290 // Write out the keys and values. |
| 2291 const bool is_canonical = RawObject::IsCanonical(tags); |
| 2292 RawArray* data_array = ptr()->data_; |
| 2293 RawObject** data_elements = data_array->ptr()->data(); |
| 2294 ASSERT(used_data <= Smi::Value(data_array->ptr()->length_)); |
| 2295 #if defined(DEBUG) |
| 2296 intptr_t deleted_keys_found = 0; |
| 2297 #endif // DEBUG |
| 2298 for (intptr_t i = 0; i < used_data; i += 2) { |
| 2299 RawObject* key = data_elements[i]; |
| 2300 if (key == data_array) { |
| 2301 #if defined(DEBUG) |
| 2302 ++deleted_keys_found; |
| 2303 #endif // DEBUG |
| 2304 continue; |
| 2305 } |
| 2306 RawObject* value = data_elements[i + 1]; |
| 2307 if (is_canonical) { |
| 2308 writer->WriteObjectImpl(key); |
| 2309 writer->WriteObjectImpl(value); |
| 2310 } else { |
| 2311 writer->WriteObjectRef(key); |
| 2312 writer->WriteObjectRef(value); |
| 2313 } |
| 2314 } |
| 2315 DEBUG_ASSERT(deleted_keys_found == deleted_keys); |
2259 } | 2316 } |
2260 | 2317 |
2261 | 2318 |
2262 RawFloat32x4* Float32x4::ReadFrom(SnapshotReader* reader, | 2319 RawFloat32x4* Float32x4::ReadFrom(SnapshotReader* reader, |
2263 intptr_t object_id, | 2320 intptr_t object_id, |
2264 intptr_t tags, | 2321 intptr_t tags, |
2265 Snapshot::Kind kind) { | 2322 Snapshot::Kind kind) { |
2266 ASSERT(reader != NULL); | 2323 ASSERT(reader != NULL); |
2267 // Read the values. | 2324 // Read the values. |
2268 float value0 = reader->Read<float>(); | 2325 float value0 = reader->Read<float>(); |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2884 // We do not allow objects with native fields in an isolate message. | 2941 // We do not allow objects with native fields in an isolate message. |
2885 writer->SetWriteException(Exceptions::kArgument, | 2942 writer->SetWriteException(Exceptions::kArgument, |
2886 "Illegal argument in isolate message" | 2943 "Illegal argument in isolate message" |
2887 " : (object is a UserTag)"); | 2944 " : (object is a UserTag)"); |
2888 } else { | 2945 } else { |
2889 UNREACHABLE(); | 2946 UNREACHABLE(); |
2890 } | 2947 } |
2891 } | 2948 } |
2892 | 2949 |
2893 } // namespace dart | 2950 } // namespace dart |
OLD | NEW |