Line data Source code
1 : // Copyright 2014 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 <cmath>
6 : #include <iostream>
7 : #include <limits>
8 :
9 : #include "src/handles-inl.h"
10 : #include "src/heap/heap.h"
11 : #include "src/heap/spaces-inl.h"
12 : #include "src/objects-inl.h"
13 : #include "test/unittests/test-utils.h"
14 : #include "testing/gtest/include/gtest/gtest.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 :
19 : using HeapTest = TestWithIsolate;
20 : using HeapWithPointerCompressionTest = TestWithIsolateAndPointerCompression;
21 :
22 15443 : TEST(Heap, SemiSpaceSize) {
23 : const size_t MB = static_cast<size_t>(i::MB);
24 : const size_t pm = i::Heap::kPointerMultiplier;
25 2 : ASSERT_EQ(512u * pm, i::Heap::ComputeMaxSemiSpaceSize(0u));
26 2 : ASSERT_EQ(512u * pm, i::Heap::ComputeMaxSemiSpaceSize(512u * MB));
27 2 : ASSERT_EQ(2048u * pm, i::Heap::ComputeMaxSemiSpaceSize(1024u * MB));
28 2 : ASSERT_EQ(5120u * pm, i::Heap::ComputeMaxSemiSpaceSize(2024u * MB));
29 2 : ASSERT_EQ(8192u * pm, i::Heap::ComputeMaxSemiSpaceSize(4095u * MB));
30 : }
31 :
32 15444 : TEST_F(HeapTest, ASLR) {
33 : #if V8_TARGET_ARCH_X64
34 : #if V8_OS_MACOSX
35 : Heap* heap = i_isolate()->heap();
36 : std::set<void*> hints;
37 : for (int i = 0; i < 1000; i++) {
38 : hints.insert(heap->GetRandomMmapAddr());
39 : }
40 : if (hints.size() == 1) {
41 : EXPECT_TRUE((*hints.begin()) == nullptr);
42 : EXPECT_TRUE(i::GetRandomMmapAddr() == nullptr);
43 : } else {
44 : // It is unlikely that 1000 random samples will collide to less then 500
45 : // values.
46 : EXPECT_GT(hints.size(), 500u);
47 : const uintptr_t kRegionMask = 0xFFFFFFFFu;
48 : void* first = *hints.begin();
49 : for (void* hint : hints) {
50 : uintptr_t diff = reinterpret_cast<uintptr_t>(first) ^
51 : reinterpret_cast<uintptr_t>(hint);
52 : EXPECT_LE(diff, kRegionMask);
53 : }
54 : }
55 : #endif // V8_OS_MACOSX
56 : #endif // V8_TARGET_ARCH_X64
57 1 : }
58 :
59 15444 : TEST_F(HeapTest, ExternalLimitDefault) {
60 : Heap* heap = i_isolate()->heap();
61 2 : EXPECT_EQ(kExternalAllocationSoftLimit,
62 0 : heap->isolate()->isolate_data()->external_memory_limit_);
63 1 : }
64 :
65 15444 : TEST_F(HeapTest, ExternalLimitStaysAboveDefaultForExplicitHandling) {
66 : v8_isolate()->AdjustAmountOfExternalAllocatedMemory(+10 * MB);
67 : v8_isolate()->AdjustAmountOfExternalAllocatedMemory(-10 * MB);
68 : Heap* heap = i_isolate()->heap();
69 1 : EXPECT_GE(heap->isolate()->isolate_data()->external_memory_limit_,
70 0 : kExternalAllocationSoftLimit);
71 1 : }
72 :
73 : #if V8_TARGET_ARCH_64_BIT
74 15444 : TEST_F(HeapWithPointerCompressionTest, HeapLayout) {
75 : // Produce some garbage.
76 : RunJS(
77 : "let ar = [];"
78 : "for (let i = 0; i < 100; i++) {"
79 : " ar.push(Array(i));"
80 : "}"
81 1 : "ar.push(Array(32 * 1024 * 1024));");
82 :
83 : Address isolate_root = i_isolate()->isolate_root();
84 1 : EXPECT_TRUE(IsAligned(isolate_root, size_t{4} * GB));
85 :
86 : // Check that all memory chunks belong this region.
87 : base::AddressRegion heap_reservation(isolate_root - size_t{2} * GB,
88 1 : size_t{4} * GB);
89 :
90 : OldGenerationMemoryChunkIterator iter(i_isolate()->heap());
91 5 : for (;;) {
92 6 : MemoryChunk* chunk = iter.next();
93 6 : if (chunk == nullptr) break;
94 :
95 : Address address = chunk->address();
96 5 : size_t size = chunk->area_end() - address;
97 5 : EXPECT_TRUE(heap_reservation.contains(address, size));
98 : }
99 1 : }
100 : #endif // V8_TARGET_ARCH_64_BIT
101 :
102 : } // namespace internal
103 9264 : } // namespace v8
|