5#ifndef V8_COMPILER_TURBOSHAFT_SNAPSHOT_TABLE_H_
6#define V8_COMPILER_TURBOSHAFT_SNAPSHOT_TABLE_H_
37 template <
class Key,
class Value>
39 const Value& new_value)
const {}
42template <
class Value,
class KeyData>
46template <
class Value,
class KeyData>
62 std::numeric_limits<uint32_t>::max();
64 std::numeric_limits<uint32_t>::max();
72template <
class Value,
class KeyData>
76 return entry_ == other.entry_;
91template <
class Value,
class KeyData = NoKeyData>
151 template <
class ChangeCallback = NoChangeCallback>
153 const ChangeCallback& change_callback = {})
154 requires(std::is_invocable_v<ChangeCallback, Key, Value, Value>)
159 snapshot_was_created_with_merge =
false;
162 template <
class ChangeCallback = NoChangeCallback>
164 const ChangeCallback& change_callback = {})
165 requires(std::is_invocable_v<ChangeCallback, Key, Value, Value>)
169 template <
class ChangeCallback = NoChangeCallback>
171 const ChangeCallback& change_callback = {})
172 requires(std::is_invocable_v<ChangeCallback, Key, Value, Value>)
176 template <
class MergeFun,
class ChangeCallback = NoChangeCallback>
178 const MergeFun& merge_fun,
179 const ChangeCallback& change_callback = {})
181 std::is_invocable_v<ChangeCallback, Key, Value, Value>)
186 snapshot_was_created_with_merge =
true;
189 template <
class MergeFun,
class ChangeCallback = NoChangeCallback>
191 const MergeFun& merge_fun,
192 const ChangeCallback& change_callback = {})
194 std::is_invocable_v<ChangeCallback, Key, Value, Value>)
233 DCHECK(snapshot_was_created_with_merge);
241 if (
key.entry_->value == new_value)
return false;
243 key.entry_->value = new_value;
259 TableEntry{std::move(initial_value), std::move(data)})};
288 bool snapshot_was_created_with_merge =
false;
299 template <
class ChangeCallback = NoChangeCallback>
304 DCHECK_EQ(entry.table_entry.value, entry.new_value);
305 DCHECK_NE(entry.new_value, entry.old_value);
306 change_callback(
Key{entry.table_entry}, entry.new_value, entry.old_value);
307 entry.table_entry.value = entry.old_value;
313 template <
class ChangeCallback = NoChangeCallback>
317 DCHECK_EQ(entry.table_entry.value, entry.old_value);
318 DCHECK_NE(entry.new_value, entry.old_value);
319 change_callback(
Key{entry.table_entry}, entry.old_value, entry.new_value);
320 entry.table_entry.value = entry.new_value;
326 uint32_t predecessor_index, uint32_t predecessor_count);
327 template <
class ChangeCallback>
329 const ChangeCallback& change_callback);
330 template <
class MergeFun,
class ChangeCallback>
332 const MergeFun& merge_fun,
333 const ChangeCallback& change_callback);
336 std::numeric_limits<uint32_t>::max();
338 std::numeric_limits<uint32_t>::max();
341template <
class Value,
class KeyData>
348template <
class Value,
class KeyData>
352 const uint32_t depth = parent ? parent->
depth + 1 : 0;
354 size_t log_end = kInvalidOffset;
356 static constexpr size_t kInvalidOffset = std::numeric_limits<size_t>::max();
359 : parent(parent), log_begin(log_begin) {}
363 while (other->depth > self->
depth) other = other->
parent;
364 while (self->
depth > other->depth) self = self->
parent;
365 while (other != self) {
376 bool IsSealed()
const {
return log_end != kInvalidOffset; }
379template <
class Value,
class KeyData>
382 uint32_t predecessor_count) {
394 CHECK_LE(merge_values_.size() + predecessor_count,
395 std::numeric_limits<uint32_t>::max());
396 entry.
merge_offset =
static_cast<uint32_t
>(merge_values_.size());
397 merging_entries_.push_back(&entry);
398 merge_values_.insert(merge_values_.end(), predecessor_count, entry.
value);
425template <
class Value,
class KeyData>
426template <
class ChangeCallback>
430 const ChangeCallback& change_callback) {
432 current_snapshot_->IsSealed(),
433 "A new Snapshot was opened before the previous Snapshot was sealed");
436 if (predecessors.
empty()) {
437 common_ancestor = root_snapshot_;
439 common_ancestor = predecessors.
first().data_;
445 while (current_snapshot_ != go_back_to) {
446 RevertCurrentSnapshot(change_callback);
455 ReplaySnapshot(s, change_callback);
459 DCHECK_EQ(current_snapshot_, common_ancestor);
460 SnapshotData& new_snapshot = NewSnapshot(common_ancestor);
461 current_snapshot_ = &new_snapshot;
467template <
class Value,
class KeyData>
468template <
class MergeFun,
class ChangeCallback>
471 const ChangeCallback& change_callback) {
472 CHECK_LE(predecessors.
size(), std::numeric_limits<uint32_t>::max());
473 uint32_t predecessor_count =
static_cast<uint32_t
>(predecessors.
size());
474 if (predecessor_count < 1)
return;
481 DCHECK(merge_values_.empty());
482 DCHECK(merging_entries_.empty());
487 for (uint32_t
i = 0;
i < predecessor_count; ++
i) {
489 predecessor != common_ancestor; predecessor = predecessor->
parent) {
492 RecordMergeValue(entry.table_entry, entry.new_value,
i,
501 Value value = merge_fun(
504 Value old_value = entry->value;
505 if (
Set(
key, std::move(value))) {
506 change_callback(
key, old_value, entry->value);
518template <
class Derived,
class Value,
class KeyData = NoKeyData>
524 using typename Super::Snapshot;
530 static_cast<Derived*
>(
this)->OnValueChange(
key, old_value, new_value);
537 template <
class MergeFun>
539 const MergeFun& merge_fun)
540 requires(std::is_invocable_v<MergeFun, Key, base::Vector<const Value>>)
543 predecessors, merge_fun,
545 static_cast<Derived*
>(
this)->OnValueChange(
key, old_value, new_value);
548 template <
class MergeFun>
550 const MergeFun& merge_fun)
551 requires(std::is_invocable_v<MergeFun, Key, base::Vector<const Value>>)
559 static_cast<Derived*
>(
this)->OnValueChange(
key, old_value,
uint8_t data_[MAX_STACK_LENGTH]
constexpr bool empty() const
constexpr size_t size() const
Vector< T > SubVectorFrom(size_t from) const
void SetNoNotify(Key key, Value new_value)
void StartNewSnapshot(base::Vector< const Snapshot > predecessors, const MergeFun &merge_fun)
void StartNewSnapshot(std::initializer_list< Snapshot > predecessors, const MergeFun &merge_fun)
void StartNewSnapshot(std::initializer_list< Snapshot > predecessors={})
void Set(Key key, Value new_value)
Key NewKey(KeyData data, Value initial_value=Value{})
void StartNewSnapshot(base::Vector< const Snapshot > predecessors)
SnapshotTableKey< Value, KeyData > Key
Key NewKey(Value initial_value=Value{})
void StartNewSnapshot(Snapshot parent)
bool operator==(SnapshotTableKey other) const
SnapshotTableEntry< Value, KeyData > * entry_
const KeyData & data() const
SnapshotTableKey(SnapshotTableEntry< Value, KeyData > &entry)
void Set(Snapshot snapshot)
MaybeSnapshot(Snapshot snapshot)
Snapshot(SnapshotData &data)
Snapshot(SnapshotData *data)
bool operator==(Snapshot other) const
base::Vector< LogEntry > LogEntries(SnapshotData *s)
ZoneDeque< TableEntry > table_
Key NewKey(Value initial_value=Value{})
void RecordMergeValue(TableEntry &entry, const Value &value, uint32_t predecessor_index, uint32_t predecessor_count)
void StartNewSnapshot(Snapshot parent, const ChangeCallback &change_callback={})
void MergePredecessors(base::Vector< const Snapshot > predecessors, const MergeFun &merge_fun, const ChangeCallback &change_callback)
static constexpr uint32_t kNoMergeOffset
Key NewKey(KeyData data, Value initial_value=Value{})
void StartNewSnapshot(std::initializer_list< Snapshot > predecessors, const MergeFun &merge_fun, const ChangeCallback &change_callback={})
SnapshotData & NewSnapshot(SnapshotData *parent)
ZoneVector< Value > merge_values_
ZoneVector< LogEntry > log_
void StartNewSnapshot(base::Vector< const Snapshot > predecessors, const MergeFun &merge_fun, const ChangeCallback &change_callback={})
void RevertCurrentSnapshot(ChangeCallback &change_callback)
void StartNewSnapshot(std::initializer_list< Snapshot > predecessors={}, const ChangeCallback &change_callback={})
SnapshotData * current_snapshot_
void ReplaySnapshot(SnapshotData *snapshot, ChangeCallback &change_callback)
SnapshotTableEntry< Value, KeyData > TableEntry
SnapshotData * root_snapshot_
ZoneDeque< SnapshotData > snapshots_
static constexpr uint32_t kNoMergedPredecessor
const Value & Get(Key key) const
SnapshotTable(Zone *zone)
ZoneVector< SnapshotData * > path_
SnapshotTableKey< Value, KeyData > Key
const Value & GetPredecessorValue(Key key, int predecessor_index)
void StartNewSnapshot(base::Vector< const Snapshot > predecessors, const ChangeCallback &change_callback={})
ZoneVector< TableEntry * > merging_entries_
bool Set(Key key, Value new_value)
SnapshotData & MoveToNewSnapshot(base::Vector< const Snapshot > predecessors, const ChangeCallback &change_callback)
constexpr Vector< T > VectorOf(T *start, size_t size)
#define DCHECK_WITH_MSG(condition, msg)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
void operator()(Key key, const Value &old_value, const Value &new_value) const
uint32_t last_merged_predecessor
SnapshotTableEntry(Value value, KeyData data)
static constexpr uint32_t kNoMergeOffset
static constexpr uint32_t kNoMergedPredecessor
SnapshotData(SnapshotData *parent, size_t log_begin)
SnapshotData * CommonAncestor(SnapshotData *other)