| 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 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 current_page_->set_scan_on_scavenge(true); | 984 current_page_->set_scan_on_scavenge(true); |
| 985 ASSERT(start_of_current_page_ != store_buffer_->Top()); | 985 ASSERT(start_of_current_page_ != store_buffer_->Top()); |
| 986 store_buffer_->SetTop(start_of_current_page_); | 986 store_buffer_->SetTop(start_of_current_page_); |
| 987 } | 987 } |
| 988 } else { | 988 } else { |
| 989 UNREACHABLE(); | 989 UNREACHABLE(); |
| 990 } | 990 } |
| 991 } | 991 } |
| 992 | 992 |
| 993 | 993 |
| 994 static void ScavengeObjectAndMarkSlot(HeapObject** p, HeapObject* object) { |
| 995 Heap::ScavengeObject(p, object); |
| 996 |
| 997 // TODO(gc) ISOLATES MERGE |
| 998 if (HEAP->InNewSpace(*p)) { |
| 999 ASSERT(HEAP->InToSpace(*p)); |
| 1000 HEAP->store_buffer()->EnterDirectlyIntoStoreBuffer( |
| 1001 reinterpret_cast<Address>(p)); |
| 1002 } |
| 1003 } |
| 1004 |
| 1005 |
| 994 void Heap::Scavenge() { | 1006 void Heap::Scavenge() { |
| 995 #ifdef DEBUG | 1007 #ifdef DEBUG |
| 996 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers(); | 1008 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers(); |
| 997 #endif | 1009 #endif |
| 998 | 1010 |
| 999 gc_state_ = SCAVENGE; | 1011 gc_state_ = SCAVENGE; |
| 1000 | 1012 |
| 1001 // Implements Cheney's copying algorithm | 1013 // Implements Cheney's copying algorithm |
| 1002 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1014 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
| 1003 | 1015 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 | 1059 |
| 1048 ScavengeVisitor scavenge_visitor(this); | 1060 ScavengeVisitor scavenge_visitor(this); |
| 1049 // Copy roots. | 1061 // Copy roots. |
| 1050 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); | 1062 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); |
| 1051 | 1063 |
| 1052 // Copy objects reachable from the old generation. | 1064 // Copy objects reachable from the old generation. |
| 1053 { | 1065 { |
| 1054 StoreBufferRebuildScope scope(this, | 1066 StoreBufferRebuildScope scope(this, |
| 1055 store_buffer(), | 1067 store_buffer(), |
| 1056 &ScavengeStoreBufferCallback); | 1068 &ScavengeStoreBufferCallback); |
| 1057 store_buffer()->IteratePointersToNewSpace(&ScavengeObject); | 1069 store_buffer()->IteratePointersToNewSpace(&ScavengeObjectAndMarkSlot); |
| 1058 } | 1070 } |
| 1059 | 1071 |
| 1060 // Copy objects reachable from cells by scavenging cell values directly. | 1072 // Copy objects reachable from cells by scavenging cell values directly. |
| 1061 HeapObjectIterator cell_iterator(cell_space_); | 1073 HeapObjectIterator cell_iterator(cell_space_); |
| 1062 for (HeapObject* cell = cell_iterator.Next(); | 1074 for (HeapObject* cell = cell_iterator.Next(); |
| 1063 cell != NULL; cell = cell_iterator.Next()) { | 1075 cell != NULL; cell = cell_iterator.Next()) { |
| 1064 if (cell->IsJSGlobalPropertyCell()) { | 1076 if (cell->IsJSGlobalPropertyCell()) { |
| 1065 Address value_address = | 1077 Address value_address = |
| 1066 reinterpret_cast<Address>(cell) + | 1078 reinterpret_cast<Address>(cell) + |
| 1067 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 1079 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 heap->promotion_queue()->insert(target, object_size); | 1467 heap->promotion_queue()->insert(target, object_size); |
| 1456 } | 1468 } |
| 1457 | 1469 |
| 1458 heap->tracer()->increment_promoted_objects_size(object_size); | 1470 heap->tracer()->increment_promoted_objects_size(object_size); |
| 1459 return; | 1471 return; |
| 1460 } | 1472 } |
| 1461 } | 1473 } |
| 1462 Object* result = | 1474 Object* result = |
| 1463 heap->new_space()->AllocateRaw(object_size)->ToObjectUnchecked(); | 1475 heap->new_space()->AllocateRaw(object_size)->ToObjectUnchecked(); |
| 1464 *slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); | 1476 *slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); |
| 1465 // TODO(gc) isolates | |
| 1466 if (!HEAP->InNewSpace(reinterpret_cast<Address>(slot))) { | |
| 1467 HEAP->store_buffer()->EnterDirectlyIntoStoreBuffer( | |
| 1468 reinterpret_cast<Address>(slot)); | |
| 1469 } | |
| 1470 return; | 1477 return; |
| 1471 } | 1478 } |
| 1472 | 1479 |
| 1473 | 1480 |
| 1474 static inline void EvacuateFixedArray(Map* map, | 1481 static inline void EvacuateFixedArray(Map* map, |
| 1475 HeapObject** slot, | 1482 HeapObject** slot, |
| 1476 HeapObject* object) { | 1483 HeapObject* object) { |
| 1477 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); | 1484 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); |
| 1478 EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE>(map, | 1485 EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE>(map, |
| 1479 slot, | 1486 slot, |
| (...skipping 2548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4028 } | 4035 } |
| 4029 } else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) { | 4036 } else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) { |
| 4030 // If we have received more than kIdlesBeforeMarkCompact idle | 4037 // If we have received more than kIdlesBeforeMarkCompact idle |
| 4031 // notifications we do not perform any cleanup because we don't | 4038 // notifications we do not perform any cleanup because we don't |
| 4032 // expect to gain much by doing so. | 4039 // expect to gain much by doing so. |
| 4033 finished = true; | 4040 finished = true; |
| 4034 } | 4041 } |
| 4035 | 4042 |
| 4036 // Make sure that we have no pending context disposals and | 4043 // Make sure that we have no pending context disposals and |
| 4037 // conditionally uncommit from space. | 4044 // conditionally uncommit from space. |
| 4038 ASSERT(contexts_disposed_ == 0); | 4045 ASSERT((contexts_disposed_ == 0) || incremental_marking()->IsMarking()); |
| 4039 if (uncommit) UncommitFromSpace(); | 4046 if (uncommit) UncommitFromSpace(); |
| 4040 return finished; | 4047 return finished; |
| 4041 } | 4048 } |
| 4042 | 4049 |
| 4043 | 4050 |
| 4044 #ifdef DEBUG | 4051 #ifdef DEBUG |
| 4045 | 4052 |
| 4046 void Heap::Print() { | 4053 void Heap::Print() { |
| 4047 if (!HasBeenSetup()) return; | 4054 if (!HasBeenSetup()) return; |
| 4048 isolate()->PrintStack(); | 4055 isolate()->PrintStack(); |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4407 Object* object = *slot; | 4414 Object* object = *slot; |
| 4408 // If the store buffer becomes overfull we mark pages as being exempt from | 4415 // If the store buffer becomes overfull we mark pages as being exempt from |
| 4409 // the store buffer. These pages are scanned to find pointers that point | 4416 // the store buffer. These pages are scanned to find pointers that point |
| 4410 // to the new space. In that case we may hit newly promoted objects and | 4417 // to the new space. In that case we may hit newly promoted objects and |
| 4411 // fix the pointers before the promotion queue gets to them. Thus the 'if'. | 4418 // fix the pointers before the promotion queue gets to them. Thus the 'if'. |
| 4412 if (Heap::InFromSpace(object)) { | 4419 if (Heap::InFromSpace(object)) { |
| 4413 callback(reinterpret_cast<HeapObject**>(slot), HeapObject::cast(object)); | 4420 callback(reinterpret_cast<HeapObject**>(slot), HeapObject::cast(object)); |
| 4414 if (InNewSpace(*slot)) { | 4421 if (InNewSpace(*slot)) { |
| 4415 ASSERT(Heap::InToSpace(*slot)); | 4422 ASSERT(Heap::InToSpace(*slot)); |
| 4416 ASSERT((*slot)->IsHeapObject()); | 4423 ASSERT((*slot)->IsHeapObject()); |
| 4424 store_buffer_.EnterDirectlyIntoStoreBuffer( |
| 4425 reinterpret_cast<Address>(slot)); |
| 4417 } | 4426 } |
| 4418 } | 4427 } |
| 4419 slot_address += kPointerSize; | 4428 slot_address += kPointerSize; |
| 4420 } | 4429 } |
| 4421 } | 4430 } |
| 4422 | 4431 |
| 4423 | 4432 |
| 4424 #ifdef DEBUG | 4433 #ifdef DEBUG |
| 4425 typedef bool (*CheckStoreBufferFilter)(Object** addr); | 4434 typedef bool (*CheckStoreBufferFilter)(Object** addr); |
| 4426 | 4435 |
| (...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6004 } | 6013 } |
| 6005 | 6014 |
| 6006 | 6015 |
| 6007 void ExternalStringTable::TearDown() { | 6016 void ExternalStringTable::TearDown() { |
| 6008 new_space_strings_.Free(); | 6017 new_space_strings_.Free(); |
| 6009 old_space_strings_.Free(); | 6018 old_space_strings_.Free(); |
| 6010 } | 6019 } |
| 6011 | 6020 |
| 6012 | 6021 |
| 6013 } } // namespace v8::internal | 6022 } } // namespace v8::internal |
| OLD | NEW |