ReactOS 0.4.16-dev-715-ga1a169f
expand.cpp
Go to the documentation of this file.
1//
2// expand.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Implementation of _expand().
7//
8#include <corecrt_internal.h>
9#include <malloc.h>
10
11
12
13// Enclaves have a different heap implementation.
14
15#ifdef _UCRT_ENCLAVE_BUILD
16
17// Tests whether the allocation contraction is possible
18__inline static bool is_contraction_possible(size_t const) throw()
19{
20 return FALSE;
21}
22
23#else /* ^^^ _UCRT_ENCLAVE_BUILD ^^^ // vvv !_UCRT_ENCLAVE_BUILD vvv */
24
25// Tests whether the allocation contraction is possible
26__inline static bool is_contraction_possible(size_t const old_size) throw()
27{
28 // Check if object allocated on low fragmentation heap.
29 //The LFH can only allocate blocks up to 16KB in size.
30 if (old_size <= 0x4000)
31 {
32 LONG heap_type = -1;
36 &heap_type,
37 sizeof(heap_type),
38 nullptr))
39 {
40 return FALSE;
41 }
42 return heap_type != 2;
43 }
44 // Contraction possible for objects not on the LFH
45 return TRUE;
46}
47
48#endif /* _UCRT_ENCLAVE_BUILD */
49
50
51// This function implements the logic of expand(). It is called directly by the
52// _expand() function in the Release CRT, and called by the debug heap in the
53// Debug CRT.
54//
55// This function must be marked noinline, otherwise _expand and
56// _expand_base will have identical COMDATs, and the linker will fold
57// them when calling one from the CRT. This is necessary because _expand
58// needs to support users patching in custom implementations.
59extern "C" __declspec(noinline) void* __cdecl _expand_base(void* const block, size_t const size)
60{
61 // Validation section
62 _VALIDATE_RETURN (block != nullptr, EINVAL, nullptr);
64
65 size_t const old_size = static_cast<size_t>(HeapSize(__acrt_heap, 0, block));
66 size_t const new_size = size == 0 ? 1 : size;
67
69 if (new_block != nullptr)
70 return new_block;
71
72 // If a failure to contract was caused by platform limitations, just
73 // return the original block.
75 return block;
76
78 return nullptr;
79}
80
81// Expands or contracts a block of memory in the heap.
82//
83// This function resizes a block of memory in the heap to 'size' bytes. The
84// new size may be either greater (expansion) or less (contraction) than the
85// original size of the block. This function never moves the block. In the
86// case of expansion, if the block cannot be expanded to 'size', it is expanded
87// as much as possible.
88//
89// This function supports patching and therefore must be marked noinline.
90// Both _expand_dbg and _expand_base must also be marked noinline
91// to prevent identical COMDAT folding from substituting calls to _expand
92// with either other function or vice versa.
93extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) void* __cdecl _expand(void* const block, size_t const size)
94{
95 #ifdef _DEBUG
96 return _expand_dbg(block, size, _NORMAL_BLOCK, nullptr, 0);
97 #else
98 return _expand_base(block, size);
99 #endif
100}
#define __inline
Definition: _wctype.cpp:15
#define EINVAL
Definition: acclib.h:90
#define ENOMEM
Definition: acclib.h:84
#define __cdecl
Definition: accygwin.h:79
int __cdecl __acrt_errno_from_os_error(unsigned long)
Definition: errno.cpp:103
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
#define _NORMAL_BLOCK
Definition: crtdbg.h:67
#define _expand_dbg(p, s, t, f, l)
Definition: crtdbg.h:208
#define _HEAP_MAXREQ
Definition: malloc.h:24
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define HeapReAlloc
Definition: compat.h:734
#define noinline
Definition: types.h:64
size_t const size
Definition: expand.cpp:60
errno
Definition: expand.cpp:77
static __inline bool is_contraction_possible(size_t const old_size)
Definition: expand.cpp:26
size_t const old_size
Definition: expand.cpp:65
void * new_block
Definition: expand.cpp:68
size_t const new_size
Definition: expand.cpp:66
void __declspec(noinline) __cdecl _free_base(void *const block)
Definition: free_base.cpp:98
GLsizeiptr size
Definition: glext.h:5919
HANDLE __acrt_heap
Definition: heap_handle.cpp:15
BOOL WINAPI HeapQueryInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation OPTIONAL, SIZE_T HeapInformationLength OPTIONAL, PSIZE_T ReturnLength OPTIONAL)
Definition: heapmem.c:314
#define _VALIDATE_RETURN_NOEXC(expr, errorcode, retexpr)
void * _expand(void *_ptr, size_t _size)
Definition: malloc.c:100
@ HeapCompatibilityInformation
Definition: rtltypes.h:488
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
long LONG
Definition: pedump.c:60
#define _CRT_HYBRIDPATCHABLE
Definition: corecrt.h:188
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
static unsigned int block
Definition: xmlmemory.c:101