| Index: src/mark-compact.cc
|
| diff --git a/src/mark-compact.cc b/src/mark-compact.cc
|
| index 263de4878fcbc83661a57d70183df2166b04860a..65d838cdf95b895a8c86430f452f9b8e1715dcf2 100644
|
| --- a/src/mark-compact.cc
|
| +++ b/src/mark-compact.cc
|
| @@ -38,7 +38,6 @@
|
| #include "ic-inl.h"
|
| #include "incremental-marking.h"
|
| #include "mark-compact.h"
|
| -#include "marking-thread.h"
|
| #include "objects-visiting.h"
|
| #include "objects-visiting-inl.h"
|
| #include "stub-cache.h"
|
| @@ -92,10 +91,8 @@ class VerifyMarkingVisitor: public ObjectVisitor {
|
|
|
| void VisitEmbeddedPointer(RelocInfo* rinfo) {
|
| ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
|
| - if (!FLAG_weak_embedded_maps_in_optimized_code || !FLAG_collect_maps ||
|
| - rinfo->host()->kind() != Code::OPTIMIZED_FUNCTION ||
|
| - !rinfo->target_object()->IsMap() ||
|
| - !Map::cast(rinfo->target_object())->CanTransition()) {
|
| + if (!Code::IsWeakEmbeddedObject(rinfo->host()->kind(),
|
| + rinfo->target_object())) {
|
| VisitPointer(rinfo->target_object_address());
|
| }
|
| }
|
| @@ -408,6 +405,8 @@ void MarkCompactCollector::CollectGarbage() {
|
| ASSERT(state_ == PREPARE_GC);
|
| ASSERT(encountered_weak_collections_ == Smi::FromInt(0));
|
|
|
| + heap()->allocation_mementos_found_ = 0;
|
| +
|
| MarkLiveObjects();
|
| ASSERT(heap_->incremental_marking()->IsStopped());
|
|
|
| @@ -432,9 +431,8 @@ void MarkCompactCollector::CollectGarbage() {
|
| #endif
|
|
|
| #ifdef VERIFY_HEAP
|
| - if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_optimized_code &&
|
| - heap()->weak_embedded_maps_verification_enabled()) {
|
| - VerifyWeakEmbeddedMapsInOptimizedCode();
|
| + if (heap()->weak_embedded_objects_verification_enabled()) {
|
| + VerifyWeakEmbeddedObjectsInOptimizedCode();
|
| }
|
| if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) {
|
| VerifyOmittedMapChecks();
|
| @@ -450,6 +448,11 @@ void MarkCompactCollector::CollectGarbage() {
|
| marking_parity_ = EVEN_MARKING_PARITY;
|
| }
|
|
|
| + if (FLAG_trace_track_allocation_sites &&
|
| + heap()->allocation_mementos_found_ > 0) {
|
| + PrintF("AllocationMementos found during mark-sweep = %d\n",
|
| + heap()->allocation_mementos_found_);
|
| + }
|
| tracer_ = NULL;
|
| }
|
|
|
| @@ -495,7 +498,7 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() {
|
| }
|
|
|
|
|
| -void MarkCompactCollector::VerifyWeakEmbeddedMapsInOptimizedCode() {
|
| +void MarkCompactCollector::VerifyWeakEmbeddedObjectsInOptimizedCode() {
|
| HeapObjectIterator code_iterator(heap()->code_space());
|
| for (HeapObject* obj = code_iterator.Next();
|
| obj != NULL;
|
| @@ -503,7 +506,7 @@ void MarkCompactCollector::VerifyWeakEmbeddedMapsInOptimizedCode() {
|
| Code* code = Code::cast(obj);
|
| if (code->kind() != Code::OPTIMIZED_FUNCTION) continue;
|
| if (WillBeDeoptimized(code)) continue;
|
| - code->VerifyEmbeddedMapsDependency();
|
| + code->VerifyEmbeddedObjectsDependency();
|
| }
|
| }
|
|
|
| @@ -601,20 +604,6 @@ bool MarkCompactCollector::IsConcurrentSweepingInProgress() {
|
| }
|
|
|
|
|
| -void MarkCompactCollector::MarkInParallel() {
|
| - for (int i = 0; i < FLAG_marking_threads; i++) {
|
| - isolate()->marking_threads()[i]->StartMarking();
|
| - }
|
| -}
|
| -
|
| -
|
| -void MarkCompactCollector::WaitUntilMarkingCompleted() {
|
| - for (int i = 0; i < FLAG_marking_threads; i++) {
|
| - isolate()->marking_threads()[i]->WaitForMarkingThread();
|
| - }
|
| -}
|
| -
|
| -
|
| bool Marking::TransferMark(Address old_start, Address new_start) {
|
| // This is only used when resizing an object.
|
| ASSERT(MemoryChunk::FromAddress(old_start) ==
|
| @@ -1481,7 +1470,7 @@ class MarkCompactMarkingVisitor
|
| // Mark the backing hash table without pushing it on the marking stack.
|
| Object* table_object = weak_collection->table();
|
| if (!table_object->IsHashTable()) return;
|
| - ObjectHashTable* table = ObjectHashTable::cast(table_object);
|
| + WeakHashTable* table = WeakHashTable::cast(table_object);
|
| Object** table_slot =
|
| HeapObject::RawField(weak_collection, JSWeakCollection::kTableOffset);
|
| MarkBit table_mark = Marking::MarkBitFrom(table);
|
| @@ -2017,6 +2006,13 @@ int MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage(
|
| int size = object->Size();
|
| survivors_size += size;
|
|
|
| + if (FLAG_trace_track_allocation_sites && object->IsJSObject()) {
|
| + if (AllocationMemento::FindForJSObject(JSObject::cast(object), true)
|
| + != NULL) {
|
| + heap()->allocation_mementos_found_++;
|
| + }
|
| + }
|
| +
|
| offset++;
|
| current_cell >>= 1;
|
| // Aggressively promote young survivors to the old space.
|
| @@ -2116,6 +2112,8 @@ void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
|
| // Handle the string table specially.
|
| MarkStringTable(visitor);
|
|
|
| + MarkWeakObjectToCodeTable();
|
| +
|
| // There may be overflowed objects in the heap. Visit them now.
|
| while (marking_deque_.overflowed()) {
|
| RefillMarkingDeque();
|
| @@ -2156,6 +2154,16 @@ void MarkCompactCollector::MarkImplicitRefGroups() {
|
| }
|
|
|
|
|
| +void MarkCompactCollector::MarkWeakObjectToCodeTable() {
|
| + HeapObject* weak_object_to_code_table =
|
| + HeapObject::cast(heap()->weak_object_to_code_table());
|
| + if (!IsMarked(weak_object_to_code_table)) {
|
| + MarkBit mark = Marking::MarkBitFrom(weak_object_to_code_table);
|
| + SetMark(weak_object_to_code_table, mark);
|
| + }
|
| +}
|
| +
|
| +
|
| // Mark all objects reachable from the objects on the marking stack.
|
| // Before: the marking stack contains zero or more heap object pointers.
|
| // After: the marking stack is empty, and all objects reachable from the
|
| @@ -2523,7 +2531,8 @@ void MarkCompactCollector::ClearNonLiveReferences() {
|
| if (map_mark.Get()) {
|
| ClearNonLiveDependentCode(map->dependent_code());
|
| } else {
|
| - ClearAndDeoptimizeDependentCode(map);
|
| + ClearAndDeoptimizeDependentCode(map->dependent_code());
|
| + map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
|
| }
|
| }
|
|
|
| @@ -2537,6 +2546,31 @@ void MarkCompactCollector::ClearNonLiveReferences() {
|
| ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code());
|
| }
|
| }
|
| +
|
| + if (heap_->weak_object_to_code_table()->IsHashTable()) {
|
| + WeakHashTable* table =
|
| + WeakHashTable::cast(heap_->weak_object_to_code_table());
|
| + uint32_t capacity = table->Capacity();
|
| + for (uint32_t i = 0; i < capacity; i++) {
|
| + uint32_t key_index = table->EntryToIndex(i);
|
| + Object* key = table->get(key_index);
|
| + if (!table->IsKey(key)) continue;
|
| + uint32_t value_index = table->EntryToValueIndex(i);
|
| + Object* value = table->get(value_index);
|
| + if (IsMarked(key)) {
|
| + if (!IsMarked(value)) {
|
| + HeapObject* obj = HeapObject::cast(value);
|
| + MarkBit mark = Marking::MarkBitFrom(obj);
|
| + SetMark(obj, mark);
|
| + }
|
| + ClearNonLiveDependentCode(DependentCode::cast(value));
|
| + } else {
|
| + ClearAndDeoptimizeDependentCode(DependentCode::cast(value));
|
| + table->set(key_index, heap_->the_hole_value());
|
| + table->set(value_index, heap_->the_hole_value());
|
| + }
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -2602,9 +2636,9 @@ void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
|
| }
|
|
|
|
|
| -void MarkCompactCollector::ClearAndDeoptimizeDependentCode(Map* map) {
|
| +void MarkCompactCollector::ClearAndDeoptimizeDependentCode(
|
| + DependentCode* entries) {
|
| DisallowHeapAllocation no_allocation;
|
| - DependentCode* entries = map->dependent_code();
|
| DependentCode::GroupStartIndexes starts(entries);
|
| int number_of_entries = starts.number_of_entries();
|
| if (number_of_entries == 0) return;
|
| @@ -2620,7 +2654,6 @@ void MarkCompactCollector::ClearAndDeoptimizeDependentCode(Map* map) {
|
| }
|
| entries->clear_at(i);
|
| }
|
| - map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
|
| }
|
|
|
|
|
| @@ -2727,9 +2760,8 @@ void MarkCompactCollector::MigrateObject(Address dst,
|
| int size,
|
| AllocationSpace dest) {
|
| HEAP_PROFILE(heap(), ObjectMoveEvent(src, dst));
|
| - // TODO(hpayer): Replace these checks with asserts.
|
| - CHECK(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest));
|
| - CHECK(dest != LO_SPACE && size <= Page::kMaxNonCodeHeapObjectSize);
|
| + ASSERT(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest));
|
| + ASSERT(dest != LO_SPACE && size <= Page::kMaxNonCodeHeapObjectSize);
|
| if (dest == OLD_POINTER_SPACE) {
|
| Address src_slot = src;
|
| Address dst_slot = dst;
|
| @@ -3459,6 +3491,13 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
| updating_visitor.VisitPointer(heap_->native_contexts_list_address());
|
|
|
| heap_->string_table()->Iterate(&updating_visitor);
|
| + updating_visitor.VisitPointer(heap_->weak_object_to_code_table_address());
|
| + if (heap_->weak_object_to_code_table()->IsHashTable()) {
|
| + WeakHashTable* table =
|
| + WeakHashTable::cast(heap_->weak_object_to_code_table());
|
| + table->Iterate(&updating_visitor);
|
| + table->Rehash(heap_->undefined_value());
|
| + }
|
|
|
| // Update pointers from external string table.
|
| heap_->UpdateReferencesInExternalStringTable(
|
|
|