VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/alloc-ef.cpp@ 28800

Last change on this file since 28800 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 21.1 KB
Line 
1/* $Id: alloc-ef.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
2/** @file
3 * IPRT - Memory Allocation, electric fence.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "alloc-ef.h"
32#include <iprt/mem.h>
33#include <iprt/log.h>
34#include <iprt/asm.h>
35#include <iprt/thread.h>
36#include <VBox/sup.h>
37#include <iprt/err.h>
38#include <errno.h>
39#include <stdio.h>
40#include <stdlib.h>
41
42#include <iprt/alloc.h>
43#include <iprt/assert.h>
44#include <iprt/param.h>
45#include <iprt/string.h>
46
47
48/*******************************************************************************
49* Global Variables *
50*******************************************************************************/
51#ifdef RTALLOC_EFENCE_TRACE
52/** Spinlock protecting the allthe blocks globals. */
53static volatile uint32_t g_BlocksLock;
54/** Tree tracking the allocations. */
55static AVLPVTREE g_BlocksTree;
56#ifdef RTALLOC_EFENCE_FREE_DELAYED
57/** Tail of the delayed blocks. */
58static volatile PRTMEMBLOCK g_pBlocksDelayHead;
59/** Tail of the delayed blocks. */
60static volatile PRTMEMBLOCK g_pBlocksDelayTail;
61/** Number of bytes in the delay list (includes fences). */
62static volatile size_t g_cbBlocksDelay;
63#endif
64#endif
65/** Array of pointers free watches for. */
66void *gapvRTMemFreeWatch[4] = {NULL, NULL, NULL, NULL};
67/** Enable logging of all freed memory. */
68bool gfRTMemFreeLog = false;
69
70
71/*******************************************************************************
72* Internal Functions *
73*******************************************************************************/
74/**
75 * Complains about something.
76 */
77static void rtmemComplain(const char *pszOp, const char *pszFormat, ...)
78{
79 va_list args;
80 fprintf(stderr, "RTMem error: %s: ", pszOp);
81 va_start(args, pszFormat);
82 vfprintf(stderr, pszFormat, args);
83 va_end(args);
84 RTAssertDoPanic();
85}
86
87/**
88 * Log an event.
89 */
90DECLINLINE(void) rtmemLog(const char *pszOp, const char *pszFormat, ...)
91{
92#if 0
93 va_list args;
94 fprintf(stderr, "RTMem info: %s: ", pszOp);
95 va_start(args, pszFormat);
96 vfprintf(stderr, pszFormat, args);
97 va_end(args);
98#endif
99}
100
101
102#ifdef RTALLOC_EFENCE_TRACE
103
104/**
105 * Aquires the lock.
106 */
107DECLINLINE(void) rtmemBlockLock(void)
108{
109 unsigned c = 0;
110 while (!ASMAtomicCmpXchgU32(&g_BlocksLock, 1, 0))
111 RTThreadSleep(((++c) >> 2) & 31);
112}
113
114
115/**
116 * Releases the lock.
117 */
118DECLINLINE(void) rtmemBlockUnlock(void)
119{
120 Assert(g_BlocksLock == 1);
121 ASMAtomicXchgU32(&g_BlocksLock, 0);
122}
123
124
125/**
126 * Creates a block.
127 */
128DECLINLINE(PRTMEMBLOCK) rtmemBlockCreate(RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned,
129 void *pvCaller, RT_SRC_POS_DECL)
130{
131 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)malloc(sizeof(*pBlock));
132 if (pBlock)
133 {
134 pBlock->enmType = enmType;
135 pBlock->cbUnaligned = cbUnaligned;
136 pBlock->cbAligned = cbAligned;
137 pBlock->pvCaller = pvCaller;
138 pBlock->iLine = iLine;
139 pBlock->pszFile = pszFile;
140 pBlock->pszFunction = pszFunction;
141 }
142 return pBlock;
143}
144
145
146/**
147 * Frees a block.
148 */
149DECLINLINE(void) rtmemBlockFree(PRTMEMBLOCK pBlock)
150{
151 free(pBlock);
152}
153
154
155/**
156 * Insert a block from the tree.
157 */
158DECLINLINE(void) rtmemBlockInsert(PRTMEMBLOCK pBlock, void *pv)
159{
160 pBlock->Core.Key = pv;
161 rtmemBlockLock();
162 bool fRc = RTAvlPVInsert(&g_BlocksTree, &pBlock->Core);
163 rtmemBlockUnlock();
164 AssertRelease(fRc);
165}
166
167
168/**
169 * Remove a block from the tree and returns it to the caller.
170 */
171DECLINLINE(PRTMEMBLOCK) rtmemBlockRemove(void *pv)
172{
173 rtmemBlockLock();
174 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)RTAvlPVRemove(&g_BlocksTree, pv);
175 rtmemBlockUnlock();
176 return pBlock;
177}
178
179/**
180 * Gets a block.
181 */
182DECLINLINE(PRTMEMBLOCK) rtmemBlockGet(void *pv)
183{
184 rtmemBlockLock();
185 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)RTAvlPVGet(&g_BlocksTree, pv);
186 rtmemBlockUnlock();
187 return pBlock;
188}
189
190/**
191 * Dumps one allocation.
192 */
193static DECLCALLBACK(int) RTMemDumpOne(PAVLPVNODECORE pNode, void *pvUser)
194{
195 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)pNode;
196 fprintf(stderr, "%p %08lx(+%02lx) %p\n",
197 pBlock->Core.Key,
198 (unsigned long)pBlock->cbUnaligned,
199 (unsigned long)(pBlock->cbAligned - pBlock->cbUnaligned),
200 pBlock->pvCaller);
201 return 0;
202}
203
204/**
205 * Dumps the allocated blocks.
206 * This is something which you should call from gdb.
207 */
208extern "C" void RTMemDump(void);
209void RTMemDump(void)
210{
211 fprintf(stderr, "address size(alg) caller\n");
212 RTAvlPVDoWithAll(&g_BlocksTree, true, RTMemDumpOne, NULL);
213}
214
215
216#ifdef RTALLOC_EFENCE_FREE_DELAYED
217/**
218 * Insert a delayed block.
219 */
220DECLINLINE(void) rtmemBlockDelayInsert(PRTMEMBLOCK pBlock)
221{
222 size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
223 pBlock->Core.pRight = NULL;
224 pBlock->Core.pLeft = NULL;
225 rtmemBlockLock();
226 if (g_pBlocksDelayHead)
227 {
228 g_pBlocksDelayHead->Core.pLeft = (PAVLPVNODECORE)pBlock;
229 pBlock->Core.pRight = (PAVLPVNODECORE)g_pBlocksDelayHead;
230 g_pBlocksDelayHead = pBlock;
231 }
232 else
233 {
234 g_pBlocksDelayTail = pBlock;
235 g_pBlocksDelayHead = pBlock;
236 }
237 g_cbBlocksDelay += cbBlock;
238 rtmemBlockUnlock();
239}
240
241/**
242 * Removes a delayed block.
243 */
244DECLINLINE(PRTMEMBLOCK) rtmemBlockDelayRemove(void)
245{
246 PRTMEMBLOCK pBlock = NULL;
247 rtmemBlockLock();
248 if (g_cbBlocksDelay > RTALLOC_EFENCE_FREE_DELAYED)
249 {
250 pBlock = g_pBlocksDelayTail;
251 if (pBlock)
252 {
253 g_pBlocksDelayTail = (PRTMEMBLOCK)pBlock->Core.pLeft;
254 if (pBlock->Core.pLeft)
255 pBlock->Core.pLeft->pRight = NULL;
256 else
257 g_pBlocksDelayHead = NULL;
258 g_cbBlocksDelay -= RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
259 }
260 }
261 rtmemBlockUnlock();
262 return pBlock;
263}
264
265
266#endif /* DELAY */
267
268#endif /* RTALLOC_EFENCE_TRACE */
269
270
271/**
272 * Internal allocator.
273 */
274RTDECL(void *) rtR3MemAlloc(const char *pszOp, RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned,
275 void *pvCaller, RT_SRC_POS_DECL)
276{
277 /*
278 * Sanity.
279 */
280 if ( RT_ALIGN_Z(RTALLOC_EFENCE_SIZE, PAGE_SIZE) != RTALLOC_EFENCE_SIZE
281 && RTALLOC_EFENCE_SIZE <= 0)
282 {
283 rtmemComplain(pszOp, "Invalid E-fence size! %#x\n", RTALLOC_EFENCE_SIZE);
284 return NULL;
285 }
286 if (!cbUnaligned)
287 {
288#if 0
289 rtmemComplain(pszOp, "Request of ZERO bytes allocation!\n");
290 return NULL;
291#else
292 cbAligned = cbUnaligned = 1;
293#endif
294 }
295
296#ifndef RTALLOC_EFENCE_IN_FRONT
297 /* Alignment decreases fence accuracy, but this is at least partially
298 * counteracted by filling and checking the alignment padding. When the
299 * fence is in front then then no extra alignment is needed. */
300 cbAligned = RT_ALIGN_Z(cbAligned, RTALLOC_EFENCE_ALIGNMENT);
301#endif
302
303#ifdef RTALLOC_EFENCE_TRACE
304 /*
305 * Allocate the trace block.
306 */
307 PRTMEMBLOCK pBlock = rtmemBlockCreate(enmType, cbUnaligned, cbAligned, pvCaller, RT_SRC_POS_ARGS);
308 if (!pBlock)
309 {
310 rtmemComplain(pszOp, "Failed to allocate trace block!\n");
311 return NULL;
312 }
313#endif
314
315 /*
316 * Allocate a block with page alignment space + the size of the E-fence.
317 */
318 size_t cbBlock = RT_ALIGN_Z(cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
319 void *pvBlock = RTMemPageAlloc(cbBlock);
320 if (pvBlock)
321 {
322 /*
323 * Calc the start of the fence and the user block
324 * and then change the page protection of the fence.
325 */
326#ifdef RTALLOC_EFENCE_IN_FRONT
327 void *pvEFence = pvBlock;
328 void *pv = (char *)pvEFence + RTALLOC_EFENCE_SIZE;
329# ifdef RTALLOC_EFENCE_NOMAN_FILLER
330 memset((char *)pv + cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER, cbBlock - RTALLOC_EFENCE_SIZE - cbUnaligned);
331# endif
332#else
333 void *pvEFence = (char *)pvBlock + (cbBlock - RTALLOC_EFENCE_SIZE);
334 void *pv = (char *)pvEFence - cbAligned;
335# ifdef RTALLOC_EFENCE_NOMAN_FILLER
336 memset(pvBlock, RTALLOC_EFENCE_NOMAN_FILLER, cbBlock - RTALLOC_EFENCE_SIZE - cbAligned);
337 memset((char *)pv + cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER, cbAligned - cbUnaligned);
338# endif
339#endif
340
341#ifdef RTALLOC_EFENCE_FENCE_FILLER
342 memset(pvEFence, RTALLOC_EFENCE_FENCE_FILLER, RTALLOC_EFENCE_SIZE);
343#endif
344 int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_NONE);
345 if (!rc)
346 {
347#ifdef RTALLOC_EFENCE_TRACE
348 rtmemBlockInsert(pBlock, pv);
349#endif
350 if (enmType == RTMEMTYPE_RTMEMALLOCZ)
351 memset(pv, 0, cbUnaligned);
352#ifdef RTALLOC_EFENCE_FILLER
353 else
354 memset(pv, RTALLOC_EFENCE_FILLER, cbUnaligned);
355#endif
356
357 rtmemLog(pszOp, "returns %p (pvBlock=%p cbBlock=%#x pvEFence=%p cbUnaligned=%#x)\n", pv, pvBlock, cbBlock, pvEFence, cbUnaligned);
358 return pv;
359 }
360 rtmemComplain(pszOp, "RTMemProtect failed, pvEFence=%p size %d, rc=%d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc);
361 RTMemPageFree(pvBlock, cbBlock);
362 }
363 else
364 rtmemComplain(pszOp, "Failed to allocated %lu (%lu) bytes.\n", (unsigned long)cbBlock, (unsigned long)cbUnaligned);
365
366#ifdef RTALLOC_EFENCE_TRACE
367 rtmemBlockFree(pBlock);
368#endif
369 return NULL;
370}
371
372
373/**
374 * Internal free.
375 */
376RTDECL(void) rtR3MemFree(const char *pszOp, RTMEMTYPE enmType, void *pv, void *pvCaller, RT_SRC_POS_DECL)
377{
378 /*
379 * Simple case.
380 */
381 if (!pv)
382 return;
383
384 /*
385 * Check watch points.
386 */
387 for (unsigned i = 0; i < RT_ELEMENTS(gapvRTMemFreeWatch); i++)
388 if (gapvRTMemFreeWatch[i] == pv)
389 RTAssertDoPanic();
390
391#ifdef RTALLOC_EFENCE_TRACE
392 /*
393 * Find the block.
394 */
395 PRTMEMBLOCK pBlock = rtmemBlockRemove(pv);
396 if (pBlock)
397 {
398 if (gfRTMemFreeLog)
399 RTLogPrintf("RTMem %s: pv=%p pvCaller=%p cbUnaligned=%#x\n", pszOp, pv, pvCaller, pBlock->cbUnaligned);
400
401# ifdef RTALLOC_EFENCE_NOMAN_FILLER
402 /*
403 * Check whether the no man's land is untouched.
404 */
405# ifdef RTALLOC_EFENCE_IN_FRONT
406 void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned,
407 RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbUnaligned,
408 RTALLOC_EFENCE_NOMAN_FILLER);
409# else
410 /* Alignment must match allocation alignment in rtMemAlloc(). */
411 void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned,
412 pBlock->cbAligned - pBlock->cbUnaligned,
413 RTALLOC_EFENCE_NOMAN_FILLER);
414 if (pvWrong)
415 RTAssertDoPanic();
416 pvWrong = ASMMemIsAll8((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK),
417 RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbAligned,
418 RTALLOC_EFENCE_NOMAN_FILLER);
419# endif
420 if (pvWrong)
421 RTAssertDoPanic();
422# endif
423
424# ifdef RTALLOC_EFENCE_FREE_FILL
425 /*
426 * Fill the user part of the block.
427 */
428 memset(pv, RTALLOC_EFENCE_FREE_FILL, pBlock->cbUnaligned);
429# endif
430
431# if defined(RTALLOC_EFENCE_FREE_DELAYED) && RTALLOC_EFENCE_FREE_DELAYED > 0
432 /*
433 * We're doing delayed freeing.
434 * That means we'll expand the E-fence to cover the entire block.
435 */
436 int rc = RTMemProtect(pv, pBlock->cbAligned, RTMEM_PROT_NONE);
437 if (RT_SUCCESS(rc))
438 {
439 /*
440 * Insert it into the free list and process pending frees.
441 */
442 rtmemBlockDelayInsert(pBlock);
443 while ((pBlock = rtmemBlockDelayRemove()) != NULL)
444 {
445 pv = pBlock->Core.Key;
446# ifdef RTALLOC_EFENCE_IN_FRONT
447 void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE;
448# else
449 void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
450# endif
451 size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
452 rc = RTMemProtect(pvBlock, cbBlock, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
453 if (RT_SUCCESS(rc))
454 RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE);
455 else
456 rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvBlock, cbBlock, rc);
457 rtmemBlockFree(pBlock);
458 }
459 }
460 else
461 rtmemComplain(pszOp, "Failed to expand the efence of pv=%p cb=%d, rc=%d.\n", pv, pBlock, rc);
462
463# else /* !RTALLOC_EFENCE_FREE_DELAYED */
464
465 /*
466 * Turn of the E-fence and free it.
467 */
468# ifdef RTALLOC_EFENCE_IN_FRONT
469 void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE;
470 void *pvEFence = pvBlock;
471# else
472 void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
473 void *pvEFence = (char *)pv + pBlock->cb;
474# endif
475 int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
476 if (RT_SUCCESS(rc))
477 RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE);
478 else
479 rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc);
480 rtmemBlockFree(pBlock);
481
482# endif /* !RTALLOC_EFENCE_FREE_DELAYED */
483 }
484 else
485 rtmemComplain(pszOp, "pv=%p not found! Incorrect free!\n", pv);
486
487#else /* !RTALLOC_EFENCE_TRACE */
488
489 /*
490 * We have no size tracking, so we're not doing any freeing because
491 * we cannot if the E-fence is after the block.
492 * Let's just expand the E-fence to the first page of the user bit
493 * since we know that it's around.
494 */
495 int rc = RTMemProtect((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), PAGE_SIZE, RTMEM_PROT_NONE);
496 if (RT_FAILURE(rc))
497 rtmemComplain(pszOp, "RTMemProtect(%p, PAGE_SIZE, RTMEM_PROT_NONE) -> %d\n", (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), rc);
498#endif /* !RTALLOC_EFENCE_TRACE */
499}
500
501
502/**
503 * Internal realloc.
504 */
505RTDECL(void *) rtR3MemRealloc(const char *pszOp, RTMEMTYPE enmType, void *pvOld, size_t cbNew, void *pvCaller, RT_SRC_POS_DECL)
506{
507 /*
508 * Allocate new and copy.
509 */
510 if (!pvOld)
511 return rtR3MemAlloc(pszOp, enmType, cbNew, cbNew, pvCaller, RT_SRC_POS_ARGS);
512 if (!cbNew)
513 {
514 rtR3MemFree(pszOp, RTMEMTYPE_RTMEMREALLOC, pvOld, pvCaller, RT_SRC_POS_ARGS);
515 return NULL;
516 }
517
518#ifdef RTALLOC_EFENCE_TRACE
519
520 /*
521 * Get the block, allocate the new, copy the data, free the old one.
522 */
523 PRTMEMBLOCK pBlock = rtmemBlockGet(pvOld);
524 if (pBlock)
525 {
526 void *pvRet = rtR3MemAlloc(pszOp, enmType, cbNew, cbNew, pvCaller, RT_SRC_POS_ARGS);
527 if (pvRet)
528 {
529 memcpy(pvRet, pvOld, RT_MIN(cbNew, pBlock->cbUnaligned));
530 rtR3MemFree(pszOp, RTMEMTYPE_RTMEMREALLOC, pvOld, pvCaller, RT_SRC_POS_ARGS);
531 }
532 return pvRet;
533 }
534 else
535 rtmemComplain(pszOp, "pvOld=%p was not found!\n", pvOld);
536 return NULL;
537
538#else /* !RTALLOC_EFENCE_TRACE */
539
540 rtmemComplain(pszOp, "Not supported if RTALLOC_EFENCE_TRACE isn't defined!\n");
541 return NULL;
542
543#endif /* !RTALLOC_EFENCE_TRACE */
544}
545
546
547
548
549RTDECL(void *) RTMemEfTmpAlloc(size_t cb, RT_SRC_POS_DECL) RT_NO_THROW
550{
551 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOC, cb, cb, ASMReturnAddress(), RT_SRC_POS_ARGS);
552}
553
554
555RTDECL(void *) RTMemEfTmpAllocZ(size_t cb, RT_SRC_POS_DECL) RT_NO_THROW
556{
557 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOCZ, cb, cb, ASMReturnAddress(), RT_SRC_POS_ARGS);
558}
559
560
561RTDECL(void) RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW
562{
563 if (pv)
564 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), RT_SRC_POS_ARGS);
565}
566
567
568RTDECL(void *) RTMemEfAlloc(size_t cb, RT_SRC_POS_DECL) RT_NO_THROW
569{
570 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, ASMReturnAddress(), RT_SRC_POS_ARGS);
571}
572
573
574RTDECL(void *) RTMemEfAllocZ(size_t cb, RT_SRC_POS_DECL) RT_NO_THROW
575{
576 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, ASMReturnAddress(), RT_SRC_POS_ARGS);
577}
578
579
580RTDECL(void *) RTMemEfAllocVar(size_t cbUnaligned, RT_SRC_POS_DECL) RT_NO_THROW
581{
582 size_t cbAligned;
583 if (cbUnaligned >= 16)
584 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
585 else
586 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
587 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, ASMReturnAddress(), RT_SRC_POS_ARGS);
588}
589
590
591RTDECL(void *) RTMemEfAllocZVar(size_t cbUnaligned, RT_SRC_POS_DECL) RT_NO_THROW
592{
593 size_t cbAligned;
594 if (cbUnaligned >= 16)
595 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
596 else
597 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
598 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, ASMReturnAddress(), RT_SRC_POS_ARGS);
599}
600
601
602RTDECL(void *) RTMemEfRealloc(void *pvOld, size_t cbNew, RT_SRC_POS_DECL) RT_NO_THROW
603{
604 return rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, ASMReturnAddress(), RT_SRC_POS_ARGS);
605}
606
607
608RTDECL(void) RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW
609{
610 if (pv)
611 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), RT_SRC_POS_ARGS);
612}
613
614
615RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, RT_SRC_POS_DECL) RT_NO_THROW
616{
617 void *pvDst = RTMemEfAlloc(cb, RT_SRC_POS_ARGS);
618 if (pvDst)
619 memcpy(pvDst, pvSrc, cb);
620 return pvDst;
621}
622
623
624RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, RT_SRC_POS_DECL) RT_NO_THROW
625{
626 void *pvDst = RTMemEfAlloc(cbSrc + cbExtra, RT_SRC_POS_ARGS);
627 if (pvDst)
628 {
629 memcpy(pvDst, pvSrc, cbSrc);
630 memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
631 }
632 return pvDst;
633}
634
635
636
637
638/*
639 *
640 * The NP (no position) versions.
641 *
642 */
643
644
645
646RTDECL(void *) RTMemEfTmpAllocNP(size_t cb) RT_NO_THROW
647{
648 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOC, cb, cb, ASMReturnAddress(), NULL, 0, NULL);
649}
650
651
652RTDECL(void *) RTMemEfTmpAllocZNP(size_t cb) RT_NO_THROW
653{
654 return rtR3MemAlloc("TmpAllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, ASMReturnAddress(), NULL, 0, NULL);
655}
656
657
658RTDECL(void) RTMemEfTmpFreeNP(void *pv) RT_NO_THROW
659{
660 if (pv)
661 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
662}
663
664
665RTDECL(void *) RTMemEfAllocNP(size_t cb) RT_NO_THROW
666{
667 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, ASMReturnAddress(), NULL, 0, NULL);
668}
669
670
671RTDECL(void *) RTMemEfAllocZNP(size_t cb) RT_NO_THROW
672{
673 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, ASMReturnAddress(), NULL, 0, NULL);
674}
675
676
677RTDECL(void *) RTMemEfAllocVarNP(size_t cbUnaligned) RT_NO_THROW
678{
679 size_t cbAligned;
680 if (cbUnaligned >= 16)
681 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
682 else
683 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
684 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, ASMReturnAddress(), NULL, 0, NULL);
685}
686
687
688RTDECL(void *) RTMemEfAllocZVarNP(size_t cbUnaligned) RT_NO_THROW
689{
690 size_t cbAligned;
691 if (cbUnaligned >= 16)
692 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
693 else
694 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
695 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, ASMReturnAddress(), NULL, 0, NULL);
696}
697
698
699RTDECL(void *) RTMemEfReallocNP(void *pvOld, size_t cbNew) RT_NO_THROW
700{
701 return rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, ASMReturnAddress(), NULL, 0, NULL);
702}
703
704
705RTDECL(void) RTMemEfFreeNP(void *pv) RT_NO_THROW
706{
707 if (pv)
708 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
709}
710
711
712RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb) RT_NO_THROW
713{
714 void *pvDst = RTMemEfAlloc(cb, NULL, 0, NULL);
715 if (pvDst)
716 memcpy(pvDst, pvSrc, cb);
717 return pvDst;
718}
719
720
721RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra) RT_NO_THROW
722{
723 void *pvDst = RTMemEfAlloc(cbSrc + cbExtra, NULL, 0, NULL);
724 if (pvDst)
725 {
726 memcpy(pvDst, pvSrc, cbSrc);
727 memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
728 }
729 return pvDst;
730}
731
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette