LCOV - code coverage report
Current view: top level - src - allocation.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 73 84 86.9 %
Date: 2017-10-20 Functions: 16 19 84.2 %

          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             : #include "src/allocation.h"
       6             : 
       7             : #include <stdlib.h>  // For free, malloc.
       8             : #include "src/base/bits.h"
       9             : #include "src/base/logging.h"
      10             : #include "src/base/platform/platform.h"
      11             : #include "src/utils.h"
      12             : #include "src/v8.h"
      13             : 
      14             : #if V8_LIBC_BIONIC
      15             : #include <malloc.h>  // NOLINT
      16             : #endif
      17             : 
      18             : #if defined(LEAK_SANITIZER)
      19             : #include <sanitizer/lsan_interface.h>
      20             : #endif
      21             : 
      22             : namespace v8 {
      23             : namespace internal {
      24             : 
      25             : namespace {
      26             : 
      27             : void* AlignedAllocInternal(size_t size, size_t alignment) {
      28             :   void* ptr;
      29             : #if V8_OS_WIN
      30             :   ptr = _aligned_malloc(size, alignment);
      31             : #elif V8_LIBC_BIONIC
      32             :   // posix_memalign is not exposed in some Android versions, so we fall back to
      33             :   // memalign. See http://code.google.com/p/android/issues/detail?id=35391.
      34             :   ptr = memalign(alignment, size);
      35             : #else
      36         287 :   if (posix_memalign(&ptr, alignment, size)) ptr = nullptr;
      37             : #endif
      38         287 :   return ptr;
      39             : }
      40             : 
      41             : }  // namespace
      42             : 
      43     1310828 : void* Malloced::New(size_t size) {
      44     1310828 :   void* result = malloc(size);
      45     1310828 :   if (result == nullptr) {
      46           6 :     V8::GetCurrentPlatform()->OnCriticalMemoryPressure();
      47           6 :     result = malloc(size);
      48           6 :     if (result == nullptr) {
      49           6 :       V8::FatalProcessOutOfMemory("Malloced operator new");
      50             :     }
      51             :   }
      52     1310822 :   return result;
      53             : }
      54             : 
      55             : 
      56     1355043 : void Malloced::Delete(void* p) {
      57     1355043 :   free(p);
      58     1355043 : }
      59             : 
      60             : 
      61   101953864 : char* StrDup(const char* str) {
      62             :   int length = StrLength(str);
      63   101953864 :   char* result = NewArray<char>(length + 1);
      64   101953864 :   MemCopy(result, str, length);
      65   101953864 :   result[length] = '\0';
      66   101953864 :   return result;
      67             : }
      68             : 
      69             : 
      70           0 : char* StrNDup(const char* str, int n) {
      71             :   int length = StrLength(str);
      72           0 :   if (n < length) length = n;
      73           0 :   char* result = NewArray<char>(length + 1);
      74           0 :   MemCopy(result, str, length);
      75           0 :   result[length] = '\0';
      76           0 :   return result;
      77             : }
      78             : 
      79             : 
      80         281 : void* AlignedAlloc(size_t size, size_t alignment) {
      81             :   DCHECK_LE(V8_ALIGNOF(void*), alignment);
      82             :   DCHECK(base::bits::IsPowerOfTwo(alignment));
      83             :   void* ptr = AlignedAllocInternal(size, alignment);
      84         281 :   if (ptr == nullptr) {
      85           6 :     V8::GetCurrentPlatform()->OnCriticalMemoryPressure();
      86             :     ptr = AlignedAllocInternal(size, alignment);
      87           6 :     if (ptr == nullptr) {
      88           6 :       V8::FatalProcessOutOfMemory("AlignedAlloc");
      89             :     }
      90             :   }
      91         275 :   return ptr;
      92             : }
      93             : 
      94             : 
      95         275 : void AlignedFree(void *ptr) {
      96             : #if V8_OS_WIN
      97             :   _aligned_free(ptr);
      98             : #elif V8_LIBC_BIONIC
      99             :   // Using free is not correct in general, but for V8_LIBC_BIONIC it is.
     100             :   free(ptr);
     101             : #else
     102         275 :   free(ptr);
     103             : #endif
     104         275 : }
     105             : 
     106     2546062 : VirtualMemory::VirtualMemory() : address_(nullptr), size_(0) {}
     107             : 
     108           0 : VirtualMemory::VirtualMemory(size_t size, void* hint)
     109       55011 :     : address_(base::OS::ReserveRegion(size, hint)), size_(size) {
     110             : #if defined(LEAK_SANITIZER)
     111             :   __lsan_register_root_region(address_, size_);
     112             : #endif
     113           0 : }
     114             : 
     115           0 : VirtualMemory::VirtualMemory(size_t size, size_t alignment, void* hint)
     116      494811 :     : address_(nullptr), size_(0) {
     117      494811 :   address_ = base::OS::ReserveAlignedRegion(size, alignment, hint, &size_);
     118             : #if defined(LEAK_SANITIZER)
     119             :   __lsan_register_root_region(address_, size_);
     120             : #endif
     121           0 : }
     122             : 
     123     3129992 : VirtualMemory::~VirtualMemory() {
     124     3184997 :   if (IsReserved()) {
     125           0 :     bool result = base::OS::ReleaseRegion(address(), size());
     126             :     DCHECK(result);
     127             :     USE(result);
     128             :   }
     129     2635183 : }
     130             : 
     131      762713 : void VirtualMemory::Reset() {
     132     3377062 :   address_ = nullptr;
     133     3377062 :   size_ = 0;
     134      762713 : }
     135             : 
     136     1111033 : bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
     137     1111033 :   CHECK(InVM(address, size));
     138     1111033 :   return base::OS::CommitRegion(address, size, is_executable);
     139             : }
     140             : 
     141      300713 : bool VirtualMemory::Uncommit(void* address, size_t size) {
     142      300713 :   CHECK(InVM(address, size));
     143      300713 :   return base::OS::UncommitRegion(address, size);
     144             : }
     145             : 
     146      619866 : bool VirtualMemory::Guard(void* address) {
     147     1239732 :   CHECK(InVM(address, base::OS::CommitPageSize()));
     148      619866 :   base::OS::Guard(address, base::OS::CommitPageSize());
     149      619866 :   return true;
     150             : }
     151             : 
     152      109926 : size_t VirtualMemory::ReleasePartial(void* free_start) {
     153             :   DCHECK(IsReserved());
     154             :   // Notice: Order is important here. The VirtualMemory object might live
     155             :   // inside the allocated region.
     156      109926 :   const size_t free_size = size_ - (reinterpret_cast<size_t>(free_start) -
     157      109926 :                                     reinterpret_cast<size_t>(address_));
     158      109926 :   CHECK(InVM(free_start, free_size));
     159             :   DCHECK_LT(address_, free_start);
     160             :   DCHECK_LT(free_start, reinterpret_cast<void*>(
     161             :                             reinterpret_cast<size_t>(address_) + size_));
     162             : #if defined(LEAK_SANITIZER)
     163             :   __lsan_unregister_root_region(address_, size_);
     164             :   __lsan_register_root_region(address_, size_ - free_size);
     165             : #endif
     166      109926 :   const bool result = base::OS::ReleasePartialRegion(free_start, free_size);
     167             :   USE(result);
     168             :   DCHECK(result);
     169      109926 :   size_ -= free_size;
     170      109926 :   return free_size;
     171             : }
     172             : 
     173      370257 : void VirtualMemory::Release() {
     174             :   DCHECK(IsReserved());
     175             :   // Notice: Order is important here. The VirtualMemory object might live
     176             :   // inside the allocated region.
     177      370257 :   void* address = address_;
     178      370257 :   size_t size = size_;
     179      370257 :   CHECK(InVM(address, size));
     180             :   Reset();
     181      370257 :   bool result = base::OS::ReleaseRegion(address, size);
     182             :   USE(result);
     183             :   DCHECK(result);
     184      370267 : }
     185             : 
     186     1749283 : void VirtualMemory::TakeControl(VirtualMemory* from) {
     187             :   DCHECK(!IsReserved());
     188     2299097 :   address_ = from->address_;
     189     2299097 :   size_ = from->size_;
     190             :   from->Reset();
     191     1749283 : }
     192             : 
     193       55005 : bool AllocVirtualMemory(size_t size, void* hint, VirtualMemory* result) {
     194             :   VirtualMemory first_try(size, hint);
     195       55005 :   if (first_try.IsReserved()) {
     196             :     result->TakeControl(&first_try);
     197       54999 :     return true;
     198             :   }
     199             : 
     200           6 :   V8::GetCurrentPlatform()->OnCriticalMemoryPressure();
     201             :   VirtualMemory second_try(size, hint);
     202             :   result->TakeControl(&second_try);
     203             :   return result->IsReserved();
     204             : }
     205             : 
     206      494805 : bool AlignedAllocVirtualMemory(size_t size, size_t alignment, void* hint,
     207             :                                VirtualMemory* result) {
     208             :   VirtualMemory first_try(size, alignment, hint);
     209      494809 :   if (first_try.IsReserved()) {
     210             :     result->TakeControl(&first_try);
     211      494803 :     return true;
     212             :   }
     213             : 
     214           6 :   V8::GetCurrentPlatform()->OnCriticalMemoryPressure();
     215             :   VirtualMemory second_try(size, alignment, hint);
     216             :   result->TakeControl(&second_try);
     217             :   return result->IsReserved();
     218             : }
     219             : 
     220             : }  // namespace internal
     221             : }  // namespace v8

Generated by: LCOV version 1.10