declare_folded_class NO LONGER _in_file
[hiphop-php.git] / hphp / util / data-block.cpp
blob71847fc345305fce18f426ecb4545926537e9168
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/util/data-block.h"
19 namespace HPHP {
21 void* DataBlock::allocInner(size_t len) {
22 assert(len < std::numeric_limits<Size>::max());
24 if (!len) return nullptr;
26 auto freeList = m_freeLists.lower_bound(len);
27 if (freeList == m_freeLists.end()) {
28 return nullptr;
30 always_assert(!freeList->second.empty());
32 auto size = freeList->first;
33 auto off = *freeList->second.begin();
34 freeList->second.erase(off);
35 m_freeRanges.erase(off);
36 m_freeRanges.erase(off + size);
38 assert(size >= len);
40 if (size != len) {
41 m_freeLists[size - len].emplace(off + len);
42 m_freeRanges[off + len] = size - len;
43 m_freeRanges[off + size] = -(int64_t)(size - len);
46 ++m_nalloc;
47 m_bytesFree -= len;
49 if (freeList->second.empty()) m_freeLists.erase(freeList);
51 return m_destBase + off;
54 void DataBlock::free(void* vaddr, size_t len) {
55 auto addr = static_cast<void*>(((char*)vaddr - (char*)m_destBase) + m_base);
57 assert(len < std::numeric_limits<uint32_t>::max() &&
58 (CodeAddress)addr + len <= m_frontier);
60 ++m_nfree;
62 Offset off = (Offset)((CodeAddress)addr - m_base);
64 auto after = m_freeRanges.find(off + len);
65 auto before = m_freeRanges.find(off);
66 if (before != m_freeRanges.end()) {
67 assertx(before->second < 0);
68 auto beforeEnd = before;
69 before = m_freeRanges.find(off + before->second);
70 m_freeRanges.erase(beforeEnd);
71 assertx(before != m_freeRanges.end());
74 if (before != m_freeRanges.end()) {
75 auto list = m_freeLists.find(before->second);
76 assertx(list != m_freeLists.end());
78 list->second.erase(before->first);
79 if (list->second.empty()) m_freeLists.erase(list);
82 if ((CodeAddress)addr + len == m_frontier) {
83 if (before != m_freeRanges.end()) {
84 m_bytesFree -= before->second;
85 len += before->second;
86 m_freeRanges.erase(before);
88 assert(after == m_freeRanges.end());
89 m_frontier -= len;
90 return;
93 m_bytesFree += len;
95 if (after != m_freeRanges.end()) {
96 len += after->second;
97 auto list = m_freeLists.find(after->second);
98 assertx(list != m_freeLists.end());
100 list->second.erase(after->first);
101 if (list->second.empty()) m_freeLists.erase(list);
102 m_freeRanges.erase(after);
105 if (before != m_freeRanges.end()) {
106 before->second = (len += before->second);
107 off = before->first;
108 } else {
109 m_freeRanges[off] = len;
111 m_freeLists[len].emplace(off);
112 m_freeRanges[off + len] = -(int64_t)len;
115 void DataBlock::reportFull(size_t nBytes) const {
116 throw DataBlockFull(m_name, folly::sformat(
117 "Attempted to emit {} byte(s) into a {} byte DataBlock with {} bytes "
118 "available ({} max bytes). This almost certainly means the TC is full. If "
119 "this is the case, increasing Eval.JitASize, Eval.JitAColdSize, "
120 "Eval.JitAFrozenSize and Eval.JitGlobalDataSize in the configuration "
121 "file when running this script or application should fix this problem.",
122 nBytes, m_size, m_size - (m_frontier - m_base), m_maxGrow));
125 void DataBlock::reportMallocError(size_t nBytes) const {
126 throw DataBlockFull(m_name, folly::sformat(
127 "Encountered a malloc/realloc error while attempting to grow a {} byte "
128 "DataBlock to {} bytes. The maximum size for this DataBlock is {} byte(s).",
129 m_size, nBytes, m_maxGrow));