1// Copyright 2022 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_
6#define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_
7
8#include <climits>
9#include <cstddef>
10
11#include "cppgc/internal/api-constants.h"
12#include "cppgc/internal/base-page-handle.h"
13#include "v8config.h"  // NOLINT(build/include_directory)
14
15#if defined(CPPGC_CAGED_HEAP)
16
17namespace cppgc {
18namespace internal {
19
20class V8_EXPORT CagedHeapBase {
21 public:
22  V8_INLINE static uintptr_t OffsetFromAddress(const void* address) {
23    return reinterpret_cast<uintptr_t>(address) &
24           (api_constants::kCagedHeapReservationAlignment - 1);
25  }
26
27  V8_INLINE static bool IsWithinCage(const void* address) {
28    CPPGC_DCHECK(g_heap_base_);
29    return (reinterpret_cast<uintptr_t>(address) &
30            ~(api_constants::kCagedHeapReservationAlignment - 1)) ==
31           g_heap_base_;
32  }
33
34  V8_INLINE static bool AreWithinCage(const void* addr1, const void* addr2) {
35#if defined(CPPGC_2GB_CAGE)
36    static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT - 1;
37#else   //! defined(CPPGC_2GB_CAGE)
38    static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT;
39#endif  //! defined(CPPGC_2GB_CAGE)
40    static_assert((static_cast<size_t>(1) << kHalfWordShift) ==
41                  api_constants::kCagedHeapReservationSize);
42    CPPGC_DCHECK(g_heap_base_);
43    return !(((reinterpret_cast<uintptr_t>(addr1) ^ g_heap_base_) |
44              (reinterpret_cast<uintptr_t>(addr2) ^ g_heap_base_)) >>
45             kHalfWordShift);
46  }
47
48  V8_INLINE static uintptr_t GetBase() { return g_heap_base_; }
49
50 private:
51  friend class CagedHeap;
52
53  static uintptr_t g_heap_base_;
54};
55
56}  // namespace internal
57}  // namespace cppgc
58
59#endif  // defined(CPPGC_CAGED_HEAP)
60
61#endif  // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_
62