this repo has no description
at trunk 136 lines 4.0 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "heap.h" 3 4#include "gtest/gtest.h" 5 6#include "globals.h" 7#include "os.h" 8#include "runtime.h" 9#include "test-utils.h" 10 11namespace py { 12namespace testing { 13 14using HeapTest = RuntimeFixture; 15 16TEST(HeapTestNoFixture, AllocateObjects) { 17 const int size = OS::kPageSize * 4; 18 Heap heap(size); 19 20 // Allocate the first half of the heap. 21 uword address1; 22 bool result1 = heap.allocate(size / 2, &address1); 23 ASSERT_TRUE(result1); 24 EXPECT_TRUE(heap.contains(address1)); 25 26 // Allocate the second half of the heap. 27 uword address2; 28 bool result2 = heap.allocate(size / 2, &address2); 29 ASSERT_TRUE(result2); 30 EXPECT_TRUE(heap.contains(address2)); 31} 32 33static RawObject createLargeStr(Heap* heap, word length) { 34 DCHECK(length > RawSmallStr::kMaxLength, 35 "string len %ld is too small to be a large string", length); 36 word size = LargeStr::allocationSize(length); 37 uword address; 38 CHECK(heap->allocate(size, &address), "out of memory"); 39 return LargeStr::cast( 40 DataArray::initialize(address, length, LayoutId::kLargeStr)); 41} 42 43TEST_F(HeapTest, AllocateFails) { 44 HandleScope scope(thread_); 45 Heap* heap = runtime_->heap(); 46 word free_space = heap->space()->end() - heap->space()->fill(); 47 48 // Allocate the first half of the heap. Use a handle to prevent gc 49 word first_half = Utils::roundUp(free_space / 2, kPointerSize * 2); 50 Object object1(&scope, createLargeStr(runtime_->heap(), first_half)); 51 RawObject raw1 = *object1; 52 ASSERT_FALSE(raw1.isError()); 53 EXPECT_TRUE(heap->contains(HeapObject::cast(raw1).address())); 54 55 // Try over allocating. 56 uword address2; 57 bool result2 = heap->allocate(free_space, &address2); 58 ASSERT_FALSE(result2); 59 60 // Allocate the second half of the heap. 61 word second_half = heap->space()->end() - heap->space()->fill(); 62 uword address3; 63 bool result3 = heap->allocate(second_half, &address3); 64 ASSERT_TRUE(result3); 65 EXPECT_TRUE(heap->contains(address3)); 66 67 ASSERT_EQ(heap->space()->end(), heap->space()->fill()); 68} 69 70TEST_F(HeapTest, AllocateBigLargeInt) { 71 HandleScope scope(thread_); 72 Object result(&scope, runtime_->createLargeInt(100000)); 73 ASSERT_TRUE(result.isLargeInt()); 74 EXPECT_EQ(LargeInt::cast(*result).numDigits(), 100000); 75} 76 77TEST_F(HeapTest, AllocateImmortalPlacesObjectInImmortalSpace) { 78 Heap* heap = runtime_->heap(); 79 80 uword address1; 81 bool result1 = heap->allocateImmortal(8, &address1); 82 ASSERT_TRUE(result1); 83 EXPECT_TRUE(heap->contains(address1)); 84 EXPECT_TRUE(heap->isImmortal(address1)); 85} 86 87TEST_F(HeapTest, AllocateBigInstance) { 88 HandleScope scope(thread_); 89 Layout layout(&scope, testing::layoutCreateEmpty(thread_)); 90 Object result(&scope, runtime_->newInstanceWithSize(layout.id(), 91 100000 * kPointerSize)); 92 ASSERT_TRUE(result.isInstance()); 93 EXPECT_EQ(Instance::cast(*result).headerCountOrOverflow(), 100000); 94} 95 96class DummyVisitor : public HeapObjectVisitor { 97 public: 98 explicit DummyVisitor() : count_(0) {} 99 100 void visitHeapObject(RawHeapObject obj) { 101 visited_.push_back(obj); 102 count_++; 103 } 104 105 word count() { return count_; } 106 107 bool visited(RawObject obj) { 108 for (word i = 0; i < visited_.size(); i++) { 109 if (visited_[i] == obj) return true; 110 } 111 return false; 112 } 113 114 private: 115 Vector<RawObject> visited_; 116 word count_; 117}; 118 119TEST(HeapTestNoFixture, VisitAllObjectsVisitsAllObjects) { 120 Heap heap(OS::kPageSize * 4); 121 DummyVisitor visitor; 122 EXPECT_EQ(visitor.count(), 0); 123 heap.visitAllObjects(&visitor); 124 EXPECT_EQ(visitor.count(), 0); 125 RawObject obj1 = createLargeStr(&heap, 10); 126 RawObject obj2 = createLargeStr(&heap, 10); 127 RawObject obj3 = createLargeStr(&heap, 10); 128 heap.visitAllObjects(&visitor); 129 EXPECT_TRUE(visitor.visited(obj1)); 130 EXPECT_TRUE(visitor.visited(obj2)); 131 EXPECT_TRUE(visitor.visited(obj3)); 132 EXPECT_EQ(visitor.count(), 3); 133} 134 135} // namespace testing 136} // namespace py