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

Side by Side Diff: src/heap.cc

Issue 7833033: Promote and inflate string slices during scavenging GC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 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
« no previous file with comments | « no previous file | test/cctest/test-strings.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-strings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698