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

Side by Side Diff: src/serialize.cc

Issue 645533003: Use hash map to look for objects in the root array when serializing. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: make use of the hash map more often. Created 6 years, 2 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 unified diff | Download patch | Annotate | Revision Log
« src/serialize.h ('K') | « src/serialize.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 (&current[repeat_count] < end - 1 && 1677 while (&current[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
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
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
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
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
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
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
OLDNEW
« src/serialize.h ('K') | « src/serialize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698