%PDF- %PDF-
| Direktori : /home2/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/ |
| Current File : //home2/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/allocation-observer.h |
// 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_ALLOCATION_OBSERVER_H_
#define V8_HEAP_ALLOCATION_OBSERVER_H_
#include <cstdint>
#include <unordered_set>
#include <vector>
#include "src/common/globals.h"
namespace v8 {
namespace internal {
// Observer for allocations that is aware of LAB-based allocation.
class AllocationObserver {
public:
static constexpr intptr_t kNotUsingFixedStepSize = -1;
explicit AllocationObserver(intptr_t step_size) : step_size_(step_size) {}
virtual ~AllocationObserver() = default;
AllocationObserver(const AllocationObserver&) = delete;
AllocationObserver& operator=(const AllocationObserver&) = delete;
protected:
// Called when at least `step_size_` bytes have been allocated. `soon_object`
// points to the uninitialized memory that has just been allocated and is the
// result for a request of `size` bytes.
//
// Some caveats:
// 1. `soon_object` will be nullptr in cases zwhere the allocation returns a
// filler object, which is e.g. needed at page boundaries.
// 2. `soon_object` may actually be the first object in an
// allocation-folding group. In such a case size is the size of the group
// rather than the first object.
// 3. `size` is the requested size at the time of allocation. Right-trimming
// may change the object size dynamically.
virtual void Step(int bytes_allocated, Address soon_object, size_t size) = 0;
// Subclasses can override this method to make step size dynamic.
virtual intptr_t GetNextStepSize() {
DCHECK_NE(kNotUsingFixedStepSize, step_size_);
return step_size_;
}
private:
const intptr_t step_size_;
friend class AllocationCounter;
};
// A global allocation counter observers can be added to.
class AllocationCounter final {
public:
AllocationCounter() = default;
// Adds an observer. May be called from `AllocationObserver::Step()`.
V8_EXPORT_PRIVATE void AddAllocationObserver(AllocationObserver* observer);
// Removes an observer. May be called from `AllocationObserver::Step()`.
V8_EXPORT_PRIVATE void RemoveAllocationObserver(AllocationObserver* observer);
// Advances forward by `allocated` bytes. Does not invoke any observers.
V8_EXPORT_PRIVATE void AdvanceAllocationObservers(size_t allocated);
// Invokes observers via `AllocationObserver::Step()` and computes new step
// sizes. Does not advance the current allocation counter.
V8_EXPORT_PRIVATE void InvokeAllocationObservers(Address soon_object,
size_t object_size,
size_t aligned_object_size);
bool IsStepInProgress() const { return step_in_progress_; }
size_t NextBytes() const {
if (observers_.empty()) return SIZE_MAX;
return next_counter_ - current_counter_;
}
private:
struct AllocationObserverCounter final {
AllocationObserverCounter(AllocationObserver* observer, size_t prev_counter,
size_t next_counter)
: observer_(observer),
prev_counter_(prev_counter),
next_counter_(next_counter) {}
AllocationObserver* observer_;
size_t prev_counter_;
size_t next_counter_;
};
std::vector<AllocationObserverCounter> observers_;
std::vector<AllocationObserverCounter> pending_added_;
std::unordered_set<AllocationObserver*> pending_removed_;
size_t current_counter_ = 0;
size_t next_counter_ = 0;
bool step_in_progress_ = false;
};
class V8_EXPORT_PRIVATE V8_NODISCARD PauseAllocationObserversScope {
public:
explicit PauseAllocationObserversScope(Heap* heap);
~PauseAllocationObserversScope();
PauseAllocationObserversScope(const PauseAllocationObserversScope&) = delete;
PauseAllocationObserversScope& operator=(
const PauseAllocationObserversScope&) = delete;
private:
Heap* heap_;
};
} // namespace internal
} // namespace v8
#endif // V8_HEAP_ALLOCATION_OBSERVER_H_