summaryrefslogtreecommitdiff
path: root/deps/v8/src/heap/cppgc/object-start-bitmap-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/heap/cppgc/object-start-bitmap-inl.h')
-rw-r--r--deps/v8/src/heap/cppgc/object-start-bitmap-inl.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/deps/v8/src/heap/cppgc/object-start-bitmap-inl.h b/deps/v8/src/heap/cppgc/object-start-bitmap-inl.h
new file mode 100644
index 0000000000..93243979aa
--- /dev/null
+++ b/deps/v8/src/heap/cppgc/object-start-bitmap-inl.h
@@ -0,0 +1,95 @@
+// 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 V8_HEAP_CPPGC_OBJECT_START_BITMAP_INL_H_
+#define V8_HEAP_CPPGC_OBJECT_START_BITMAP_INL_H_
+
+#include <algorithm>
+
+#include "src/base/bits.h"
+#include "src/heap/cppgc/object-start-bitmap.h"
+
+namespace cppgc {
+namespace internal {
+
+ObjectStartBitmap::ObjectStartBitmap(Address offset) : offset_(offset) {
+ Clear();
+}
+
+HeapObjectHeader* ObjectStartBitmap::FindHeader(
+ ConstAddress address_maybe_pointing_to_the_middle_of_object) const {
+ size_t object_offset =
+ address_maybe_pointing_to_the_middle_of_object - offset_;
+ size_t object_start_number = object_offset / kAllocationGranularity;
+ size_t cell_index = object_start_number / kBitsPerCell;
+ DCHECK_GT(object_start_bit_map_.size(), cell_index);
+ const size_t bit = object_start_number & kCellMask;
+ uint8_t byte = object_start_bit_map_[cell_index] & ((1 << (bit + 1)) - 1);
+ while (!byte && cell_index) {
+ DCHECK_LT(0u, cell_index);
+ byte = object_start_bit_map_[--cell_index];
+ }
+ const int leading_zeroes = v8::base::bits::CountLeadingZeros(byte);
+ object_start_number =
+ (cell_index * kBitsPerCell) + (kBitsPerCell - 1) - leading_zeroes;
+ object_offset = object_start_number * kAllocationGranularity;
+ return reinterpret_cast<HeapObjectHeader*>(object_offset + offset_);
+}
+
+void ObjectStartBitmap::SetBit(ConstAddress header_address) {
+ size_t cell_index, object_bit;
+ ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
+ object_start_bit_map_[cell_index] |= (1 << object_bit);
+}
+
+void ObjectStartBitmap::ClearBit(ConstAddress header_address) {
+ size_t cell_index, object_bit;
+ ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
+ object_start_bit_map_[cell_index] &= ~(1 << object_bit);
+}
+
+bool ObjectStartBitmap::CheckBit(ConstAddress header_address) const {
+ size_t cell_index, object_bit;
+ ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
+ return object_start_bit_map_[cell_index] & (1 << object_bit);
+}
+
+void ObjectStartBitmap::ObjectStartIndexAndBit(ConstAddress header_address,
+ size_t* cell_index,
+ size_t* bit) const {
+ const size_t object_offset = header_address - offset_;
+ DCHECK(!(object_offset & kAllocationMask));
+ const size_t object_start_number = object_offset / kAllocationGranularity;
+ *cell_index = object_start_number / kBitsPerCell;
+ DCHECK_GT(kBitmapSize, *cell_index);
+ *bit = object_start_number & kCellMask;
+}
+
+template <typename Callback>
+inline void ObjectStartBitmap::Iterate(Callback callback) const {
+ for (size_t cell_index = 0; cell_index < kReservedForBitmap; cell_index++) {
+ if (!object_start_bit_map_[cell_index]) continue;
+
+ uint8_t value = object_start_bit_map_[cell_index];
+ while (value) {
+ const int trailing_zeroes = v8::base::bits::CountTrailingZeros(value);
+ const size_t object_start_number =
+ (cell_index * kBitsPerCell) + trailing_zeroes;
+ const Address object_address =
+ offset_ + (kAllocationGranularity * object_start_number);
+ callback(object_address);
+ // Clear current object bit in temporary value to advance iteration.
+ value &= ~(1 << (object_start_number & kCellMask));
+ }
+ }
+}
+
+void ObjectStartBitmap::Clear() {
+ std::fill(object_start_bit_map_.begin(), object_start_bit_map_.end(), 0);
+}
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // V8_HEAP_CPPGC_OBJECT_START_BITMAP_INL_H_