1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/virtual_memory.h"
6#include "platform/assert.h"
7#include "vm/heap/heap.h"
8#include "vm/unit_test.h"
9
10namespace dart {
11
12bool IsZero(char* begin, char* end) {
13 for (char* current = begin; current < end; ++current) {
14 if (*current != 0) {
15 return false;
16 }
17 }
18 return true;
19}
20
21VM_UNIT_TEST_CASE(AllocateVirtualMemory) {
22 const intptr_t kVirtualMemoryBlockSize = 64 * KB;
23 VirtualMemory* vm =
24 VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, "test");
25 EXPECT(vm != NULL);
26 EXPECT(vm->address() != NULL);
27 EXPECT_EQ(kVirtualMemoryBlockSize, vm->size());
28 EXPECT_EQ(vm->start(), reinterpret_cast<uword>(vm->address()));
29 EXPECT_EQ(vm->start() + kVirtualMemoryBlockSize, vm->end());
30 EXPECT(vm->Contains(vm->start()));
31 EXPECT(vm->Contains(vm->start() + 1));
32 EXPECT(vm->Contains(vm->start() + kVirtualMemoryBlockSize - 1));
33 EXPECT(vm->Contains(vm->start() + (kVirtualMemoryBlockSize / 2)));
34 EXPECT(!vm->Contains(vm->start() - 1));
35 EXPECT(!vm->Contains(vm->end()));
36 EXPECT(!vm->Contains(vm->end() + 1));
37 EXPECT(!vm->Contains(0));
38 EXPECT(!vm->Contains(static_cast<uword>(-1)));
39
40 char* buf = reinterpret_cast<char*>(vm->address());
41 EXPECT(IsZero(buf, buf + vm->size()));
42 buf[0] = 'a';
43 buf[1] = 'c';
44 buf[2] = '/';
45 buf[3] = 'd';
46 buf[4] = 'c';
47 buf[5] = 0;
48 EXPECT_STREQ("ac/dc", buf);
49
50 delete vm;
51}
52
53VM_UNIT_TEST_CASE(AllocateAlignedVirtualMemory) {
54 intptr_t kHeapPageSize = kOldPageSize;
55 intptr_t kVirtualPageSize = 4096;
56
57 intptr_t kIterations = kHeapPageSize / kVirtualPageSize;
58 for (intptr_t i = 0; i < kIterations; i++) {
59 VirtualMemory* vm = VirtualMemory::AllocateAligned(
60 kHeapPageSize, kHeapPageSize, false, "test");
61 EXPECT(Utils::IsAligned(vm->start(), kHeapPageSize));
62 EXPECT_EQ(kHeapPageSize, vm->size());
63 delete vm;
64 }
65}
66
67VM_UNIT_TEST_CASE(FreeVirtualMemory) {
68 // Reservations should always be handed back to OS upon destruction.
69 const intptr_t kVirtualMemoryBlockSize = 10 * MB;
70 const intptr_t kIterations = 900; // Enough to exhaust 32-bit address space.
71 for (intptr_t i = 0; i < kIterations; ++i) {
72 VirtualMemory* vm =
73 VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, "test");
74 delete vm;
75 }
76 // Check that truncation does not introduce leaks.
77 for (intptr_t i = 0; i < kIterations; ++i) {
78 VirtualMemory* vm =
79 VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, "test");
80 vm->Truncate(kVirtualMemoryBlockSize / 2);
81 delete vm;
82 }
83 for (intptr_t i = 0; i < kIterations; ++i) {
84 VirtualMemory* vm =
85 VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, "test");
86 vm->Truncate(0);
87 delete vm;
88 }
89}
90
91} // namespace dart
92