1342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved.
2342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch// found in the LICENSE file.
4342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
5342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/remembered-set.h"
6342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/heap-inl.h"
7342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/heap.h"
8342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/mark-compact.h"
9342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/slot-set.h"
10342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/spaces.h"
11342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/heap/store-buffer.h"
12342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
13342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochnamespace v8 {
14342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochnamespace internal {
15342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
16342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtemplate <PointerDirection direction>
17342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochvoid RememberedSet<direction>::ClearInvalidSlots(Heap* heap) {
18342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  STATIC_ASSERT(direction == OLD_TO_NEW);
1921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  for (MemoryChunk* chunk : *heap->old_space()) {
20342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    SlotSet* slots = GetSlotSet(chunk);
21342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if (slots != nullptr) {
221b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      slots->Iterate([heap, chunk](Address addr) {
23342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        Object** slot = reinterpret_cast<Object**>(addr);
241b268ca467c924004286c97bac133db489cf43d0Ben Murdoch        return IsValidSlot(heap, chunk, slot) ? KEEP_SLOT : REMOVE_SLOT;
25342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      });
26342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    }
27342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  }
28342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch}
29342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
30342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtemplate <PointerDirection direction>
31342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochvoid RememberedSet<direction>::VerifyValidSlots(Heap* heap) {
32342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  Iterate(heap, [heap](Address addr) {
331b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    HeapObject* obj =
341b268ca467c924004286c97bac133db489cf43d0Ben Murdoch        heap->mark_compact_collector()->FindBlackObjectBySlotSlow(addr);
351b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    if (obj == nullptr) {
361b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      // The slot is in dead object.
371b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      MemoryChunk* chunk = MemoryChunk::FromAnyPointerAddress(heap, addr);
381b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      AllocationSpace owner = chunk->owner()->identity();
391b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      // The old to old remembered set should not have dead slots.
401b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      CHECK_NE(direction, OLD_TO_OLD);
411b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      // The old to new remembered set is allowed to have slots in dead
421b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      // objects only in map and large object space because these space
431b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      // cannot have raw untagged pointers.
441b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      CHECK(owner == MAP_SPACE || owner == LO_SPACE);
451b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    } else {
461b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      int offset = static_cast<int>(addr - obj->address());
471b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      CHECK(obj->IsValidSlot(offset));
48342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    }
491b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    return KEEP_SLOT;
50342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  });
51342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch}
52342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
53342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtemplate <PointerDirection direction>
541b268ca467c924004286c97bac133db489cf43d0Ben Murdochbool RememberedSet<direction>::IsValidSlot(Heap* heap, MemoryChunk* chunk,
551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                           Object** slot) {
56342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  STATIC_ASSERT(direction == OLD_TO_NEW);
57342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  Object* object = *slot;
58342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  if (!heap->InNewSpace(object)) {
59342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    return false;
60342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  }
61342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  HeapObject* heap_object = HeapObject::cast(object);
62342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  // If the target object is not black, the source slot must be part
63342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  // of a non-black (dead) object.
64342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  return Marking::IsBlack(Marking::MarkBitFrom(heap_object)) &&
651b268ca467c924004286c97bac133db489cf43d0Ben Murdoch         heap->mark_compact_collector()->IsSlotInBlackObject(
661b268ca467c924004286c97bac133db489cf43d0Ben Murdoch             chunk, reinterpret_cast<Address>(slot));
67342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch}
68342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
69342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtemplate void RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(Heap* heap);
70342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtemplate void RememberedSet<OLD_TO_NEW>::VerifyValidSlots(Heap* heap);
711b268ca467c924004286c97bac133db489cf43d0Ben Murdochtemplate void RememberedSet<OLD_TO_OLD>::VerifyValidSlots(Heap* heap);
72342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
73342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch}  // namespace internal
74342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch}  // namespace v8
75