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 #include "src/heap/base/active-system-pages.h"
6
7 #include <climits>
8
9 #include "src/base/bits.h"
10 #include "src/base/macros.h"
11
12 namespace heap {
13 namespace base {
14
Init(size_t header_size,size_t page_size_bits,size_t user_page_size)15 size_t ActiveSystemPages::Init(size_t header_size, size_t page_size_bits,
16 size_t user_page_size) {
17 #if DEBUG
18 size_t page_size = 1 << page_size_bits;
19 DCHECK_LE(RoundUp(user_page_size, page_size) >> page_size_bits,
20 ActiveSystemPages::kMaxPages);
21 #endif // DEBUG
22 Clear();
23 return Add(0, header_size, page_size_bits);
24 }
25
Add(uintptr_t start,uintptr_t end,size_t page_size_bits)26 size_t ActiveSystemPages::Add(uintptr_t start, uintptr_t end,
27 size_t page_size_bits) {
28 const size_t page_size = 1 << page_size_bits;
29
30 DCHECK_LE(start, end);
31 DCHECK_LE(end, kMaxPages * page_size);
32
33 // Make sure we actually get the bitcount as argument.
34 DCHECK_LT(page_size_bits, sizeof(uintptr_t) * CHAR_BIT);
35
36 const uintptr_t start_page_bit =
37 RoundDown(start, page_size) >> page_size_bits;
38 const uintptr_t end_page_bit = RoundUp(end, page_size) >> page_size_bits;
39 DCHECK_LE(start_page_bit, end_page_bit);
40
41 const uintptr_t bits = end_page_bit - start_page_bit;
42 DCHECK_LE(bits, kMaxPages);
43 const bitset_t mask = bits == kMaxPages
44 ? int64_t{-1}
45 : ((uint64_t{1} << bits) - 1) << start_page_bit;
46 const bitset_t added_pages = ~value_ & mask;
47 value_ |= mask;
48 return added_pages.count();
49 }
50
Reduce(ActiveSystemPages updated_value)51 size_t ActiveSystemPages::Reduce(ActiveSystemPages updated_value) {
52 DCHECK_EQ(~value_ & updated_value.value_, 0);
53 const bitset_t removed_pages(value_ & ~updated_value.value_);
54 value_ = updated_value.value_;
55 return removed_pages.count();
56 }
57
Clear()58 size_t ActiveSystemPages::Clear() {
59 const size_t removed_pages = value_.count();
60 value_ = 0;
61 return removed_pages;
62 }
63
Size(size_t page_size_bits) const64 size_t ActiveSystemPages::Size(size_t page_size_bits) const {
65 // Make sure we don't get the full page size as argument.
66 DCHECK_LT(page_size_bits, sizeof(uintptr_t) * CHAR_BIT);
67 return value_.count() * (size_t{1} << page_size_bits);
68 }
69
70 } // namespace base
71 } // namespace heap
72