Line data Source code
1 : // Copyright 2012 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 : #ifndef V8_ALLOCATION_H_
6 : #define V8_ALLOCATION_H_
7 :
8 : #include "include/v8-platform.h"
9 : #include "src/base/compiler-specific.h"
10 : #include "src/base/platform/platform.h"
11 : #include "src/globals.h"
12 : #include "src/v8.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // This file defines memory allocation functions. If a first attempt at an
18 : // allocation fails, these functions call back into the embedder, then attempt
19 : // the allocation a second time. The embedder callback must not reenter V8.
20 :
21 : // Called when allocation routines fail to allocate, even with a possible retry.
22 : // This function should not return, but should terminate the current processing.
23 : V8_EXPORT_PRIVATE void FatalProcessOutOfMemory(const char* message);
24 :
25 : // Superclass for classes managed with new & delete.
26 : class V8_EXPORT_PRIVATE Malloced {
27 : public:
28 971229 : void* operator new(size_t size) { return New(size); }
29 1015451 : void operator delete(void* p) { Delete(p); }
30 :
31 : static void* New(size_t size);
32 : static void Delete(void* p);
33 : };
34 :
35 : template <typename T>
36 139478360 : T* NewArray(size_t size) {
37 189328725 : T* result = new (std::nothrow) T[size];
38 139478566 : if (result == nullptr) {
39 6 : V8::GetCurrentPlatform()->OnCriticalMemoryPressure();
40 6 : result = new (std::nothrow) T[size];
41 6 : if (result == nullptr) FatalProcessOutOfMemory("NewArray");
42 : }
43 139478560 : return result;
44 : }
45 :
46 : template <typename T,
47 : typename = typename std::enable_if<IS_TRIVIALLY_COPYABLE(T)>::type>
48 5947766 : T* NewArray(size_t size, T default_val) {
49 5947766 : T* result = reinterpret_cast<T*>(NewArray<uint8_t>(sizeof(T) * size));
50 5947804 : for (size_t i = 0; i < size; ++i) result[i] = default_val;
51 5947804 : return result;
52 : }
53 :
54 : template <typename T>
55 1209 : void DeleteArray(T* array) {
56 155012647 : delete[] array;
57 1209 : }
58 :
59 :
60 : // The normal strdup functions use malloc. These versions of StrDup
61 : // and StrNDup uses new and calls the FatalProcessOutOfMemory handler
62 : // if allocation fails.
63 : V8_EXPORT_PRIVATE char* StrDup(const char* str);
64 : char* StrNDup(const char* str, int n);
65 :
66 :
67 : // Allocation policy for allocating in the C free store using malloc
68 : // and free. Used as the default policy for lists.
69 : class FreeStoreAllocationPolicy {
70 : public:
71 266248 : INLINE(void* New(size_t size)) { return Malloced::New(size); }
72 266248 : INLINE(static void Delete(void* p)) { Malloced::Delete(p); }
73 : };
74 :
75 :
76 : void* AlignedAlloc(size_t size, size_t alignment);
77 : void AlignedFree(void *ptr);
78 :
79 : // Represents and controls an area of reserved memory.
80 : class V8_EXPORT_PRIVATE VirtualMemory {
81 : public:
82 : // Empty VirtualMemory object, controlling no reserved memory.
83 : VirtualMemory();
84 :
85 : // Reserves virtual memory with size.
86 : explicit VirtualMemory(size_t size, void* hint);
87 :
88 : // Reserves virtual memory containing an area of the given size that
89 : // is aligned per alignment. This may not be at the position returned
90 : // by address().
91 : VirtualMemory(size_t size, size_t alignment, void* hint);
92 :
93 : // Construct a virtual memory by assigning it some already mapped address
94 : // and size.
95 17368 : VirtualMemory(void* address, size_t size) : address_(address), size_(size) {}
96 :
97 : // Releases the reserved memory, if any, controlled by this VirtualMemory
98 : // object.
99 : ~VirtualMemory();
100 :
101 : // Returns whether the memory has been reserved.
102 12 : bool IsReserved() const { return address_ != nullptr; }
103 :
104 : // Initialize or resets an embedded VirtualMemory object.
105 : void Reset();
106 :
107 : // Returns the start address of the reserved memory.
108 : // If the memory was reserved with an alignment, this address is not
109 : // necessarily aligned. The user might need to round it up to a multiple of
110 : // the alignment to get the start of the aligned block.
111 : void* address() const {
112 : DCHECK(IsReserved());
113 : return address_;
114 : }
115 :
116 : void* end() const {
117 : DCHECK(IsReserved());
118 436768 : return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address_) +
119 436768 : size_);
120 : }
121 :
122 : // Returns the size of the reserved memory. The returned value is only
123 : // meaningful when IsReserved() returns true.
124 : // If the memory was reserved with an alignment, this size may be larger
125 : // than the requested size.
126 : size_t size() const { return size_; }
127 :
128 : // Commits real memory. Returns whether the operation succeeded.
129 : bool Commit(void* address, size_t size, bool is_executable);
130 :
131 : // Uncommit real memory. Returns whether the operation succeeded.
132 : bool Uncommit(void* address, size_t size);
133 :
134 : // Creates a single guard page at the given address.
135 : bool Guard(void* address);
136 :
137 : // Releases the memory after |free_start|. Returns the bytes released.
138 : size_t ReleasePartial(void* free_start);
139 :
140 : void Release();
141 :
142 : // Assign control of the reserved region to a different VirtualMemory object.
143 : // The old object is no longer functional (IsReserved() returns false).
144 : void TakeControl(VirtualMemory* from);
145 :
146 : bool InVM(void* address, size_t size) {
147 2031612 : return (reinterpret_cast<uintptr_t>(address_) <=
148 4283076 : reinterpret_cast<uintptr_t>(address)) &&
149 2141538 : ((reinterpret_cast<uintptr_t>(address_) + size_) >=
150 2141538 : (reinterpret_cast<uintptr_t>(address) + size));
151 : }
152 :
153 : private:
154 : void* address_; // Start address of the virtual memory.
155 : size_t size_; // Size of the virtual memory.
156 : };
157 :
158 : bool AllocVirtualMemory(size_t size, void* hint, VirtualMemory* result);
159 : bool AlignedAllocVirtualMemory(size_t size, size_t alignment, void* hint,
160 : VirtualMemory* result);
161 :
162 : } // namespace internal
163 : } // namespace v8
164 :
165 : #endif // V8_ALLOCATION_H_
|