| Index: test/cctest/test-spaces.cc
|
| diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc
|
| index 923227ff500af2903ac7605b0dcabfcb91929575..e11d82b03b965a6d7d06dd7ffa176f50aecae0c5 100644
|
| --- a/test/cctest/test-spaces.cc
|
| +++ b/test/cctest/test-spaces.cc
|
| @@ -792,3 +792,99 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
|
| }
|
| isolate->Dispose();
|
| }
|
| +
|
| +
|
| +static HeapObject* AllocateUnaligned(NewSpace* space, int size) {
|
| + AllocationResult allocation = space->AllocateRawUnaligned(size);
|
| + CHECK(!allocation.IsRetry());
|
| + HeapObject* filler = NULL;
|
| + CHECK(allocation.To(&filler));
|
| + space->heap()->CreateFillerObjectAt(filler->address(), size);
|
| + return filler;
|
| +}
|
| +
|
| +class Observer : public InlineAllocationObserver {
|
| + public:
|
| + explicit Observer(intptr_t step_size)
|
| + : InlineAllocationObserver(step_size), count_(0) {}
|
| +
|
| + virtual void Step(int bytes_allocated) { count_++; }
|
| +
|
| + int count() const { return count_; }
|
| +
|
| + private:
|
| + int count_;
|
| +};
|
| +
|
| +
|
| +UNINITIALIZED_TEST(InlineAllocationObserver) {
|
| + v8::Isolate::CreateParams create_params;
|
| + create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
| + v8::Isolate* isolate = v8::Isolate::New(create_params);
|
| + {
|
| + v8::Isolate::Scope isolate_scope(isolate);
|
| + v8::HandleScope handle_scope(isolate);
|
| + v8::Context::New(isolate)->Enter();
|
| +
|
| + Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
|
| +
|
| + NewSpace* new_space = i_isolate->heap()->new_space();
|
| +
|
| + Observer observer1(128);
|
| + new_space->AddInlineAllocationObserver(&observer1);
|
| +
|
| + // The observer should not get notified if we have only allocated less than
|
| + // 128 bytes.
|
| + AllocateUnaligned(new_space, 64);
|
| + CHECK_EQ(observer1.count(), 0);
|
| +
|
| + // The observer should not get called even 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.
|
| + AllocateUnaligned(new_space, 136);
|
| + CHECK_EQ(observer1.count(), 2);
|
| +
|
| + // Allocating a large object should get only one notification.
|
| + AllocateUnaligned(new_space, 1024);
|
| + CHECK_EQ(observer1.count(), 3);
|
| +
|
| + // Allocating another 2048 bytes in small objects should get 12
|
| + // notifications.
|
| + for (int i = 0; i < 64; ++i) {
|
| + AllocateUnaligned(new_space, 32);
|
| + }
|
| + CHECK_EQ(observer1.count(), 15);
|
| +
|
| + // Multiple observers should work.
|
| + Observer observer2(96);
|
| + new_space->AddInlineAllocationObserver(&observer2);
|
| +
|
| + AllocateUnaligned(new_space, 2048);
|
| + CHECK_EQ(observer1.count(), 16);
|
| + CHECK_EQ(observer2.count(), 1);
|
| +
|
| + AllocateUnaligned(new_space, 104);
|
| + CHECK_EQ(observer1.count(), 16);
|
| + 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(observer2.count(), 3); // this one is still active.
|
| +
|
| + new_space->RemoveInlineAllocationObserver(&observer2);
|
| + AllocateUnaligned(new_space, 384);
|
| + CHECK_EQ(observer1.count(), 16);
|
| + CHECK_EQ(observer2.count(), 3);
|
| + }
|
| + isolate->Dispose();
|
| +}
|
|
|