Use smi zero instead of undefine_value to zap dead weak cells.
authorulan@chromium.org <ulan@chromium.org>
Tue, 21 Oct 2014 09:42:16 +0000 (09:42 +0000)
committerulan@chromium.org <ulan@chromium.org>
Tue, 21 Oct 2014 09:42:16 +0000 (09:42 +0000)
It is faster to test for smi zero from generated code.

BUG=
R=erikcorry@chromium.org

Review URL: https://codereview.chromium.org/637253004

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24758 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/heap/mark-compact.cc
src/heap/objects-visiting-inl.h
src/objects-inl.h
src/objects.cc
src/objects.h
test/cctest/test-heap.cc

index 7e674ab..f309eae 100644 (file)
@@ -2744,9 +2744,11 @@ void MarkCompactCollector::ProcessAndClearWeakCells() {
   Object* weak_cell_obj = heap()->encountered_weak_cells();
   while (weak_cell_obj != Smi::FromInt(0)) {
     WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj);
-    HeapObject* value = weak_cell->value();
+    // We do not insert cleared weak cells into the list, so the value
+    // cannot be a Smi here.
+    HeapObject* value = HeapObject::cast(weak_cell->value());
     if (!MarkCompactCollector::IsMarked(value)) {
-      weak_cell->clear(undefined);
+      weak_cell->clear();
     } else {
       Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset);
       heap()->mark_compact_collector()->RecordSlot(slot, slot, value);
index 28dfbc5..1f37306 100644 (file)
@@ -359,9 +359,9 @@ void StaticMarkingVisitor<StaticVisitor>::VisitWeakCell(Map* map,
   WeakCell* weak_cell = reinterpret_cast<WeakCell*>(object);
   Object* undefined = heap->undefined_value();
   // Enqueue weak cell in linked list of encountered weak collections.
-  // We can ignore weak cells with cleared values because they will always point
-  // to the undefined_value.
-  if (weak_cell->next() == undefined && weak_cell->value() != undefined) {
+  // We can ignore weak cells with cleared values because they will always
+  // contain smi zero.
+  if (weak_cell->next() == undefined && !weak_cell->cleared()) {
     weak_cell->set_next(heap->encountered_weak_cells());
     heap->set_encountered_weak_cells(weak_cell);
   }
index a5b46a4..26adbc1 100644 (file)
@@ -1930,13 +1930,14 @@ void PropertyCell::set_type_raw(Object* val, WriteBarrierMode ignored) {
 }
 
 
-HeapObject* WeakCell::value() const {
+Object* WeakCell::value() const {
   return HeapObject::cast(READ_FIELD(this, kValueOffset));
 }
 
 
-void WeakCell::clear(HeapObject* undefined) {
-  WRITE_FIELD(this, kValueOffset, undefined);
+void WeakCell::clear() {
+  DCHECK(GetHeap()->gc_state() == Heap::MARK_COMPACT);
+  WRITE_FIELD(this, kValueOffset, Smi::FromInt(0));
 }
 
 
@@ -1946,6 +1947,9 @@ void WeakCell::initialize(HeapObject* val) {
 }
 
 
+bool WeakCell::cleared() const { return value() == Smi::FromInt(0); }
+
+
 Object* WeakCell::next() const { return READ_FIELD(this, kNextOffset); }
 
 
index 07ad6f1..811ad74 100644 (file)
@@ -9829,7 +9829,7 @@ Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
   Isolate* isolate = script->GetIsolate();
   if (!script->wrapper()->IsUndefined()) {
     Handle<WeakCell> cell(WeakCell::cast(script->wrapper()));
-    if (!cell->value()->IsUndefined()) {
+    if (!cell->cleared()) {
       // Return a handle for the existing script wrapper from the cache.
       return handle(JSObject::cast(cell->value()));
     }
index 41beca4..f7be910 100644 (file)
@@ -9590,14 +9590,16 @@ class PropertyCell: public Cell {
 
 class WeakCell : public HeapObject {
  public:
-  inline HeapObject* value() const;
+  inline Object* value() const;
 
   // This should not be called by anyone except GC.
-  inline void clear(HeapObject* undefined);
+  inline void clear();
 
   // This should not be called by anyone except allocator.
   inline void initialize(HeapObject* value);
 
+  inline bool cleared() const;
+
   DECL_ACCESSORS(next, Object)
 
   DECLARE_CAST(WeakCell)
index f3dfeca..ac121e0 100644 (file)
@@ -4310,8 +4310,8 @@ TEST(WeakCell) {
   CHECK(weak_cell1->value()->IsFixedArray());
   CHECK_EQ(*survivor, weak_cell2->value());
   heap->CollectAllAvailableGarbage();
+  CHECK(weak_cell1->cleared());
   CHECK_EQ(*survivor, weak_cell2->value());
-  CHECK(weak_cell2->value()->IsFixedArray());
 }
 
 
@@ -4342,7 +4342,7 @@ TEST(WeakCellsWithIncrementalMarking) {
   heap->CollectAllGarbage(Heap::kNoGCFlags);
   CHECK_EQ(*survivor, weak_cells[0]->value());
   for (int i = 1; i < N; i++) {
-    CHECK(weak_cells[i]->value()->IsUndefined());
+    CHECK(weak_cells[i]->cleared());
   }
 }