VirtualBox

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

最後變更 在這個檔案從39083是 39083,由 vboxsync 提交於 13 年 前

IPRT: -Wunused-parameter.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 21.9 KB
 
1/* $Id: alloc-ef.cpp 39083 2011-10-22 00:28:46Z 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.alldomusa.eu.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 all the block's 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#else
99 NOREF(pszOp); NOREF(pszFormat);
100#endif
101}
102
103
104#ifdef RTALLOC_EFENCE_TRACE
105
106/**
107 * Acquires the lock.
108 */
109DECLINLINE(void) rtmemBlockLock(void)
110{
111 unsigned c = 0;
112 while (!ASMAtomicCmpXchgU32(&g_BlocksLock, 1, 0))
113 RTThreadSleep(((++c) >> 2) & 31);
114}
115
116
117/**
118 * Releases the lock.
119 */
120DECLINLINE(void) rtmemBlockUnlock(void)
121{
122 Assert(g_BlocksLock == 1);
123 ASMAtomicXchgU32(&g_BlocksLock, 0);
124}
125
126
127/**
128 * Creates a block.
129 */
130DECLINLINE(PRTMEMBLOCK) rtmemBlockCreate(RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned,
131 const char *pszTag, void *pvCaller, RT_SRC_POS_DECL)
132{
133 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)malloc(sizeof(*pBlock));
134 if (pBlock)
135 {
136 pBlock->enmType = enmType;
137 pBlock->cbUnaligned = cbUnaligned;
138 pBlock->cbAligned = cbAligned;
139 pBlock->pszTag = pszTag;
140 pBlock->pvCaller = pvCaller;
141 pBlock->iLine = iLine;
142 pBlock->pszFile = pszFile;
143 pBlock->pszFunction = pszFunction;
144 }
145 return pBlock;
146}
147
148
149/**
150 * Frees a block.
151 */
152DECLINLINE(void) rtmemBlockFree(PRTMEMBLOCK pBlock)
153{
154 free(pBlock);
155}
156
157
158/**
159 * Insert a block from the tree.
160 */
161DECLINLINE(void) rtmemBlockInsert(PRTMEMBLOCK pBlock, void *pv)
162{
163 pBlock->Core.Key = pv;
164 rtmemBlockLock();
165 bool fRc = RTAvlPVInsert(&g_BlocksTree, &pBlock->Core);
166 rtmemBlockUnlock();
167 AssertRelease(fRc);
168}
169
170
171/**
172 * Remove a block from the tree and returns it to the caller.
173 */
174DECLINLINE(PRTMEMBLOCK) rtmemBlockRemove(void *pv)
175{
176 rtmemBlockLock();
177 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)RTAvlPVRemove(&g_BlocksTree, pv);
178 rtmemBlockUnlock();
179 return pBlock;
180}
181
182/**
183 * Gets a block.
184 */
185DECLINLINE(PRTMEMBLOCK) rtmemBlockGet(void *pv)
186{
187 rtmemBlockLock();
188 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)RTAvlPVGet(&g_BlocksTree, pv);
189 rtmemBlockUnlock();
190 return pBlock;
191}
192
193/**
194 * Dumps one allocation.
195 */
196static DECLCALLBACK(int) RTMemDumpOne(PAVLPVNODECORE pNode, void *pvUser)
197{
198 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)pNode;
199 fprintf(stderr, "%p %08lx(+%02lx) %p\n",
200 pBlock->Core.Key,
201 (unsigned long)pBlock->cbUnaligned,
202 (unsigned long)(pBlock->cbAligned - pBlock->cbUnaligned),
203 pBlock->pvCaller);
204 NOREF(pvUser);
205 return 0;
206}
207
208/**
209 * Dumps the allocated blocks.
210 * This is something which you should call from gdb.
211 */
212extern "C" void RTMemDump(void);
213void RTMemDump(void)
214{
215 fprintf(stderr, "address size(alg) caller\n");
216 RTAvlPVDoWithAll(&g_BlocksTree, true, RTMemDumpOne, NULL);
217}
218
219
220#ifdef RTALLOC_EFENCE_FREE_DELAYED
221/**
222 * Insert a delayed block.
223 */
224DECLINLINE(void) rtmemBlockDelayInsert(PRTMEMBLOCK pBlock)
225{
226 size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
227 pBlock->Core.pRight = NULL;
228 pBlock->Core.pLeft = NULL;
229 rtmemBlockLock();
230 if (g_pBlocksDelayHead)
231 {
232 g_pBlocksDelayHead->Core.pLeft = (PAVLPVNODECORE)pBlock;
233 pBlock->Core.pRight = (PAVLPVNODECORE)g_pBlocksDelayHead;
234 g_pBlocksDelayHead = pBlock;
235 }
236 else
237 {
238 g_pBlocksDelayTail = pBlock;
239 g_pBlocksDelayHead = pBlock;
240 }
241 g_cbBlocksDelay += cbBlock;
242 rtmemBlockUnlock();
243}
244
245/**
246 * Removes a delayed block.
247 */
248DECLINLINE(PRTMEMBLOCK) rtmemBlockDelayRemove(void)
249{
250 PRTMEMBLOCK pBlock = NULL;
251 rtmemBlockLock();
252 if (g_cbBlocksDelay > RTALLOC_EFENCE_FREE_DELAYED)
253 {
254 pBlock = g_pBlocksDelayTail;
255 if (pBlock)
256 {
257 g_pBlocksDelayTail = (PRTMEMBLOCK)pBlock->Core.pLeft;
258 if (pBlock->Core.pLeft)
259 pBlock->Core.pLeft->pRight = NULL;
260 else
261 g_pBlocksDelayHead = NULL;
262 g_cbBlocksDelay -= RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
263 }
264 }
265 rtmemBlockUnlock();
266 return pBlock;
267}
268
269
270#endif /* DELAY */
271
272#endif /* RTALLOC_EFENCE_TRACE */
273
274
275/**
276 * Internal allocator.
277 */
278RTDECL(void *) rtR3MemAlloc(const char *pszOp, RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned,
279 const char *pszTag, void *pvCaller, RT_SRC_POS_DECL)
280{
281 /*
282 * Sanity.
283 */
284 if ( RT_ALIGN_Z(RTALLOC_EFENCE_SIZE, PAGE_SIZE) != RTALLOC_EFENCE_SIZE
285 && RTALLOC_EFENCE_SIZE <= 0)
286 {
287 rtmemComplain(pszOp, "Invalid E-fence size! %#x\n", RTALLOC_EFENCE_SIZE);
288 return NULL;
289 }
290 if (!cbUnaligned)
291 {
292#if 0
293 rtmemComplain(pszOp, "Request of ZERO bytes allocation!\n");
294 return NULL;
295#else
296 cbAligned = cbUnaligned = 1;
297#endif
298 }
299
300#ifndef RTALLOC_EFENCE_IN_FRONT
301 /* Alignment decreases fence accuracy, but this is at least partially
302 * counteracted by filling and checking the alignment padding. When the
303 * fence is in front then then no extra alignment is needed. */
304 cbAligned = RT_ALIGN_Z(cbAligned, RTALLOC_EFENCE_ALIGNMENT);
305#endif
306
307#ifdef RTALLOC_EFENCE_TRACE
308 /*
309 * Allocate the trace block.
310 */
311 PRTMEMBLOCK pBlock = rtmemBlockCreate(enmType, cbUnaligned, cbAligned, pszTag, pvCaller, RT_SRC_POS_ARGS);
312 if (!pBlock)
313 {
314 rtmemComplain(pszOp, "Failed to allocate trace block!\n");
315 return NULL;
316 }
317#endif
318
319 /*
320 * Allocate a block with page alignment space + the size of the E-fence.
321 */
322 size_t cbBlock = RT_ALIGN_Z(cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
323 void *pvBlock = RTMemPageAlloc(cbBlock);
324 if (pvBlock)
325 {
326 /*
327 * Calc the start of the fence and the user block
328 * and then change the page protection of the fence.
329 */
330#ifdef RTALLOC_EFENCE_IN_FRONT
331 void *pvEFence = pvBlock;
332 void *pv = (char *)pvEFence + RTALLOC_EFENCE_SIZE;
333# ifdef RTALLOC_EFENCE_NOMAN_FILLER
334 memset((char *)pv + cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER, cbBlock - RTALLOC_EFENCE_SIZE - cbUnaligned);
335# endif
336#else
337 void *pvEFence = (char *)pvBlock + (cbBlock - RTALLOC_EFENCE_SIZE);
338 void *pv = (char *)pvEFence - cbAligned;
339# ifdef RTALLOC_EFENCE_NOMAN_FILLER
340 memset(pvBlock, RTALLOC_EFENCE_NOMAN_FILLER, cbBlock - RTALLOC_EFENCE_SIZE - cbAligned);
341 memset((char *)pv + cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER, cbAligned - cbUnaligned);
342# endif
343#endif
344
345#ifdef RTALLOC_EFENCE_FENCE_FILLER
346 memset(pvEFence, RTALLOC_EFENCE_FENCE_FILLER, RTALLOC_EFENCE_SIZE);
347#endif
348 int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_NONE);
349 if (!rc)
350 {
351#ifdef RTALLOC_EFENCE_TRACE
352 rtmemBlockInsert(pBlock, pv);
353#endif
354 if (enmType == RTMEMTYPE_RTMEMALLOCZ)
355 memset(pv, 0, cbUnaligned);
356#ifdef RTALLOC_EFENCE_FILLER
357 else
358 memset(pv, RTALLOC_EFENCE_FILLER, cbUnaligned);
359#endif
360
361 rtmemLog(pszOp, "returns %p (pvBlock=%p cbBlock=%#x pvEFence=%p cbUnaligned=%#x)\n", pv, pvBlock, cbBlock, pvEFence, cbUnaligned);
362 return pv;
363 }
364 rtmemComplain(pszOp, "RTMemProtect failed, pvEFence=%p size %d, rc=%d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc);
365 RTMemPageFree(pvBlock, cbBlock);
366 }
367 else
368 rtmemComplain(pszOp, "Failed to allocated %lu (%lu) bytes.\n", (unsigned long)cbBlock, (unsigned long)cbUnaligned);
369
370#ifdef RTALLOC_EFENCE_TRACE
371 rtmemBlockFree(pBlock);
372#endif
373 return NULL;
374}
375
376
377/**
378 * Internal free.
379 */
380RTDECL(void) rtR3MemFree(const char *pszOp, RTMEMTYPE enmType, void *pv, void *pvCaller, RT_SRC_POS_DECL)
381{
382 NOREF(enmType); RT_SRC_POS_NOREF();
383
384 /*
385 * Simple case.
386 */
387 if (!pv)
388 return;
389
390 /*
391 * Check watch points.
392 */
393 for (unsigned i = 0; i < RT_ELEMENTS(gapvRTMemFreeWatch); i++)
394 if (gapvRTMemFreeWatch[i] == pv)
395 RTAssertDoPanic();
396
397#ifdef RTALLOC_EFENCE_TRACE
398 /*
399 * Find the block.
400 */
401 PRTMEMBLOCK pBlock = rtmemBlockRemove(pv);
402 if (pBlock)
403 {
404 if (gfRTMemFreeLog)
405 RTLogPrintf("RTMem %s: pv=%p pvCaller=%p cbUnaligned=%#x\n", pszOp, pv, pvCaller, pBlock->cbUnaligned);
406
407# ifdef RTALLOC_EFENCE_NOMAN_FILLER
408 /*
409 * Check whether the no man's land is untouched.
410 */
411# ifdef RTALLOC_EFENCE_IN_FRONT
412 void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned,
413 RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbUnaligned,
414 RTALLOC_EFENCE_NOMAN_FILLER);
415# else
416 /* Alignment must match allocation alignment in rtMemAlloc(). */
417 void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned,
418 pBlock->cbAligned - pBlock->cbUnaligned,
419 RTALLOC_EFENCE_NOMAN_FILLER);
420 if (pvWrong)
421 RTAssertDoPanic();
422 pvWrong = ASMMemIsAll8((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK),
423 RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbAligned,
424 RTALLOC_EFENCE_NOMAN_FILLER);
425# endif
426 if (pvWrong)
427 RTAssertDoPanic();
428# endif
429
430# ifdef RTALLOC_EFENCE_FREE_FILL
431 /*
432 * Fill the user part of the block.
433 */
434 memset(pv, RTALLOC_EFENCE_FREE_FILL, pBlock->cbUnaligned);
435# endif
436
437# if defined(RTALLOC_EFENCE_FREE_DELAYED) && RTALLOC_EFENCE_FREE_DELAYED > 0
438 /*
439 * We're doing delayed freeing.
440 * That means we'll expand the E-fence to cover the entire block.
441 */
442 int rc = RTMemProtect(pv, pBlock->cbAligned, RTMEM_PROT_NONE);
443 if (RT_SUCCESS(rc))
444 {
445 /*
446 * Insert it into the free list and process pending frees.
447 */
448 rtmemBlockDelayInsert(pBlock);
449 while ((pBlock = rtmemBlockDelayRemove()) != NULL)
450 {
451 pv = pBlock->Core.Key;
452# ifdef RTALLOC_EFENCE_IN_FRONT
453 void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE;
454# else
455 void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
456# endif
457 size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
458 rc = RTMemProtect(pvBlock, cbBlock, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
459 if (RT_SUCCESS(rc))
460 RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE);
461 else
462 rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvBlock, cbBlock, rc);
463 rtmemBlockFree(pBlock);
464 }
465 }
466 else
467 rtmemComplain(pszOp, "Failed to expand the efence of pv=%p cb=%d, rc=%d.\n", pv, pBlock, rc);
468
469# else /* !RTALLOC_EFENCE_FREE_DELAYED */
470
471 /*
472 * Turn of the E-fence and free it.
473 */
474# ifdef RTALLOC_EFENCE_IN_FRONT
475 void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE;
476 void *pvEFence = pvBlock;
477# else
478 void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
479 void *pvEFence = (char *)pv + pBlock->cb;
480# endif
481 int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
482 if (RT_SUCCESS(rc))
483 RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE);
484 else
485 rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc);
486 rtmemBlockFree(pBlock);
487
488# endif /* !RTALLOC_EFENCE_FREE_DELAYED */
489 }
490 else
491 rtmemComplain(pszOp, "pv=%p not found! Incorrect free!\n", pv);
492
493#else /* !RTALLOC_EFENCE_TRACE */
494
495 /*
496 * We have no size tracking, so we're not doing any freeing because
497 * we cannot if the E-fence is after the block.
498 * Let's just expand the E-fence to the first page of the user bit
499 * since we know that it's around.
500 */
501 int rc = RTMemProtect((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), PAGE_SIZE, RTMEM_PROT_NONE);
502 if (RT_FAILURE(rc))
503 rtmemComplain(pszOp, "RTMemProtect(%p, PAGE_SIZE, RTMEM_PROT_NONE) -> %d\n", (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), rc);
504#endif /* !RTALLOC_EFENCE_TRACE */
505}
506
507
508/**
509 * Internal realloc.
510 */
511RTDECL(void *) rtR3MemRealloc(const char *pszOp, RTMEMTYPE enmType, void *pvOld, size_t cbNew,
512 const char *pszTag, void *pvCaller, RT_SRC_POS_DECL)
513{
514 /*
515 * Allocate new and copy.
516 */
517 if (!pvOld)
518 return rtR3MemAlloc(pszOp, enmType, cbNew, cbNew, pszTag, pvCaller, RT_SRC_POS_ARGS);
519 if (!cbNew)
520 {
521 rtR3MemFree(pszOp, RTMEMTYPE_RTMEMREALLOC, pvOld, pvCaller, RT_SRC_POS_ARGS);
522 return NULL;
523 }
524
525#ifdef RTALLOC_EFENCE_TRACE
526
527 /*
528 * Get the block, allocate the new, copy the data, free the old one.
529 */
530 PRTMEMBLOCK pBlock = rtmemBlockGet(pvOld);
531 if (pBlock)
532 {
533 void *pvRet = rtR3MemAlloc(pszOp, enmType, cbNew, cbNew, pszTag, pvCaller, RT_SRC_POS_ARGS);
534 if (pvRet)
535 {
536 memcpy(pvRet, pvOld, RT_MIN(cbNew, pBlock->cbUnaligned));
537 rtR3MemFree(pszOp, RTMEMTYPE_RTMEMREALLOC, pvOld, pvCaller, RT_SRC_POS_ARGS);
538 }
539 return pvRet;
540 }
541 else
542 rtmemComplain(pszOp, "pvOld=%p was not found!\n", pvOld);
543 return NULL;
544
545#else /* !RTALLOC_EFENCE_TRACE */
546
547 rtmemComplain(pszOp, "Not supported if RTALLOC_EFENCE_TRACE isn't defined!\n");
548 return NULL;
549
550#endif /* !RTALLOC_EFENCE_TRACE */
551}
552
553
554
555
556RTDECL(void *) RTMemEfTmpAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
557{
558 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
559}
560
561
562RTDECL(void *) RTMemEfTmpAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
563{
564 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
565}
566
567
568RTDECL(void) RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW
569{
570 if (pv)
571 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), RT_SRC_POS_ARGS);
572}
573
574
575RTDECL(void *) RTMemEfAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
576{
577 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
578}
579
580
581RTDECL(void *) RTMemEfAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
582{
583 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
584}
585
586
587RTDECL(void *) RTMemEfAllocVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
588{
589 size_t cbAligned;
590 if (cbUnaligned >= 16)
591 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
592 else
593 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
594 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
595}
596
597
598RTDECL(void *) RTMemEfAllocZVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
599{
600 size_t cbAligned;
601 if (cbUnaligned >= 16)
602 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
603 else
604 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
605 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
606}
607
608
609RTDECL(void *) RTMemEfRealloc(void *pvOld, size_t cbNew, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
610{
611 return rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
612}
613
614
615RTDECL(void) RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW
616{
617 if (pv)
618 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), RT_SRC_POS_ARGS);
619}
620
621
622RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
623{
624 void *pvDst = RTMemEfAlloc(cb, pszTag, RT_SRC_POS_ARGS);
625 if (pvDst)
626 memcpy(pvDst, pvSrc, cb);
627 return pvDst;
628}
629
630
631RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
632{
633 void *pvDst = RTMemEfAlloc(cbSrc + cbExtra, pszTag, RT_SRC_POS_ARGS);
634 if (pvDst)
635 {
636 memcpy(pvDst, pvSrc, cbSrc);
637 memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
638 }
639 return pvDst;
640}
641
642
643
644
645/*
646 *
647 * The NP (no position) versions.
648 *
649 */
650
651
652
653RTDECL(void *) RTMemEfTmpAllocNP(size_t cb, const char *pszTag) RT_NO_THROW
654{
655 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
656}
657
658
659RTDECL(void *) RTMemEfTmpAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW
660{
661 return rtR3MemAlloc("TmpAllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
662}
663
664
665RTDECL(void) RTMemEfTmpFreeNP(void *pv) RT_NO_THROW
666{
667 if (pv)
668 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
669}
670
671
672RTDECL(void *) RTMemEfAllocNP(size_t cb, const char *pszTag) RT_NO_THROW
673{
674 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
675}
676
677
678RTDECL(void *) RTMemEfAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW
679{
680 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
681}
682
683
684RTDECL(void *) RTMemEfAllocVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW
685{
686 size_t cbAligned;
687 if (cbUnaligned >= 16)
688 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
689 else
690 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
691 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), NULL, 0, NULL);
692}
693
694
695RTDECL(void *) RTMemEfAllocZVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW
696{
697 size_t cbAligned;
698 if (cbUnaligned >= 16)
699 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
700 else
701 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
702 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), NULL, 0, NULL);
703}
704
705
706RTDECL(void *) RTMemEfReallocNP(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW
707{
708 return rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, pszTag, ASMReturnAddress(), NULL, 0, NULL);
709}
710
711
712RTDECL(void) RTMemEfFreeNP(void *pv) RT_NO_THROW
713{
714 if (pv)
715 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
716}
717
718
719RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW
720{
721 void *pvDst = RTMemEfAlloc(cb, pszTag, NULL, 0, NULL);
722 if (pvDst)
723 memcpy(pvDst, pvSrc, cb);
724 return pvDst;
725}
726
727
728RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW
729{
730 void *pvDst = RTMemEfAlloc(cbSrc + cbExtra, pszTag, NULL, 0, NULL);
731 if (pvDst)
732 {
733 memcpy(pvDst, pvSrc, cbSrc);
734 memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
735 }
736 return pvDst;
737}
738
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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