OLD | NEW |
| (Empty) |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/heap/array-buffer-tracker.h" | |
6 #include "test/cctest/cctest.h" | |
7 #include "test/cctest/heap/heap-utils.h" | |
8 | |
9 namespace { | |
10 | |
11 v8::Isolate* NewIsolateForPagePromotion() { | |
12 i::FLAG_page_promotion = true; | |
13 i::FLAG_page_promotion_threshold = 0; // % | |
14 i::FLAG_min_semi_space_size = 8 * (i::Page::kPageSize / i::MB); | |
15 // We cannot optimize for size as we require a new space with more than one | |
16 // page. | |
17 i::FLAG_optimize_for_size = false; | |
18 // Set max_semi_space_size because it could've been initialized by an | |
19 // implication of optimize_for_size. | |
20 i::FLAG_max_semi_space_size = i::FLAG_min_semi_space_size; | |
21 v8::Isolate::CreateParams create_params; | |
22 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | |
23 v8::Isolate* isolate = v8::Isolate::New(create_params); | |
24 return isolate; | |
25 } | |
26 | |
27 } // namespace | |
28 | |
29 namespace v8 { | |
30 namespace internal { | |
31 | |
32 UNINITIALIZED_TEST(PagePromotion_NewToOld) { | |
33 v8::Isolate* isolate = NewIsolateForPagePromotion(); | |
34 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
35 { | |
36 v8::Isolate::Scope isolate_scope(isolate); | |
37 v8::HandleScope handle_scope(isolate); | |
38 v8::Context::New(isolate)->Enter(); | |
39 Heap* heap = i_isolate->heap(); | |
40 | |
41 std::vector<Handle<FixedArray>> handles; | |
42 heap::SimulateFullSpace(heap->new_space(), &handles); | |
43 heap->CollectGarbage(NEW_SPACE); | |
44 CHECK_GT(handles.size(), 0u); | |
45 // First object in handle should be on the first page. | |
46 Handle<FixedArray> first_object = handles.front(); | |
47 Page* first_page = Page::FromAddress(first_object->address()); | |
48 // To perform a sanity check on live bytes we need to mark the heap. | |
49 heap::SimulateIncrementalMarking(heap, true); | |
50 // Sanity check that the page meets the requirements for promotion. | |
51 const int threshold_bytes = | |
52 FLAG_page_promotion_threshold * Page::kAllocatableMemory / 100; | |
53 CHECK_GE(first_page->LiveBytes(), threshold_bytes); | |
54 | |
55 // Actual checks: The page is in new space first, but is moved to old space | |
56 // during a full GC. | |
57 CHECK(heap->new_space()->ContainsSlow(first_page->address())); | |
58 CHECK(!heap->old_space()->ContainsSlow(first_page->address())); | |
59 heap::GcAndSweep(heap, OLD_SPACE); | |
60 CHECK(!heap->new_space()->ContainsSlow(first_page->address())); | |
61 CHECK(heap->old_space()->ContainsSlow(first_page->address())); | |
62 } | |
63 } | |
64 | |
65 UNINITIALIZED_TEST(PagePromotion_NewToNew) { | |
66 v8::Isolate* isolate = NewIsolateForPagePromotion(); | |
67 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); | |
68 { | |
69 v8::Isolate::Scope isolate_scope(isolate); | |
70 v8::HandleScope handle_scope(isolate); | |
71 v8::Context::New(isolate)->Enter(); | |
72 Heap* heap = i_isolate->heap(); | |
73 | |
74 std::vector<Handle<FixedArray>> handles; | |
75 heap::SimulateFullSpace(heap->new_space(), &handles); | |
76 CHECK_GT(handles.size(), 0u); | |
77 // Last object in handles should definitely be on the last page which does | |
78 // not contain the age mark. | |
79 Handle<FixedArray> last_object = handles.back(); | |
80 Page* to_be_promoted_page = Page::FromAddress(last_object->address()); | |
81 CHECK(to_be_promoted_page->Contains(last_object->address())); | |
82 CHECK(heap->new_space()->ToSpaceContainsSlow(last_object->address())); | |
83 heap::GcAndSweep(heap, OLD_SPACE); | |
84 CHECK(heap->new_space()->ToSpaceContainsSlow(last_object->address())); | |
85 CHECK(to_be_promoted_page->Contains(last_object->address())); | |
86 } | |
87 } | |
88 | |
89 UNINITIALIZED_TEST(PagePromotion_NewToNewJSArrayBuffer) { | |
90 // Test makes sure JSArrayBuffer backing stores are still tracked after | |
91 // new-to-new promotion. | |
92 v8::Isolate* isolate = NewIsolateForPagePromotion(); | |
93 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); | |
94 { | |
95 v8::Isolate::Scope isolate_scope(isolate); | |
96 v8::HandleScope handle_scope(isolate); | |
97 v8::Context::New(isolate)->Enter(); | |
98 Heap* heap = i_isolate->heap(); | |
99 | |
100 // Fill the current page which potentially contains the age mark. | |
101 heap::FillCurrentPage(heap->new_space()); | |
102 | |
103 // Allocate a buffer we would like to check against. | |
104 Handle<JSArrayBuffer> buffer = | |
105 i_isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); | |
106 JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, 100); | |
107 std::vector<Handle<FixedArray>> handles; | |
108 // Simulate a full space, filling the interesting page with live objects. | |
109 heap::SimulateFullSpace(heap->new_space(), &handles); | |
110 CHECK_GT(handles.size(), 0u); | |
111 // Last object in handles should definitely be on the last page which does | |
112 // not contain the age mark. | |
113 Handle<FixedArray> first_object = handles.front(); | |
114 Page* to_be_promoted_page = Page::FromAddress(first_object->address()); | |
115 CHECK(to_be_promoted_page->Contains(first_object->address())); | |
116 CHECK(to_be_promoted_page->Contains(buffer->address())); | |
117 CHECK(heap->new_space()->ToSpaceContainsSlow(first_object->address())); | |
118 CHECK(heap->new_space()->ToSpaceContainsSlow(buffer->address())); | |
119 heap::GcAndSweep(heap, OLD_SPACE); | |
120 CHECK(heap->new_space()->ToSpaceContainsSlow(first_object->address())); | |
121 CHECK(heap->new_space()->ToSpaceContainsSlow(buffer->address())); | |
122 CHECK(to_be_promoted_page->Contains(first_object->address())); | |
123 CHECK(to_be_promoted_page->Contains(buffer->address())); | |
124 CHECK(ArrayBufferTracker::IsTracked(*buffer)); | |
125 } | |
126 } | |
127 | |
128 } // namespace internal | |
129 } // namespace v8 | |
OLD | NEW |