allocation.h 5.6 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8_ALLOCATION_H_
#define V8_ALLOCATION_H_

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 15
namespace v8 {
namespace internal {
16

17 18 19 20 21 22
// This file defines memory allocation functions. If a first attempt at an
// allocation fails, these functions call back into the embedder, then attempt
// the allocation a second time. The embedder callback must not reenter V8.

// Called when allocation routines fail to allocate, even with a possible retry.
// 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 28 29 30 31 32 33 34 35
 public:
  void* operator new(size_t size) { return New(size); }
  void  operator delete(void* p) { Delete(p); }

  static void* New(size_t size);
  static void Delete(void* p);
};

template <typename T>
36
T* NewArray(size_t size) {
37 38
  T* result = new (std::nothrow) T[size];
  if (result == nullptr) {
39
    V8::GetCurrentPlatform()->OnCriticalMemoryPressure();
40 41
    result = new (std::nothrow) T[size];
    if (result == nullptr) FatalProcessOutOfMemory("NewArray");
42
  }
43
  return result;
44 45
}

46 47 48 49 50 51 52 53
template <typename T,
          typename = typename std::enable_if<IS_TRIVIALLY_COPYABLE(T)>::type>
T* NewArray(size_t size, T default_val) {
  T* result = reinterpret_cast<T*>(NewArray<uint8_t>(sizeof(T) * size));
  for (size_t i = 0; i < size; ++i) result[i] = default_val;
  return result;
}

54
template <typename T>
55
void DeleteArray(T* array) {
56 57 58 59
  delete[] array;
}


60 61 62
// The normal strdup functions use malloc.  These versions of StrDup
// and StrNDup uses new and calls the FatalProcessOutOfMemory handler
// if allocation fails.
63
V8_EXPORT_PRIVATE char* StrDup(const char* str);
64
char* StrNDup(const char* str, int n);
65 66 67 68 69 70


// Allocation policy for allocating in the C free store using malloc
// and free. Used as the default policy for lists.
class FreeStoreAllocationPolicy {
 public:
71
  INLINE(void* New(size_t size)) { return Malloced::New(size); }
72 73 74 75
  INLINE(static void Delete(void* p)) { Malloced::Delete(p); }
};


76 77 78
void* AlignedAlloc(size_t size, size_t alignment);
void AlignedFree(void *ptr);

79 80 81 82 83
// Allocates a single system memory page with read/write permissions. The
// address parameter is a hint. Returns the base address of the memory, or null
// on failure. Permissions can be changed on the base address.
byte* AllocateSystemPage(void* address, size_t* allocated);

84 85 86 87 88 89
// Represents and controls an area of reserved memory.
class V8_EXPORT_PRIVATE VirtualMemory {
 public:
  // Empty VirtualMemory object, controlling no reserved memory.
  VirtualMemory();

90 91 92 93 94
  // Reserves virtual memory containing an area of the given size that is
  // aligned per alignment. This may not be at the position returned by
  // address().
  VirtualMemory(size_t size, void* hint,
                size_t alignment = base::OS::AllocatePageSize());
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

  // Construct a virtual memory by assigning it some already mapped address
  // and size.
  VirtualMemory(void* address, size_t size) : address_(address), size_(size) {}

  // Releases the reserved memory, if any, controlled by this VirtualMemory
  // object.
  ~VirtualMemory();

  // Returns whether the memory has been reserved.
  bool IsReserved() const { return address_ != nullptr; }

  // Initialize or resets an embedded VirtualMemory object.
  void Reset();

  // Returns the start address of the reserved memory.
  // If the memory was reserved with an alignment, this address is not
  // necessarily aligned. The user might need to round it up to a multiple of
  // the alignment to get the start of the aligned block.
  void* address() const {
    DCHECK(IsReserved());
    return address_;
  }

  void* end() const {
    DCHECK(IsReserved());
    return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address_) +
                                   size_);
  }

  // Returns the size of the reserved memory. The returned value is only
  // meaningful when IsReserved() returns true.
  // If the memory was reserved with an alignment, this size may be larger
  // than the requested size.
  size_t size() const { return size_; }

131 132 133 134
  // Sets permissions according to the access argument. address and size must be
  // multiples of CommitPageSize(). Returns true on success, otherwise false.
  bool SetPermissions(void* address, size_t size,
                      base::OS::MemoryPermission access);
135

136 137
  // Releases memory after |free_start|. Returns the number of bytes released.
  size_t Release(void* free_start);
138

139 140
  // Frees all memory.
  void Free();
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

  // Assign control of the reserved region to a different VirtualMemory object.
  // The old object is no longer functional (IsReserved() returns false).
  void TakeControl(VirtualMemory* from);

  bool InVM(void* address, size_t size) {
    return (reinterpret_cast<uintptr_t>(address_) <=
            reinterpret_cast<uintptr_t>(address)) &&
           ((reinterpret_cast<uintptr_t>(address_) + size_) >=
            (reinterpret_cast<uintptr_t>(address) + size));
  }

 private:
  void* address_;  // Start address of the virtual memory.
  size_t size_;    // Size of the virtual memory.
};

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 163
}  // namespace internal
}  // namespace v8
164 165

#endif  // V8_ALLOCATION_H_