pointer-policies.cc 3.79 KB
Newer Older
Anton Bikineev's avatar
Anton Bikineev committed
1 2 3 4
// Copyright 2020 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
#include "include/cppgc/internal/pointer-policies.h"
Anton Bikineev's avatar
Anton Bikineev committed
6

7
#include "include/cppgc/internal/caged-heap-local-data.h"
8
#include "include/cppgc/internal/persistent-node.h"
9
#include "src/base/logging.h"
Anton Bikineev's avatar
Anton Bikineev committed
10
#include "src/base/macros.h"
11 12
#include "src/base/platform/platform.h"
#include "src/heap/cppgc/heap-object-header.h"
13
#include "src/heap/cppgc/heap-page.h"
14
#include "src/heap/cppgc/heap.h"
15
#include "src/heap/cppgc/page-memory.h"
16
#include "src/heap/cppgc/prefinalizer-handler.h"
17
#include "src/heap/cppgc/process-heap.h"
Anton Bikineev's avatar
Anton Bikineev committed
18 19 20 21

namespace cppgc {
namespace internal {

22 23
namespace {

24
#if defined(DEBUG)
25 26 27 28
bool IsOnStack(const void* address) {
  return v8::base::Stack::GetCurrentStackPosition() <= address &&
         address < v8::base::Stack::GetStackStart();
}
29
#endif  // defined(DEBUG)
Anton Bikineev's avatar
Anton Bikineev committed
30

31 32
}  // namespace

33 34
void EnabledCheckingPolicy::CheckPointerImpl(const void* ptr,
                                             bool points_to_payload) {
35 36 37 38 39 40 41
  // `ptr` must not reside on stack.
  DCHECK(!IsOnStack(ptr));
  auto* base_page = BasePage::FromPayload(ptr);
  // Large objects do not support mixins. This also means that `base_page` is
  // valid for large objects.
  DCHECK_IMPLIES(base_page->is_large(), points_to_payload);

42 43 44 45 46 47 48 49 50 51
  // References cannot change their heap association which means that state is
  // immutable once it is set.
  if (!heap_) {
    heap_ = base_page->heap();
    if (!heap_->page_backend()->Lookup(reinterpret_cast<Address>(this))) {
      // If `this` is not contained within the heap of `ptr`, we must deal with
      // an on-stack or off-heap reference. For both cases there should be no
      // heap registered.
      CHECK(!HeapRegistry::TryFromManagedPointer(this));
    }
52 53 54
  }

  // Member references should never mix heaps.
55
  DCHECK_EQ(heap_, base_page->heap());
56 57 58 59

  // Header checks.
  const HeapObjectHeader* header = nullptr;
  if (points_to_payload) {
Omer Katz's avatar
Omer Katz committed
60
    header = &HeapObjectHeader::FromObject(ptr);
61
  } else if (!heap_->sweeper().IsSweepingInProgress()) {
62 63
    // Mixin case.
    header = &base_page->ObjectHeaderFromInnerAddress(ptr);
Omer Katz's avatar
Omer Katz committed
64 65
    DCHECK_LE(header->ObjectStart(), ptr);
    DCHECK_GT(header->ObjectEnd(), ptr);
66 67 68 69 70
  }
  if (header) {
    DCHECK(!header->IsFree());
  }

71 72 73 74 75 76 77 78 79 80 81 82 83 84
#ifdef CPPGC_CHECK_ASSIGNMENTS_IN_PREFINALIZERS
  if (heap_->prefinalizer_handler()->IsInvokingPreFinalizers()) {
    // During prefinalizers invocation, check that |ptr| refers to a live object
    // and that it is assigned to a live slot.
    DCHECK(header->IsMarked());
    // Slot can be in a large object.
    const auto* slot_page = BasePage::FromInnerAddress(heap_, this);
    // Off-heap slots (from other heaps or on-stack) are considered live.
    bool slot_is_live =
        !slot_page || slot_page->ObjectHeaderFromInnerAddress(this).IsMarked();
    DCHECK(slot_is_live);
    USE(slot_is_live);
  }
#endif  // CPPGC_CHECK_ASSIGNMENTS_IN_PREFINALIZERS
Anton Bikineev's avatar
Anton Bikineev committed
85 86
}

87 88
PersistentRegion& StrongPersistentPolicy::GetPersistentRegion(
    const void* object) {
89
  auto* heap = BasePage::FromPayload(object)->heap();
90 91 92
  return heap->GetStrongPersistentRegion();
}

93 94
PersistentRegion& WeakPersistentPolicy::GetPersistentRegion(
    const void* object) {
95
  auto* heap = BasePage::FromPayload(object)->heap();
96 97 98
  return heap->GetWeakPersistentRegion();
}

99 100
CrossThreadPersistentRegion&
StrongCrossThreadPersistentPolicy::GetPersistentRegion(const void* object) {
101 102 103 104
  auto* heap = BasePage::FromPayload(object)->heap();
  return heap->GetStrongCrossThreadPersistentRegion();
}

105 106
CrossThreadPersistentRegion&
WeakCrossThreadPersistentPolicy::GetPersistentRegion(const void* object) {
107 108 109 110
  auto* heap = BasePage::FromPayload(object)->heap();
  return heap->GetWeakCrossThreadPersistentRegion();
}

Anton Bikineev's avatar
Anton Bikineev committed
111 112
}  // namespace internal
}  // namespace cppgc