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