| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 } | 1271 } |
| 1272 | 1272 |
| 1273 | 1273 |
| 1274 template<LoggingAndProfiling logging_and_profiling_mode> | 1274 template<LoggingAndProfiling logging_and_profiling_mode> |
| 1275 class ScavengingVisitor : public StaticVisitorBase { | 1275 class ScavengingVisitor : public StaticVisitorBase { |
| 1276 public: | 1276 public: |
| 1277 static void Initialize() { | 1277 static void Initialize() { |
| 1278 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); | 1278 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); |
| 1279 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 1279 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); |
| 1280 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 1280 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); |
| 1281 table_.Register(kVisitSlicedString, &EvacuateSlicedString); |
| 1281 table_.Register(kVisitByteArray, &EvacuateByteArray); | 1282 table_.Register(kVisitByteArray, &EvacuateByteArray); |
| 1282 table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 1283 table_.Register(kVisitFixedArray, &EvacuateFixedArray); |
| 1283 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 1284 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); |
| 1284 | 1285 |
| 1285 table_.Register(kVisitGlobalContext, | 1286 table_.Register(kVisitGlobalContext, |
| 1286 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1287 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1287 template VisitSpecialized<Context::kSize>); | 1288 template VisitSpecialized<Context::kSize>); |
| 1288 | 1289 |
| 1289 table_.Register(kVisitConsString, | 1290 table_.Register(kVisitConsString, |
| 1290 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1291 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1291 template VisitSpecialized<ConsString::kSize>); | 1292 template VisitSpecialized<ConsString::kSize>); |
| 1292 | 1293 |
| 1293 table_.Register(kVisitSlicedString, | |
| 1294 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | |
| 1295 template VisitSpecialized<SlicedString::kSize>); | |
| 1296 | |
| 1297 table_.Register(kVisitSharedFunctionInfo, | 1294 table_.Register(kVisitSharedFunctionInfo, |
| 1298 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1295 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1299 template VisitSpecialized<SharedFunctionInfo::kSize>); | 1296 template VisitSpecialized<SharedFunctionInfo::kSize>); |
| 1300 | 1297 |
| 1301 table_.Register(kVisitJSWeakMap, | 1298 table_.Register(kVisitJSWeakMap, |
| 1302 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1299 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1303 Visit); | 1300 Visit); |
| 1304 | 1301 |
| 1305 table_.Register(kVisitJSRegExp, | 1302 table_.Register(kVisitJSRegExp, |
| 1306 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1303 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 should_record = should_record || FLAG_log_gc; | 1336 should_record = should_record || FLAG_log_gc; |
| 1340 if (should_record) { | 1337 if (should_record) { |
| 1341 if (heap->new_space()->Contains(obj)) { | 1338 if (heap->new_space()->Contains(obj)) { |
| 1342 heap->new_space()->RecordAllocation(obj); | 1339 heap->new_space()->RecordAllocation(obj); |
| 1343 } else { | 1340 } else { |
| 1344 heap->new_space()->RecordPromotion(obj); | 1341 heap->new_space()->RecordPromotion(obj); |
| 1345 } | 1342 } |
| 1346 } | 1343 } |
| 1347 } | 1344 } |
| 1348 | 1345 |
| 1349 // Helper function used by CopyObject to copy a source object to an | |
| 1350 // allocated target object and update the forwarding pointer in the source | |
| 1351 // object. Returns the target object. | |
| 1352 INLINE(static HeapObject* MigrateObject(Heap* heap, | |
| 1353 HeapObject* source, | |
| 1354 HeapObject* target, | |
| 1355 int size)) { | |
| 1356 // Copy the content of source to target. | |
| 1357 heap->CopyBlock(target->address(), source->address(), size); | |
| 1358 | 1346 |
| 1347 INLINE(static void ForwardAndLogMigration(Heap* heap, |
| 1348 HeapObject* source, |
| 1349 HeapObject* target)) { |
| 1359 // Set the forwarding address. | 1350 // Set the forwarding address. |
| 1360 source->set_map_word(MapWord::FromForwardingAddress(target)); | 1351 source->set_map_word(MapWord::FromForwardingAddress(target)); |
| 1361 | 1352 |
| 1362 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) { | 1353 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) { |
| 1363 // Update NewSpace stats if necessary. | 1354 // Update NewSpace stats if necessary. |
| 1364 RecordCopiedObject(heap, target); | 1355 RecordCopiedObject(heap, target); |
| 1365 HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address())); | 1356 HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address())); |
| 1366 Isolate* isolate = heap->isolate(); | 1357 Isolate* isolate = heap->isolate(); |
| 1367 if (isolate->logger()->is_logging() || | 1358 if (isolate->logger()->is_logging() || |
| 1368 CpuProfiler::is_profiling(isolate)) { | 1359 CpuProfiler::is_profiling(isolate)) { |
| 1369 if (target->IsSharedFunctionInfo()) { | 1360 if (target->IsSharedFunctionInfo()) { |
| 1370 PROFILE(isolate, SharedFunctionInfoMoveEvent( | 1361 PROFILE(isolate, SharedFunctionInfoMoveEvent( |
| 1371 source->address(), target->address())); | 1362 source->address(), target->address())); |
| 1372 } | 1363 } |
| 1373 } | 1364 } |
| 1374 } | 1365 } |
| 1366 } |
| 1367 |
| 1368 // Helper function used by CopyObject to copy a source object to an |
| 1369 // allocated target object and update the forwarding pointer in the source |
| 1370 // object. Returns the target object. |
| 1371 INLINE(static HeapObject* MigrateObject(Heap* heap, |
| 1372 HeapObject* source, |
| 1373 HeapObject* target, |
| 1374 int size)) { |
| 1375 // Copy the content of source to target. |
| 1376 heap->CopyBlock(target->address(), source->address(), size); |
| 1377 |
| 1378 ForwardAndLogMigration(heap, source, target); |
| 1375 | 1379 |
| 1376 return target; | 1380 return target; |
| 1377 } | 1381 } |
| 1378 | 1382 |
| 1379 | 1383 |
| 1380 template<ObjectContents object_contents, SizeRestriction size_restriction> | 1384 template<ObjectContents object_contents, SizeRestriction size_restriction> |
| 1381 static inline void EvacuateObject(Map* map, | 1385 static inline void EvacuateObject(Map* map, |
| 1382 HeapObject** slot, | 1386 HeapObject** slot, |
| 1383 HeapObject* object, | 1387 HeapObject* object, |
| 1384 int object_size) { | 1388 int object_size) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1397 if (object_contents == DATA_OBJECT) { | 1401 if (object_contents == DATA_OBJECT) { |
| 1398 maybe_result = heap->old_data_space()->AllocateRaw(object_size); | 1402 maybe_result = heap->old_data_space()->AllocateRaw(object_size); |
| 1399 } else { | 1403 } else { |
| 1400 maybe_result = heap->old_pointer_space()->AllocateRaw(object_size); | 1404 maybe_result = heap->old_pointer_space()->AllocateRaw(object_size); |
| 1401 } | 1405 } |
| 1402 } | 1406 } |
| 1403 | 1407 |
| 1404 Object* result = NULL; // Initialization to please compiler. | 1408 Object* result = NULL; // Initialization to please compiler. |
| 1405 if (maybe_result->ToObject(&result)) { | 1409 if (maybe_result->ToObject(&result)) { |
| 1406 HeapObject* target = HeapObject::cast(result); | 1410 HeapObject* target = HeapObject::cast(result); |
| 1407 *slot = MigrateObject(heap, object , target, object_size); | 1411 *slot = MigrateObject(heap, object, target, object_size); |
| 1408 | 1412 |
| 1409 if (object_contents == POINTER_OBJECT) { | 1413 if (object_contents == POINTER_OBJECT) { |
| 1410 heap->promotion_queue()->insert(target, object_size); | 1414 heap->promotion_queue()->insert(target, object_size); |
| 1411 } | 1415 } |
| 1412 | 1416 |
| 1413 heap->tracer()->increment_promoted_objects_size(object_size); | 1417 heap->tracer()->increment_promoted_objects_size(object_size); |
| 1414 return; | 1418 return; |
| 1415 } | 1419 } |
| 1416 } | 1420 } |
| 1417 Object* result = | 1421 Object* result = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 | 1467 |
| 1464 static inline void EvacuateSeqTwoByteString(Map* map, | 1468 static inline void EvacuateSeqTwoByteString(Map* map, |
| 1465 HeapObject** slot, | 1469 HeapObject** slot, |
| 1466 HeapObject* object) { | 1470 HeapObject* object) { |
| 1467 int object_size = SeqTwoByteString::cast(object)-> | 1471 int object_size = SeqTwoByteString::cast(object)-> |
| 1468 SeqTwoByteStringSize(map->instance_type()); | 1472 SeqTwoByteStringSize(map->instance_type()); |
| 1469 EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); | 1473 EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); |
| 1470 } | 1474 } |
| 1471 | 1475 |
| 1472 | 1476 |
| 1477 static inline void EvacuateSlicedString(Map* map, |
| 1478 HeapObject** slot, |
| 1479 HeapObject* object) { |
| 1480 ASSERT(object->IsSlicedString()); |
| 1481 Heap* heap = map->heap(); |
| 1482 int slice_size = SlicedString::kSize; |
| 1483 if (heap->ShouldBePromoted(object->address(), slice_size)) { |
| 1484 SlicedString* slice = SlicedString::cast(object); |
| 1485 String* parent = slice->parent(); |
| 1486 |
| 1487 // Parent string might just have been moved and forwarded. |
| 1488 MapWord parent_word = parent->map_word(); |
| 1489 if (parent_word.IsForwardingAddress()) { |
| 1490 parent = String::cast(parent_word.ToForwardingAddress()); |
| 1491 } |
| 1492 ASSERT(!StringShape(parent).IsIndirect()); |
| 1493 |
| 1494 int length = slice->length(); |
| 1495 // Allocate space for unpacked and truncated substring. |
| 1496 int size = parent->IsAsciiRepresentation() |
| 1497 ? SeqAsciiString::SizeFor(length) |
| 1498 : SeqTwoByteString::SizeFor(length); |
| 1499 MaybeObject* maybe_result; |
| 1500 if (size > Page::kMaxHeapObjectSize) { |
| 1501 maybe_result = heap->lo_space()->AllocateRawFixedArray(size); |
| 1502 } else { |
| 1503 maybe_result = heap->old_data_space()->AllocateRaw(size); |
| 1504 } |
| 1505 |
| 1506 Object* result = NULL; |
| 1507 // Write substring to allocated space. |
| 1508 if (maybe_result->ToObject(&result)) { |
| 1509 int offset = slice->offset(); |
| 1510 if (parent->IsAsciiRepresentation()) { |
| 1511 HeapObject::cast(result)->set_map(heap->ascii_string_map()); |
| 1512 char* dest = SeqAsciiString::cast(result)->GetChars(); |
| 1513 String::WriteToFlat(parent, dest, offset, length + offset); |
| 1514 } else { |
| 1515 HeapObject::cast(result)->set_map(heap->string_map()); |
| 1516 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
| 1517 String::WriteToFlat(parent, dest, offset, length + offset); |
| 1518 } |
| 1519 ASSERT(!heap->InNewSpace(result)); |
| 1520 String* string_result = String::cast(result); |
| 1521 string_result->set_length(length); |
| 1522 string_result->set_hash_field(parent->hash_field()); |
| 1523 |
| 1524 *slot = HeapObject::cast(result); |
| 1525 ForwardAndLogMigration(heap, object, *slot); |
| 1526 |
| 1527 heap->tracer()->increment_promoted_objects_size(size); |
| 1528 return; |
| 1529 } |
| 1530 // If allocation failed, just skip promotion. |
| 1531 } |
| 1532 Object* result = |
| 1533 heap->new_space()->AllocateRaw(slice_size)->ToObjectUnchecked(); |
| 1534 *slot = MigrateObject(heap, object, HeapObject::cast(result), slice_size); |
| 1535 return; |
| 1536 } |
| 1537 |
| 1538 |
| 1473 static inline bool IsShortcutCandidate(int type) { | 1539 static inline bool IsShortcutCandidate(int type) { |
| 1474 return ((type & kShortcutTypeMask) == kShortcutTypeTag); | 1540 return ((type & kShortcutTypeMask) == kShortcutTypeTag); |
| 1475 } | 1541 } |
| 1476 | 1542 |
| 1477 static inline void EvacuateShortcutCandidate(Map* map, | 1543 static inline void EvacuateShortcutCandidate(Map* map, |
| 1478 HeapObject** slot, | 1544 HeapObject** slot, |
| 1479 HeapObject* object) { | 1545 HeapObject* object) { |
| 1480 ASSERT(IsShortcutCandidate(map->instance_type())); | 1546 ASSERT(IsShortcutCandidate(map->instance_type())); |
| 1481 | 1547 |
| 1482 if (ConsString::cast(object)->unchecked_second() == | 1548 if (ConsString::cast(object)->unchecked_second() == |
| (...skipping 4663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6146 } | 6212 } |
| 6147 | 6213 |
| 6148 | 6214 |
| 6149 void ExternalStringTable::TearDown() { | 6215 void ExternalStringTable::TearDown() { |
| 6150 new_space_strings_.Free(); | 6216 new_space_strings_.Free(); |
| 6151 old_space_strings_.Free(); | 6217 old_space_strings_.Free(); |
| 6152 } | 6218 } |
| 6153 | 6219 |
| 6154 | 6220 |
| 6155 } } // namespace v8::internal | 6221 } } // namespace v8::internal |
| OLD | NEW |