2020-06-15 18:57:06 +00:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
#ifndef INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
|
|
|
|
#define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
|
|
|
|
|
2020-06-16 22:41:00 +00:00
|
|
|
#include <array>
|
2022-04-13 13:19:02 +00:00
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdint>
|
2020-06-16 22:41:00 +00:00
|
|
|
|
|
|
|
#include "cppgc/internal/api-constants.h"
|
2022-06-09 09:26:07 +00:00
|
|
|
#include "cppgc/internal/caged-heap.h"
|
2020-06-16 22:41:00 +00:00
|
|
|
#include "cppgc/internal/logging.h"
|
|
|
|
#include "cppgc/platform.h"
|
2021-01-18 15:45:12 +00:00
|
|
|
#include "v8config.h" // NOLINT(build/include_directory)
|
2020-06-16 22:41:00 +00:00
|
|
|
|
2022-05-02 12:49:27 +00:00
|
|
|
#if __cpp_lib_bitopts
|
|
|
|
#include <bit>
|
|
|
|
#endif // __cpp_lib_bitopts
|
|
|
|
|
2022-06-09 12:56:45 +00:00
|
|
|
#if defined(CPPGC_CAGED_HEAP)
|
|
|
|
|
2020-06-15 18:57:06 +00:00
|
|
|
namespace cppgc {
|
|
|
|
namespace internal {
|
|
|
|
|
2020-06-16 22:41:00 +00:00
|
|
|
class HeapBase;
|
|
|
|
|
|
|
|
#if defined(CPPGC_YOUNG_GENERATION)
|
|
|
|
|
2022-04-13 13:19:02 +00:00
|
|
|
// AgeTable is the bytemap needed for the fast generation check in the write
|
2022-05-08 11:01:06 +00:00
|
|
|
// barrier. AgeTable contains entries that correspond to 4096 bytes memory
|
2022-04-13 13:19:02 +00:00
|
|
|
// regions (cards). Each entry in the table represents generation of the objects
|
|
|
|
// that reside on the corresponding card (young, old or mixed).
|
2022-04-26 09:24:35 +00:00
|
|
|
class V8_EXPORT AgeTable final {
|
2022-07-13 21:25:24 +00:00
|
|
|
static constexpr size_t kRequiredSize = 1 * api_constants::kMB;
|
2022-04-13 13:19:02 +00:00
|
|
|
static constexpr size_t kAllocationGranularity =
|
|
|
|
api_constants::kAllocationGranularity;
|
2020-06-16 22:41:00 +00:00
|
|
|
|
|
|
|
public:
|
2022-04-26 09:24:35 +00:00
|
|
|
// Represents age of the objects living on a single card.
|
2022-04-13 13:19:02 +00:00
|
|
|
enum class Age : uint8_t { kOld, kYoung, kMixed };
|
2022-04-26 09:24:35 +00:00
|
|
|
// When setting age for a range, consider or ignore ages of the adjacent
|
|
|
|
// cards.
|
|
|
|
enum class AdjacentCardsPolicy : uint8_t { kConsider, kIgnore };
|
2020-06-16 22:41:00 +00:00
|
|
|
|
2022-04-13 13:19:02 +00:00
|
|
|
static constexpr size_t kCardSizeInBytes =
|
2022-05-08 11:01:06 +00:00
|
|
|
api_constants::kCagedHeapReservationSize / kRequiredSize;
|
2020-06-16 22:41:00 +00:00
|
|
|
|
2022-04-13 13:19:02 +00:00
|
|
|
void SetAge(uintptr_t cage_offset, Age age) {
|
|
|
|
table_[card(cage_offset)] = age;
|
|
|
|
}
|
2022-04-26 09:24:35 +00:00
|
|
|
|
2022-04-13 13:19:02 +00:00
|
|
|
V8_INLINE Age GetAge(uintptr_t cage_offset) const {
|
|
|
|
return table_[card(cage_offset)];
|
|
|
|
}
|
2020-06-16 22:41:00 +00:00
|
|
|
|
2022-06-13 11:41:34 +00:00
|
|
|
void SetAgeForRange(uintptr_t cage_offset_begin, uintptr_t cage_offset_end,
|
|
|
|
Age age, AdjacentCardsPolicy adjacent_cards_policy);
|
|
|
|
|
|
|
|
Age GetAgeForRange(uintptr_t cage_offset_begin,
|
|
|
|
uintptr_t cage_offset_end) const;
|
|
|
|
|
2022-06-15 10:57:15 +00:00
|
|
|
void ResetForTesting();
|
2020-06-16 22:41:00 +00:00
|
|
|
|
|
|
|
private:
|
2022-04-13 13:19:02 +00:00
|
|
|
V8_INLINE size_t card(uintptr_t offset) const {
|
|
|
|
constexpr size_t kGranularityBits =
|
2022-05-02 12:49:27 +00:00
|
|
|
#if __cpp_lib_bitopts
|
|
|
|
std::countr_zero(static_cast<uint32_t>(kCardSizeInBytes));
|
|
|
|
#elif V8_HAS_BUILTIN_CTZ
|
2022-04-13 13:19:02 +00:00
|
|
|
__builtin_ctz(static_cast<uint32_t>(kCardSizeInBytes));
|
2022-05-02 12:49:27 +00:00
|
|
|
#else //! V8_HAS_BUILTIN_CTZ
|
|
|
|
// Hardcode and check with assert.
|
2022-07-13 21:25:24 +00:00
|
|
|
12;
|
2022-05-02 12:49:27 +00:00
|
|
|
#endif // !V8_HAS_BUILTIN_CTZ
|
|
|
|
static_assert((1 << kGranularityBits) == kCardSizeInBytes);
|
2020-06-16 22:41:00 +00:00
|
|
|
const size_t entry = offset >> kGranularityBits;
|
|
|
|
CPPGC_DCHECK(table_.size() > entry);
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
2022-04-13 13:19:02 +00:00
|
|
|
std::array<Age, kRequiredSize> table_;
|
2020-06-16 22:41:00 +00:00
|
|
|
};
|
|
|
|
|
2022-07-13 21:25:24 +00:00
|
|
|
static_assert(sizeof(AgeTable) == 1 * api_constants::kMB,
|
|
|
|
"Size of AgeTable is 1MB");
|
2020-06-16 22:41:00 +00:00
|
|
|
|
|
|
|
#endif // CPPGC_YOUNG_GENERATION
|
|
|
|
|
2022-06-08 15:07:01 +00:00
|
|
|
// TODO(v8:12231): Remove this class entirely so that it doesn't occupy space is
|
|
|
|
// when CPPGC_YOUNG_GENERATION is off.
|
2020-06-15 18:57:06 +00:00
|
|
|
struct CagedHeapLocalData final {
|
2022-06-09 09:26:07 +00:00
|
|
|
V8_INLINE static CagedHeapLocalData& Get() {
|
|
|
|
return *reinterpret_cast<CagedHeapLocalData*>(CagedHeapBase::GetBase());
|
|
|
|
}
|
2020-06-16 22:41:00 +00:00
|
|
|
|
|
|
|
#if defined(CPPGC_YOUNG_GENERATION)
|
|
|
|
AgeTable age_table;
|
|
|
|
#endif
|
2020-06-15 18:57:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace cppgc
|
|
|
|
|
2022-06-09 12:56:45 +00:00
|
|
|
#endif // defined(CPPGC_CAGED_HEAP)
|
|
|
|
|
2020-06-15 18:57:06 +00:00
|
|
|
#endif // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
|