Commit 0514fa20 authored by ofrobots's avatar ofrobots Committed by Commit bot

[heap] make inline-allocation-observers precise

Now that we no longer require AllocationInfo::limit to be aligned [1], we can do
more accurate inline-allocation-observation. This lets us get notified when the
next allocation that crosses the step-size boundary is allocated.

Fixed the test-cases. They make significantly more sense now given the step
sizes and the number of times we get notifications. For example, with a step
size of 512, an allocation of 16kb results in 32 notifications instead of 30
now.

[1] https://codereview.chromium.org/1444883003

R=hpayer@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1448913003

Cr-Commit-Position: refs/heads/master@{#32091}
parent 1511374a
......@@ -1516,7 +1516,7 @@ void NewSpace::UpdateInlineAllocationLimit(int size_in_bytes) {
// Lower limit during incremental marking.
Address high = to_space_.page_high();
Address new_top = allocation_info_.top() + size_in_bytes;
Address new_limit = new_top + GetNextInlineAllocationStepSize();
Address new_limit = new_top + GetNextInlineAllocationStepSize() - 1;
allocation_info_.set_limit(Min(new_limit, high));
}
DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
......
......@@ -1493,9 +1493,6 @@ class AllocationInfo {
}
INLINE(Address limit()) const {
SLOW_DCHECK(limit_ == NULL ||
(reinterpret_cast<intptr_t>(limit_) & kHeapObjectTagMask) ==
0);
return limit_;
}
......@@ -2513,7 +2510,7 @@ 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);
DCHECK(step_size >= kPointerSize);
}
virtual ~InlineAllocationObserver() {}
......@@ -2521,15 +2518,13 @@ class InlineAllocationObserver {
intptr_t step_size() const { return step_size_; }
intptr_t bytes_to_next_step() const { return bytes_to_next_step_; }
// Pure virtual method provided by the subclasses that gets called when more
// than step_size byte have been allocated.
// Pure virtual method provided by the subclasses that gets called when at
// least step_size bytes 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.
// multiple observers, or when page or space boundary is encountered.)
void InlineAllocationStep(int bytes_allocated) {
bytes_to_next_step_ -= bytes_allocated;
if (bytes_to_next_step_ <= 0) {
......
......@@ -834,13 +834,8 @@ UNINITIALIZED_TEST(InlineAllocationObserver) {
AllocateUnaligned(new_space, 64);
CHECK_EQ(observer1.count(), 0);
// The observer should not get called even when we have allocated exactly
// 128 bytes.
// The observer should get called when we have allocated exactly 128 bytes.
AllocateUnaligned(new_space, 64);
CHECK_EQ(observer1.count(), 0);
// The next allocation gets the notification.
AllocateUnaligned(new_space, 8);
CHECK_EQ(observer1.count(), 1);
// Another >128 bytes should get another notification.
......@@ -851,35 +846,35 @@ UNINITIALIZED_TEST(InlineAllocationObserver) {
AllocateUnaligned(new_space, 1024);
CHECK_EQ(observer1.count(), 3);
// Allocating another 2048 bytes in small objects should get 12
// Allocating another 2048 bytes in small objects should get 16
// notifications.
for (int i = 0; i < 64; ++i) {
AllocateUnaligned(new_space, 32);
}
CHECK_EQ(observer1.count(), 15);
CHECK_EQ(observer1.count(), 19);
// Multiple observers should work.
Observer observer2(96);
new_space->AddInlineAllocationObserver(&observer2);
AllocateUnaligned(new_space, 2048);
CHECK_EQ(observer1.count(), 16);
CHECK_EQ(observer1.count(), 20);
CHECK_EQ(observer2.count(), 1);
AllocateUnaligned(new_space, 104);
CHECK_EQ(observer1.count(), 16);
CHECK_EQ(observer1.count(), 20);
CHECK_EQ(observer2.count(), 2);
// Callback should stop getting called after an observer is removed.
new_space->RemoveInlineAllocationObserver(&observer1);
AllocateUnaligned(new_space, 384);
CHECK_EQ(observer1.count(), 16); // no more notifications.
CHECK_EQ(observer1.count(), 20); // no more notifications.
CHECK_EQ(observer2.count(), 3); // this one is still active.
new_space->RemoveInlineAllocationObserver(&observer2);
AllocateUnaligned(new_space, 384);
CHECK_EQ(observer1.count(), 16);
CHECK_EQ(observer1.count(), 20);
CHECK_EQ(observer2.count(), 3);
}
isolate->Dispose();
......@@ -911,8 +906,8 @@ UNINITIALIZED_TEST(InlineAllocationObserverCadence) {
new_space->RemoveInlineAllocationObserver(&observer1);
new_space->RemoveInlineAllocationObserver(&observer2);
CHECK_EQ(observer1.count(), 30);
CHECK_EQ(observer2.count(), 26);
CHECK_EQ(observer1.count(), 32);
CHECK_EQ(observer2.count(), 28);
}
isolate->Dispose();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment