| Index: src/heap/spaces.h
|
| diff --git a/src/heap/spaces.h b/src/heap/spaces.h
|
| index 18a6a0e65fac6189098fe993c79e9c0fa254d6c8..8790e4cf1224cd6ef5077dc56d084e1c3324eed7 100644
|
| --- a/src/heap/spaces.h
|
| +++ b/src/heap/spaces.h
|
| @@ -2509,6 +2509,43 @@ class NewSpacePageIterator BASE_EMBEDDED {
|
| NewSpacePage* last_page_;
|
| };
|
|
|
| +// -----------------------------------------------------------------------------
|
| +// Allows observation of inline allocation in the new space.
|
| +class InlineAllocationObserver {
|
| + public:
|
| + explicit InlineAllocationObserver(intptr_t step_size)
|
| + : step_size_(step_size), bytes_to_next_step_(step_size) {
|
| + DCHECK(step_size >= kPointerSize && (step_size & kHeapObjectTagMask) == 0);
|
| + }
|
| + virtual ~InlineAllocationObserver() {}
|
| +
|
| + private:
|
| + intptr_t step_size() const { return step_size_; }
|
| +
|
| + // Pure virtual method provided by the subclasses that gets called when more
|
| + // than step_size byte have been allocated.
|
| + virtual void Step(int bytes_allocated) = 0;
|
| +
|
| + // Called each time the new space does an inline allocation step. This may be
|
| + // more frequently than the step_size we are monitoring (e.g. when there are
|
| + // multiple observers, or when page or space boundary is encountered.) The
|
| + // Step method is only called once more than step_size bytes have been
|
| + // allocated.
|
| + void InlineAllocationStep(int bytes_allocated) {
|
| + bytes_to_next_step_ -= bytes_allocated;
|
| + if (bytes_to_next_step_ <= 0) {
|
| + Step(static_cast<int>(step_size_ - bytes_to_next_step_));
|
| + bytes_to_next_step_ = step_size_;
|
| + }
|
| + }
|
| +
|
| + intptr_t step_size_;
|
| + intptr_t bytes_to_next_step_;
|
| +
|
| + friend class NewSpace;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(InlineAllocationObserver);
|
| +};
|
|
|
| // -----------------------------------------------------------------------------
|
| // The young generation space.
|
| @@ -2698,10 +2735,21 @@ class NewSpace : public Space {
|
| void ResetAllocationInfo();
|
|
|
| void UpdateInlineAllocationLimit(int size_in_bytes);
|
| - void LowerInlineAllocationLimit(intptr_t step) {
|
| - inline_allocation_limit_step_ = step;
|
| + void UpdateInlineAllocationLimitStep();
|
| +
|
| + // Allows observation of inline allocation. The observer->Step() method gets
|
| + // called after every step_size bytes have been allocated (approximately).
|
| + // This works by adjusting the allocation limit to a lower value and adjusting
|
| + // it after each step.
|
| + void AddInlineAllocationObserver(InlineAllocationObserver* observer);
|
| +
|
| + // Removes a previously installed observer.
|
| + void RemoveInlineAllocationObserver(InlineAllocationObserver* observer);
|
| +
|
| + void DisableInlineAllocationSteps() {
|
| + inline_allocation_limit_step_ = 0;
|
| + top_on_previous_step_ = 0;
|
| UpdateInlineAllocationLimit(0);
|
| - top_on_previous_step_ = step ? allocation_info_.top() : 0;
|
| }
|
|
|
| // Get the extent of the inactive semispace (for use as a marking stack,
|
| @@ -2771,10 +2819,6 @@ class NewSpace : public Space {
|
|
|
| bool IsFromSpaceCommitted() { return from_space_.is_committed(); }
|
|
|
| - inline intptr_t inline_allocation_limit_step() {
|
| - return inline_allocation_limit_step_;
|
| - }
|
| -
|
| SemiSpace* active_space() { return &to_space_; }
|
|
|
| private:
|
| @@ -2800,11 +2844,13 @@ class NewSpace : public Space {
|
| // mark-compact collection.
|
| AllocationInfo allocation_info_;
|
|
|
| - // When incremental marking is active we will set allocation_info_.limit
|
| - // to be lower than actual limit and then will gradually increase it
|
| - // in steps to guarantee that we do incremental marking steps even
|
| - // when all allocation is performed from inlined generated code.
|
| + // When inline allocation stepping is active, either because of incremental
|
| + // marking or because of idle scavenge, we 'interrupt' inline allocation every
|
| + // once in a while. This is done by setting allocation_info_.limit to be lower
|
| + // than the actual limit and and increasing it in steps to guarantee that the
|
| + // observers are notified periodically.
|
| intptr_t inline_allocation_limit_step_;
|
| + List<InlineAllocationObserver*> inline_allocation_observers_;
|
|
|
| Address top_on_previous_step_;
|
|
|
| @@ -2814,8 +2860,7 @@ class NewSpace : public Space {
|
| bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment);
|
|
|
| // If we are doing inline allocation in steps, this method performs the 'step'
|
| - // operation. Right now incremental marking is the only consumer of inline
|
| - // allocation steps. top is the memory address of the bump pointer at the last
|
| + // operation. top is the memory address of the bump pointer at the last
|
| // inline allocation (i.e. it determines the numbers of bytes actually
|
| // allocated since the last step.) new_top is the address of the bump pointer
|
| // where the next byte is going to be allocated from. top and new_top may be
|
|
|