invalidated-slots-inl.h 2.52 KB
Newer Older
1 2 3 4
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_HEAP_INVALIDATED_SLOTS_INL_H_
#define V8_HEAP_INVALIDATED_SLOTS_INL_H_
7 8 9 10 11

#include <map>

#include "src/heap/invalidated-slots.h"
#include "src/heap/spaces.h"
12 13
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/objects-body-descriptors.h"
14
#include "src/objects/objects.h"
15
#include "src/utils/allocation.h"
16 17 18 19 20 21 22 23 24 25 26 27 28 29

namespace v8 {
namespace internal {

bool InvalidatedSlotsFilter::IsValid(Address slot) {
#ifdef DEBUG
  DCHECK_LT(slot, sentinel_);
  // Slots must come in non-decreasing order.
  DCHECK_LE(last_slot_, slot);
  last_slot_ = slot;
#endif
  if (slot < invalidated_start_) {
    return true;
  }
30 31 32 33 34 35 36 37

  while (slot >= next_invalidated_start_) {
    NextInvalidatedObject();
  }

  HeapObject invalidated_object = HeapObject::FromAddress(invalidated_start_);

  if (invalidated_size_ == 0) {
38
    DCHECK(invalidated_object.map().IsMap());
39
    invalidated_size_ = invalidated_object.Size();
40
  }
41

42 43
  int offset = static_cast<int>(slot - invalidated_start_);
  DCHECK_GT(offset, 0);
44 45 46 47 48 49 50 51 52 53
  if (offset < invalidated_size_)
    return invalidated_object.IsValidSlot(invalidated_object.map(), offset);

  NextInvalidatedObject();
  return true;
}

void InvalidatedSlotsFilter::NextInvalidatedObject() {
  invalidated_start_ = next_invalidated_start_;
  invalidated_size_ = 0;
54

55 56 57 58 59
  if (iterator_ == iterator_end_) {
    next_invalidated_start_ = sentinel_;
  } else {
    next_invalidated_start_ = iterator_->address();
    iterator_++;
60 61 62
  }
}

63 64 65 66 67 68 69 70 71 72
void InvalidatedSlotsCleanup::Free(Address free_start, Address free_end) {
#ifdef DEBUG
  DCHECK_LT(free_start, free_end);
  // Free regions should come in increasing order and do not overlap
  DCHECK_LE(last_free_, free_start);
  last_free_ = free_start;
#endif

  if (iterator_ == iterator_end_) return;

73 74
  // Ignore invalidated objects that start before free region
  while (invalidated_start_ < free_start) {
75 76 77 78
    ++iterator_;
    NextInvalidatedObject();
  }

79 80 81 82
  // Remove all invalidated objects that start within
  // free region.
  while (invalidated_start_ < free_end) {
    iterator_ = invalidated_slots_->erase(iterator_);
83 84 85 86 87 88
    NextInvalidatedObject();
  }
}

void InvalidatedSlotsCleanup::NextInvalidatedObject() {
  if (iterator_ != iterator_end_) {
89
    invalidated_start_ = iterator_->address();
90 91 92 93 94
  } else {
    invalidated_start_ = sentinel_;
  }
}

95 96 97
}  // namespace internal
}  // namespace v8

98
#endif  // V8_HEAP_INVALIDATED_SLOTS_INL_H_