OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
474 | 474 |
475 | 475 |
476 ExternalReferenceDecoder::~ExternalReferenceDecoder() { | 476 ExternalReferenceDecoder::~ExternalReferenceDecoder() { |
477 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { | 477 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { |
478 DeleteArray(encodings_[type]); | 478 DeleteArray(encodings_[type]); |
479 } | 479 } |
480 DeleteArray(encodings_); | 480 DeleteArray(encodings_); |
481 } | 481 } |
482 | 482 |
483 | 483 |
484 RootIndexMap::RootIndexMap(Isolate* isolate) { | |
485 map_ = new HashMap(HashMap::PointersMatch); | |
486 Object** root_array = isolate->heap()->roots_array_start(); | |
487 for (int i = 0; i < Heap::kStrongRootListLength; i++) { | |
488 Object* root = root_array[i]; | |
489 if (root->IsHeapObject() && !isolate->heap()->InNewSpace(root)) { | |
490 HeapObject* heap_object = HeapObject::cast(root); | |
491 if (LookupEntry(map_, heap_object, false) != NULL) { | |
492 // Some root values are initialized to the empty FixedArray(); | |
493 // Do not add them to the map. | |
494 DCHECK_EQ(isolate->heap()->empty_fixed_array(), heap_object); | |
495 } else { | |
496 SetValue(LookupEntry(map_, heap_object, true), i); | |
497 } | |
498 } | |
499 } | |
500 } | |
501 | |
502 | |
484 class CodeAddressMap: public CodeEventLogger { | 503 class CodeAddressMap: public CodeEventLogger { |
485 public: | 504 public: |
486 explicit CodeAddressMap(Isolate* isolate) | 505 explicit CodeAddressMap(Isolate* isolate) |
487 : isolate_(isolate) { | 506 : isolate_(isolate) { |
488 isolate->logger()->addCodeEventListener(this); | 507 isolate->logger()->addCodeEventListener(this); |
489 } | 508 } |
490 | 509 |
491 virtual ~CodeAddressMap() { | 510 virtual ~CodeAddressMap() { |
492 isolate_->logger()->removeCodeEventListener(this); | 511 isolate_->logger()->removeCodeEventListener(this); |
493 } | 512 } |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1230 } | 1249 } |
1231 } | 1250 } |
1232 DCHECK_EQ(limit, current); | 1251 DCHECK_EQ(limit, current); |
1233 } | 1252 } |
1234 | 1253 |
1235 | 1254 |
1236 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) | 1255 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
1237 : isolate_(isolate), | 1256 : isolate_(isolate), |
1238 sink_(sink), | 1257 sink_(sink), |
1239 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), | 1258 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), |
1240 root_index_wave_front_(0), | 1259 root_index_map_(isolate), |
1241 code_address_map_(NULL), | 1260 code_address_map_(NULL), |
1242 seen_large_objects_index_(0) { | 1261 seen_large_objects_index_(0) { |
1243 // The serializer is meant to be used only to generate initial heap images | 1262 // The serializer is meant to be used only to generate initial heap images |
1244 // from a context in which there is only one isolate. | 1263 // from a context in which there is only one isolate. |
1245 for (int i = 0; i < kNumberOfSpaces; i++) pending_chunk_[i] = 0; | 1264 for (int i = 0; i < kNumberOfSpaces; i++) pending_chunk_[i] = 0; |
1246 } | 1265 } |
1247 | 1266 |
1248 | 1267 |
1249 Serializer::~Serializer() { | 1268 Serializer::~Serializer() { |
1250 delete external_reference_encoder_; | 1269 delete external_reference_encoder_; |
1251 if (code_address_map_ != NULL) delete code_address_map_; | 1270 if (code_address_map_ != NULL) delete code_address_map_; |
1252 } | 1271 } |
1253 | 1272 |
1254 | 1273 |
1255 void StartupSerializer::SerializeStrongReferences() { | 1274 void StartupSerializer::SerializeStrongReferences() { |
1256 Isolate* isolate = this->isolate(); | 1275 Isolate* isolate = this->isolate(); |
1257 // No active threads. | 1276 // No active threads. |
1258 CHECK_EQ(NULL, isolate->thread_manager()->FirstThreadStateInUse()); | 1277 CHECK_EQ(NULL, isolate->thread_manager()->FirstThreadStateInUse()); |
1259 // No active or weak handles. | 1278 // No active or weak handles. |
1260 CHECK(isolate->handle_scope_implementer()->blocks()->is_empty()); | 1279 CHECK(isolate->handle_scope_implementer()->blocks()->is_empty()); |
1261 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); | 1280 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); |
1262 CHECK_EQ(0, isolate->eternal_handles()->NumberOfHandles()); | 1281 CHECK_EQ(0, isolate->eternal_handles()->NumberOfHandles()); |
1263 // We don't support serializing installed extensions. | 1282 // We don't support serializing installed extensions. |
1264 CHECK(!isolate->has_installed_extensions()); | 1283 CHECK(!isolate->has_installed_extensions()); |
1265 isolate->heap()->IterateSmiRoots(this); | 1284 isolate->heap()->IterateSmiRoots(this); |
1266 isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 1285 isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
1267 } | 1286 } |
1268 | 1287 |
1269 | 1288 |
1289 void StartupSerializer::VisitPointers(Object** start, Object** end) { | |
1290 for (Object** current = start; current < end; current++) { | |
1291 if (start == isolate()->heap()->roots_array_start()) { | |
1292 root_index_wave_front_ = | |
1293 Max(root_index_wave_front_, static_cast<intptr_t>(current - start)); | |
1294 } | |
1295 if (ShouldBeSkipped(current)) { | |
1296 sink_->Put(kSkip, "Skip"); | |
1297 sink_->PutInt(kPointerSize, "SkipOneWord"); | |
1298 } else if ((*current)->IsSmi()) { | |
1299 sink_->Put(kRawData + 1, "Smi"); | |
1300 for (int i = 0; i < kPointerSize; i++) { | |
1301 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); | |
1302 } | |
1303 } else { | |
1304 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); | |
1305 } | |
1306 } | |
1307 } | |
1308 | |
1309 | |
1270 void PartialSerializer::Serialize(Object** object) { | 1310 void PartialSerializer::Serialize(Object** object) { |
1271 this->VisitPointer(object); | 1311 this->VisitPointer(object); |
1272 Pad(); | 1312 Pad(); |
1273 } | 1313 } |
1274 | 1314 |
1275 | 1315 |
1276 bool Serializer::ShouldBeSkipped(Object** current) { | 1316 bool Serializer::ShouldBeSkipped(Object** current) { |
1277 Object** roots = isolate()->heap()->roots_array_start(); | 1317 Object** roots = isolate()->heap()->roots_array_start(); |
1278 return current == &roots[Heap::kStoreBufferTopRootIndex] | 1318 return current == &roots[Heap::kStoreBufferTopRootIndex] |
1279 || current == &roots[Heap::kStackLimitRootIndex] | 1319 || current == &roots[Heap::kStackLimitRootIndex] |
1280 || current == &roots[Heap::kRealStackLimitRootIndex]; | 1320 || current == &roots[Heap::kRealStackLimitRootIndex]; |
1281 } | 1321 } |
1282 | 1322 |
1283 | 1323 |
1284 void Serializer::VisitPointers(Object** start, Object** end) { | 1324 void Serializer::VisitPointers(Object** start, Object** end) { |
1285 Isolate* isolate = this->isolate();; | |
1286 | |
1287 for (Object** current = start; current < end; current++) { | 1325 for (Object** current = start; current < end; current++) { |
1288 if (start == isolate->heap()->roots_array_start()) { | 1326 if ((*current)->IsSmi()) { |
1289 root_index_wave_front_ = | |
1290 Max(root_index_wave_front_, static_cast<intptr_t>(current - start)); | |
1291 } | |
1292 if (ShouldBeSkipped(current)) { | |
1293 sink_->Put(kSkip, "Skip"); | |
1294 sink_->PutInt(kPointerSize, "SkipOneWord"); | |
1295 } else if ((*current)->IsSmi()) { | |
1296 sink_->Put(kRawData + 1, "Smi"); | 1327 sink_->Put(kRawData + 1, "Smi"); |
1297 for (int i = 0; i < kPointerSize; i++) { | 1328 for (int i = 0; i < kPointerSize; i++) { |
1298 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); | 1329 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); |
1299 } | 1330 } |
1300 } else { | 1331 } else { |
1301 SerializeObject(*current, kPlain, kStartOfObject, 0); | 1332 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); |
1302 } | 1333 } |
1303 } | 1334 } |
1304 } | 1335 } |
1305 | 1336 |
1306 | 1337 |
1307 void Serializer::FinalizeAllocation() { | 1338 void Serializer::FinalizeAllocation() { |
1308 DCHECK_EQ(0, completed_chunks_[LO_SPACE].length()); // Not yet finalized. | 1339 DCHECK_EQ(0, completed_chunks_[LO_SPACE].length()); // Not yet finalized. |
1309 for (int i = 0; i < kNumberOfSpaces; i++) { | 1340 for (int i = 0; i < kNumberOfSpaces; i++) { |
1310 // Complete the last pending chunk and if there are no completed chunks, | 1341 // Complete the last pending chunk and if there are no completed chunks, |
1311 // make sure there is at least one empty chunk. | 1342 // make sure there is at least one empty chunk. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1361 int length = isolate->serialize_partial_snapshot_cache_length(); | 1392 int length = isolate->serialize_partial_snapshot_cache_length(); |
1362 isolate->PushToPartialSnapshotCache(heap_object); | 1393 isolate->PushToPartialSnapshotCache(heap_object); |
1363 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); | 1394 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); |
1364 // We don't recurse from the startup snapshot generator into the partial | 1395 // We don't recurse from the startup snapshot generator into the partial |
1365 // snapshot generator. | 1396 // snapshot generator. |
1366 DCHECK(length == isolate->serialize_partial_snapshot_cache_length() - 1); | 1397 DCHECK(length == isolate->serialize_partial_snapshot_cache_length() - 1); |
1367 return length; | 1398 return length; |
1368 } | 1399 } |
1369 | 1400 |
1370 | 1401 |
1371 int Serializer::RootIndex(HeapObject* heap_object, HowToCode from) { | |
1372 Heap* heap = isolate()->heap(); | |
1373 if (heap->InNewSpace(heap_object)) return kInvalidRootIndex; | |
1374 for (int i = 0; i < root_index_wave_front_; i++) { | |
1375 Object* root = heap->roots_array_start()[i]; | |
1376 if (!root->IsSmi() && root == heap_object) { | |
1377 return i; | |
1378 } | |
1379 } | |
1380 return kInvalidRootIndex; | |
1381 } | |
1382 | |
1383 | |
1384 // Encode the location of an already deserialized object in order to write its | 1402 // Encode the location of an already deserialized object in order to write its |
1385 // location into a later object. We can encode the location as an offset from | 1403 // location into a later object. We can encode the location as an offset from |
1386 // the start of the deserialized objects or as an offset backwards from the | 1404 // the start of the deserialized objects or as an offset backwards from the |
1387 // current allocation pointer. | 1405 // current allocation pointer. |
1388 void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, | 1406 void Serializer::SerializeBackReference(BackReference back_reference, |
1389 HowToCode how_to_code, | 1407 HowToCode how_to_code, |
1390 WhereToPoint where_to_point, | 1408 WhereToPoint where_to_point, int skip) { |
1391 int skip) { | 1409 AllocationSpace space = back_reference.space(); |
1392 int space = SpaceOfObject(heap_object); | |
1393 | |
1394 if (skip == 0) { | 1410 if (skip == 0) { |
1395 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); | 1411 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); |
1396 } else { | 1412 } else { |
1397 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, | 1413 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, |
1398 "BackRefSerWithSkip"); | 1414 "BackRefSerWithSkip"); |
1399 sink_->PutInt(skip, "BackRefSkipDistance"); | 1415 sink_->PutInt(skip, "BackRefSkipDistance"); |
1400 } | 1416 } |
1401 | 1417 |
1402 if (space == LO_SPACE) { | 1418 sink_->PutInt(back_reference.reference(), |
1403 int index = address_mapper_.MappedTo(heap_object); | 1419 (space == LO_SPACE) ? "large object index" : "allocation"); |
1404 sink_->PutInt(index, "large object index"); | |
1405 } else { | |
1406 uint32_t existing_allocation = address_mapper_.MappedTo(heap_object); | |
1407 // Shift out the bits that are always 0. | |
1408 existing_allocation >>= kObjectAlignmentBits; | |
1409 sink_->PutInt(existing_allocation, "allocation"); | |
1410 } | |
1411 } | 1420 } |
1412 | 1421 |
1413 | 1422 |
1414 void StartupSerializer::SerializeObject( | 1423 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
1415 Object* o, | 1424 WhereToPoint where_to_point, int skip) { |
1416 HowToCode how_to_code, | 1425 DCHECK(!obj->IsJSFunction()); |
1417 WhereToPoint where_to_point, | |
1418 int skip) { | |
1419 CHECK(o->IsHeapObject()); | |
1420 HeapObject* heap_object = HeapObject::cast(o); | |
1421 DCHECK(!heap_object->IsJSFunction()); | |
1422 | 1426 |
1423 int root_index; | 1427 int root_index = root_index_map_.Lookup(obj); |
1424 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1428 // We can only encode roots as such if it has already been serialized. |
1425 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1429 // That applies to root indices below the wave front. |
1430 if (root_index != RootIndexMap::kInvalidRootIndex && | |
1431 root_index < root_index_wave_front_) { | |
1432 PutRoot(root_index, obj, how_to_code, where_to_point, skip); | |
1426 return; | 1433 return; |
1427 } | 1434 } |
1428 | 1435 |
1429 if (address_mapper_.IsMapped(heap_object)) { | 1436 BackReference back_reference = back_reference_map_.Lookup(obj); |
1430 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, | 1437 if (back_reference.is_valid()) { |
1431 skip); | 1438 SerializeBackReference(back_reference, how_to_code, where_to_point, skip); |
1432 } else { | 1439 return; |
1433 if (skip != 0) { | 1440 } |
1434 sink_->Put(kSkip, "FlushPendingSkip"); | |
1435 sink_->PutInt(skip, "SkipDistance"); | |
1436 } | |
1437 | 1441 |
1438 // Object has not yet been serialized. Serialize it here. | 1442 if (skip != 0) { |
1439 ObjectSerializer object_serializer(this, | 1443 sink_->Put(kSkip, "FlushPendingSkip"); |
1440 heap_object, | 1444 sink_->PutInt(skip, "SkipDistance"); |
1441 sink_, | |
1442 how_to_code, | |
1443 where_to_point); | |
1444 object_serializer.Serialize(); | |
1445 } | 1445 } |
1446 | |
1447 // Object has not yet been serialized. Serialize it here. | |
1448 ObjectSerializer object_serializer(this, obj, sink_, how_to_code, | |
1449 where_to_point); | |
1450 object_serializer.Serialize(); | |
1446 } | 1451 } |
1447 | 1452 |
1448 | 1453 |
1449 void StartupSerializer::SerializeWeakReferences() { | 1454 void StartupSerializer::SerializeWeakReferences() { |
1450 // This phase comes right after the partial serialization (of the snapshot). | 1455 // This phase comes right after the partial serialization (of the snapshot). |
1451 // After we have done the partial serialization the partial snapshot cache | 1456 // After we have done the partial serialization the partial snapshot cache |
1452 // will contain some references needed to decode the partial snapshot. We | 1457 // will contain some references needed to decode the partial snapshot. We |
1453 // add one entry with 'undefined' which is the sentinel that the deserializer | 1458 // add one entry with 'undefined' which is the sentinel that the deserializer |
1454 // uses to know it is done deserializing the array. | 1459 // uses to know it is done deserializing the array. |
1455 Object* undefined = isolate()->heap()->undefined_value(); | 1460 Object* undefined = isolate()->heap()->undefined_value(); |
(...skipping 24 matching lines...) Expand all Loading... | |
1480 if (skip != 0) { | 1485 if (skip != 0) { |
1481 sink_->Put(kSkip, "SkipFromPutRoot"); | 1486 sink_->Put(kSkip, "SkipFromPutRoot"); |
1482 sink_->PutInt(skip, "SkipFromPutRootDistance"); | 1487 sink_->PutInt(skip, "SkipFromPutRootDistance"); |
1483 } | 1488 } |
1484 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); | 1489 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); |
1485 sink_->PutInt(root_index, "root_index"); | 1490 sink_->PutInt(root_index, "root_index"); |
1486 } | 1491 } |
1487 } | 1492 } |
1488 | 1493 |
1489 | 1494 |
1490 void PartialSerializer::SerializeObject( | 1495 void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
1491 Object* o, | 1496 WhereToPoint where_to_point, int skip) { |
1492 HowToCode how_to_code, | 1497 if (obj->IsMap()) { |
1493 WhereToPoint where_to_point, | |
1494 int skip) { | |
1495 CHECK(o->IsHeapObject()); | |
1496 HeapObject* heap_object = HeapObject::cast(o); | |
1497 | |
1498 if (heap_object->IsMap()) { | |
1499 // The code-caches link to context-specific code objects, which | 1498 // The code-caches link to context-specific code objects, which |
1500 // the startup and context serializes cannot currently handle. | 1499 // the startup and context serializes cannot currently handle. |
1501 DCHECK(Map::cast(heap_object)->code_cache() == | 1500 DCHECK(Map::cast(obj)->code_cache() == obj->GetHeap()->empty_fixed_array()); |
1502 heap_object->GetHeap()->empty_fixed_array()); | |
1503 } | 1501 } |
1504 | 1502 |
1505 int root_index; | 1503 int root_index = root_index_map_.Lookup(obj); |
1506 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1504 if (root_index != RootIndexMap::kInvalidRootIndex) { |
1507 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1505 PutRoot(root_index, obj, how_to_code, where_to_point, skip); |
1508 return; | 1506 return; |
1509 } | 1507 } |
1510 | 1508 |
1511 if (ShouldBeInThePartialSnapshotCache(heap_object)) { | 1509 if (ShouldBeInThePartialSnapshotCache(obj)) { |
1512 if (skip != 0) { | 1510 if (skip != 0) { |
1513 sink_->Put(kSkip, "SkipFromSerializeObject"); | 1511 sink_->Put(kSkip, "SkipFromSerializeObject"); |
1514 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 1512 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
1515 } | 1513 } |
1516 | 1514 |
1517 int cache_index = PartialSnapshotCacheIndex(heap_object); | 1515 int cache_index = PartialSnapshotCacheIndex(obj); |
1518 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, | 1516 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, |
1519 "PartialSnapshotCache"); | 1517 "PartialSnapshotCache"); |
1520 sink_->PutInt(cache_index, "partial_snapshot_cache_index"); | 1518 sink_->PutInt(cache_index, "partial_snapshot_cache_index"); |
1521 return; | 1519 return; |
1522 } | 1520 } |
1523 | 1521 |
1524 // Pointers from the partial snapshot to the objects in the startup snapshot | 1522 // Pointers from the partial snapshot to the objects in the startup snapshot |
1525 // should go through the root array or through the partial snapshot cache. | 1523 // should go through the root array or through the partial snapshot cache. |
1526 // If this is not the case you may have to add something to the root array. | 1524 // If this is not the case you may have to add something to the root array. |
1527 DCHECK(!startup_serializer_->address_mapper()->IsMapped(heap_object)); | 1525 DCHECK(!startup_serializer_->back_reference_map()->Lookup(obj).is_valid()); |
1528 // All the internalized strings that the partial snapshot needs should be | 1526 // All the internalized strings that the partial snapshot needs should be |
1529 // either in the root table or in the partial snapshot cache. | 1527 // either in the root table or in the partial snapshot cache. |
1530 DCHECK(!heap_object->IsInternalizedString()); | 1528 DCHECK(!obj->IsInternalizedString()); |
1531 | 1529 |
1532 if (address_mapper_.IsMapped(heap_object)) { | 1530 BackReference back_reference = back_reference_map_.Lookup(obj); |
1533 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, | 1531 if (back_reference.is_valid()) { |
1534 skip); | 1532 SerializeBackReference(back_reference, how_to_code, where_to_point, skip); |
1535 } else { | 1533 return; |
1536 if (skip != 0) { | |
1537 sink_->Put(kSkip, "SkipFromSerializeObject"); | |
1538 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | |
1539 } | |
1540 // Object has not yet been serialized. Serialize it here. | |
1541 ObjectSerializer serializer(this, | |
1542 heap_object, | |
1543 sink_, | |
1544 how_to_code, | |
1545 where_to_point); | |
1546 serializer.Serialize(); | |
1547 } | 1534 } |
1535 | |
1536 if (skip != 0) { | |
1537 sink_->Put(kSkip, "SkipFromSerializeObject"); | |
1538 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | |
1539 } | |
1540 // Object has not yet been serialized. Serialize it here. | |
1541 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); | |
1542 serializer.Serialize(); | |
1548 } | 1543 } |
1549 | 1544 |
1550 | 1545 |
1551 void Serializer::ObjectSerializer::SerializePrologue(int space, int size, | 1546 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
1552 Map* map) { | 1547 int size, Map* map) { |
1553 sink_->Put(kNewObject + reference_representation_ + space, | 1548 sink_->Put(kNewObject + reference_representation_ + space, |
1554 "ObjectSerialization"); | 1549 "ObjectSerialization"); |
1555 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); | 1550 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
1556 | 1551 |
1557 if (serializer_->code_address_map_) { | 1552 if (serializer_->code_address_map_) { |
1558 const char* code_name = | 1553 const char* code_name = |
1559 serializer_->code_address_map_->Lookup(object_->address()); | 1554 serializer_->code_address_map_->Lookup(object_->address()); |
1560 LOG(serializer_->isolate_, | 1555 LOG(serializer_->isolate_, |
1561 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1556 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
1562 LOG(serializer_->isolate_, | 1557 LOG(serializer_->isolate_, |
1563 SnapshotPositionEvent(object_->address(), sink_->Position())); | 1558 SnapshotPositionEvent(object_->address(), sink_->Position())); |
1564 } | 1559 } |
1565 | 1560 |
1566 // Mark this object as already serialized. | 1561 // Mark this object as already serialized. |
1562 BackReference back_reference; | |
1567 if (space == LO_SPACE) { | 1563 if (space == LO_SPACE) { |
1568 if (object_->IsCode()) { | 1564 if (object_->IsCode()) { |
1569 sink_->Put(EXECUTABLE, "executable large object"); | 1565 sink_->Put(EXECUTABLE, "executable large object"); |
1570 } else { | 1566 } else { |
1571 sink_->Put(NOT_EXECUTABLE, "not executable large object"); | 1567 sink_->Put(NOT_EXECUTABLE, "not executable large object"); |
1572 } | 1568 } |
1573 int index = serializer_->AllocateLargeObject(size); | 1569 back_reference = serializer_->AllocateLargeObject(size); |
1574 serializer_->address_mapper()->AddMapping(object_, index); | |
1575 } else { | 1570 } else { |
1576 int allocation = serializer_->Allocate(space, size); | 1571 back_reference = serializer_->Allocate(space, size); |
1577 serializer_->address_mapper()->AddMapping(object_, allocation); | |
1578 } | 1572 } |
1573 serializer_->back_reference_map()->Add(object_, back_reference); | |
1579 | 1574 |
1580 // Serialize the map (first word of the object). | 1575 // Serialize the map (first word of the object). |
1581 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); | 1576 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); |
1582 } | 1577 } |
1583 | 1578 |
1584 | 1579 |
1585 void Serializer::ObjectSerializer::SerializeExternalString() { | 1580 void Serializer::ObjectSerializer::SerializeExternalString() { |
1586 // Instead of serializing this as an external string, we serialize | 1581 // Instead of serializing this as an external string, we serialize |
1587 // an imaginary sequential string with the same content. | 1582 // an imaginary sequential string with the same content. |
1588 Isolate* isolate = serializer_->isolate(); | 1583 Isolate* isolate = serializer_->isolate(); |
1589 DCHECK(object_->IsExternalString()); | 1584 DCHECK(object_->IsExternalString()); |
1590 DCHECK(object_->map() != isolate->heap()->native_source_string_map()); | 1585 DCHECK(object_->map() != isolate->heap()->native_source_string_map()); |
1591 ExternalString* string = ExternalString::cast(object_); | 1586 ExternalString* string = ExternalString::cast(object_); |
1592 int length = string->length(); | 1587 int length = string->length(); |
1593 Map* map; | 1588 Map* map; |
1594 int size; | 1589 int size; |
1595 const char* resource; | 1590 const char* resource; |
1596 // Find the map and size for the imaginary sequential string. | 1591 // Find the map and size for the imaginary sequential string. |
1597 if (object_->IsExternalOneByteString()) { | 1592 if (object_->IsExternalOneByteString()) { |
1598 map = isolate->heap()->one_byte_internalized_string_map(); | 1593 map = isolate->heap()->one_byte_internalized_string_map(); |
1599 size = SeqOneByteString::SizeFor(length); | 1594 size = SeqOneByteString::SizeFor(length); |
1600 resource = ExternalOneByteString::cast(string)->resource()->data(); | 1595 resource = ExternalOneByteString::cast(string)->resource()->data(); |
1601 } else { | 1596 } else { |
1602 map = isolate->heap()->internalized_string_map(); | 1597 map = isolate->heap()->internalized_string_map(); |
1603 size = SeqTwoByteString::SizeFor(length); | 1598 size = SeqTwoByteString::SizeFor(length); |
1604 resource = reinterpret_cast<const char*>( | 1599 resource = reinterpret_cast<const char*>( |
1605 ExternalTwoByteString::cast(string)->resource()->data()); | 1600 ExternalTwoByteString::cast(string)->resource()->data()); |
1606 } | 1601 } |
1607 | 1602 |
1608 int space = | 1603 AllocationSpace space = |
1609 (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE; | 1604 (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE; |
1610 SerializePrologue(space, size, map); | 1605 SerializePrologue(space, size, map); |
1611 | 1606 |
1612 // Output the rest of the imaginary string. | 1607 // Output the rest of the imaginary string. |
1613 int bytes_to_output = size - HeapObject::kHeaderSize; | 1608 int bytes_to_output = size - HeapObject::kHeaderSize; |
1614 | 1609 |
1615 // Output raw data header. Do not bother with common raw length cases here. | 1610 // Output raw data header. Do not bother with common raw length cases here. |
1616 sink_->Put(kRawData, "RawDataForString"); | 1611 sink_->Put(kRawData, "RawDataForString"); |
1617 sink_->PutInt(bytes_to_output, "length"); | 1612 sink_->PutInt(bytes_to_output, "length"); |
1618 | 1613 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1663 | 1658 |
1664 void Serializer::ObjectSerializer::VisitPointers(Object** start, | 1659 void Serializer::ObjectSerializer::VisitPointers(Object** start, |
1665 Object** end) { | 1660 Object** end) { |
1666 Object** current = start; | 1661 Object** current = start; |
1667 while (current < end) { | 1662 while (current < end) { |
1668 while (current < end && (*current)->IsSmi()) current++; | 1663 while (current < end && (*current)->IsSmi()) current++; |
1669 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); | 1664 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); |
1670 | 1665 |
1671 while (current < end && !(*current)->IsSmi()) { | 1666 while (current < end && !(*current)->IsSmi()) { |
1672 HeapObject* current_contents = HeapObject::cast(*current); | 1667 HeapObject* current_contents = HeapObject::cast(*current); |
1673 int root_index = serializer_->RootIndex(current_contents, kPlain); | 1668 int root_index = serializer_->root_index_map()->Lookup(current_contents); |
1674 // Repeats are not subject to the write barrier so there are only some | 1669 // Repeats are not subject to the write barrier so there are only some |
1675 // objects that can be used in a repeat encoding. These are the early | 1670 // objects that can be used in a repeat encoding. These are the early |
1676 // ones in the root array that are never in new space. | 1671 // ones in the root array that are never in new space. |
Erik Corry
2014/10/23 12:57:15
I think now this is _all_ the entries in the root
| |
1677 if (current != start && | 1672 if (current != start && root_index != RootIndexMap::kInvalidRootIndex && |
1678 root_index != kInvalidRootIndex && | |
1679 root_index < kRootArrayNumberOfConstantEncodings && | 1673 root_index < kRootArrayNumberOfConstantEncodings && |
1680 current_contents == current[-1]) { | 1674 current_contents == current[-1]) { |
1681 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); | 1675 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); |
1682 int repeat_count = 1; | 1676 int repeat_count = 1; |
1683 while (¤t[repeat_count] < end - 1 && | 1677 while (¤t[repeat_count] < end - 1 && |
1684 current[repeat_count] == current_contents) { | 1678 current[repeat_count] == current_contents) { |
1685 repeat_count++; | 1679 repeat_count++; |
1686 } | 1680 } |
1687 current += repeat_count; | 1681 current += repeat_count; |
1688 bytes_processed_so_far_ += repeat_count * kPointerSize; | 1682 bytes_processed_so_far_ += repeat_count * kPointerSize; |
(...skipping 15 matching lines...) Expand all Loading... | |
1704 | 1698 |
1705 | 1699 |
1706 void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) { | 1700 void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) { |
1707 // Out-of-line constant pool entries will be visited by the ConstantPoolArray. | 1701 // Out-of-line constant pool entries will be visited by the ConstantPoolArray. |
1708 if (FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool()) return; | 1702 if (FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool()) return; |
1709 | 1703 |
1710 int skip = OutputRawData(rinfo->target_address_address(), | 1704 int skip = OutputRawData(rinfo->target_address_address(), |
1711 kCanReturnSkipInsteadOfSkipping); | 1705 kCanReturnSkipInsteadOfSkipping); |
1712 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 1706 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
1713 Object* object = rinfo->target_object(); | 1707 Object* object = rinfo->target_object(); |
1714 serializer_->SerializeObject(object, how_to_code, kStartOfObject, skip); | 1708 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, |
1709 kStartOfObject, skip); | |
1715 bytes_processed_so_far_ += rinfo->target_address_size(); | 1710 bytes_processed_so_far_ += rinfo->target_address_size(); |
1716 } | 1711 } |
1717 | 1712 |
1718 | 1713 |
1719 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { | 1714 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { |
1720 int skip = OutputRawData(reinterpret_cast<Address>(p), | 1715 int skip = OutputRawData(reinterpret_cast<Address>(p), |
1721 kCanReturnSkipInsteadOfSkipping); | 1716 kCanReturnSkipInsteadOfSkipping); |
1722 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); | 1717 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); |
1723 sink_->PutInt(skip, "SkipB4ExternalRef"); | 1718 sink_->PutInt(skip, "SkipB4ExternalRef"); |
1724 Address target = *p; | 1719 Address target = *p; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1880 } | 1875 } |
1881 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 1876 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
1882 sink_->Put(kSkip, "Skip"); | 1877 sink_->Put(kSkip, "Skip"); |
1883 sink_->PutInt(to_skip, "SkipDistance"); | 1878 sink_->PutInt(to_skip, "SkipDistance"); |
1884 to_skip = 0; | 1879 to_skip = 0; |
1885 } | 1880 } |
1886 return to_skip; | 1881 return to_skip; |
1887 } | 1882 } |
1888 | 1883 |
1889 | 1884 |
1890 int Serializer::SpaceOfObject(HeapObject* object) { | 1885 AllocationSpace Serializer::SpaceOfObject(HeapObject* object) { |
1891 for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) { | 1886 for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) { |
1892 AllocationSpace s = static_cast<AllocationSpace>(i); | 1887 AllocationSpace s = static_cast<AllocationSpace>(i); |
1893 if (object->GetHeap()->InSpace(object, s)) { | 1888 if (object->GetHeap()->InSpace(object, s)) { |
1894 DCHECK(i < kNumberOfSpaces); | 1889 DCHECK(i < kNumberOfSpaces); |
1895 return i; | 1890 return s; |
1896 } | 1891 } |
1897 } | 1892 } |
1898 UNREACHABLE(); | 1893 UNREACHABLE(); |
1899 return 0; | 1894 return INVALID_SPACE; |
1900 } | 1895 } |
1901 | 1896 |
1902 | 1897 |
1903 uint32_t Serializer::AllocateLargeObject(int size) { | 1898 BackReference Serializer::AllocateLargeObject(int size) { |
1904 // Large objects are allocated one-by-one when deserializing. We do not | 1899 // Large objects are allocated one-by-one when deserializing. We do not |
1905 // have to keep track of multiple chunks. | 1900 // have to keep track of multiple chunks. |
1906 pending_chunk_[LO_SPACE] += size; | 1901 pending_chunk_[LO_SPACE] += size; |
1907 return seen_large_objects_index_++; | 1902 return BackReference(LO_SPACE, 0, seen_large_objects_index_++); |
1908 } | 1903 } |
1909 | 1904 |
1910 | 1905 |
1911 uint32_t Serializer::Allocate(int space, int size) { | 1906 BackReference Serializer::Allocate(AllocationSpace space, int size) { |
1912 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); | 1907 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); |
1913 DCHECK(size > 0 && size < Page::kMaxRegularHeapObjectSize); | 1908 DCHECK(size > 0 && size < Page::kMaxRegularHeapObjectSize); |
1914 uint32_t new_chunk_size = pending_chunk_[space] + size; | 1909 uint32_t new_chunk_size = pending_chunk_[space] + size; |
1915 uint32_t allocation; | |
1916 if (new_chunk_size > static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)) { | 1910 if (new_chunk_size > static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)) { |
1917 // The new chunk size would not fit onto a single page. Complete the | 1911 // The new chunk size would not fit onto a single page. Complete the |
1918 // current chunk and start a new one. | 1912 // current chunk and start a new one. |
1919 completed_chunks_[space].Add(pending_chunk_[space]); | 1913 completed_chunks_[space].Add(pending_chunk_[space]); |
1920 pending_chunk_[space] = 0; | 1914 pending_chunk_[space] = 0; |
1921 new_chunk_size = size; | 1915 new_chunk_size = size; |
1922 } | 1916 } |
1923 // For back-referencing, each allocation is encoded as a combination | 1917 uint32_t offset = pending_chunk_[space]; |
1924 // of chunk index and offset inside the chunk. | |
1925 allocation = ChunkIndexBits::encode(completed_chunks_[space].length()) | | |
1926 OffsetBits::encode(pending_chunk_[space]); | |
1927 pending_chunk_[space] = new_chunk_size; | 1918 pending_chunk_[space] = new_chunk_size; |
1928 return allocation; | 1919 return BackReference(space, completed_chunks_[space].length(), offset); |
1929 } | 1920 } |
1930 | 1921 |
1931 | 1922 |
1932 int Serializer::SpaceAreaSize(int space) { | 1923 int Serializer::SpaceAreaSize(int space) { |
1933 if (space == CODE_SPACE) { | 1924 if (space == CODE_SPACE) { |
1934 return isolate_->memory_allocator()->CodePageAreaSize(); | 1925 return isolate_->memory_allocator()->CodePageAreaSize(); |
1935 } else { | 1926 } else { |
1936 return Page::kPageSize - Page::kObjectStartOffset; | 1927 return Page::kPageSize - Page::kObjectStartOffset; |
1937 } | 1928 } |
1938 } | 1929 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1972 SnapshotByteSink* sink = FLAG_serializer_trace_level > 1 | 1963 SnapshotByteSink* sink = FLAG_serializer_trace_level > 1 |
1973 ? static_cast<SnapshotByteSink*>(&debug_sink) | 1964 ? static_cast<SnapshotByteSink*>(&debug_sink) |
1974 : static_cast<SnapshotByteSink*>(&list_sink); | 1965 : static_cast<SnapshotByteSink*>(&list_sink); |
1975 CodeSerializer cs(isolate, sink, *source, info->code()); | 1966 CodeSerializer cs(isolate, sink, *source, info->code()); |
1976 DisallowHeapAllocation no_gc; | 1967 DisallowHeapAllocation no_gc; |
1977 Object** location = Handle<Object>::cast(info).location(); | 1968 Object** location = Handle<Object>::cast(info).location(); |
1978 cs.VisitPointer(location); | 1969 cs.VisitPointer(location); |
1979 cs.Pad(); | 1970 cs.Pad(); |
1980 cs.FinalizeAllocation(); | 1971 cs.FinalizeAllocation(); |
1981 | 1972 |
1973 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { | |
1974 // Fail if any chunk index exceeds the limit. | |
1975 if (cs.FinalAllocationChunks(i).length() > BackReference::kMaxChunkIndex) { | |
1976 return NULL; | |
1977 } | |
1978 } | |
1979 | |
1982 SerializedCodeData data(&payload, &cs); | 1980 SerializedCodeData data(&payload, &cs); |
1983 ScriptData* script_data = data.GetScriptData(); | 1981 ScriptData* script_data = data.GetScriptData(); |
1984 | 1982 |
1985 if (FLAG_profile_deserialization) { | 1983 if (FLAG_profile_deserialization) { |
1986 double ms = timer.Elapsed().InMillisecondsF(); | 1984 double ms = timer.Elapsed().InMillisecondsF(); |
1987 int length = script_data->length(); | 1985 int length = script_data->length(); |
1988 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); | 1986 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); |
1989 } | 1987 } |
1990 | 1988 |
1991 return script_data; | 1989 return script_data; |
1992 } | 1990 } |
1993 | 1991 |
1994 | 1992 |
1995 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, | 1993 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
1996 WhereToPoint where_to_point, int skip) { | 1994 WhereToPoint where_to_point, int skip) { |
1997 HeapObject* heap_object = HeapObject::cast(o); | 1995 int root_index = root_index_map_.Lookup(obj); |
1998 | 1996 if (root_index != RootIndexMap::kInvalidRootIndex) { |
1999 int root_index; | |
2000 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | |
2001 if (FLAG_serializer_trace_level > 0) { | 1997 if (FLAG_serializer_trace_level > 0) { |
2002 PrintF(" Encoding root: %d\n", root_index); | 1998 PrintF(" Encoding root: %d\n", root_index); |
2003 } | 1999 } |
2004 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 2000 PutRoot(root_index, obj, how_to_code, where_to_point, skip); |
2005 return; | 2001 return; |
2006 } | 2002 } |
2007 | 2003 |
2008 if (address_mapper_.IsMapped(heap_object)) { | 2004 BackReference back_reference = back_reference_map_.Lookup(obj); |
2005 if (back_reference.is_valid()) { | |
2009 if (FLAG_serializer_trace_level > 0) { | 2006 if (FLAG_serializer_trace_level > 0) { |
2010 PrintF(" Encoding back reference to: "); | 2007 PrintF(" Encoding back reference to: "); |
2011 heap_object->ShortPrint(); | 2008 obj->ShortPrint(); |
2012 PrintF("\n"); | 2009 PrintF("\n"); |
2013 } | 2010 } |
2014 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, | 2011 SerializeBackReference(back_reference, how_to_code, where_to_point, skip); |
2015 skip); | |
2016 return; | 2012 return; |
2017 } | 2013 } |
2018 | 2014 |
2019 if (skip != 0) { | 2015 if (skip != 0) { |
2020 sink_->Put(kSkip, "SkipFromSerializeObject"); | 2016 sink_->Put(kSkip, "SkipFromSerializeObject"); |
2021 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 2017 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
2022 } | 2018 } |
2023 | 2019 |
2024 if (heap_object->IsCode()) { | 2020 if (obj->IsCode()) { |
2025 Code* code_object = Code::cast(heap_object); | 2021 Code* code_object = Code::cast(obj); |
2026 switch (code_object->kind()) { | 2022 switch (code_object->kind()) { |
2027 case Code::OPTIMIZED_FUNCTION: // No optimized code compiled yet. | 2023 case Code::OPTIMIZED_FUNCTION: // No optimized code compiled yet. |
2028 case Code::HANDLER: // No handlers patched in yet. | 2024 case Code::HANDLER: // No handlers patched in yet. |
2029 case Code::REGEXP: // No regexp literals initialized yet. | 2025 case Code::REGEXP: // No regexp literals initialized yet. |
2030 case Code::NUMBER_OF_KINDS: // Pseudo enum value. | 2026 case Code::NUMBER_OF_KINDS: // Pseudo enum value. |
2031 CHECK(false); | 2027 CHECK(false); |
2032 case Code::BUILTIN: | 2028 case Code::BUILTIN: |
2033 SerializeBuiltin(code_object->builtin_index(), how_to_code, | 2029 SerializeBuiltin(code_object->builtin_index(), how_to_code, |
2034 where_to_point); | 2030 where_to_point); |
2035 return; | 2031 return; |
2036 case Code::STUB: | 2032 case Code::STUB: |
2037 SerializeCodeStub(code_object->stub_key(), how_to_code, where_to_point); | 2033 SerializeCodeStub(code_object->stub_key(), how_to_code, where_to_point); |
2038 return; | 2034 return; |
2039 #define IC_KIND_CASE(KIND) case Code::KIND: | 2035 #define IC_KIND_CASE(KIND) case Code::KIND: |
2040 IC_KIND_LIST(IC_KIND_CASE) | 2036 IC_KIND_LIST(IC_KIND_CASE) |
2041 #undef IC_KIND_CASE | 2037 #undef IC_KIND_CASE |
2042 SerializeIC(code_object, how_to_code, where_to_point); | 2038 SerializeIC(code_object, how_to_code, where_to_point); |
2043 return; | 2039 return; |
2044 case Code::FUNCTION: | 2040 case Code::FUNCTION: |
2045 // Only serialize the code for the toplevel function. Replace code | 2041 // Only serialize the code for the toplevel function. Replace code |
2046 // of included function literals by the lazy compile builtin. | 2042 // of included function literals by the lazy compile builtin. |
2047 // This is safe, as checked in Compiler::BuildFunctionInfo. | 2043 // This is safe, as checked in Compiler::BuildFunctionInfo. |
2048 if (code_object != main_code_) { | 2044 if (code_object != main_code_) { |
2049 SerializeBuiltin(Builtins::kCompileLazy, how_to_code, where_to_point); | 2045 SerializeBuiltin(Builtins::kCompileLazy, how_to_code, where_to_point); |
2050 } else { | 2046 } else { |
2051 code_object->MakeYoung(); | 2047 code_object->MakeYoung(); |
2052 SerializeHeapObject(code_object, how_to_code, where_to_point); | 2048 SerializeGeneric(code_object, how_to_code, where_to_point); |
2053 } | 2049 } |
2054 return; | 2050 return; |
2055 } | 2051 } |
2056 UNREACHABLE(); | 2052 UNREACHABLE(); |
2057 } | 2053 } |
2058 | 2054 |
2059 if (heap_object == source_) { | 2055 if (obj == source_) { |
2060 SerializeSourceObject(how_to_code, where_to_point); | 2056 SerializeSourceObject(how_to_code, where_to_point); |
2061 return; | 2057 return; |
2062 } | 2058 } |
2063 | 2059 |
2064 // Past this point we should not see any (context-specific) maps anymore. | 2060 // Past this point we should not see any (context-specific) maps anymore. |
2065 CHECK(!heap_object->IsMap()); | 2061 CHECK(!obj->IsMap()); |
2066 // There should be no references to the global object embedded. | 2062 // There should be no references to the global object embedded. |
2067 CHECK(!heap_object->IsJSGlobalProxy() && !heap_object->IsGlobalObject()); | 2063 CHECK(!obj->IsJSGlobalProxy() && !obj->IsGlobalObject()); |
2068 // There should be no hash table embedded. They would require rehashing. | 2064 // There should be no hash table embedded. They would require rehashing. |
2069 CHECK(!heap_object->IsHashTable()); | 2065 CHECK(!obj->IsHashTable()); |
2070 | 2066 |
2071 SerializeHeapObject(heap_object, how_to_code, where_to_point); | 2067 SerializeGeneric(obj, how_to_code, where_to_point); |
2072 } | 2068 } |
2073 | 2069 |
2074 | 2070 |
2075 void CodeSerializer::SerializeHeapObject(HeapObject* heap_object, | 2071 void CodeSerializer::SerializeGeneric(HeapObject* heap_object, |
2076 HowToCode how_to_code, | 2072 HowToCode how_to_code, |
2077 WhereToPoint where_to_point) { | 2073 WhereToPoint where_to_point) { |
2078 if (FLAG_serializer_trace_level > 0) { | 2074 if (FLAG_serializer_trace_level > 0) { |
2079 PrintF(" Encoding heap object: "); | 2075 PrintF(" Encoding heap object: "); |
2080 heap_object->ShortPrint(); | 2076 heap_object->ShortPrint(); |
2081 PrintF("\n"); | 2077 PrintF("\n"); |
2082 } | 2078 } |
2083 | 2079 |
2084 // Object has not yet been serialized. Serialize it here. | 2080 // Object has not yet been serialized. Serialize it here. |
2085 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, | 2081 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, |
2086 where_to_point); | 2082 where_to_point); |
2087 serializer.Serialize(); | 2083 serializer.Serialize(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2154 SerializeBuiltin(builtin_index, how_to_code, where_to_point); | 2150 SerializeBuiltin(builtin_index, how_to_code, where_to_point); |
2155 return; | 2151 return; |
2156 } | 2152 } |
2157 } | 2153 } |
2158 // The IC may also just be a piece of code kept in the non_monomorphic_cache. | 2154 // The IC may also just be a piece of code kept in the non_monomorphic_cache. |
2159 // In that case, just serialize as a normal code object. | 2155 // In that case, just serialize as a normal code object. |
2160 if (FLAG_serializer_trace_level > 0) { | 2156 if (FLAG_serializer_trace_level > 0) { |
2161 PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind())); | 2157 PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind())); |
2162 } | 2158 } |
2163 DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC); | 2159 DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC); |
2164 SerializeHeapObject(ic, how_to_code, where_to_point); | 2160 SerializeGeneric(ic, how_to_code, where_to_point); |
2165 } | 2161 } |
2166 | 2162 |
2167 | 2163 |
2168 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { | 2164 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { |
2169 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). | 2165 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). |
2170 int index = 0; | 2166 int index = 0; |
2171 while (index < stub_keys_.length()) { | 2167 while (index < stub_keys_.length()) { |
2172 if (stub_keys_[index] == stub_key) return index; | 2168 if (stub_keys_[index] == stub_key) return index; |
2173 index++; | 2169 index++; |
2174 } | 2170 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2236 int length = data->length(); | 2232 int length = data->length(); |
2237 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); | 2233 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); |
2238 } | 2234 } |
2239 Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate); | 2235 Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate); |
2240 result->set_deserialized(true); | 2236 result->set_deserialized(true); |
2241 return result; | 2237 return result; |
2242 } | 2238 } |
2243 | 2239 |
2244 | 2240 |
2245 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) | 2241 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) |
2246 : owns_script_data_(true) { | 2242 : script_data_(NULL), owns_script_data_(true) { |
2247 DisallowHeapAllocation no_gc; | 2243 DisallowHeapAllocation no_gc; |
2248 List<uint32_t>* stub_keys = cs->stub_keys(); | 2244 List<uint32_t>* stub_keys = cs->stub_keys(); |
2249 | 2245 |
2250 // Gather reservation chunk sizes. | 2246 // Gather reservation chunk sizes. |
2251 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); | 2247 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); |
2252 STATIC_ASSERT(NEW_SPACE == 0); | 2248 STATIC_ASSERT(NEW_SPACE == 0); |
2253 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { | 2249 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { |
2254 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i); | 2250 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i); |
2255 for (int j = 0; j < chunks.length(); j++) { | 2251 for (int j = 0; j < chunks.length(); j++) { |
2256 DCHECK(i == LO_SPACE || | 2252 DCHECK(i == LO_SPACE || |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2303 | 2299 |
2304 int SerializedCodeData::CheckSum(String* string) { | 2300 int SerializedCodeData::CheckSum(String* string) { |
2305 int checksum = Version::Hash(); | 2301 int checksum = Version::Hash(); |
2306 #ifdef DEBUG | 2302 #ifdef DEBUG |
2307 uint32_t seed = static_cast<uint32_t>(checksum); | 2303 uint32_t seed = static_cast<uint32_t>(checksum); |
2308 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2304 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
2309 #endif // DEBUG | 2305 #endif // DEBUG |
2310 return checksum; | 2306 return checksum; |
2311 } | 2307 } |
2312 } } // namespace v8::internal | 2308 } } // namespace v8::internal |
OLD | NEW |