1de4a1d01951937632098a6cda45859afa587a06fsewardj 2de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 3de4a1d01951937632098a6cda45859afa587a06fsewardj/*--- An implementation of malloc/free which doesn't use sbrk. ---*/ 4717cde5bda18d17792d1994c61b6a27408b4b4a7njn/*--- m_mallocfree.c ---*/ 5de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 6de4a1d01951937632098a6cda45859afa587a06fsewardj 7de4a1d01951937632098a6cda45859afa587a06fsewardj/* 8b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn This file is part of Valgrind, a dynamic binary instrumentation 9b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn framework. 10de4a1d01951937632098a6cda45859afa587a06fsewardj 11b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2000-2015 Julian Seward 12de4a1d01951937632098a6cda45859afa587a06fsewardj jseward@acm.org 13de4a1d01951937632098a6cda45859afa587a06fsewardj 14de4a1d01951937632098a6cda45859afa587a06fsewardj This program is free software; you can redistribute it and/or 15de4a1d01951937632098a6cda45859afa587a06fsewardj modify it under the terms of the GNU General Public License as 16de4a1d01951937632098a6cda45859afa587a06fsewardj published by the Free Software Foundation; either version 2 of the 17de4a1d01951937632098a6cda45859afa587a06fsewardj License, or (at your option) any later version. 18de4a1d01951937632098a6cda45859afa587a06fsewardj 19de4a1d01951937632098a6cda45859afa587a06fsewardj This program is distributed in the hope that it will be useful, but 20de4a1d01951937632098a6cda45859afa587a06fsewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21de4a1d01951937632098a6cda45859afa587a06fsewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22de4a1d01951937632098a6cda45859afa587a06fsewardj General Public License for more details. 23de4a1d01951937632098a6cda45859afa587a06fsewardj 24de4a1d01951937632098a6cda45859afa587a06fsewardj You should have received a copy of the GNU General Public License 25de4a1d01951937632098a6cda45859afa587a06fsewardj along with this program; if not, write to the Free Software 26de4a1d01951937632098a6cda45859afa587a06fsewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27de4a1d01951937632098a6cda45859afa587a06fsewardj 02111-1307, USA. 28de4a1d01951937632098a6cda45859afa587a06fsewardj 29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn The GNU General Public License is contained in the file COPYING. 30de4a1d01951937632098a6cda45859afa587a06fsewardj*/ 31de4a1d01951937632098a6cda45859afa587a06fsewardj 32c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h" 334cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 3445f4e7c91119c7d01a59f5e827c67841632c9314sewardj#include "pub_core_debuglog.h" 3597405b2d134b52880d6dbec3eb2929e2002c2542njn#include "pub_core_libcbase.h" 3645f4e7c91119c7d01a59f5e827c67841632c9314sewardj#include "pub_core_aspacemgr.h" 37132bfccd21960e462352175f8553a5bdce8a210cnjn#include "pub_core_libcassert.h" 3836a20fa5f779a0a6fb7b4a90dcaa6376481f1faanjn#include "pub_core_libcprint.h" 39af1d7dfc9412c09d24ea10118f3fd1082f92e49dnjn#include "pub_core_mallocfree.h" 402024234c590f408994b373abfb00bc2cd2a90c48njn#include "pub_core_options.h" 4132397c0c26fd49181e87a409ad986b9e1b5b0dfdnjn#include "pub_core_threadstate.h" // For VG_INVALID_THREADID 424f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe#include "pub_core_gdbserver.h" 43d043de9147df029a98833d0251434f6f2d391bfbsewardj#include "pub_core_transtab.h" 44fc51f8d9538eda285c2ea0974f29b075168f3433njn#include "pub_core_tooliface.h" 4555f9d1a56f3542c68f5b24006c14b1f9aaefff6fsewardj 46c91f58449e6fc2a4ce0851639a342c4277612fbbflorian#include "pub_core_inner.h" 4772faf10172c04674ac1e31cf4f7e57be241da7daphilippe#if defined(ENABLE_INNER_CLIENT_REQUEST) 4872faf10172c04674ac1e31cf4f7e57be241da7daphilippe#include "memcheck/memcheck.h" 4972faf10172c04674ac1e31cf4f7e57be241da7daphilippe#endif 50de4a1d01951937632098a6cda45859afa587a06fsewardj 510b3fd2daacb085f02b58918e4495be00ba8b418csewardj// #define DEBUG_MALLOC // turn on heavyweight debugging machinery 520b3fd2daacb085f02b58918e4495be00ba8b418csewardj// #define VERBOSE_MALLOC // make verbose, esp. in debugging machinery 53de4a1d01951937632098a6cda45859afa587a06fsewardj 54545380e43e6f1669af91e55bf9840a950db6469fbart/* Number and total size of blocks in free queue. Used by mallinfo(). */ 55545380e43e6f1669af91e55bf9840a950db6469fbartLong VG_(free_queue_volume) = 0; 56545380e43e6f1669af91e55bf9840a950db6469fbartLong VG_(free_queue_length) = 0; 57545380e43e6f1669af91e55bf9840a950db6469fbart 589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void cc_analyse_alloc_arena ( ArenaId aid ); /* fwds */ 599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 6098abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge/*------------------------------------------------------------*/ 612d5b816a492793741082445c8065dd9bc6298fadnethercote/*--- Main types ---*/ 6298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge/*------------------------------------------------------------*/ 6398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 64c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj#define N_MALLOC_LISTS 112 // do not change this 6598abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 667ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote// The amount you can ask for is limited only by sizeof(SizeT)... 677ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote#define MAX_PSZB (~((SizeT)0x0)) 68de4a1d01951937632098a6cda45859afa587a06fsewardj 690b3fd2daacb085f02b58918e4495be00ba8b418csewardj// Each arena has a sorted array of superblocks, which expands 700b3fd2daacb085f02b58918e4495be00ba8b418csewardj// dynamically. This is its initial size. 710b3fd2daacb085f02b58918e4495be00ba8b418csewardj#define SBLOCKS_SIZE_INITIAL 50 720b3fd2daacb085f02b58918e4495be00ba8b418csewardj 732d5b816a492793741082445c8065dd9bc6298fadnethercotetypedef UChar UByte; 74de4a1d01951937632098a6cda45859afa587a06fsewardj 758d3f84576d91676a445744a7462a9bba82d41da5njn/* Layout of an in-use block: 768d3f84576d91676a445744a7462a9bba82d41da5njn 77341a664b2de8d7c1e988ae1a5b8a97e1c58f9881njn cost center (OPTIONAL) (VG_MIN_MALLOC_SZB bytes, only when h-p enabled) 788d3f84576d91676a445744a7462a9bba82d41da5njn this block total szB (sizeof(SizeT) bytes) 797ce831126fbe7b162a08353e92342b0fb10ec5bdnjn red zone bytes (depends on Arena.rz_szB, but >= sizeof(void*)) 808d3f84576d91676a445744a7462a9bba82d41da5njn (payload bytes) 817ce831126fbe7b162a08353e92342b0fb10ec5bdnjn red zone bytes (depends on Arena.rz_szB, but >= sizeof(void*)) 828d3f84576d91676a445744a7462a9bba82d41da5njn this block total szB (sizeof(SizeT) bytes) 838d3f84576d91676a445744a7462a9bba82d41da5njn 848d3f84576d91676a445744a7462a9bba82d41da5njn Layout of a block on the free list: 858d3f84576d91676a445744a7462a9bba82d41da5njn 86341a664b2de8d7c1e988ae1a5b8a97e1c58f9881njn cost center (OPTIONAL) (VG_MIN_MALLOC_SZB bytes, only when h-p enabled) 878d3f84576d91676a445744a7462a9bba82d41da5njn this block total szB (sizeof(SizeT) bytes) 888d3f84576d91676a445744a7462a9bba82d41da5njn freelist previous ptr (sizeof(void*) bytes) 898d3f84576d91676a445744a7462a9bba82d41da5njn excess red zone bytes (if Arena.rz_szB > sizeof(void*)) 908d3f84576d91676a445744a7462a9bba82d41da5njn (payload bytes) 918d3f84576d91676a445744a7462a9bba82d41da5njn excess red zone bytes (if Arena.rz_szB > sizeof(void*)) 928d3f84576d91676a445744a7462a9bba82d41da5njn freelist next ptr (sizeof(void*) bytes) 938d3f84576d91676a445744a7462a9bba82d41da5njn this block total szB (sizeof(SizeT) bytes) 948d3f84576d91676a445744a7462a9bba82d41da5njn 958d3f84576d91676a445744a7462a9bba82d41da5njn Total size in bytes (bszB) and payload size in bytes (pszB) 968d3f84576d91676a445744a7462a9bba82d41da5njn are related by: 978d3f84576d91676a445744a7462a9bba82d41da5njn 9894c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj bszB == pszB + 2*sizeof(SizeT) + 2*a->rz_szB 9994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 10094c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj when heap profiling is not enabled, and 10194c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 102341a664b2de8d7c1e988ae1a5b8a97e1c58f9881njn bszB == pszB + 2*sizeof(SizeT) + 2*a->rz_szB + VG_MIN_MALLOC_SZB 1038d3f84576d91676a445744a7462a9bba82d41da5njn 10494c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj when it is enabled. It follows that the minimum overhead per heap 10594c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj block for arenas used by the core is: 10694c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 10794c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 32-bit platforms: 2*4 + 2*4 == 16 bytes 10894c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 64-bit platforms: 2*8 + 2*8 == 32 bytes 10994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 11094c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj when heap profiling is not enabled, and 111a527a4998aa88e72f0108deefb2cf4cb182a86b3njn 112341a664b2de8d7c1e988ae1a5b8a97e1c58f9881njn 32-bit platforms: 2*4 + 2*4 + 8 == 24 bytes 113341a664b2de8d7c1e988ae1a5b8a97e1c58f9881njn 64-bit platforms: 2*8 + 2*8 + 16 == 48 bytes 114a527a4998aa88e72f0108deefb2cf4cb182a86b3njn 11594c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj when it is enabled. In all cases, extra overhead may be incurred 11694c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj when rounding the payload size up to VG_MIN_MALLOC_SZB. 117a527a4998aa88e72f0108deefb2cf4cb182a86b3njn 1188d3f84576d91676a445744a7462a9bba82d41da5njn Furthermore, both size fields in the block have their least-significant 1198d3f84576d91676a445744a7462a9bba82d41da5njn bit set if the block is not in use, and unset if it is in use. 1208d3f84576d91676a445744a7462a9bba82d41da5njn (The bottom 3 or so bits are always free for this because of alignment.) 1218d3f84576d91676a445744a7462a9bba82d41da5njn A block size of zero is not possible, because a block always has at 1228d3f84576d91676a445744a7462a9bba82d41da5njn least two SizeTs and two pointers of overhead. 1238d3f84576d91676a445744a7462a9bba82d41da5njn 1248d3f84576d91676a445744a7462a9bba82d41da5njn Nb: All Block payloads must be VG_MIN_MALLOC_SZB-aligned. This is 1258d3f84576d91676a445744a7462a9bba82d41da5njn achieved by ensuring that Superblocks are VG_MIN_MALLOC_SZB-aligned 1268d3f84576d91676a445744a7462a9bba82d41da5njn (see newSuperblock() for how), and that the lengths of the following 1278d3f84576d91676a445744a7462a9bba82d41da5njn things are a multiple of VG_MIN_MALLOC_SZB: 1288d3f84576d91676a445744a7462a9bba82d41da5njn - Superblock admin section lengths (due to elastic padding) 1298d3f84576d91676a445744a7462a9bba82d41da5njn - Block admin section (low and high) lengths (due to elastic redzones) 1308d3f84576d91676a445744a7462a9bba82d41da5njn - Block payload lengths (due to req_pszB rounding up) 1319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj The heap-profile cost-center field is 8 bytes even on 32 bit 1339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj platforms. This is so as to keep the payload field 8-aligned. On 1349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj a 64-bit platform, this cc-field contains a pointer to a const 1359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj HChar*, which is the cost center name. On 32-bit platforms, the 1369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pointer lives in the lower-addressed half of the field, regardless 1379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of the endianness of the host. 1382d5b816a492793741082445c8065dd9bc6298fadnethercote*/ 1392d5b816a492793741082445c8065dd9bc6298fadnethercotetypedef 1402d5b816a492793741082445c8065dd9bc6298fadnethercote struct { 1412d5b816a492793741082445c8065dd9bc6298fadnethercote // No fields are actually used in this struct, because a Block has 14237517e8a08e55df8df3eda785806ee3ebd442576njn // many variable sized fields and so can't be accessed 1432d5b816a492793741082445c8065dd9bc6298fadnethercote // meaningfully with normal fields. So we use access functions all 1442d5b816a492793741082445c8065dd9bc6298fadnethercote // the time. This struct gives us a type to use, though. Also, we 1452d5b816a492793741082445c8065dd9bc6298fadnethercote // make sizeof(Block) 1 byte so that we can do arithmetic with the 1462d5b816a492793741082445c8065dd9bc6298fadnethercote // Block* type in increments of 1! 1472d5b816a492793741082445c8065dd9bc6298fadnethercote UByte dummy; 1482d5b816a492793741082445c8065dd9bc6298fadnethercote } 1492d5b816a492793741082445c8065dd9bc6298fadnethercote Block; 1502d5b816a492793741082445c8065dd9bc6298fadnethercote 1512d5b816a492793741082445c8065dd9bc6298fadnethercote// A superblock. 'padding' is never used, it just ensures that if the 1522d5b816a492793741082445c8065dd9bc6298fadnethercote// entire Superblock is aligned to VG_MIN_MALLOC_SZB, then payload_bytes[] 1532d5b816a492793741082445c8065dd9bc6298fadnethercote// will be too. It can add small amounts of padding unnecessarily -- eg. 1542d5b816a492793741082445c8065dd9bc6298fadnethercote// 8-bytes on 32-bit machines with an 8-byte VG_MIN_MALLOC_SZB -- because 1552d5b816a492793741082445c8065dd9bc6298fadnethercote// it's too hard to make a constant expression that works perfectly in all 1562d5b816a492793741082445c8065dd9bc6298fadnethercote// cases. 157d043de9147df029a98833d0251434f6f2d391bfbsewardj// 'unsplittable' is set to NULL if superblock can be splitted, otherwise 158d043de9147df029a98833d0251434f6f2d391bfbsewardj// it is set to the address of the superblock. An unsplittable superblock 159d043de9147df029a98833d0251434f6f2d391bfbsewardj// will contain only one allocated block. An unsplittable superblock will 160d043de9147df029a98833d0251434f6f2d391bfbsewardj// be unmapped when its (only) allocated block is freed. 161d043de9147df029a98833d0251434f6f2d391bfbsewardj// The free space at the end of an unsplittable superblock is not used to 162d043de9147df029a98833d0251434f6f2d391bfbsewardj// make a free block. Note that this means that an unsplittable superblock can 163d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj// have up to slightly less than 1 page of unused bytes at the end of the 164d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj// superblock. 165d043de9147df029a98833d0251434f6f2d391bfbsewardj// 'unsplittable' is used to avoid quadratic memory usage for linear 166d043de9147df029a98833d0251434f6f2d391bfbsewardj// reallocation of big structures 167d043de9147df029a98833d0251434f6f2d391bfbsewardj// (see http://bugs.kde.org/show_bug.cgi?id=250101). 168d043de9147df029a98833d0251434f6f2d391bfbsewardj// ??? unsplittable replaces 'void *padding2'. Choosed this 169d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj// ??? to avoid changing the alignment logic. Maybe something cleaner 170d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj// ??? can be done. 171d043de9147df029a98833d0251434f6f2d391bfbsewardj// A splittable block can be reclaimed when all its blocks are freed : 172d043de9147df029a98833d0251434f6f2d391bfbsewardj// the reclaim of such a block is deferred till either another superblock 173d043de9147df029a98833d0251434f6f2d391bfbsewardj// of the same arena can be reclaimed or till a new superblock is needed 174d043de9147df029a98833d0251434f6f2d391bfbsewardj// in any arena. 1752d5b816a492793741082445c8065dd9bc6298fadnethercote// payload_bytes[] is made a single big Block when the Superblock is 1762d5b816a492793741082445c8065dd9bc6298fadnethercote// created, and then can be split and the splittings remerged, but Blocks 1772d5b816a492793741082445c8065dd9bc6298fadnethercote// always cover its entire length -- there's never any unused bytes at the 1782d5b816a492793741082445c8065dd9bc6298fadnethercote// end, for example. 1790b3fd2daacb085f02b58918e4495be00ba8b418csewardjtypedef 180de4a1d01951937632098a6cda45859afa587a06fsewardj struct _Superblock { 1817ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT n_payload_bytes; 182d043de9147df029a98833d0251434f6f2d391bfbsewardj struct _Superblock* unsplittable; 1830b3fd2daacb085f02b58918e4495be00ba8b418csewardj UByte padding[ VG_MIN_MALLOC_SZB - 1840b3fd2daacb085f02b58918e4495be00ba8b418csewardj ((sizeof(struct _Superblock*) + sizeof(SizeT)) % 1857ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote VG_MIN_MALLOC_SZB) ]; 1862d5b816a492793741082445c8065dd9bc6298fadnethercote UByte payload_bytes[0]; 187de4a1d01951937632098a6cda45859afa587a06fsewardj } 188de4a1d01951937632098a6cda45859afa587a06fsewardj Superblock; 189de4a1d01951937632098a6cda45859afa587a06fsewardj 1902d5b816a492793741082445c8065dd9bc6298fadnethercote// An arena. 'freelist' is a circular, doubly-linked list. 'rz_szB' is 1912d5b816a492793741082445c8065dd9bc6298fadnethercote// elastic, in that it can be bigger than asked-for to ensure alignment. 1920b3fd2daacb085f02b58918e4495be00ba8b418csewardjtypedef 193de4a1d01951937632098a6cda45859afa587a06fsewardj struct { 19454fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian const HChar* name; 1950b3fd2daacb085f02b58918e4495be00ba8b418csewardj Bool clientmem; // Allocates in the client address space? 1960b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT rz_szB; // Red zone size in bytes 1970b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT min_sblock_szB; // Minimum superblock size in bytes 198d043de9147df029a98833d0251434f6f2d391bfbsewardj SizeT min_unsplittable_sblock_szB; 199d043de9147df029a98833d0251434f6f2d391bfbsewardj // Minimum unsplittable superblock size in bytes. To be marked as 200d043de9147df029a98833d0251434f6f2d391bfbsewardj // unsplittable, a superblock must have a 201d043de9147df029a98833d0251434f6f2d391bfbsewardj // size >= min_unsplittable_sblock_szB and cannot be splitted. 202d043de9147df029a98833d0251434f6f2d391bfbsewardj // So, to avoid big overhead, superblocks used to provide aligned 203d043de9147df029a98833d0251434f6f2d391bfbsewardj // blocks on big alignments are splittable. 204d043de9147df029a98833d0251434f6f2d391bfbsewardj // Unsplittable superblocks will be reclaimed when their (only) 205d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // allocated block is freed. 206d043de9147df029a98833d0251434f6f2d391bfbsewardj // Smaller size superblocks are splittable and can be reclaimed when all 207d043de9147df029a98833d0251434f6f2d391bfbsewardj // their blocks are freed. 2080b3fd2daacb085f02b58918e4495be00ba8b418csewardj Block* freelist[N_MALLOC_LISTS]; 2090b3fd2daacb085f02b58918e4495be00ba8b418csewardj // A dynamically expanding, ordered array of (pointers to) 2100b3fd2daacb085f02b58918e4495be00ba8b418csewardj // superblocks in the arena. If this array is expanded, which 2110b3fd2daacb085f02b58918e4495be00ba8b418csewardj // is rare, the previous space it occupies is simply abandoned. 2120b3fd2daacb085f02b58918e4495be00ba8b418csewardj // To avoid having to get yet another block from m_aspacemgr for 2130b3fd2daacb085f02b58918e4495be00ba8b418csewardj // the first incarnation of this array, the first allocation of 2140b3fd2daacb085f02b58918e4495be00ba8b418csewardj // it is within this struct. If it has to be expanded then the 2150b3fd2daacb085f02b58918e4495be00ba8b418csewardj // new space is acquired from m_aspacemgr as you would expect. 2160b3fd2daacb085f02b58918e4495be00ba8b418csewardj Superblock** sblocks; 2170b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT sblocks_size; 2180b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT sblocks_used; 2190b3fd2daacb085f02b58918e4495be00ba8b418csewardj Superblock* sblocks_initial[SBLOCKS_SIZE_INITIAL]; 220d043de9147df029a98833d0251434f6f2d391bfbsewardj Superblock* deferred_reclaimed_sb; 2216e4b71339ecdf4accc77e86a892718516a531b0fphilippe 2226e4b71339ecdf4accc77e86a892718516a531b0fphilippe // VG_(arena_perm_malloc) returns memory from superblocks 2236e4b71339ecdf4accc77e86a892718516a531b0fphilippe // only used for permanent blocks. No overhead. These superblocks 2246e4b71339ecdf4accc77e86a892718516a531b0fphilippe // are not stored in sblocks array above. 2256e4b71339ecdf4accc77e86a892718516a531b0fphilippe Addr perm_malloc_current; // first byte free in perm_malloc sb. 2266e4b71339ecdf4accc77e86a892718516a531b0fphilippe Addr perm_malloc_limit; // maximum usable byte in perm_malloc sb. 2276e4b71339ecdf4accc77e86a892718516a531b0fphilippe 2286e4b71339ecdf4accc77e86a892718516a531b0fphilippe // Stats only 2296e4b71339ecdf4accc77e86a892718516a531b0fphilippe SizeT stats__perm_bytes_on_loan; 2306e4b71339ecdf4accc77e86a892718516a531b0fphilippe SizeT stats__perm_blocks; 2316e4b71339ecdf4accc77e86a892718516a531b0fphilippe 232d043de9147df029a98833d0251434f6f2d391bfbsewardj ULong stats__nreclaim_unsplit; 233d043de9147df029a98833d0251434f6f2d391bfbsewardj ULong stats__nreclaim_split; 234d043de9147df029a98833d0251434f6f2d391bfbsewardj /* total # of reclaim executed for unsplittable/splittable superblocks */ 2357d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj SizeT stats__bytes_on_loan; 2367d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj SizeT stats__bytes_mmaped; 2377d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj SizeT stats__bytes_on_loan_max; 2387d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj ULong stats__tot_blocks; /* total # blocks alloc'd */ 2397d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj ULong stats__tot_bytes; /* total # bytes alloc'd */ 2407d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj ULong stats__nsearches; /* total # freelist checks */ 2417d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj // If profiling, when should the next profile happen at 2427d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj // (in terms of stats__bytes_on_loan_max) ? 2439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj SizeT next_profile_at; 244d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj SizeT stats__bytes_mmaped_max; 2450b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 246de4a1d01951937632098a6cda45859afa587a06fsewardj Arena; 247de4a1d01951937632098a6cda45859afa587a06fsewardj 248de4a1d01951937632098a6cda45859afa587a06fsewardj 2492d5b816a492793741082445c8065dd9bc6298fadnethercote/*------------------------------------------------------------*/ 2502d5b816a492793741082445c8065dd9bc6298fadnethercote/*--- Low-level functions for working with Blocks. ---*/ 2512d5b816a492793741082445c8065dd9bc6298fadnethercote/*------------------------------------------------------------*/ 252de4a1d01951937632098a6cda45859afa587a06fsewardj 2537ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote#define SIZE_T_0x1 ((SizeT)0x1) 2547ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote 2556bd9dc18c043927c1196caba20a327238a179c42florianstatic const char* probably_your_fault = 256b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn "This is probably caused by your program erroneously writing past the\n" 257b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn "end of a heap block and corrupting heap metadata. If you fix any\n" 258b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn "invalid writes reported by Memcheck, this assertion failure will\n" 259b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn "probably go away. Please try that before reporting this as a bug.\n"; 260b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn 2618d3f84576d91676a445744a7462a9bba82d41da5njn// Mark a bszB as in-use, and not in-use, and remove the in-use attribute. 2622d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 2637ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSizeT mk_inuse_bszB ( SizeT bszB ) 2642d5b816a492793741082445c8065dd9bc6298fadnethercote{ 265b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn vg_assert2(bszB != 0, probably_your_fault); 2667ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote return bszB & (~SIZE_T_0x1); 2672d5b816a492793741082445c8065dd9bc6298fadnethercote} 2682d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 2697ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSizeT mk_free_bszB ( SizeT bszB ) 2702d5b816a492793741082445c8065dd9bc6298fadnethercote{ 271b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn vg_assert2(bszB != 0, probably_your_fault); 2727ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote return bszB | SIZE_T_0x1; 2732d5b816a492793741082445c8065dd9bc6298fadnethercote} 2742d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 2757ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSizeT mk_plain_bszB ( SizeT bszB ) 2762d5b816a492793741082445c8065dd9bc6298fadnethercote{ 277b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn vg_assert2(bszB != 0, probably_your_fault); 2787ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote return bszB & (~SIZE_T_0x1); 2792d5b816a492793741082445c8065dd9bc6298fadnethercote} 280de4a1d01951937632098a6cda45859afa587a06fsewardj 281d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// Forward definition. 282d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippestatic 283d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippevoid ensure_mm_init ( ArenaId aid ); 284d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 28594c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj// return either 0 or sizeof(ULong) depending on whether or not 28694c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj// heap profiling is engaged 287d043de9147df029a98833d0251434f6f2d391bfbsewardj#define hp_overhead_szB() set_at_init_hp_overhead_szB 288d043de9147df029a98833d0251434f6f2d391bfbsewardjstatic SizeT set_at_init_hp_overhead_szB = -1000000; 289d043de9147df029a98833d0251434f6f2d391bfbsewardj// startup value chosen to very likely cause a problem if used before 290d043de9147df029a98833d0251434f6f2d391bfbsewardj// a proper value is given by ensure_mm_init. 29194c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj 292402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 293402c86183de4dc752884314d4b012cffb04a797bnjn 294402c86183de4dc752884314d4b012cffb04a797bnjn// Get a block's size as stored, ie with the in-use/free attribute. 2952d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 296402c86183de4dc752884314d4b012cffb04a797bnjnSizeT get_bszB_as_is ( Block* b ) 2972d5b816a492793741082445c8065dd9bc6298fadnethercote{ 298402c86183de4dc752884314d4b012cffb04a797bnjn UByte* b2 = (UByte*)b; 29994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj SizeT bszB_lo = *(SizeT*)&b2[0 + hp_overhead_szB()]; 300402c86183de4dc752884314d4b012cffb04a797bnjn SizeT bszB_hi = *(SizeT*)&b2[mk_plain_bszB(bszB_lo) - sizeof(SizeT)]; 301402c86183de4dc752884314d4b012cffb04a797bnjn vg_assert2(bszB_lo == bszB_hi, 302b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn "Heap block lo/hi size mismatch: lo = %llu, hi = %llu.\n%s", 303b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn (ULong)bszB_lo, (ULong)bszB_hi, probably_your_fault); 304402c86183de4dc752884314d4b012cffb04a797bnjn return bszB_lo; 3052d5b816a492793741082445c8065dd9bc6298fadnethercote} 3062d5b816a492793741082445c8065dd9bc6298fadnethercote 307402c86183de4dc752884314d4b012cffb04a797bnjn// Get a block's plain size, ie. remove the in-use/free attribute. 308472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjnstatic __inline__ 309402c86183de4dc752884314d4b012cffb04a797bnjnSizeT get_bszB ( Block* b ) 310472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn{ 311402c86183de4dc752884314d4b012cffb04a797bnjn return mk_plain_bszB(get_bszB_as_is(b)); 312472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn} 313472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn 314402c86183de4dc752884314d4b012cffb04a797bnjn// Set the size fields of a block. bszB may have the in-use/free attribute. 3152d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 316402c86183de4dc752884314d4b012cffb04a797bnjnvoid set_bszB ( Block* b, SizeT bszB ) 3172d5b816a492793741082445c8065dd9bc6298fadnethercote{ 3182d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 31994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj *(SizeT*)&b2[0 + hp_overhead_szB()] = bszB; 320402c86183de4dc752884314d4b012cffb04a797bnjn *(SizeT*)&b2[mk_plain_bszB(bszB) - sizeof(SizeT)] = bszB; 3212d5b816a492793741082445c8065dd9bc6298fadnethercote} 322de4a1d01951937632098a6cda45859afa587a06fsewardj 323402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 3248d3f84576d91676a445744a7462a9bba82d41da5njn 325402c86183de4dc752884314d4b012cffb04a797bnjn// Does this block have the in-use attribute? 3268d3f84576d91676a445744a7462a9bba82d41da5njnstatic __inline__ 327402c86183de4dc752884314d4b012cffb04a797bnjnBool is_inuse_block ( Block* b ) 3288d3f84576d91676a445744a7462a9bba82d41da5njn{ 329402c86183de4dc752884314d4b012cffb04a797bnjn SizeT bszB = get_bszB_as_is(b); 330b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn vg_assert2(bszB != 0, probably_your_fault); 331402c86183de4dc752884314d4b012cffb04a797bnjn return (0 != (bszB & SIZE_T_0x1)) ? False : True; 3328d3f84576d91676a445744a7462a9bba82d41da5njn} 3338d3f84576d91676a445744a7462a9bba82d41da5njn 334402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 335402c86183de4dc752884314d4b012cffb04a797bnjn 336089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn// Return the lower, upper and total overhead in bytes for a block. 337089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn// These are determined purely by which arena the block lives in. 338089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnstatic __inline__ 339089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT overhead_szB_lo ( Arena* a ) 340089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn{ 34194c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj return hp_overhead_szB() + sizeof(SizeT) + a->rz_szB; 342089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn} 343089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnstatic __inline__ 344089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT overhead_szB_hi ( Arena* a ) 345089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn{ 3468d3f84576d91676a445744a7462a9bba82d41da5njn return a->rz_szB + sizeof(SizeT); 347089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn} 348089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnstatic __inline__ 349089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT overhead_szB ( Arena* a ) 350089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn{ 351089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn return overhead_szB_lo(a) + overhead_szB_hi(a); 352089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn} 353089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn 354402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 355402c86183de4dc752884314d4b012cffb04a797bnjn 356089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn// Return the minimum bszB for a block in this arena. Can have zero-length 357089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn// payloads, so it's the size of the admin bytes. 358089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnstatic __inline__ 359089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT min_useful_bszB ( Arena* a ) 360089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn{ 361089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn return overhead_szB(a); 362089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn} 363089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn 364402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 365402c86183de4dc752884314d4b012cffb04a797bnjn 366089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn// Convert payload size <--> block size (both in bytes). 367089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnstatic __inline__ 368089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT pszB_to_bszB ( Arena* a, SizeT pszB ) 369089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn{ 370089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn return pszB + overhead_szB(a); 371089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn} 372089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnstatic __inline__ 373089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT bszB_to_pszB ( Arena* a, SizeT bszB ) 374089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn{ 375b8329f0ce649067dc5d9d74f8392c6a0ab8d2d40njn vg_assert2(bszB >= overhead_szB(a), probably_your_fault); 376089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn return bszB - overhead_szB(a); 377089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn} 378089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn 379402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 380de4a1d01951937632098a6cda45859afa587a06fsewardj 381089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn// Get a block's payload size. 3827ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercotestatic __inline__ 383089f51f394a17ed460c10a9f4ba748a0c4efea8dnjnSizeT get_pszB ( Arena* a, Block* b ) 3847ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote{ 385089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn return bszB_to_pszB(a, get_bszB(b)); 3867ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote} 3877ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote 388402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 389402c86183de4dc752884314d4b012cffb04a797bnjn 390402c86183de4dc752884314d4b012cffb04a797bnjn// Given the addr of a block, return the addr of its payload, and vice versa. 3912d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 3922d5b816a492793741082445c8065dd9bc6298fadnethercoteUByte* get_block_payload ( Arena* a, Block* b ) 393de4a1d01951937632098a6cda45859afa587a06fsewardj{ 3942d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 3957ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote return & b2[ overhead_szB_lo(a) ]; 3962d5b816a492793741082445c8065dd9bc6298fadnethercote} 3972d5b816a492793741082445c8065dd9bc6298fadnethercote// Given the addr of a block's payload, return the addr of the block itself. 3982d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 3992d5b816a492793741082445c8065dd9bc6298fadnethercoteBlock* get_payload_block ( Arena* a, UByte* payload ) 4002d5b816a492793741082445c8065dd9bc6298fadnethercote{ 4017ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote return (Block*)&payload[ -overhead_szB_lo(a) ]; 4022d5b816a492793741082445c8065dd9bc6298fadnethercote} 4032d5b816a492793741082445c8065dd9bc6298fadnethercote 404402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 4052d5b816a492793741082445c8065dd9bc6298fadnethercote 4062d5b816a492793741082445c8065dd9bc6298fadnethercote// Set and get the next and previous link fields of a block. 4072d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4082d5b816a492793741082445c8065dd9bc6298fadnethercotevoid set_prev_b ( Block* b, Block* prev_p ) 4092d5b816a492793741082445c8065dd9bc6298fadnethercote{ 4102d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 41194c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj *(Block**)&b2[hp_overhead_szB() + sizeof(SizeT)] = prev_p; 4122d5b816a492793741082445c8065dd9bc6298fadnethercote} 4132d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4142d5b816a492793741082445c8065dd9bc6298fadnethercotevoid set_next_b ( Block* b, Block* next_p ) 4152d5b816a492793741082445c8065dd9bc6298fadnethercote{ 416402c86183de4dc752884314d4b012cffb04a797bnjn UByte* b2 = (UByte*)b; 417402c86183de4dc752884314d4b012cffb04a797bnjn *(Block**)&b2[get_bszB(b) - sizeof(SizeT) - sizeof(void*)] = next_p; 4182d5b816a492793741082445c8065dd9bc6298fadnethercote} 4192d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4202d5b816a492793741082445c8065dd9bc6298fadnethercoteBlock* get_prev_b ( Block* b ) 4212d5b816a492793741082445c8065dd9bc6298fadnethercote{ 4222d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 42394c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj return *(Block**)&b2[hp_overhead_szB() + sizeof(SizeT)]; 4242d5b816a492793741082445c8065dd9bc6298fadnethercote} 4252d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4262d5b816a492793741082445c8065dd9bc6298fadnethercoteBlock* get_next_b ( Block* b ) 4272d5b816a492793741082445c8065dd9bc6298fadnethercote{ 428402c86183de4dc752884314d4b012cffb04a797bnjn UByte* b2 = (UByte*)b; 429402c86183de4dc752884314d4b012cffb04a797bnjn return *(Block**)&b2[get_bszB(b) - sizeof(SizeT) - sizeof(void*)]; 4302d5b816a492793741082445c8065dd9bc6298fadnethercote} 4312d5b816a492793741082445c8065dd9bc6298fadnethercote 432402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 4332d5b816a492793741082445c8065dd9bc6298fadnethercote 4349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Set and get the cost-center field of a block. 4359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic __inline__ 43654fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid set_cc ( Block* b, const HChar* cc ) 4379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 4389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UByte* b2 = (UByte*)b; 43994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj vg_assert( VG_(clo_profile_heap) ); 44054fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian *(const HChar**)&b2[0] = cc; 4419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 4429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic __inline__ 44354fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianconst HChar* get_cc ( Block* b ) 4449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 4459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UByte* b2 = (UByte*)b; 44694c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj vg_assert( VG_(clo_profile_heap) ); 44754fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian return *(const HChar**)&b2[0]; 4489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 4499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 4509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj//--------------------------------------------------------------------------- 4519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 4522d5b816a492793741082445c8065dd9bc6298fadnethercote// Get the block immediately preceding this one in the Superblock. 4532d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4542d5b816a492793741082445c8065dd9bc6298fadnethercoteBlock* get_predecessor_block ( Block* b ) 4552d5b816a492793741082445c8065dd9bc6298fadnethercote{ 4562d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 4577ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT bszB = mk_plain_bszB( (*(SizeT*)&b2[-sizeof(SizeT)]) ); 4582d5b816a492793741082445c8065dd9bc6298fadnethercote return (Block*)&b2[-bszB]; 4592d5b816a492793741082445c8065dd9bc6298fadnethercote} 4602d5b816a492793741082445c8065dd9bc6298fadnethercote 461402c86183de4dc752884314d4b012cffb04a797bnjn//--------------------------------------------------------------------------- 462402c86183de4dc752884314d4b012cffb04a797bnjn 4632d5b816a492793741082445c8065dd9bc6298fadnethercote// Read and write the lower and upper red-zone bytes of a block. 4642d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4651dcee097db02f9ef3ba355162c4373d90d0e895cnjnvoid set_rz_lo_byte ( Block* b, UInt rz_byteno, UByte v ) 4662d5b816a492793741082445c8065dd9bc6298fadnethercote{ 4672d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 46894c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj b2[hp_overhead_szB() + sizeof(SizeT) + rz_byteno] = v; 4692d5b816a492793741082445c8065dd9bc6298fadnethercote} 4702d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4711dcee097db02f9ef3ba355162c4373d90d0e895cnjnvoid set_rz_hi_byte ( Block* b, UInt rz_byteno, UByte v ) 4722d5b816a492793741082445c8065dd9bc6298fadnethercote{ 473402c86183de4dc752884314d4b012cffb04a797bnjn UByte* b2 = (UByte*)b; 474402c86183de4dc752884314d4b012cffb04a797bnjn b2[get_bszB(b) - sizeof(SizeT) - rz_byteno - 1] = v; 4752d5b816a492793741082445c8065dd9bc6298fadnethercote} 4762d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4771dcee097db02f9ef3ba355162c4373d90d0e895cnjnUByte get_rz_lo_byte ( Block* b, UInt rz_byteno ) 4782d5b816a492793741082445c8065dd9bc6298fadnethercote{ 4792d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* b2 = (UByte*)b; 48094c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj return b2[hp_overhead_szB() + sizeof(SizeT) + rz_byteno]; 4812d5b816a492793741082445c8065dd9bc6298fadnethercote} 4822d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 4831dcee097db02f9ef3ba355162c4373d90d0e895cnjnUByte get_rz_hi_byte ( Block* b, UInt rz_byteno ) 4842d5b816a492793741082445c8065dd9bc6298fadnethercote{ 485402c86183de4dc752884314d4b012cffb04a797bnjn UByte* b2 = (UByte*)b; 486402c86183de4dc752884314d4b012cffb04a797bnjn return b2[get_bszB(b) - sizeof(SizeT) - rz_byteno - 1]; 4872d5b816a492793741082445c8065dd9bc6298fadnethercote} 4882d5b816a492793741082445c8065dd9bc6298fadnethercote 4890b9d0646949bd382758763664d3bf2d6115993aephilippe#if defined(ENABLE_INNER_CLIENT_REQUEST) 4900b9d0646949bd382758763664d3bf2d6115993aephilippe/* When running as an inner, the block headers before and after 4910b9d0646949bd382758763664d3bf2d6115993aephilippe (see 'Layout of an in-use block:' above) are made non accessible 4920b9d0646949bd382758763664d3bf2d6115993aephilippe by VALGRIND_MALLOCLIKE_BLOCK/VALGRIND_FREELIKE_BLOCK 4930b9d0646949bd382758763664d3bf2d6115993aephilippe to allow the outer to detect block overrun. 4940b9d0646949bd382758763664d3bf2d6115993aephilippe The below two functions are used when these headers must be 4950b9d0646949bd382758763664d3bf2d6115993aephilippe temporarily accessed. */ 4960b9d0646949bd382758763664d3bf2d6115993aephilippestatic void mkBhdrAccess( Arena* a, Block* b ) 4970b9d0646949bd382758763664d3bf2d6115993aephilippe{ 4980b9d0646949bd382758763664d3bf2d6115993aephilippe VALGRIND_MAKE_MEM_DEFINED (b, 4990b9d0646949bd382758763664d3bf2d6115993aephilippe hp_overhead_szB() + sizeof(SizeT) + a->rz_szB); 5000b9d0646949bd382758763664d3bf2d6115993aephilippe VALGRIND_MAKE_MEM_DEFINED (b + get_bszB(b) - a->rz_szB - sizeof(SizeT), 5010b9d0646949bd382758763664d3bf2d6115993aephilippe a->rz_szB + sizeof(SizeT)); 5020b9d0646949bd382758763664d3bf2d6115993aephilippe} 5030b9d0646949bd382758763664d3bf2d6115993aephilippe 5040b9d0646949bd382758763664d3bf2d6115993aephilippe/* Mark block hdr as not accessible. 5050b9d0646949bd382758763664d3bf2d6115993aephilippe !!! Currently, we do not mark the cost center and szB fields unaccessible 5060b9d0646949bd382758763664d3bf2d6115993aephilippe as these are accessed at too many places. */ 5070b9d0646949bd382758763664d3bf2d6115993aephilippestatic void mkBhdrNoAccess( Arena* a, Block* b ) 5080b9d0646949bd382758763664d3bf2d6115993aephilippe{ 5090b9d0646949bd382758763664d3bf2d6115993aephilippe VALGRIND_MAKE_MEM_NOACCESS (b + hp_overhead_szB() + sizeof(SizeT), 5100b9d0646949bd382758763664d3bf2d6115993aephilippe a->rz_szB); 5110b9d0646949bd382758763664d3bf2d6115993aephilippe VALGRIND_MAKE_MEM_NOACCESS (b + get_bszB(b) - sizeof(SizeT) - a->rz_szB, 5120b9d0646949bd382758763664d3bf2d6115993aephilippe a->rz_szB); 5130b9d0646949bd382758763664d3bf2d6115993aephilippe} 5140b9d0646949bd382758763664d3bf2d6115993aephilippe 5150b9d0646949bd382758763664d3bf2d6115993aephilippe/* Make the cc+szB fields accessible. */ 5160b9d0646949bd382758763664d3bf2d6115993aephilippestatic void mkBhdrSzAccess( Arena* a, Block* b ) 5170b9d0646949bd382758763664d3bf2d6115993aephilippe{ 5180b9d0646949bd382758763664d3bf2d6115993aephilippe VALGRIND_MAKE_MEM_DEFINED (b, 5190b9d0646949bd382758763664d3bf2d6115993aephilippe hp_overhead_szB() + sizeof(SizeT)); 5200b9d0646949bd382758763664d3bf2d6115993aephilippe /* We cannot use get_bszB(b), as this reads the 'hi' szB we want 5210b9d0646949bd382758763664d3bf2d6115993aephilippe to mark accessible. So, we only access the 'lo' szB. */ 5220b9d0646949bd382758763664d3bf2d6115993aephilippe SizeT bszB_lo = mk_plain_bszB(*(SizeT*)&b[0 + hp_overhead_szB()]); 5230b9d0646949bd382758763664d3bf2d6115993aephilippe VALGRIND_MAKE_MEM_DEFINED (b + bszB_lo - sizeof(SizeT), 5240b9d0646949bd382758763664d3bf2d6115993aephilippe sizeof(SizeT)); 5250b9d0646949bd382758763664d3bf2d6115993aephilippe} 5260b9d0646949bd382758763664d3bf2d6115993aephilippe#endif 5272d5b816a492793741082445c8065dd9bc6298fadnethercote 528de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 5292d5b816a492793741082445c8065dd9bc6298fadnethercote/*--- Arena management ---*/ 530de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 531de4a1d01951937632098a6cda45859afa587a06fsewardj 5322d5b816a492793741082445c8065dd9bc6298fadnethercote#define CORE_ARENA_MIN_SZB 1048576 533c314eba94e45cf266382d5ecb173b1bbd960c2e9nethercote 5342d5b816a492793741082445c8065dd9bc6298fadnethercote// The arena structures themselves. 535de4a1d01951937632098a6cda45859afa587a06fsewardjstatic Arena vg_arena[VG_N_ARENAS]; 536de4a1d01951937632098a6cda45859afa587a06fsewardj 5372d5b816a492793741082445c8065dd9bc6298fadnethercote// Functions external to this module identify arenas using ArenaIds, 5382d5b816a492793741082445c8065dd9bc6298fadnethercote// not Arena*s. This fn converts the former to the latter. 539de4a1d01951937632098a6cda45859afa587a06fsewardjstatic Arena* arenaId_to_ArenaP ( ArenaId arena ) 540de4a1d01951937632098a6cda45859afa587a06fsewardj{ 541de4a1d01951937632098a6cda45859afa587a06fsewardj vg_assert(arena >= 0 && arena < VG_N_ARENAS); 542de4a1d01951937632098a6cda45859afa587a06fsewardj return & vg_arena[arena]; 543de4a1d01951937632098a6cda45859afa587a06fsewardj} 544de4a1d01951937632098a6cda45859afa587a06fsewardj 5456e4b71339ecdf4accc77e86a892718516a531b0fphilippestatic ArenaId arenaP_to_ArenaId ( Arena *a ) 5466e4b71339ecdf4accc77e86a892718516a531b0fphilippe{ 5476e4b71339ecdf4accc77e86a892718516a531b0fphilippe ArenaId arena = a -vg_arena; 5486e4b71339ecdf4accc77e86a892718516a531b0fphilippe vg_assert(arena >= 0 && arena < VG_N_ARENAS); 5496e4b71339ecdf4accc77e86a892718516a531b0fphilippe return arena; 5506e4b71339ecdf4accc77e86a892718516a531b0fphilippe} 5516e4b71339ecdf4accc77e86a892718516a531b0fphilippe 552d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// Initialise an arena. rz_szB is the (default) minimum redzone size; 553d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// It might be overriden by VG_(clo_redzone_size) or VG_(clo_core_redzone_size). 554d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// it might be made bigger to ensure that VG_MIN_MALLOC_SZB is observed. 555de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 55654fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid arena_init ( ArenaId aid, const HChar* name, SizeT rz_szB, 557d043de9147df029a98833d0251434f6f2d391bfbsewardj SizeT min_sblock_szB, SizeT min_unsplittable_sblock_szB ) 558de4a1d01951937632098a6cda45859afa587a06fsewardj{ 5590b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT i; 5602d5b816a492793741082445c8065dd9bc6298fadnethercote Arena* a = arenaId_to_ArenaP(aid); 561d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 562d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe // Ensure default redzones are a reasonable size. 563d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe vg_assert(rz_szB <= MAX_REDZONE_SZB); 5642d5b816a492793741082445c8065dd9bc6298fadnethercote 565d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe /* Override the default redzone size if a clo value was given. 566d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe Note that the clo value can be significantly bigger than MAX_REDZONE_SZB 567d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe to allow the user to chase horrible bugs using up to 1 page 568d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe of protection. */ 569d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe if (VG_AR_CLIENT == aid) { 570d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe if (VG_(clo_redzone_size) != -1) 571d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe rz_szB = VG_(clo_redzone_size); 572d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe } else { 573d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe if (VG_(clo_core_redzone_size) != rz_szB) 574d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe rz_szB = VG_(clo_core_redzone_size); 575d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe } 576d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 577d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe // Redzones must always be at least the size of a pointer, for holding the 578d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe // prev/next pointer (see the layout details at the top of this file). 5797ce831126fbe7b162a08353e92342b0fb10ec5bdnjn if (rz_szB < sizeof(void*)) rz_szB = sizeof(void*); 5802d5b816a492793741082445c8065dd9bc6298fadnethercote 5812d5b816a492793741082445c8065dd9bc6298fadnethercote // The size of the low and high admin sections in a block must be a 58230490557c2796d70fd7152983f87e64134eaf44cnjn // multiple of VG_MIN_MALLOC_SZB. So we round up the asked-for 5832d5b816a492793741082445c8065dd9bc6298fadnethercote // redzone size if necessary to achieve this. 5842d5b816a492793741082445c8065dd9bc6298fadnethercote a->rz_szB = rz_szB; 5852d5b816a492793741082445c8065dd9bc6298fadnethercote while (0 != overhead_szB_lo(a) % VG_MIN_MALLOC_SZB) a->rz_szB++; 586341a664b2de8d7c1e988ae1a5b8a97e1c58f9881njn vg_assert(overhead_szB_lo(a) - hp_overhead_szB() == overhead_szB_hi(a)); 5872d5b816a492793741082445c8065dd9bc6298fadnethercote 588d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe // Here we have established the effective redzone size. 589d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 590d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 591d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe vg_assert((min_sblock_szB % VKI_PAGE_SIZE) == 0); 592d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe a->name = name; 593d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe a->clientmem = ( VG_AR_CLIENT == aid ? True : False ); 594d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 5952d5b816a492793741082445c8065dd9bc6298fadnethercote a->min_sblock_szB = min_sblock_szB; 596d043de9147df029a98833d0251434f6f2d391bfbsewardj a->min_unsplittable_sblock_szB = min_unsplittable_sblock_szB; 5976e6588ce963e7c3608c1bfe20b60925d74c1d0canjn for (i = 0; i < N_MALLOC_LISTS; i++) a->freelist[i] = NULL; 5980b3fd2daacb085f02b58918e4495be00ba8b418csewardj 5997d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->sblocks = & a->sblocks_initial[0]; 6007d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->sblocks_size = SBLOCKS_SIZE_INITIAL; 6017d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->sblocks_used = 0; 6026e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->deferred_reclaimed_sb = 0; 6036e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->perm_malloc_current = 0; 6046e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->perm_malloc_limit = 0; 6056e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__perm_bytes_on_loan= 0; 6066e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__perm_blocks = 0; 607d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__nreclaim_unsplit = 0; 608d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__nreclaim_split = 0; 6097d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan = 0; 6107d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_mmaped = 0; 6117d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan_max = 0; 612d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->stats__bytes_mmaped_max = 0; 6137d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__tot_blocks = 0; 6147d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__tot_bytes = 0; 6157d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__nsearches = 0; 6167d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->next_profile_at = 25 * 1000 * 1000; 6170b3fd2daacb085f02b58918e4495be00ba8b418csewardj vg_assert(sizeof(a->sblocks_initial) 6180b3fd2daacb085f02b58918e4495be00ba8b418csewardj == SBLOCKS_SIZE_INITIAL * sizeof(Superblock*)); 619de4a1d01951937632098a6cda45859afa587a06fsewardj} 620de4a1d01951937632098a6cda45859afa587a06fsewardj 621de4a1d01951937632098a6cda45859afa587a06fsewardj/* Print vital stats for an arena. */ 622885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercotevoid VG_(print_all_arena_stats) ( void ) 623de4a1d01951937632098a6cda45859afa587a06fsewardj{ 6247ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt i; 625de4a1d01951937632098a6cda45859afa587a06fsewardj for (i = 0; i < VG_N_ARENAS; i++) { 6262d5b816a492793741082445c8065dd9bc6298fadnethercote Arena* a = arenaId_to_ArenaP(i); 627de4a1d01951937632098a6cda45859afa587a06fsewardj VG_(message)(Vg_DebugMsg, 62892527134b798677918361f954a6e1bf2bda57fdcphilippe "%-8s: %'13lu/%'13lu max/curr mmap'd, " 629d043de9147df029a98833d0251434f6f2d391bfbsewardj "%llu/%llu unsplit/split sb unmmap'd, " 63092527134b798677918361f954a6e1bf2bda57fdcphilippe "%'13lu/%'13lu max/curr, " 6317d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj "%10llu/%10llu totalloc-blocks/bytes," 632d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe " %10llu searches %lu rzB\n", 633d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->name, 634d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->stats__bytes_mmaped_max, a->stats__bytes_mmaped, 635d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__nreclaim_unsplit, a->stats__nreclaim_split, 6367d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan_max, 6377d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan, 6387d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__tot_blocks, a->stats__tot_bytes, 639d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe a->stats__nsearches, 640d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe a->rz_szB 641de4a1d01951937632098a6cda45859afa587a06fsewardj ); 642de4a1d01951937632098a6cda45859afa587a06fsewardj } 643de4a1d01951937632098a6cda45859afa587a06fsewardj} 644de4a1d01951937632098a6cda45859afa587a06fsewardj 6459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(print_arena_cc_analysis) ( void ) 6469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 6479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UInt i; 6489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert( VG_(clo_profile_heap) ); 6499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = 0; i < VG_N_ARENAS; i++) { 6509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj cc_analyse_alloc_arena(i); 6519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 6529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 6539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 6549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 6552d5b816a492793741082445c8065dd9bc6298fadnethercote/* This library is self-initialising, as it makes this more self-contained, 6562d5b816a492793741082445c8065dd9bc6298fadnethercote less coupled with the outside world. Hence VG_(arena_malloc)() and 6572d5b816a492793741082445c8065dd9bc6298fadnethercote VG_(arena_free)() below always call ensure_mm_init() to ensure things are 65845f4e7c91119c7d01a59f5e827c67841632c9314sewardj correctly initialised. 65945f4e7c91119c7d01a59f5e827c67841632c9314sewardj 66045f4e7c91119c7d01a59f5e827c67841632c9314sewardj We initialise the client arena separately (and later) because the core 66145f4e7c91119c7d01a59f5e827c67841632c9314sewardj must do non-client allocation before the tool has a chance to set the 66245f4e7c91119c7d01a59f5e827c67841632c9314sewardj client arena's redzone size. 66345f4e7c91119c7d01a59f5e827c67841632c9314sewardj*/ 6640b3fd2daacb085f02b58918e4495be00ba8b418csewardjstatic Bool client_inited = False; 6650b3fd2daacb085f02b58918e4495be00ba8b418csewardjstatic Bool nonclient_inited = False; 6660b3fd2daacb085f02b58918e4495be00ba8b418csewardj 667de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 66845f4e7c91119c7d01a59f5e827c67841632c9314sewardjvoid ensure_mm_init ( ArenaId aid ) 669de4a1d01951937632098a6cda45859afa587a06fsewardj{ 67095c2329a0b7754c7f947a03a76215879762c8939njn static SizeT client_rz_szB = 8; // default: be paranoid 671fc51f8d9538eda285c2ea0974f29b075168f3433njn 67245f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* We use checked red zones (of various sizes) for our internal stuff, 673de4a1d01951937632098a6cda45859afa587a06fsewardj and an unchecked zone of arbitrary size for the client. Of 6747cc9c239f785f2903b597cdb34418bed42d25331nethercote course the client's red zone can be checked by the tool, eg. 6753e88418f808bf2840646504481d6a5be1df16541njn by using addressibility maps, but not by the mechanism implemented 6763e88418f808bf2840646504481d6a5be1df16541njn here, which merely checks at the time of freeing that the red 6772d5b816a492793741082445c8065dd9bc6298fadnethercote zone bytes are unchanged. 678b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward 6792d5b816a492793741082445c8065dd9bc6298fadnethercote Nb: redzone sizes are *minimums*; they could be made bigger to ensure 6808d3f84576d91676a445744a7462a9bba82d41da5njn alignment. Eg. with 8 byte alignment, on 32-bit machines 4 stays as 6818d3f84576d91676a445744a7462a9bba82d41da5njn 4, but 16 becomes 20; but on 64-bit machines 4 becomes 8, and 16 6828d3f84576d91676a445744a7462a9bba82d41da5njn stays as 16 --- the extra 4 bytes in both are accounted for by the 6838d3f84576d91676a445744a7462a9bba82d41da5njn larger prev/next ptr. 6842d5b816a492793741082445c8065dd9bc6298fadnethercote */ 68545f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (VG_AR_CLIENT == aid) { 6865600ab3ee7d50d55303665ac38a00b250ae4274asewardj Int ar_client_sbszB; 68745f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (client_inited) { 68845f4e7c91119c7d01a59f5e827c67841632c9314sewardj // This assertion ensures that a tool cannot try to change the client 68945f4e7c91119c7d01a59f5e827c67841632c9314sewardj // redzone size with VG_(needs_malloc_replacement)() after this module 69045f4e7c91119c7d01a59f5e827c67841632c9314sewardj // has done its first allocation from the client arena. 69145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (VG_(needs).malloc_replacement) 69295c2329a0b7754c7f947a03a76215879762c8939njn vg_assert(client_rz_szB == VG_(tdict).tool_client_redzone_szB); 69345f4e7c91119c7d01a59f5e827c67841632c9314sewardj return; 69445f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 69545f4e7c91119c7d01a59f5e827c67841632c9314sewardj 69645f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Check and set the client arena redzone size 69745f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (VG_(needs).malloc_replacement) { 69895c2329a0b7754c7f947a03a76215879762c8939njn client_rz_szB = VG_(tdict).tool_client_redzone_szB; 699d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe if (client_rz_szB > MAX_REDZONE_SZB) { 70045f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(printf)( "\nTool error:\n" 70145f4e7c91119c7d01a59f5e827c67841632c9314sewardj " specified redzone size is too big (%llu)\n", 70295c2329a0b7754c7f947a03a76215879762c8939njn (ULong)client_rz_szB); 70345f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(exit)(1); 70445f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 70545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 7066e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj // Initialise the client arena. On all platforms, 707c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj // increasing the superblock size reduces the number of superblocks 708c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj // in the client arena, which makes findSb cheaper. 709c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj ar_client_sbszB = 4194304; 710d043de9147df029a98833d0251434f6f2d391bfbsewardj // superblocks with a size > ar_client_sbszB will be unsplittable 711d043de9147df029a98833d0251434f6f2d391bfbsewardj // (unless used for providing memalign-ed blocks). 712d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj arena_init ( VG_AR_CLIENT, "client", client_rz_szB, 713d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj ar_client_sbszB, ar_client_sbszB+1); 71445f4e7c91119c7d01a59f5e827c67841632c9314sewardj client_inited = True; 71545f4e7c91119c7d01a59f5e827c67841632c9314sewardj 71645f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 71745f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (nonclient_inited) { 71845f4e7c91119c7d01a59f5e827c67841632c9314sewardj return; 71945f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 720d043de9147df029a98833d0251434f6f2d391bfbsewardj set_at_init_hp_overhead_szB = 721d043de9147df029a98833d0251434f6f2d391bfbsewardj VG_(clo_profile_heap) ? VG_MIN_MALLOC_SZB : 0; 72245f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Initialise the non-client arenas 723d043de9147df029a98833d0251434f6f2d391bfbsewardj // Similarly to client arena, big allocations will be unsplittable. 724d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe arena_init ( VG_AR_CORE, "core", CORE_REDZONE_DEFAULT_SZB, 725d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 4194304, 4194304+1 ); 726d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe arena_init ( VG_AR_DINFO, "dinfo", CORE_REDZONE_DEFAULT_SZB, 727d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 1048576, 1048576+1 ); 728d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe arena_init ( VG_AR_DEMANGLE, "demangle", CORE_REDZONE_DEFAULT_SZB, 729d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 65536, 65536+1 ); 730d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe arena_init ( VG_AR_TTAUX, "ttaux", CORE_REDZONE_DEFAULT_SZB, 731d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe 65536, 65536+1 ); 73245f4e7c91119c7d01a59f5e827c67841632c9314sewardj nonclient_inited = True; 73345f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 73445f4e7c91119c7d01a59f5e827c67841632c9314sewardj 735de4a1d01951937632098a6cda45859afa587a06fsewardj# ifdef DEBUG_MALLOC 7360b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(printf)("ZZZ1\n"); 737885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote VG_(sanity_check_malloc_all)(); 7380b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(printf)("ZZZ2\n"); 739de4a1d01951937632098a6cda45859afa587a06fsewardj# endif 740de4a1d01951937632098a6cda45859afa587a06fsewardj} 741de4a1d01951937632098a6cda45859afa587a06fsewardj 742de4a1d01951937632098a6cda45859afa587a06fsewardj 743de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 7442d5b816a492793741082445c8065dd9bc6298fadnethercote/*--- Superblock management ---*/ 745de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 746de4a1d01951937632098a6cda45859afa587a06fsewardj 7474c245e595b9f6300d3120408ca873f7115d9cc7dnjn__attribute__((noreturn)) 74854fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid VG_(out_of_memory_NORETURN) ( const HChar* who, SizeT szB ) 74945f4e7c91119c7d01a59f5e827c67841632c9314sewardj{ 75014baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe static Int outputTrial = 0; 75114baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe // We try once to output the full memory state followed by the below message. 75214baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe // If that fails (due to out of memory during first trial), we try to just 75314baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe // output the below message. 75414baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe // And then we abandon. 75514baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe 75645f4e7c91119c7d01a59f5e827c67841632c9314sewardj ULong tot_alloc = VG_(am_get_anonsize_total)(); 75754fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian const HChar* s1 = 758b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn "\n" 759b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " Valgrind's memory management: out of memory:\n" 760b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " %s's request for %llu bytes failed.\n" 76192527134b798677918361f954a6e1bf2bda57fdcphilippe " %'13llu bytes have already been mmap-ed ANONYMOUS.\n" 762b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " Valgrind cannot continue. Sorry.\n\n" 763b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " There are several possible reasons for this.\n" 764b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " - You have some kind of memory limit in place. Look at the\n" 765b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " output of 'ulimit -a'. Is there a limit on the size of\n" 766b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " virtual memory or address space?\n" 767b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " - You have run out of swap space.\n" 768b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " - Valgrind has a bug. If you think this is the case or you are\n" 769b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " not sure, please let us know and we'll try to fix it.\n" 770b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " Please note that programs can take substantially more memory than\n" 771b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " normal when running under Valgrind tools, eg. up to twice or\n" 772b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " more, depending on the tool. On a 64-bit machine, Valgrind\n" 773b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " should be able to make use of up 32GB memory. On a 32-bit\n" 774b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " machine, Valgrind should be able to use all the memory available\n" 775b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " to a single process, up to 4GB if that's how you have your\n" 776b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " kernel configured. Most 32-bit Linux setups allow a maximum of\n" 777b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " 3GB per process.\n\n" 778b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn " Whatever the reason, Valgrind cannot continue. Sorry.\n"; 779b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn 78014baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe if (outputTrial <= 1) { 78114baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe if (outputTrial == 0) { 78214baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe outputTrial++; 7834f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe // First print the memory stats with the aspacemgr data. 78414baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe VG_(am_show_nsegments) (0, "out_of_memory"); 78514baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe VG_(print_all_arena_stats) (); 78614baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe if (VG_(clo_profile_heap)) 78714baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe VG_(print_arena_cc_analysis) (); 7884f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe // And then print some other information that might help. 7894f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe VG_(print_all_stats) (False, /* Memory stats */ 7904f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe True /* Tool stats */); 7914f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe VG_(show_sched_status) (True, // host_stacktrace 7924f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe True, // valgrind_stack_usage 7934f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe True); // exited_threads 7944f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe /* In case we are an inner valgrind, asks the outer to report 7953bf117dd6e0ab3bec8eedd36da9d9602bb82c542philippe its memory state in its log output. */ 7963bf117dd6e0ab3bec8eedd36da9d9602bb82c542philippe INNER_REQUEST(VALGRIND_MONITOR_COMMAND("v.set log_output")); 7973bf117dd6e0ab3bec8eedd36da9d9602bb82c542philippe INNER_REQUEST(VALGRIND_MONITOR_COMMAND("v.info memory aspacemgr")); 79814baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe } 79914baeb40e0f21e629b6e07edc02cf4ca4d6ab31fphilippe outputTrial++; 800b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn VG_(message)(Vg_UserMsg, s1, who, (ULong)szB, tot_alloc); 80145f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 802b81c7950c925f7be1377bb4fb40ecb1b72e6b433njn VG_(debugLog)(0,"mallocfree", s1, who, (ULong)szB, tot_alloc); 80345f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 804cda2f0fbda4c4b2644babc830244be8aed95de1dnjn 80545f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(exit)(1); 80645f4e7c91119c7d01a59f5e827c67841632c9314sewardj} 80745f4e7c91119c7d01a59f5e827c67841632c9314sewardj 80845f4e7c91119c7d01a59f5e827c67841632c9314sewardj 8092d5b816a492793741082445c8065dd9bc6298fadnethercote// Align ptr p upwards to an align-sized boundary. 8102d5b816a492793741082445c8065dd9bc6298fadnethercotestatic 8117ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercotevoid* align_upwards ( void* p, SizeT align ) 8122d5b816a492793741082445c8065dd9bc6298fadnethercote{ 8132d5b816a492793741082445c8065dd9bc6298fadnethercote Addr a = (Addr)p; 8142d5b816a492793741082445c8065dd9bc6298fadnethercote if ((a % align) == 0) return (void*)a; 8152d5b816a492793741082445c8065dd9bc6298fadnethercote return (void*)(a - (a % align) + align); 8162d5b816a492793741082445c8065dd9bc6298fadnethercote} 8172d5b816a492793741082445c8065dd9bc6298fadnethercote 818d043de9147df029a98833d0251434f6f2d391bfbsewardj// Forward definition. 819d043de9147df029a98833d0251434f6f2d391bfbsewardjstatic 820d043de9147df029a98833d0251434f6f2d391bfbsewardjvoid deferred_reclaimSuperblock ( Arena* a, Superblock* sb); 821d043de9147df029a98833d0251434f6f2d391bfbsewardj 822c314eba94e45cf266382d5ecb173b1bbd960c2e9nethercote// If not enough memory available, either aborts (for non-client memory) 823c314eba94e45cf266382d5ecb173b1bbd960c2e9nethercote// or returns 0 (for client memory). 824de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 8257ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSuperblock* newSuperblock ( Arena* a, SizeT cszB ) 826de4a1d01951937632098a6cda45859afa587a06fsewardj{ 827de4a1d01951937632098a6cda45859afa587a06fsewardj Superblock* sb; 82845f4e7c91119c7d01a59f5e827c67841632c9314sewardj SysRes sres; 829d043de9147df029a98833d0251434f6f2d391bfbsewardj Bool unsplittable; 830d043de9147df029a98833d0251434f6f2d391bfbsewardj ArenaId aid; 831d043de9147df029a98833d0251434f6f2d391bfbsewardj 832d043de9147df029a98833d0251434f6f2d391bfbsewardj // A new superblock is needed for arena a. We will execute the deferred 833d043de9147df029a98833d0251434f6f2d391bfbsewardj // reclaim in all arenas in order to minimise fragmentation and 834d043de9147df029a98833d0251434f6f2d391bfbsewardj // peak memory usage. 835d043de9147df029a98833d0251434f6f2d391bfbsewardj for (aid = 0; aid < VG_N_ARENAS; aid++) { 836d043de9147df029a98833d0251434f6f2d391bfbsewardj Arena* arena = arenaId_to_ArenaP(aid); 837d043de9147df029a98833d0251434f6f2d391bfbsewardj if (arena->deferred_reclaimed_sb != NULL) 838d043de9147df029a98833d0251434f6f2d391bfbsewardj deferred_reclaimSuperblock (arena, NULL); 839d043de9147df029a98833d0251434f6f2d391bfbsewardj } 840c314eba94e45cf266382d5ecb173b1bbd960c2e9nethercote 8412d5b816a492793741082445c8065dd9bc6298fadnethercote // Take into account admin bytes in the Superblock. 8422d5b816a492793741082445c8065dd9bc6298fadnethercote cszB += sizeof(Superblock); 84398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 8442d5b816a492793741082445c8065dd9bc6298fadnethercote if (cszB < a->min_sblock_szB) cszB = a->min_sblock_szB; 845c3c98392eb6c417013dc2d3956ce569022f1def7bart cszB = VG_PGROUNDUP(cszB); 846c314eba94e45cf266382d5ecb173b1bbd960c2e9nethercote 847d043de9147df029a98833d0251434f6f2d391bfbsewardj if (cszB >= a->min_unsplittable_sblock_szB) 848d043de9147df029a98833d0251434f6f2d391bfbsewardj unsplittable = True; 849d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj else 850d043de9147df029a98833d0251434f6f2d391bfbsewardj unsplittable = False; 851d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 852d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 85345f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (a->clientmem) { 85457e36b3e766c9e33c59f994319b66a51b37319f7nethercote // client allocation -- return 0 to client if it fails 8552fa66ce8abeb95c722dcbd5bd233a26288f2cd7dflorian sres = VG_(am_mmap_client_heap) 85617e76ec2a2f1af812eee47dbbcde11bcb7ac1895philippe ( cszB, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC ); 857cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) 85857e36b3e766c9e33c59f994319b66a51b37319f7nethercote return 0; 85944bd4465581ff28cef83bb39e684a489297d7b71florian sb = (Superblock*)(Addr)sr_Res(sres); 86057e36b3e766c9e33c59f994319b66a51b37319f7nethercote } else { 86145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // non-client allocation -- abort if it fails 86217e76ec2a2f1af812eee47dbbcde11bcb7ac1895philippe sres = VG_(am_mmap_anon_float_valgrind)( cszB ); 863cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 86445f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(out_of_memory_NORETURN)("newSuperblock", cszB); 86545f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* NOTREACHED */ 86645f4e7c91119c7d01a59f5e827c67841632c9314sewardj sb = NULL; /* keep gcc happy */ 86745f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 86844bd4465581ff28cef83bb39e684a489297d7b71florian sb = (Superblock*)(Addr)sr_Res(sres); 86945f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 87057e36b3e766c9e33c59f994319b66a51b37319f7nethercote } 8712d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(NULL != sb); 87272faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(sb, cszB)); 8732d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(0 == (Addr)sb % VG_MIN_MALLOC_SZB); 8742d5b816a492793741082445c8065dd9bc6298fadnethercote sb->n_payload_bytes = cszB - sizeof(Superblock); 875d043de9147df029a98833d0251434f6f2d391bfbsewardj sb->unsplittable = (unsplittable ? sb : NULL); 8767d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_mmaped += cszB; 877d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj if (a->stats__bytes_mmaped > a->stats__bytes_mmaped_max) 878d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->stats__bytes_mmaped_max = a->stats__bytes_mmaped; 87945264afb4bc9fe6a80f55a939a06bc067b5f006csewardj VG_(debugLog)(1, "mallocfree", 880a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "newSuperblock at %p (pszB %7lu) %s owner %s/%s\n", 881d043de9147df029a98833d0251434f6f2d391bfbsewardj sb, sb->n_payload_bytes, 882d043de9147df029a98833d0251434f6f2d391bfbsewardj (unsplittable ? "unsplittable" : ""), 88345264afb4bc9fe6a80f55a939a06bc067b5f006csewardj a->clientmem ? "CLIENT" : "VALGRIND", a->name ); 8844c89b2f59afe2a86c6e8d0a7670c40a6ac2e907dsewardj return sb; 88545264afb4bc9fe6a80f55a939a06bc067b5f006csewardj} 88645264afb4bc9fe6a80f55a939a06bc067b5f006csewardj 887d043de9147df029a98833d0251434f6f2d391bfbsewardj// Reclaims the given superblock: 888d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj// * removes sb from arena sblocks list. 889d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj// * munmap the superblock segment. 890d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardjstatic 891d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardjvoid reclaimSuperblock ( Arena* a, Superblock* sb) 892d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj{ 893d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj SysRes sres; 894d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj SizeT cszB; 895d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj UInt i, j; 896d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 897d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj VG_(debugLog)(1, "mallocfree", 898a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "reclaimSuperblock at %p (pszB %7lu) %s owner %s/%s\n", 899d043de9147df029a98833d0251434f6f2d391bfbsewardj sb, sb->n_payload_bytes, 900d043de9147df029a98833d0251434f6f2d391bfbsewardj (sb->unsplittable ? "unsplittable" : ""), 901d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->clientmem ? "CLIENT" : "VALGRIND", a->name ); 902d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 903d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // Take into account admin bytes in the Superblock. 904d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj cszB = sizeof(Superblock) + sb->n_payload_bytes; 905d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 906d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // removes sb from superblock list. 907d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj for (i = 0; i < a->sblocks_used; i++) { 908d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj if (a->sblocks[i] == sb) 909d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj break; 910d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj } 911d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj vg_assert(i >= 0 && i < a->sblocks_used); 912d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj for (j = i; j < a->sblocks_used; j++) 913d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->sblocks[j] = a->sblocks[j+1]; 914d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->sblocks_used--; 915d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->sblocks[a->sblocks_used] = NULL; 916d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // paranoia: NULLify ptr to reclaimed sb or NULLify copy of ptr to last sb. 917d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 918d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__bytes_mmaped -= cszB; 919d043de9147df029a98833d0251434f6f2d391bfbsewardj if (sb->unsplittable) 920d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__nreclaim_unsplit++; 921d043de9147df029a98833d0251434f6f2d391bfbsewardj else 922d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__nreclaim_split++; 923d043de9147df029a98833d0251434f6f2d391bfbsewardj 924d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // Now that the sb is removed from the list, mnumap its space. 925d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj if (a->clientmem) { 926d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // reclaimable client allocation 927d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj Bool need_discard = False; 928d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj sres = VG_(am_munmap_client)(&need_discard, (Addr) sb, cszB); 929d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj vg_assert2(! sr_isError(sres), "superblock client munmap failure\n"); 930d043de9147df029a98833d0251434f6f2d391bfbsewardj /* We somewhat help the client by discarding the range. 931d043de9147df029a98833d0251434f6f2d391bfbsewardj Note however that if the client has JITted some code in 932d043de9147df029a98833d0251434f6f2d391bfbsewardj a small block that was freed, we do not provide this 933d043de9147df029a98833d0251434f6f2d391bfbsewardj 'discard support' */ 934d043de9147df029a98833d0251434f6f2d391bfbsewardj /* JRS 2011-Sept-26: it would be nice to move the discard 935d043de9147df029a98833d0251434f6f2d391bfbsewardj outwards somewhat (in terms of calls) so as to make it easier 936d043de9147df029a98833d0251434f6f2d391bfbsewardj to verify that there will be no nonterminating recursive set 937d043de9147df029a98833d0251434f6f2d391bfbsewardj of calls a result of calling VG_(discard_translations). 938d043de9147df029a98833d0251434f6f2d391bfbsewardj Another day, perhaps. */ 939d043de9147df029a98833d0251434f6f2d391bfbsewardj if (need_discard) 940d043de9147df029a98833d0251434f6f2d391bfbsewardj VG_(discard_translations) ((Addr) sb, cszB, "reclaimSuperblock"); 941d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj } else { 942d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // reclaimable non-client allocation 943d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj sres = VG_(am_munmap_valgrind)((Addr) sb, cszB); 944d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj vg_assert2(! sr_isError(sres), "superblock valgrind munmap failure\n"); 945d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj } 946d043de9147df029a98833d0251434f6f2d391bfbsewardj 947d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj} 948d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 9492d5b816a492793741082445c8065dd9bc6298fadnethercote// Find the superblock containing the given chunk. 950de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 9512d5b816a492793741082445c8065dd9bc6298fadnethercoteSuperblock* findSb ( Arena* a, Block* b ) 952de4a1d01951937632098a6cda45859afa587a06fsewardj{ 9530b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT min = 0; 9540b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT max = a->sblocks_used; 95549bdd7ab8be2ccb77886fb5899d5ff3d94fb5353sewardj 9560b3fd2daacb085f02b58918e4495be00ba8b418csewardj while (min <= max) { 9570b3fd2daacb085f02b58918e4495be00ba8b418csewardj Superblock * sb; 9580b3fd2daacb085f02b58918e4495be00ba8b418csewardj SizeT pos = min + (max - min)/2; 9590b3fd2daacb085f02b58918e4495be00ba8b418csewardj 9600b3fd2daacb085f02b58918e4495be00ba8b418csewardj vg_assert(pos >= 0 && pos < a->sblocks_used); 9610b3fd2daacb085f02b58918e4495be00ba8b418csewardj sb = a->sblocks[pos]; 9620b3fd2daacb085f02b58918e4495be00ba8b418csewardj if ((Block*)&sb->payload_bytes[0] <= b 9630b3fd2daacb085f02b58918e4495be00ba8b418csewardj && b < (Block*)&sb->payload_bytes[sb->n_payload_bytes]) 9640b3fd2daacb085f02b58918e4495be00ba8b418csewardj { 9650b3fd2daacb085f02b58918e4495be00ba8b418csewardj return sb; 9660b3fd2daacb085f02b58918e4495be00ba8b418csewardj } else if ((Block*)&sb->payload_bytes[0] <= b) { 9670b3fd2daacb085f02b58918e4495be00ba8b418csewardj min = pos + 1; 9680b3fd2daacb085f02b58918e4495be00ba8b418csewardj } else { 9690b3fd2daacb085f02b58918e4495be00ba8b418csewardj max = pos - 1; 97049bdd7ab8be2ccb77886fb5899d5ff3d94fb5353sewardj } 97149bdd7ab8be2ccb77886fb5899d5ff3d94fb5353sewardj } 9720b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(printf)("findSb: can't find pointer %p in arena '%s'\n", 9730b3fd2daacb085f02b58918e4495be00ba8b418csewardj b, a->name ); 9740b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(core_panic)("findSb: VG_(arena_free)() in wrong arena?"); 9750b3fd2daacb085f02b58918e4495be00ba8b418csewardj return NULL; /*NOTREACHED*/ 976de4a1d01951937632098a6cda45859afa587a06fsewardj} 977de4a1d01951937632098a6cda45859afa587a06fsewardj 978de4a1d01951937632098a6cda45859afa587a06fsewardj 97907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe// Find the superblock containing the given address. 98007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe// If superblock not found, return NULL. 98107c08527f05caeb0062b42ca9a58ee774ec5fba1philippestatic 98207c08527f05caeb0062b42ca9a58ee774ec5fba1philippeSuperblock* maybe_findSb ( Arena* a, Addr ad ) 98307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 98407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe SizeT min = 0; 98507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe SizeT max = a->sblocks_used; 98607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 98707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe while (min <= max) { 98807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe Superblock * sb; 98907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe SizeT pos = min + (max - min)/2; 99007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (pos < 0 || pos >= a->sblocks_used) 99107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return NULL; 99207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe sb = a->sblocks[pos]; 99307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if ((Addr)&sb->payload_bytes[0] <= ad 99407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe && ad < (Addr)&sb->payload_bytes[sb->n_payload_bytes]) { 99507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return sb; 99607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } else if ((Addr)&sb->payload_bytes[0] <= ad) { 99707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe min = pos + 1; 99807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } else { 99907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe max = pos - 1; 100007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 100107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 100207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return NULL; 100307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 100407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 100507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 1006de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 1007de4a1d01951937632098a6cda45859afa587a06fsewardj/*--- Functions for working with freelists. ---*/ 1008de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 1009de4a1d01951937632098a6cda45859afa587a06fsewardj 10102d5b816a492793741082445c8065dd9bc6298fadnethercote// Nb: Determination of which freelist a block lives on is based on the 10112d5b816a492793741082445c8065dd9bc6298fadnethercote// payload size, not block size. 1012de4a1d01951937632098a6cda45859afa587a06fsewardj 10132d5b816a492793741082445c8065dd9bc6298fadnethercote// Convert a payload size in bytes to a freelist number. 1014de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 10157ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteUInt pszB_to_listNo ( SizeT pszB ) 1016de4a1d01951937632098a6cda45859afa587a06fsewardj{ 1017db247dc183a70d76c2864667abe3a0da9099e38bnjn SizeT n = pszB / VG_MIN_MALLOC_SZB; 101860a4b0b77180f0c54ddca5c8d9ca20a877637f01tom vg_assert(0 == pszB % VG_MIN_MALLOC_SZB); 101961dcab89265f284bddcaef542bcc01ac4c5a67f0njn 1020c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj // The first 64 lists hold blocks of size VG_MIN_MALLOC_SZB * list_num. 1021c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj // The final 48 hold bigger blocks. 1022c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 64) return (UInt)n; 1023c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj /* Exponential slope up, factor 1.05 */ 1024c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 67) return 64; 1025c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 70) return 65; 1026c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 74) return 66; 1027c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 77) return 67; 1028c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 81) return 68; 1029c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 85) return 69; 1030c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 90) return 70; 1031c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 94) return 71; 1032c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 99) return 72; 1033c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 104) return 73; 1034c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 109) return 74; 1035c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 114) return 75; 1036c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 120) return 76; 1037c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 126) return 77; 1038c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 133) return 78; 1039c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 139) return 79; 1040c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj /* Exponential slope up, factor 1.10 */ 1041c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 153) return 80; 1042c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 169) return 81; 1043c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 185) return 82; 1044c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 204) return 83; 1045c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 224) return 84; 1046c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 247) return 85; 1047c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 272) return 86; 1048c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 299) return 87; 1049c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 329) return 88; 1050c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 362) return 89; 1051c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 398) return 90; 1052c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 438) return 91; 1053c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 482) return 92; 1054c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 530) return 93; 1055c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 583) return 94; 1056c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 641) return 95; 1057c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj /* Exponential slope up, factor 1.20 */ 1058c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 770) return 96; 1059c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 924) return 97; 1060c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 1109) return 98; 1061c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 1331) return 99; 1062c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 1597) return 100; 1063c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 1916) return 101; 1064c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 2300) return 102; 1065c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 2760) return 103; 1066c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 3312) return 104; 1067c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 3974) return 105; 1068c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 4769) return 106; 1069c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 5723) return 107; 1070c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 6868) return 108; 1071c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 8241) return 109; 1072c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj if (n < 9890) return 110; 1073c1ac977a10952a8a40af1ce37efa9ae9360ebf7esewardj return 111; 1074de4a1d01951937632098a6cda45859afa587a06fsewardj} 1075de4a1d01951937632098a6cda45859afa587a06fsewardj 10762d5b816a492793741082445c8065dd9bc6298fadnethercote// What is the minimum payload size for a given list? 1077de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 10787ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSizeT listNo_to_pszB_min ( UInt listNo ) 1079de4a1d01951937632098a6cda45859afa587a06fsewardj{ 10801d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj /* Repeatedly computing this function at every request is 10811d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj expensive. Hence at the first call just cache the result for 10821d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj every possible argument. */ 10831d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj static SizeT cache[N_MALLOC_LISTS]; 10841d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj static Bool cache_valid = False; 10851d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj if (!cache_valid) { 10861d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj UInt i; 10871d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj for (i = 0; i < N_MALLOC_LISTS; i++) { 10881d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj SizeT pszB = 0; 10891d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj while (pszB_to_listNo(pszB) < i) 10901d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj pszB += VG_MIN_MALLOC_SZB; 10911d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj cache[i] = pszB; 10921d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj } 10931d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj cache_valid = True; 10941d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj } 10951d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj /* Returned cached answer. */ 10966e6588ce963e7c3608c1bfe20b60925d74c1d0canjn vg_assert(listNo <= N_MALLOC_LISTS); 10971d2e2e6aadac3046743e22ff1dc7665796f6dafbsewardj return cache[listNo]; 1098de4a1d01951937632098a6cda45859afa587a06fsewardj} 1099de4a1d01951937632098a6cda45859afa587a06fsewardj 11002d5b816a492793741082445c8065dd9bc6298fadnethercote// What is the maximum payload size for a given list? 1101de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 11027ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSizeT listNo_to_pszB_max ( UInt listNo ) 1103de4a1d01951937632098a6cda45859afa587a06fsewardj{ 11046e6588ce963e7c3608c1bfe20b60925d74c1d0canjn vg_assert(listNo <= N_MALLOC_LISTS); 11056e6588ce963e7c3608c1bfe20b60925d74c1d0canjn if (listNo == N_MALLOC_LISTS-1) { 11062d5b816a492793741082445c8065dd9bc6298fadnethercote return MAX_PSZB; 1107de4a1d01951937632098a6cda45859afa587a06fsewardj } else { 11082d5b816a492793741082445c8065dd9bc6298fadnethercote return listNo_to_pszB_min(listNo+1) - 1; 1109de4a1d01951937632098a6cda45859afa587a06fsewardj } 1110de4a1d01951937632098a6cda45859afa587a06fsewardj} 1111de4a1d01951937632098a6cda45859afa587a06fsewardj 1112de4a1d01951937632098a6cda45859afa587a06fsewardj 1113de4a1d01951937632098a6cda45859afa587a06fsewardj/* A nasty hack to try and reduce fragmentation. Try and replace 1114de4a1d01951937632098a6cda45859afa587a06fsewardj a->freelist[lno] with another block on the same list but with a 1115de4a1d01951937632098a6cda45859afa587a06fsewardj lower address, with the idea of attempting to recycle the same 1116de4a1d01951937632098a6cda45859afa587a06fsewardj blocks rather than cruise through the address space. */ 1117de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 11187ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercotevoid swizzle ( Arena* a, UInt lno ) 1119de4a1d01951937632098a6cda45859afa587a06fsewardj{ 11202d5b816a492793741082445c8065dd9bc6298fadnethercote Block* p_best; 11212d5b816a492793741082445c8065dd9bc6298fadnethercote Block* pp; 11222d5b816a492793741082445c8065dd9bc6298fadnethercote Block* pn; 11237ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt i; 1124de4a1d01951937632098a6cda45859afa587a06fsewardj 1125de4a1d01951937632098a6cda45859afa587a06fsewardj p_best = a->freelist[lno]; 1126de4a1d01951937632098a6cda45859afa587a06fsewardj if (p_best == NULL) return; 1127de4a1d01951937632098a6cda45859afa587a06fsewardj 1128de4a1d01951937632098a6cda45859afa587a06fsewardj pn = pp = p_best; 11292bf9ba60ff7dc3a56f8443bad8ddd91b4f82743enjn 11302bf9ba60ff7dc3a56f8443bad8ddd91b4f82743enjn // This loop bound was 20 for a long time, but experiments showed that 11312bf9ba60ff7dc3a56f8443bad8ddd91b4f82743enjn // reducing it to 10 gave the same result in all the tests, and 5 got the 11322bf9ba60ff7dc3a56f8443bad8ddd91b4f82743enjn // same result in 85--100% of cases. And it's called often enough to be 11332bf9ba60ff7dc3a56f8443bad8ddd91b4f82743enjn // noticeable in programs that allocated a lot. 11342bf9ba60ff7dc3a56f8443bad8ddd91b4f82743enjn for (i = 0; i < 5; i++) { 11352d5b816a492793741082445c8065dd9bc6298fadnethercote pn = get_next_b(pn); 11362d5b816a492793741082445c8065dd9bc6298fadnethercote pp = get_prev_b(pp); 1137de4a1d01951937632098a6cda45859afa587a06fsewardj if (pn < p_best) p_best = pn; 1138de4a1d01951937632098a6cda45859afa587a06fsewardj if (pp < p_best) p_best = pp; 1139de4a1d01951937632098a6cda45859afa587a06fsewardj } 1140de4a1d01951937632098a6cda45859afa587a06fsewardj if (p_best < a->freelist[lno]) { 11412d5b816a492793741082445c8065dd9bc6298fadnethercote# ifdef VERBOSE_MALLOC 11429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("retreat by %ld\n", (Word)(a->freelist[lno] - p_best)); 1143de4a1d01951937632098a6cda45859afa587a06fsewardj# endif 1144de4a1d01951937632098a6cda45859afa587a06fsewardj a->freelist[lno] = p_best; 1145de4a1d01951937632098a6cda45859afa587a06fsewardj } 1146de4a1d01951937632098a6cda45859afa587a06fsewardj} 1147de4a1d01951937632098a6cda45859afa587a06fsewardj 1148de4a1d01951937632098a6cda45859afa587a06fsewardj 1149de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 1150de4a1d01951937632098a6cda45859afa587a06fsewardj/*--- Sanity-check/debugging machinery. ---*/ 1151de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 1152de4a1d01951937632098a6cda45859afa587a06fsewardj 11536e6588ce963e7c3608c1bfe20b60925d74c1d0canjn#define REDZONE_LO_MASK 0x31 11546e6588ce963e7c3608c1bfe20b60925d74c1d0canjn#define REDZONE_HI_MASK 0x7c 11552d5b816a492793741082445c8065dd9bc6298fadnethercote 11567ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote// Do some crude sanity checks on a Block. 1157de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 11582d5b816a492793741082445c8065dd9bc6298fadnethercoteBool blockSane ( Arena* a, Block* b ) 1159de4a1d01951937632098a6cda45859afa587a06fsewardj{ 1160de4a1d01951937632098a6cda45859afa587a06fsewardj# define BLEAT(str) VG_(printf)("blockSane: fail -- %s\n",str) 11617ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt i; 1162402c86183de4dc752884314d4b012cffb04a797bnjn // The lo and hi size fields will be checked (indirectly) by the call 1163402c86183de4dc752884314d4b012cffb04a797bnjn // to get_rz_hi_byte(). 1164472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn if (!a->clientmem && is_inuse_block(b)) { 116572faf10172c04674ac1e31cf4f7e57be241da7daphilippe // In the inner, for memcheck sake, temporarily mark redzone accessible. 11660b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrAccess(a,b)); 11672d5b816a492793741082445c8065dd9bc6298fadnethercote for (i = 0; i < a->rz_szB; i++) { 11681dcee097db02f9ef3ba355162c4373d90d0e895cnjn if (get_rz_lo_byte(b, i) != 11696e6588ce963e7c3608c1bfe20b60925d74c1d0canjn (UByte)(((Addr)b&0xff) ^ REDZONE_LO_MASK)) 11702d5b816a492793741082445c8065dd9bc6298fadnethercote {BLEAT("redzone-lo");return False;} 11711dcee097db02f9ef3ba355162c4373d90d0e895cnjn if (get_rz_hi_byte(b, i) != 11726e6588ce963e7c3608c1bfe20b60925d74c1d0canjn (UByte)(((Addr)b&0xff) ^ REDZONE_HI_MASK)) 11732d5b816a492793741082445c8065dd9bc6298fadnethercote {BLEAT("redzone-hi");return False;} 11740b9d0646949bd382758763664d3bf2d6115993aephilippe } 11750b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrNoAccess(a,b)); 1176de4a1d01951937632098a6cda45859afa587a06fsewardj } 1177de4a1d01951937632098a6cda45859afa587a06fsewardj return True; 1178de4a1d01951937632098a6cda45859afa587a06fsewardj# undef BLEAT 1179de4a1d01951937632098a6cda45859afa587a06fsewardj} 1180de4a1d01951937632098a6cda45859afa587a06fsewardj 11810b9d0646949bd382758763664d3bf2d6115993aephilippe// Sanity checks on a Block inside an unsplittable superblock 11820b9d0646949bd382758763664d3bf2d6115993aephilippestatic 11830b9d0646949bd382758763664d3bf2d6115993aephilippeBool unsplittableBlockSane ( Arena* a, Superblock *sb, Block* b ) 11840b9d0646949bd382758763664d3bf2d6115993aephilippe{ 11850b9d0646949bd382758763664d3bf2d6115993aephilippe# define BLEAT(str) VG_(printf)("unsplittableBlockSane: fail -- %s\n",str) 11860b9d0646949bd382758763664d3bf2d6115993aephilippe Block* other_b; 11870b9d0646949bd382758763664d3bf2d6115993aephilippe UByte* sb_start; 11880b9d0646949bd382758763664d3bf2d6115993aephilippe UByte* sb_end; 11890b9d0646949bd382758763664d3bf2d6115993aephilippe 11900b9d0646949bd382758763664d3bf2d6115993aephilippe if (!blockSane (a, b)) 11910b9d0646949bd382758763664d3bf2d6115993aephilippe {BLEAT("blockSane");return False;} 11920b9d0646949bd382758763664d3bf2d6115993aephilippe 11930b9d0646949bd382758763664d3bf2d6115993aephilippe if (sb->unsplittable != sb) 11940b9d0646949bd382758763664d3bf2d6115993aephilippe {BLEAT("unsplittable");return False;} 11950b9d0646949bd382758763664d3bf2d6115993aephilippe 11960b9d0646949bd382758763664d3bf2d6115993aephilippe sb_start = &sb->payload_bytes[0]; 11970b9d0646949bd382758763664d3bf2d6115993aephilippe sb_end = &sb->payload_bytes[sb->n_payload_bytes - 1]; 11980b9d0646949bd382758763664d3bf2d6115993aephilippe 11990b9d0646949bd382758763664d3bf2d6115993aephilippe // b must be first block (i.e. no unused bytes at the beginning) 12000b9d0646949bd382758763664d3bf2d6115993aephilippe if ((Block*)sb_start != b) 12010b9d0646949bd382758763664d3bf2d6115993aephilippe {BLEAT("sb_start");return False;} 12020b9d0646949bd382758763664d3bf2d6115993aephilippe 12030b9d0646949bd382758763664d3bf2d6115993aephilippe // b must be last block (i.e. no unused bytes at the end) 12040b9d0646949bd382758763664d3bf2d6115993aephilippe other_b = b + get_bszB(b); 12050b9d0646949bd382758763664d3bf2d6115993aephilippe if (other_b-1 != (Block*)sb_end) 12060b9d0646949bd382758763664d3bf2d6115993aephilippe {BLEAT("sb_end");return False;} 12070b9d0646949bd382758763664d3bf2d6115993aephilippe 12080b9d0646949bd382758763664d3bf2d6115993aephilippe return True; 12090b9d0646949bd382758763664d3bf2d6115993aephilippe# undef BLEAT 12100b9d0646949bd382758763664d3bf2d6115993aephilippe} 12110b9d0646949bd382758763664d3bf2d6115993aephilippe 12122d5b816a492793741082445c8065dd9bc6298fadnethercote// Print superblocks (only for debugging). 1213de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 1214de4a1d01951937632098a6cda45859afa587a06fsewardjvoid ppSuperblocks ( Arena* a ) 1215de4a1d01951937632098a6cda45859afa587a06fsewardj{ 12160b3fd2daacb085f02b58918e4495be00ba8b418csewardj UInt i, j, blockno = 1; 1217d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn SizeT b_bszB; 1218de4a1d01951937632098a6cda45859afa587a06fsewardj 12190b3fd2daacb085f02b58918e4495be00ba8b418csewardj for (j = 0; j < a->sblocks_used; ++j) { 12200b3fd2daacb085f02b58918e4495be00ba8b418csewardj Superblock * sb = a->sblocks[j]; 12210b3fd2daacb085f02b58918e4495be00ba8b418csewardj 1222de4a1d01951937632098a6cda45859afa587a06fsewardj VG_(printf)( "\n" ); 1223a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(printf)( "superblock %u at %p %s, sb->n_pl_bs = %lu\n", 1224d043de9147df029a98833d0251434f6f2d391bfbsewardj blockno++, sb, (sb->unsplittable ? "unsplittable" : ""), 1225d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj sb->n_payload_bytes); 1226d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn for (i = 0; i < sb->n_payload_bytes; i += b_bszB) { 1227d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn Block* b = (Block*)&sb->payload_bytes[i]; 1228d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn b_bszB = get_bszB(b); 1229a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(printf)( " block at %u, bszB %lu: ", i, b_bszB ); 1230472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn VG_(printf)( "%s, ", is_inuse_block(b) ? "inuse" : "free"); 12312d5b816a492793741082445c8065dd9bc6298fadnethercote VG_(printf)( "%s\n", blockSane(a, b) ? "ok" : "BAD" ); 1232de4a1d01951937632098a6cda45859afa587a06fsewardj } 12332d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(i == sb->n_payload_bytes); // no overshoot at end of Sb 1234de4a1d01951937632098a6cda45859afa587a06fsewardj } 1235de4a1d01951937632098a6cda45859afa587a06fsewardj VG_(printf)( "end of superblocks\n\n" ); 1236de4a1d01951937632098a6cda45859afa587a06fsewardj} 1237de4a1d01951937632098a6cda45859afa587a06fsewardj 12382d5b816a492793741082445c8065dd9bc6298fadnethercote// Sanity check both the superblocks and the chains. 1239885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercotestatic void sanity_check_malloc_arena ( ArenaId aid ) 1240de4a1d01951937632098a6cda45859afa587a06fsewardj{ 12410b3fd2daacb085f02b58918e4495be00ba8b418csewardj UInt i, j, superblockctr, blockctr_sb, blockctr_li; 12427ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt blockctr_sb_free, listno; 12437ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT b_bszB, b_pszB, list_min_pszB, list_max_pszB; 12440b3fd2daacb085f02b58918e4495be00ba8b418csewardj Bool thisFree, lastWasFree, sblockarrOK; 12452d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b; 12462d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b_prev; 12477ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT arena_bytes_on_loan; 1248de4a1d01951937632098a6cda45859afa587a06fsewardj Arena* a; 1249de4a1d01951937632098a6cda45859afa587a06fsewardj 1250885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote# define BOMB VG_(core_panic)("sanity_check_malloc_arena") 1251de4a1d01951937632098a6cda45859afa587a06fsewardj 1252de4a1d01951937632098a6cda45859afa587a06fsewardj a = arenaId_to_ArenaP(aid); 12530b3fd2daacb085f02b58918e4495be00ba8b418csewardj 12540b3fd2daacb085f02b58918e4495be00ba8b418csewardj // Check the superblock array. 12550b3fd2daacb085f02b58918e4495be00ba8b418csewardj sblockarrOK 12560b3fd2daacb085f02b58918e4495be00ba8b418csewardj = a->sblocks != NULL 12570b3fd2daacb085f02b58918e4495be00ba8b418csewardj && a->sblocks_size >= SBLOCKS_SIZE_INITIAL 12580b3fd2daacb085f02b58918e4495be00ba8b418csewardj && a->sblocks_used <= a->sblocks_size 12590b3fd2daacb085f02b58918e4495be00ba8b418csewardj && (a->sblocks_size == SBLOCKS_SIZE_INITIAL 12600b3fd2daacb085f02b58918e4495be00ba8b418csewardj ? (a->sblocks == &a->sblocks_initial[0]) 12610b3fd2daacb085f02b58918e4495be00ba8b418csewardj : (a->sblocks != &a->sblocks_initial[0])); 12620b3fd2daacb085f02b58918e4495be00ba8b418csewardj if (!sblockarrOK) { 12630b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(printf)("sanity_check_malloc_arena: sblock array BAD\n"); 12640b3fd2daacb085f02b58918e4495be00ba8b418csewardj BOMB; 12650b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 12660b3fd2daacb085f02b58918e4495be00ba8b418csewardj 12672d5b816a492793741082445c8065dd9bc6298fadnethercote // First, traverse all the superblocks, inspecting the Blocks in each. 1268de4a1d01951937632098a6cda45859afa587a06fsewardj superblockctr = blockctr_sb = blockctr_sb_free = 0; 1269de4a1d01951937632098a6cda45859afa587a06fsewardj arena_bytes_on_loan = 0; 12700b3fd2daacb085f02b58918e4495be00ba8b418csewardj for (j = 0; j < a->sblocks_used; ++j) { 12710b3fd2daacb085f02b58918e4495be00ba8b418csewardj Superblock * sb = a->sblocks[j]; 1272de4a1d01951937632098a6cda45859afa587a06fsewardj lastWasFree = False; 1273de4a1d01951937632098a6cda45859afa587a06fsewardj superblockctr++; 12742d5b816a492793741082445c8065dd9bc6298fadnethercote for (i = 0; i < sb->n_payload_bytes; i += mk_plain_bszB(b_bszB)) { 1275de4a1d01951937632098a6cda45859afa587a06fsewardj blockctr_sb++; 12762d5b816a492793741082445c8065dd9bc6298fadnethercote b = (Block*)&sb->payload_bytes[i]; 1277d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn b_bszB = get_bszB_as_is(b); 1278de4a1d01951937632098a6cda45859afa587a06fsewardj if (!blockSane(a, b)) { 1279a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(printf)("sanity_check_malloc_arena: sb %p, block %u " 12808a7b41b41b46c0aa7bd4b6678b82285437e7f08cnjn "(bszB %lu): BAD\n", sb, i, b_bszB ); 1281de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1282de4a1d01951937632098a6cda45859afa587a06fsewardj } 1283472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn thisFree = !is_inuse_block(b); 1284de4a1d01951937632098a6cda45859afa587a06fsewardj if (thisFree && lastWasFree) { 1285a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(printf)("sanity_check_malloc_arena: sb %p, block %u " 12868a7b41b41b46c0aa7bd4b6678b82285437e7f08cnjn "(bszB %lu): UNMERGED FREES\n", sb, i, b_bszB ); 1287de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1288de4a1d01951937632098a6cda45859afa587a06fsewardj } 1289de4a1d01951937632098a6cda45859afa587a06fsewardj if (thisFree) blockctr_sb_free++; 12900b3fd2daacb085f02b58918e4495be00ba8b418csewardj if (!thisFree) 12912d5b816a492793741082445c8065dd9bc6298fadnethercote arena_bytes_on_loan += bszB_to_pszB(a, b_bszB); 12922d5b816a492793741082445c8065dd9bc6298fadnethercote lastWasFree = thisFree; 1293de4a1d01951937632098a6cda45859afa587a06fsewardj } 12942d5b816a492793741082445c8065dd9bc6298fadnethercote if (i > sb->n_payload_bytes) { 1295885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote VG_(printf)( "sanity_check_malloc_arena: sb %p: last block " 1296de4a1d01951937632098a6cda45859afa587a06fsewardj "overshoots end\n", sb); 1297de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1298de4a1d01951937632098a6cda45859afa587a06fsewardj } 1299de4a1d01951937632098a6cda45859afa587a06fsewardj } 1300de4a1d01951937632098a6cda45859afa587a06fsewardj 13016e4b71339ecdf4accc77e86a892718516a531b0fphilippe arena_bytes_on_loan += a->stats__perm_bytes_on_loan; 13026e4b71339ecdf4accc77e86a892718516a531b0fphilippe 13037d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj if (arena_bytes_on_loan != a->stats__bytes_on_loan) { 13042d5b816a492793741082445c8065dd9bc6298fadnethercote# ifdef VERBOSE_MALLOC 1305d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj VG_(printf)( "sanity_check_malloc_arena: a->bytes_on_loan %lu, " 1306d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj "arena_bytes_on_loan %lu: " 13070b9d0646949bd382758763664d3bf2d6115993aephilippe "MISMATCH\n", a->stats__bytes_on_loan, arena_bytes_on_loan); 13082d5b816a492793741082445c8065dd9bc6298fadnethercote# endif 1309de4a1d01951937632098a6cda45859afa587a06fsewardj ppSuperblocks(a); 1310de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1311de4a1d01951937632098a6cda45859afa587a06fsewardj } 1312de4a1d01951937632098a6cda45859afa587a06fsewardj 1313de4a1d01951937632098a6cda45859afa587a06fsewardj /* Second, traverse each list, checking that the back pointers make 1314de4a1d01951937632098a6cda45859afa587a06fsewardj sense, counting blocks encountered, and checking that each block 1315de4a1d01951937632098a6cda45859afa587a06fsewardj is an appropriate size for this list. */ 1316de4a1d01951937632098a6cda45859afa587a06fsewardj blockctr_li = 0; 13176e6588ce963e7c3608c1bfe20b60925d74c1d0canjn for (listno = 0; listno < N_MALLOC_LISTS; listno++) { 13182d5b816a492793741082445c8065dd9bc6298fadnethercote list_min_pszB = listNo_to_pszB_min(listno); 13192d5b816a492793741082445c8065dd9bc6298fadnethercote list_max_pszB = listNo_to_pszB_max(listno); 1320de4a1d01951937632098a6cda45859afa587a06fsewardj b = a->freelist[listno]; 1321de4a1d01951937632098a6cda45859afa587a06fsewardj if (b == NULL) continue; 1322de4a1d01951937632098a6cda45859afa587a06fsewardj while (True) { 1323de4a1d01951937632098a6cda45859afa587a06fsewardj b_prev = b; 13242d5b816a492793741082445c8065dd9bc6298fadnethercote b = get_next_b(b); 13252d5b816a492793741082445c8065dd9bc6298fadnethercote if (get_prev_b(b) != b_prev) { 1326a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(printf)( "sanity_check_malloc_arena: list %u at %p: " 13270b3fd2daacb085f02b58918e4495be00ba8b418csewardj "BAD LINKAGE\n", 1328de4a1d01951937632098a6cda45859afa587a06fsewardj listno, b ); 1329de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1330de4a1d01951937632098a6cda45859afa587a06fsewardj } 1331089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn b_pszB = get_pszB(a, b); 13322d5b816a492793741082445c8065dd9bc6298fadnethercote if (b_pszB < list_min_pszB || b_pszB > list_max_pszB) { 13330b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(printf)( 1334a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "sanity_check_malloc_arena: list %u at %p: " 13358a7b41b41b46c0aa7bd4b6678b82285437e7f08cnjn "WRONG CHAIN SIZE %luB (%luB, %luB)\n", 13362d5b816a492793741082445c8065dd9bc6298fadnethercote listno, b, b_pszB, list_min_pszB, list_max_pszB ); 1337de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1338de4a1d01951937632098a6cda45859afa587a06fsewardj } 1339de4a1d01951937632098a6cda45859afa587a06fsewardj blockctr_li++; 1340de4a1d01951937632098a6cda45859afa587a06fsewardj if (b == a->freelist[listno]) break; 1341de4a1d01951937632098a6cda45859afa587a06fsewardj } 1342de4a1d01951937632098a6cda45859afa587a06fsewardj } 1343de4a1d01951937632098a6cda45859afa587a06fsewardj 1344de4a1d01951937632098a6cda45859afa587a06fsewardj if (blockctr_sb_free != blockctr_li) { 13452d5b816a492793741082445c8065dd9bc6298fadnethercote# ifdef VERBOSE_MALLOC 13462d5b816a492793741082445c8065dd9bc6298fadnethercote VG_(printf)( "sanity_check_malloc_arena: BLOCK COUNT MISMATCH " 13472d5b816a492793741082445c8065dd9bc6298fadnethercote "(via sbs %d, via lists %d)\n", 13482d5b816a492793741082445c8065dd9bc6298fadnethercote blockctr_sb_free, blockctr_li ); 13492d5b816a492793741082445c8065dd9bc6298fadnethercote# endif 1350de4a1d01951937632098a6cda45859afa587a06fsewardj ppSuperblocks(a); 1351de4a1d01951937632098a6cda45859afa587a06fsewardj BOMB; 1352de4a1d01951937632098a6cda45859afa587a06fsewardj } 1353de4a1d01951937632098a6cda45859afa587a06fsewardj 1354885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote if (VG_(clo_verbosity) > 2) 1355885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote VG_(message)(Vg_DebugMsg, 1356a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "%-8s: %2u sbs, %5u bs, %2u/%-2u free bs, " 1357a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "%7lu mmap, %7lu loan\n", 1358885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote a->name, 1359885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote superblockctr, 1360885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote blockctr_sb, blockctr_sb_free, blockctr_li, 13617d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_mmaped, a->stats__bytes_on_loan); 1362de4a1d01951937632098a6cda45859afa587a06fsewardj# undef BOMB 1363de4a1d01951937632098a6cda45859afa587a06fsewardj} 1364de4a1d01951937632098a6cda45859afa587a06fsewardj 1365de4a1d01951937632098a6cda45859afa587a06fsewardj 13669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define N_AN_CCS 1000 13679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 136854fe2021b87b9e5edb8ec8070f47b86d5cafb8aafloriantypedef struct { 136954fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian ULong nBytes; 137054fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian ULong nBlocks; 137154fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian const HChar* cc; 137254fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian} AnCC; 13739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic AnCC anCCs[N_AN_CCS]; 13759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13764f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe/* Sorting by decreasing cost center nBytes, to have the biggest 13774f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe cost centres at the top. */ 13786bd9dc18c043927c1196caba20a327238a179c42florianstatic Int cmp_AnCC_by_vol ( const void* v1, const void* v2 ) { 13793e7986312a0ffc7646b0552d4c4ea3744a870e73florian const AnCC* ancc1 = v1; 13803e7986312a0ffc7646b0552d4c4ea3744a870e73florian const AnCC* ancc2 = v2; 13814f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe if (ancc1->nBytes < ancc2->nBytes) return 1; 13824f6f336badda2171d6e842cca3de63b53f4c9f0bphilippe if (ancc1->nBytes > ancc2->nBytes) return -1; 13839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 13849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 13859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void cc_analyse_alloc_arena ( ArenaId aid ) 13879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 13889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i, j, k; 13899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Arena* a; 13909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Block* b; 13919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool thisFree, lastWasFree; 13929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj SizeT b_bszB; 13939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 139454fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian const HChar* cc; 13959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UInt n_ccs = 0; 13969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj //return; 13979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj a = arenaId_to_ArenaP(aid); 13989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (a->name == NULL) { 13999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* arena is not in use, is not initialised and will fail the 14009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sanity check that follows. */ 14019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 14029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sanity_check_malloc_arena(aid); 14059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)( 14073743c91f664a62d42ffc337e5d447d5b21554ee8philippe "-------- Arena \"%s\": %'lu/%'lu max/curr mmap'd, " 1408d043de9147df029a98833d0251434f6f2d391bfbsewardj "%llu/%llu unsplit/split sb unmmap'd, " 14093743c91f664a62d42ffc337e5d447d5b21554ee8philippe "%'lu/%'lu max/curr on_loan %lu rzB --------\n", 1410d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj a->name, a->stats__bytes_mmaped_max, a->stats__bytes_mmaped, 1411d043de9147df029a98833d0251434f6f2d391bfbsewardj a->stats__nreclaim_unsplit, a->stats__nreclaim_split, 1412d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe a->stats__bytes_on_loan_max, a->stats__bytes_on_loan, 1413d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe a->rz_szB 14149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 14159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < a->sblocks_used; ++j) { 14179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Superblock * sb = a->sblocks[j]; 14189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj lastWasFree = False; 14199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = 0; i < sb->n_payload_bytes; i += mk_plain_bszB(b_bszB)) { 14209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj b = (Block*)&sb->payload_bytes[i]; 14219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj b_bszB = get_bszB_as_is(b); 14229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!blockSane(a, b)) { 14239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("sanity_check_malloc_arena: sb %p, block %ld " 14249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "(bszB %lu): BAD\n", sb, i, b_bszB ); 1425e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(0); 14269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj thisFree = !is_inuse_block(b); 14289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (thisFree && lastWasFree) { 14299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("sanity_check_malloc_arena: sb %p, block %ld " 14309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "(bszB %lu): UNMERGED FREES\n", sb, i, b_bszB ); 1431e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(0); 14329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj lastWasFree = thisFree; 14349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (thisFree) continue; 14369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14370b9d0646949bd382758763664d3bf2d6115993aephilippe if (VG_(clo_profile_heap)) 14380b9d0646949bd382758763664d3bf2d6115993aephilippe cc = get_cc(b); 14390b9d0646949bd382758763664d3bf2d6115993aephilippe else 14400b9d0646949bd382758763664d3bf2d6115993aephilippe cc = "(--profile-heap=yes for details)"; 14419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) 14429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("block: inUse=%d pszB=%d cc=%s\n", 14439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (Int)(!thisFree), 14449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (Int)bszB_to_pszB(a, b_bszB), 14459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj get_cc(b)); 1446e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(cc); 14479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (k = 0; k < n_ccs; k++) { 1448e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(anCCs[k].cc); 14499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 == VG_(strcmp)(cc, anCCs[k].cc)) 14509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 14519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 1452e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(k >= 0 && k <= n_ccs); 14539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (k == n_ccs) { 1455e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(n_ccs < N_AN_CCS-1); 14569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_ccs++; 14579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj anCCs[k].nBytes = 0; 14589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj anCCs[k].nBlocks = 0; 14599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj anCCs[k].cc = cc; 14609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1462e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(k >= 0 && k < n_ccs && k < N_AN_CCS); 14639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj anCCs[k].nBytes += (ULong)bszB_to_pszB(a, b_bszB); 14649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj anCCs[k].nBlocks++; 14659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (i > sb->n_payload_bytes) { 14679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)( "sanity_check_malloc_arena: sb %p: last block " 14689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "overshoots end\n", sb); 1469e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(0); 14709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14736e4b71339ecdf4accc77e86a892718516a531b0fphilippe if (a->stats__perm_bytes_on_loan > 0) { 1474e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(n_ccs < N_AN_CCS-1); 14756e4b71339ecdf4accc77e86a892718516a531b0fphilippe anCCs[n_ccs].nBytes = a->stats__perm_bytes_on_loan; 14766e4b71339ecdf4accc77e86a892718516a531b0fphilippe anCCs[n_ccs].nBlocks = a->stats__perm_blocks; 14776e4b71339ecdf4accc77e86a892718516a531b0fphilippe anCCs[n_ccs].cc = "perm_malloc"; 14786e4b71339ecdf4accc77e86a892718516a531b0fphilippe n_ccs++; 14796e4b71339ecdf4accc77e86a892718516a531b0fphilippe } 14806e4b71339ecdf4accc77e86a892718516a531b0fphilippe 14819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(ssort)( &anCCs[0], n_ccs, sizeof(anCCs[0]), cmp_AnCC_by_vol ); 14829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (k = 0; k < n_ccs; k++) { 14849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("%'13llu in %'9llu: %s\n", 14859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj anCCs[k].nBytes, anCCs[k].nBlocks, anCCs[k].cc ); 14869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); 14899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 14909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1492885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercotevoid VG_(sanity_check_malloc_all) ( void ) 1493de4a1d01951937632098a6cda45859afa587a06fsewardj{ 14947ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt i; 14950b3fd2daacb085f02b58918e4495be00ba8b418csewardj for (i = 0; i < VG_N_ARENAS; i++) { 14960b3fd2daacb085f02b58918e4495be00ba8b418csewardj if (i == VG_AR_CLIENT && !client_inited) 14970b3fd2daacb085f02b58918e4495be00ba8b418csewardj continue; 1498885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote sanity_check_malloc_arena ( i ); 14990b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 1500de4a1d01951937632098a6cda45859afa587a06fsewardj} 1501de4a1d01951937632098a6cda45859afa587a06fsewardj 150207c08527f05caeb0062b42ca9a58ee774ec5fba1philippevoid VG_(describe_arena_addr) ( Addr a, AddrArenaInfo* aai ) 150307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe{ 150407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe UInt i; 150507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe Superblock *sb; 150607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe Arena *arena; 150707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 150807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe for (i = 0; i < VG_N_ARENAS; i++) { 150907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (i == VG_AR_CLIENT && !client_inited) 151007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe continue; 151107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe arena = arenaId_to_ArenaP(i); 151207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe sb = maybe_findSb( arena, a ); 151307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (sb != NULL) { 151407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe Word j; 151507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe SizeT b_bszB; 151607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe Block *b = NULL; 151707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe 151807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->aid = i; 151907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->name = arena->name; 152007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe for (j = 0; j < sb->n_payload_bytes; j += mk_plain_bszB(b_bszB)) { 152107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe b = (Block*)&sb->payload_bytes[j]; 152207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe b_bszB = get_bszB_as_is(b); 152307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe if (a < (Addr)b + mk_plain_bszB(b_bszB)) 152407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe break; 152507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 152607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe vg_assert (b); 152707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->block_szB = get_pszB(arena, b); 152807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->rwoffset = a - (Addr)get_block_payload(arena, b); 152907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->free = !is_inuse_block(b); 153007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe return; 153107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 153207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe } 153307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->aid = 0; 153407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->name = NULL; 153507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->block_szB = 0; 153607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->rwoffset = 0; 153707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe aai->free = False; 153807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe} 1539de4a1d01951937632098a6cda45859afa587a06fsewardj 15402d5b816a492793741082445c8065dd9bc6298fadnethercote/*------------------------------------------------------------*/ 15412d5b816a492793741082445c8065dd9bc6298fadnethercote/*--- Creating and deleting blocks. ---*/ 15422d5b816a492793741082445c8065dd9bc6298fadnethercote/*------------------------------------------------------------*/ 15432d5b816a492793741082445c8065dd9bc6298fadnethercote 15442d5b816a492793741082445c8065dd9bc6298fadnethercote// Mark the bytes at b .. b+bszB-1 as not in use, and add them to the 15452d5b816a492793741082445c8065dd9bc6298fadnethercote// relevant free list. 15462d5b816a492793741082445c8065dd9bc6298fadnethercote 15472d5b816a492793741082445c8065dd9bc6298fadnethercotestatic 15487ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercotevoid mkFreeBlock ( Arena* a, Block* b, SizeT bszB, UInt b_lno ) 15492d5b816a492793741082445c8065dd9bc6298fadnethercote{ 15507ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT pszB = bszB_to_pszB(a, bszB); 15512d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(b_lno == pszB_to_listNo(pszB)); 155272faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(b, bszB)); 15532d5b816a492793741082445c8065dd9bc6298fadnethercote // Set the size fields and indicate not-in-use. 15548d3f84576d91676a445744a7462a9bba82d41da5njn set_bszB(b, mk_free_bszB(bszB)); 15552d5b816a492793741082445c8065dd9bc6298fadnethercote 15562d5b816a492793741082445c8065dd9bc6298fadnethercote // Add to the relevant list. 15572d5b816a492793741082445c8065dd9bc6298fadnethercote if (a->freelist[b_lno] == NULL) { 15582d5b816a492793741082445c8065dd9bc6298fadnethercote set_prev_b(b, b); 15592d5b816a492793741082445c8065dd9bc6298fadnethercote set_next_b(b, b); 15602d5b816a492793741082445c8065dd9bc6298fadnethercote a->freelist[b_lno] = b; 15612d5b816a492793741082445c8065dd9bc6298fadnethercote } else { 15622d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b_prev = get_prev_b(a->freelist[b_lno]); 15632d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b_next = a->freelist[b_lno]; 15642d5b816a492793741082445c8065dd9bc6298fadnethercote set_next_b(b_prev, b); 15652d5b816a492793741082445c8065dd9bc6298fadnethercote set_prev_b(b_next, b); 15662d5b816a492793741082445c8065dd9bc6298fadnethercote set_next_b(b, b_next); 15672d5b816a492793741082445c8065dd9bc6298fadnethercote set_prev_b(b, b_prev); 15682d5b816a492793741082445c8065dd9bc6298fadnethercote } 15692d5b816a492793741082445c8065dd9bc6298fadnethercote# ifdef DEBUG_MALLOC 15702d5b816a492793741082445c8065dd9bc6298fadnethercote (void)blockSane(a,b); 15712d5b816a492793741082445c8065dd9bc6298fadnethercote# endif 15722d5b816a492793741082445c8065dd9bc6298fadnethercote} 15732d5b816a492793741082445c8065dd9bc6298fadnethercote 15742d5b816a492793741082445c8065dd9bc6298fadnethercote// Mark the bytes at b .. b+bszB-1 as in use, and set up the block 15752d5b816a492793741082445c8065dd9bc6298fadnethercote// appropriately. 15762d5b816a492793741082445c8065dd9bc6298fadnethercotestatic 15777ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercotevoid mkInuseBlock ( Arena* a, Block* b, SizeT bszB ) 15782d5b816a492793741082445c8065dd9bc6298fadnethercote{ 15797ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt i; 15802d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(bszB >= min_useful_bszB(a)); 158172faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(b, bszB)); 15828d3f84576d91676a445744a7462a9bba82d41da5njn set_bszB(b, mk_inuse_bszB(bszB)); 15832d5b816a492793741082445c8065dd9bc6298fadnethercote set_prev_b(b, NULL); // Take off freelist 15842d5b816a492793741082445c8065dd9bc6298fadnethercote set_next_b(b, NULL); // ditto 15852d5b816a492793741082445c8065dd9bc6298fadnethercote if (!a->clientmem) { 15862d5b816a492793741082445c8065dd9bc6298fadnethercote for (i = 0; i < a->rz_szB; i++) { 15871dcee097db02f9ef3ba355162c4373d90d0e895cnjn set_rz_lo_byte(b, i, (UByte)(((Addr)b&0xff) ^ REDZONE_LO_MASK)); 15881dcee097db02f9ef3ba355162c4373d90d0e895cnjn set_rz_hi_byte(b, i, (UByte)(((Addr)b&0xff) ^ REDZONE_HI_MASK)); 15892d5b816a492793741082445c8065dd9bc6298fadnethercote } 15902d5b816a492793741082445c8065dd9bc6298fadnethercote } 15912d5b816a492793741082445c8065dd9bc6298fadnethercote# ifdef DEBUG_MALLOC 15922d5b816a492793741082445c8065dd9bc6298fadnethercote (void)blockSane(a,b); 15932d5b816a492793741082445c8065dd9bc6298fadnethercote# endif 15942d5b816a492793741082445c8065dd9bc6298fadnethercote} 15952d5b816a492793741082445c8065dd9bc6298fadnethercote 15960b9d0646949bd382758763664d3bf2d6115993aephilippe// Mark the bytes at b .. b+bszB-1 as being part of a block that has been shrunk. 15970b9d0646949bd382758763664d3bf2d6115993aephilippestatic 15980b9d0646949bd382758763664d3bf2d6115993aephilippevoid shrinkInuseBlock ( Arena* a, Block* b, SizeT bszB ) 15990b9d0646949bd382758763664d3bf2d6115993aephilippe{ 16000b9d0646949bd382758763664d3bf2d6115993aephilippe UInt i; 16010b9d0646949bd382758763664d3bf2d6115993aephilippe 16020b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(bszB >= min_useful_bszB(a)); 16030b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrAccess(a,b)); 16040b9d0646949bd382758763664d3bf2d6115993aephilippe set_bszB(b, mk_inuse_bszB(bszB)); 16050b9d0646949bd382758763664d3bf2d6115993aephilippe if (!a->clientmem) { 16060b9d0646949bd382758763664d3bf2d6115993aephilippe for (i = 0; i < a->rz_szB; i++) { 16070b9d0646949bd382758763664d3bf2d6115993aephilippe set_rz_lo_byte(b, i, (UByte)(((Addr)b&0xff) ^ REDZONE_LO_MASK)); 16080b9d0646949bd382758763664d3bf2d6115993aephilippe set_rz_hi_byte(b, i, (UByte)(((Addr)b&0xff) ^ REDZONE_HI_MASK)); 16090b9d0646949bd382758763664d3bf2d6115993aephilippe } 16100b9d0646949bd382758763664d3bf2d6115993aephilippe } 16110b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrNoAccess(a,b)); 16120b9d0646949bd382758763664d3bf2d6115993aephilippe 16130b9d0646949bd382758763664d3bf2d6115993aephilippe# ifdef DEBUG_MALLOC 16140b9d0646949bd382758763664d3bf2d6115993aephilippe (void)blockSane(a,b); 16150b9d0646949bd382758763664d3bf2d6115993aephilippe# endif 16160b9d0646949bd382758763664d3bf2d6115993aephilippe} 16170b9d0646949bd382758763664d3bf2d6115993aephilippe 16182d5b816a492793741082445c8065dd9bc6298fadnethercote// Remove a block from a given list. Does no sanity checking. 16192d5b816a492793741082445c8065dd9bc6298fadnethercotestatic 16207ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercotevoid unlinkBlock ( Arena* a, Block* b, UInt listno ) 1621b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward{ 16226e6588ce963e7c3608c1bfe20b60925d74c1d0canjn vg_assert(listno < N_MALLOC_LISTS); 16232d5b816a492793741082445c8065dd9bc6298fadnethercote if (get_prev_b(b) == b) { 16242d5b816a492793741082445c8065dd9bc6298fadnethercote // Only one element in the list; treat it specially. 16252d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(get_next_b(b) == b); 16262d5b816a492793741082445c8065dd9bc6298fadnethercote a->freelist[listno] = NULL; 16272d5b816a492793741082445c8065dd9bc6298fadnethercote } else { 16282d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b_prev = get_prev_b(b); 16292d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b_next = get_next_b(b); 16302d5b816a492793741082445c8065dd9bc6298fadnethercote a->freelist[listno] = b_prev; 16312d5b816a492793741082445c8065dd9bc6298fadnethercote set_next_b(b_prev, b_next); 16322d5b816a492793741082445c8065dd9bc6298fadnethercote set_prev_b(b_next, b_prev); 16332d5b816a492793741082445c8065dd9bc6298fadnethercote swizzle ( a, listno ); 16342d5b816a492793741082445c8065dd9bc6298fadnethercote } 16352d5b816a492793741082445c8065dd9bc6298fadnethercote set_prev_b(b, NULL); 16362d5b816a492793741082445c8065dd9bc6298fadnethercote set_next_b(b, NULL); 1637b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward} 1638b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward 1639b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward 1640de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 1641e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--- Core-visible functions. ---*/ 1642de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 1643de4a1d01951937632098a6cda45859afa587a06fsewardj 16442d5b816a492793741082445c8065dd9bc6298fadnethercote// Align the request size. 16452d5b816a492793741082445c8065dd9bc6298fadnethercotestatic __inline__ 16467ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercoteSizeT align_req_pszB ( SizeT req_pszB ) 16472d5b816a492793741082445c8065dd9bc6298fadnethercote{ 16487ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT n = VG_MIN_MALLOC_SZB-1; 16492d5b816a492793741082445c8065dd9bc6298fadnethercote return ((req_pszB + n) & (~n)); 16502d5b816a492793741082445c8065dd9bc6298fadnethercote} 16512d5b816a492793741082445c8065dd9bc6298fadnethercote 16526e4b71339ecdf4accc77e86a892718516a531b0fphilippestatic 16536e4b71339ecdf4accc77e86a892718516a531b0fphilippevoid add_one_block_to_stats (Arena* a, SizeT loaned) 16546e4b71339ecdf4accc77e86a892718516a531b0fphilippe{ 16556e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__bytes_on_loan += loaned; 16566e4b71339ecdf4accc77e86a892718516a531b0fphilippe if (a->stats__bytes_on_loan > a->stats__bytes_on_loan_max) { 16576e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__bytes_on_loan_max = a->stats__bytes_on_loan; 16586e4b71339ecdf4accc77e86a892718516a531b0fphilippe if (a->stats__bytes_on_loan_max >= a->next_profile_at) { 16596e4b71339ecdf4accc77e86a892718516a531b0fphilippe /* next profile after 10% more growth */ 16606e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->next_profile_at 16616e4b71339ecdf4accc77e86a892718516a531b0fphilippe = (SizeT)( 16626e4b71339ecdf4accc77e86a892718516a531b0fphilippe (((ULong)a->stats__bytes_on_loan_max) * 105ULL) / 100ULL ); 16636e4b71339ecdf4accc77e86a892718516a531b0fphilippe if (VG_(clo_profile_heap)) 16646e4b71339ecdf4accc77e86a892718516a531b0fphilippe cc_analyse_alloc_arena(arenaP_to_ArenaId (a)); 16656e4b71339ecdf4accc77e86a892718516a531b0fphilippe } 16666e4b71339ecdf4accc77e86a892718516a531b0fphilippe } 16676e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__tot_blocks += (ULong)1; 16686e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__tot_bytes += (ULong)loaned; 16696e4b71339ecdf4accc77e86a892718516a531b0fphilippe} 16706e4b71339ecdf4accc77e86a892718516a531b0fphilippe 16719b29b14fe60370a6cc29e151c9ba359c83ba8129florian/* Allocate a piece of memory of req_pszB bytes on the given arena. 16729b29b14fe60370a6cc29e151c9ba359c83ba8129florian The function may return NULL if (and only if) aid == VG_AR_CLIENT. 16739b29b14fe60370a6cc29e151c9ba359c83ba8129florian Otherwise, the function returns a non-NULL value. */ 167454fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(arena_malloc) ( ArenaId aid, const HChar* cc, SizeT req_pszB ) 1675de4a1d01951937632098a6cda45859afa587a06fsewardj{ 16767ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT req_bszB, frag_bszB, b_bszB; 16770b3fd2daacb085f02b58918e4495be00ba8b418csewardj UInt lno, i; 1678d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj Superblock* new_sb = NULL; 16792d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b = NULL; 1680de4a1d01951937632098a6cda45859afa587a06fsewardj Arena* a; 1681b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward void* v; 16827d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj UWord stats__nsearches = 0; 1683de4a1d01951937632098a6cda45859afa587a06fsewardj 168445f4e7c91119c7d01a59f5e827c67841632c9314sewardj ensure_mm_init(aid); 1685de4a1d01951937632098a6cda45859afa587a06fsewardj a = arenaId_to_ArenaP(aid); 1686de4a1d01951937632098a6cda45859afa587a06fsewardj 16877ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote vg_assert(req_pszB < MAX_PSZB); 16882d5b816a492793741082445c8065dd9bc6298fadnethercote req_pszB = align_req_pszB(req_pszB); 16892d5b816a492793741082445c8065dd9bc6298fadnethercote req_bszB = pszB_to_bszB(a, req_pszB); 1690de4a1d01951937632098a6cda45859afa587a06fsewardj 16919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj // You must provide a cost-center name against which to charge 16929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj // this allocation; it isn't optional. 16939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(cc); 16949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 16952d5b816a492793741082445c8065dd9bc6298fadnethercote // Scan through all the big-enough freelists for a block. 16964ab6d53638999e0d6caa7bb29cb23a8473536b41njn // 16974ab6d53638999e0d6caa7bb29cb23a8473536b41njn // Nb: this scanning might be expensive in some cases. Eg. if you 16984ab6d53638999e0d6caa7bb29cb23a8473536b41njn // allocate lots of small objects without freeing them, but no 16994ab6d53638999e0d6caa7bb29cb23a8473536b41njn // medium-sized objects, it will repeatedly scanning through the whole 17004ab6d53638999e0d6caa7bb29cb23a8473536b41njn // list, and each time not find any free blocks until the last element. 17014ab6d53638999e0d6caa7bb29cb23a8473536b41njn // 17024ab6d53638999e0d6caa7bb29cb23a8473536b41njn // If this becomes a noticeable problem... the loop answers the question 17034ab6d53638999e0d6caa7bb29cb23a8473536b41njn // "where is the first nonempty list above me?" And most of the time, 17044ab6d53638999e0d6caa7bb29cb23a8473536b41njn // you ask the same question and get the same answer. So it would be 17054ab6d53638999e0d6caa7bb29cb23a8473536b41njn // good to somehow cache the results of previous searches. 17064ab6d53638999e0d6caa7bb29cb23a8473536b41njn // One possibility is an array (with N_MALLOC_LISTS elements) of 17074ab6d53638999e0d6caa7bb29cb23a8473536b41njn // shortcuts. shortcut[i] would give the index number of the nearest 17084ab6d53638999e0d6caa7bb29cb23a8473536b41njn // larger list above list i which is non-empty. Then this loop isn't 17094ab6d53638999e0d6caa7bb29cb23a8473536b41njn // necessary. However, we'd have to modify some section [ .. i-1] of the 17104ab6d53638999e0d6caa7bb29cb23a8473536b41njn // shortcut array every time a list [i] changes from empty to nonempty or 17114ab6d53638999e0d6caa7bb29cb23a8473536b41njn // back. This would require care to avoid pathological worst-case 17124ab6d53638999e0d6caa7bb29cb23a8473536b41njn // behaviour. 17134ab6d53638999e0d6caa7bb29cb23a8473536b41njn // 17146e6588ce963e7c3608c1bfe20b60925d74c1d0canjn for (lno = pszB_to_listNo(req_pszB); lno < N_MALLOC_LISTS; lno++) { 17157d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj UWord nsearches_this_level = 0; 1716de4a1d01951937632098a6cda45859afa587a06fsewardj b = a->freelist[lno]; 17172d5b816a492793741082445c8065dd9bc6298fadnethercote if (NULL == b) continue; // If this list is empty, try the next one. 1718de4a1d01951937632098a6cda45859afa587a06fsewardj while (True) { 17197d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj stats__nsearches++; 17207d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj nsearches_this_level++; 17217d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj if (UNLIKELY(nsearches_this_level >= 100) 17227d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj && lno < N_MALLOC_LISTS-1) { 17237d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj /* Avoid excessive scanning on this freelist, and instead 17247d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj try the next one up. But first, move this freelist's 17257d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj start pointer one element along, so as to ensure that 17267d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj subsequent searches of this list don't endlessly 17277d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj revisit only these 100 elements, but in fact slowly 17287d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj progress through the entire list. */ 17297d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj b = a->freelist[lno]; 17307d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj vg_assert(b); // this list must be nonempty! 17317d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->freelist[lno] = get_next_b(b); // step one along 17327d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj break; 17337d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj } 1734d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn b_bszB = get_bszB(b); 17352d5b816a492793741082445c8065dd9bc6298fadnethercote if (b_bszB >= req_bszB) goto obtained_block; // success! 17362d5b816a492793741082445c8065dd9bc6298fadnethercote b = get_next_b(b); 17372d5b816a492793741082445c8065dd9bc6298fadnethercote if (b == a->freelist[lno]) break; // traversed entire freelist 1738de4a1d01951937632098a6cda45859afa587a06fsewardj } 1739de4a1d01951937632098a6cda45859afa587a06fsewardj } 1740de4a1d01951937632098a6cda45859afa587a06fsewardj 17412d5b816a492793741082445c8065dd9bc6298fadnethercote // If we reach here, no suitable block found, allocate a new superblock 17426e6588ce963e7c3608c1bfe20b60925d74c1d0canjn vg_assert(lno == N_MALLOC_LISTS); 17432d5b816a492793741082445c8065dd9bc6298fadnethercote new_sb = newSuperblock(a, req_bszB); 17442d5b816a492793741082445c8065dd9bc6298fadnethercote if (NULL == new_sb) { 17452d5b816a492793741082445c8065dd9bc6298fadnethercote // Should only fail if for client, otherwise, should have aborted 17462d5b816a492793741082445c8065dd9bc6298fadnethercote // already. 17472d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(VG_AR_CLIENT == aid); 17482d5b816a492793741082445c8065dd9bc6298fadnethercote return NULL; 1749de4a1d01951937632098a6cda45859afa587a06fsewardj } 17500b3fd2daacb085f02b58918e4495be00ba8b418csewardj 17510b3fd2daacb085f02b58918e4495be00ba8b418csewardj vg_assert(a->sblocks_used <= a->sblocks_size); 17520b3fd2daacb085f02b58918e4495be00ba8b418csewardj if (a->sblocks_used == a->sblocks_size) { 17530b3fd2daacb085f02b58918e4495be00ba8b418csewardj Superblock ** array; 175417e76ec2a2f1af812eee47dbbcde11bcb7ac1895philippe SysRes sres = VG_(am_mmap_anon_float_valgrind)(sizeof(Superblock *) * 17550b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks_size * 2); 1756cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 17570b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(out_of_memory_NORETURN)("arena_init", sizeof(Superblock *) * 17580b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks_size * 2); 17590b3fd2daacb085f02b58918e4495be00ba8b418csewardj /* NOTREACHED */ 17600b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 176144bd4465581ff28cef83bb39e684a489297d7b71florian array = (Superblock**)(Addr)sr_Res(sres); 17620b3fd2daacb085f02b58918e4495be00ba8b418csewardj for (i = 0; i < a->sblocks_used; ++i) array[i] = a->sblocks[i]; 17630b3fd2daacb085f02b58918e4495be00ba8b418csewardj 17640b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks_size *= 2; 17650b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks = array; 17660b3fd2daacb085f02b58918e4495be00ba8b418csewardj VG_(debugLog)(1, "mallocfree", 1767a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "sblock array for arena `%s' resized to %lu\n", 17680b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->name, a->sblocks_size); 17690b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 17700b3fd2daacb085f02b58918e4495be00ba8b418csewardj 17710b3fd2daacb085f02b58918e4495be00ba8b418csewardj vg_assert(a->sblocks_used < a->sblocks_size); 17720b3fd2daacb085f02b58918e4495be00ba8b418csewardj 17730b3fd2daacb085f02b58918e4495be00ba8b418csewardj i = a->sblocks_used; 17740b3fd2daacb085f02b58918e4495be00ba8b418csewardj while (i > 0) { 17750b3fd2daacb085f02b58918e4495be00ba8b418csewardj if (a->sblocks[i-1] > new_sb) { 17760b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks[i] = a->sblocks[i-1]; 17770b3fd2daacb085f02b58918e4495be00ba8b418csewardj } else { 17780b3fd2daacb085f02b58918e4495be00ba8b418csewardj break; 17790b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 17800b3fd2daacb085f02b58918e4495be00ba8b418csewardj --i; 17810b3fd2daacb085f02b58918e4495be00ba8b418csewardj } 17820b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks[i] = new_sb; 17830b3fd2daacb085f02b58918e4495be00ba8b418csewardj a->sblocks_used++; 17840b3fd2daacb085f02b58918e4495be00ba8b418csewardj 17852d5b816a492793741082445c8065dd9bc6298fadnethercote b = (Block*)&new_sb->payload_bytes[0]; 17862d5b816a492793741082445c8065dd9bc6298fadnethercote lno = pszB_to_listNo(bszB_to_pszB(a, new_sb->n_payload_bytes)); 17872d5b816a492793741082445c8065dd9bc6298fadnethercote mkFreeBlock ( a, b, new_sb->n_payload_bytes, lno); 178894c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj if (VG_(clo_profile_heap)) 178994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj set_cc(b, "admin.free-new-sb-1"); 17902d5b816a492793741082445c8065dd9bc6298fadnethercote // fall through 17912d5b816a492793741082445c8065dd9bc6298fadnethercote 17922d5b816a492793741082445c8065dd9bc6298fadnethercote obtained_block: 17932d5b816a492793741082445c8065dd9bc6298fadnethercote // Ok, we can allocate from b, which lives in list lno. 1794de4a1d01951937632098a6cda45859afa587a06fsewardj vg_assert(b != NULL); 17956e6588ce963e7c3608c1bfe20b60925d74c1d0canjn vg_assert(lno < N_MALLOC_LISTS); 1796de4a1d01951937632098a6cda45859afa587a06fsewardj vg_assert(a->freelist[lno] != NULL); 1797d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn b_bszB = get_bszB(b); 17982d5b816a492793741082445c8065dd9bc6298fadnethercote // req_bszB is the size of the block we are after. b_bszB is the 17992d5b816a492793741082445c8065dd9bc6298fadnethercote // size of what we've actually got. */ 18002d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(b_bszB >= req_bszB); 18012d5b816a492793741082445c8065dd9bc6298fadnethercote 18022d5b816a492793741082445c8065dd9bc6298fadnethercote // Could we split this block and still get a useful fragment? 1803d043de9147df029a98833d0251434f6f2d391bfbsewardj // A block in an unsplittable superblock can never be splitted. 18042d5b816a492793741082445c8065dd9bc6298fadnethercote frag_bszB = b_bszB - req_bszB; 1805d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj if (frag_bszB >= min_useful_bszB(a) 1806d043de9147df029a98833d0251434f6f2d391bfbsewardj && (NULL == new_sb || ! new_sb->unsplittable)) { 18072d5b816a492793741082445c8065dd9bc6298fadnethercote // Yes, split block in two, put the fragment on the appropriate free 18082d5b816a492793741082445c8065dd9bc6298fadnethercote // list, and update b_bszB accordingly. 18092d5b816a492793741082445c8065dd9bc6298fadnethercote // printf( "split %dB into %dB and %dB\n", b_bszB, req_bszB, frag_bszB ); 18102d5b816a492793741082445c8065dd9bc6298fadnethercote unlinkBlock(a, b, lno); 18112d5b816a492793741082445c8065dd9bc6298fadnethercote mkInuseBlock(a, b, req_bszB); 181294c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj if (VG_(clo_profile_heap)) 181394c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj set_cc(b, cc); 18142d5b816a492793741082445c8065dd9bc6298fadnethercote mkFreeBlock(a, &b[req_bszB], frag_bszB, 18152d5b816a492793741082445c8065dd9bc6298fadnethercote pszB_to_listNo(bszB_to_pszB(a, frag_bszB))); 181694c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj if (VG_(clo_profile_heap)) 181794c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj set_cc(&b[req_bszB], "admin.fragmentation-1"); 1818d0e685c71ee79b9f24d51cdef23e7d01448a059bnjn b_bszB = get_bszB(b); 1819de4a1d01951937632098a6cda45859afa587a06fsewardj } else { 18202d5b816a492793741082445c8065dd9bc6298fadnethercote // No, mark as in use and use as-is. 1821de4a1d01951937632098a6cda45859afa587a06fsewardj unlinkBlock(a, b, lno); 18222d5b816a492793741082445c8065dd9bc6298fadnethercote mkInuseBlock(a, b, b_bszB); 182394c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj if (VG_(clo_profile_heap)) 182494c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj set_cc(b, cc); 1825de4a1d01951937632098a6cda45859afa587a06fsewardj } 1826de4a1d01951937632098a6cda45859afa587a06fsewardj 18272d5b816a492793741082445c8065dd9bc6298fadnethercote // Update stats 18287d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj SizeT loaned = bszB_to_pszB(a, b_bszB); 18296e4b71339ecdf4accc77e86a892718516a531b0fphilippe add_one_block_to_stats (a, loaned); 18307d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__nsearches += (ULong)stats__nsearches; 1831de4a1d01951937632098a6cda45859afa587a06fsewardj 1832de4a1d01951937632098a6cda45859afa587a06fsewardj# ifdef DEBUG_MALLOC 1833885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote sanity_check_malloc_arena(aid); 1834de4a1d01951937632098a6cda45859afa587a06fsewardj# endif 1835de4a1d01951937632098a6cda45859afa587a06fsewardj 18362d5b816a492793741082445c8065dd9bc6298fadnethercote v = get_block_payload(a, b); 18372d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert( (((Addr)v) & (VG_MIN_MALLOC_SZB-1)) == 0 ); 1838b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 183972faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Which size should we pass to VALGRIND_MALLOCLIKE_BLOCK ? 184072faf10172c04674ac1e31cf4f7e57be241da7daphilippe // We have 2 possible options: 184172faf10172c04674ac1e31cf4f7e57be241da7daphilippe // 1. The final resulting usable size. 184272faf10172c04674ac1e31cf4f7e57be241da7daphilippe // 2. The initial (non-aligned) req_pszB. 184372faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Memcheck implements option 2 easily, as the initial requested size 184472faf10172c04674ac1e31cf4f7e57be241da7daphilippe // is maintained in the mc_chunk data structure. 184572faf10172c04674ac1e31cf4f7e57be241da7daphilippe // This is not as easy in the core, as there is no such structure. 184672faf10172c04674ac1e31cf4f7e57be241da7daphilippe // (note: using the aligned req_pszB is not simpler than 2, as 184772faf10172c04674ac1e31cf4f7e57be241da7daphilippe // requesting an aligned req_pszB might still be satisfied by returning 184872faf10172c04674ac1e31cf4f7e57be241da7daphilippe // a (slightly) bigger block than requested if the remaining part of 184972faf10172c04674ac1e31cf4f7e57be241da7daphilippe // of a free block is not big enough to make a free block by itself). 185072faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Implement Sol 2 can be done the following way: 185172faf10172c04674ac1e31cf4f7e57be241da7daphilippe // After having called VALGRIND_MALLOCLIKE_BLOCK, the non accessible 185272faf10172c04674ac1e31cf4f7e57be241da7daphilippe // redzone just after the block can be used to determine the 185372faf10172c04674ac1e31cf4f7e57be241da7daphilippe // initial requested size. 185472faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Currently, not implemented => we use Option 1. 185572faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST 185672faf10172c04674ac1e31cf4f7e57be241da7daphilippe (VALGRIND_MALLOCLIKE_BLOCK(v, 185772faf10172c04674ac1e31cf4f7e57be241da7daphilippe VG_(arena_malloc_usable_size)(aid, v), 185872faf10172c04674ac1e31cf4f7e57be241da7daphilippe a->rz_szB, False)); 1859a53462a21bcc732524d99fa25e9b125bb49809e7sewardj 1860a53462a21bcc732524d99fa25e9b125bb49809e7sewardj /* For debugging/testing purposes, fill the newly allocated area 1861a53462a21bcc732524d99fa25e9b125bb49809e7sewardj with a definite value in an attempt to shake out any 1862a53462a21bcc732524d99fa25e9b125bb49809e7sewardj uninitialised uses of the data (by V core / V tools, not by the 1863a53462a21bcc732524d99fa25e9b125bb49809e7sewardj client). Testing on 25 Nov 07 with the values 0x00, 0xFF, 0x55, 1864a53462a21bcc732524d99fa25e9b125bb49809e7sewardj 0xAA showed no differences in the regression tests on 1865a53462a21bcc732524d99fa25e9b125bb49809e7sewardj amd64-linux. Note, is disabled by default. */ 1866a53462a21bcc732524d99fa25e9b125bb49809e7sewardj if (0 && aid != VG_AR_CLIENT) 1867a53462a21bcc732524d99fa25e9b125bb49809e7sewardj VG_(memset)(v, 0xAA, (SizeT)req_pszB); 1868a53462a21bcc732524d99fa25e9b125bb49809e7sewardj 1869b1a26ae9550847cd0a62137f1a680268fcec2aa2jseward return v; 1870de4a1d01951937632098a6cda45859afa587a06fsewardj} 1871de4a1d01951937632098a6cda45859afa587a06fsewardj 1872d043de9147df029a98833d0251434f6f2d391bfbsewardj// If arena has already a deferred reclaimed superblock and 1873d043de9147df029a98833d0251434f6f2d391bfbsewardj// this superblock is still reclaimable, then this superblock is first 1874d043de9147df029a98833d0251434f6f2d391bfbsewardj// reclaimed. 1875d043de9147df029a98833d0251434f6f2d391bfbsewardj// sb becomes then the new arena deferred superblock. 1876d043de9147df029a98833d0251434f6f2d391bfbsewardj// Passing NULL as sb allows to reclaim a deferred sb without setting a new 1877d043de9147df029a98833d0251434f6f2d391bfbsewardj// deferred reclaim. 1878d043de9147df029a98833d0251434f6f2d391bfbsewardjstatic 1879d043de9147df029a98833d0251434f6f2d391bfbsewardjvoid deferred_reclaimSuperblock ( Arena* a, Superblock* sb) 1880d043de9147df029a98833d0251434f6f2d391bfbsewardj{ 1881d043de9147df029a98833d0251434f6f2d391bfbsewardj 1882d043de9147df029a98833d0251434f6f2d391bfbsewardj if (sb == NULL) { 1883d043de9147df029a98833d0251434f6f2d391bfbsewardj if (!a->deferred_reclaimed_sb) 1884d043de9147df029a98833d0251434f6f2d391bfbsewardj // no deferred sb to reclaim now, nothing to do in the future => 1885d043de9147df029a98833d0251434f6f2d391bfbsewardj // return directly. 1886d043de9147df029a98833d0251434f6f2d391bfbsewardj return; 1887d043de9147df029a98833d0251434f6f2d391bfbsewardj 1888d043de9147df029a98833d0251434f6f2d391bfbsewardj VG_(debugLog)(1, "mallocfree", 1889d043de9147df029a98833d0251434f6f2d391bfbsewardj "deferred_reclaimSuperblock NULL " 1890d043de9147df029a98833d0251434f6f2d391bfbsewardj "(prev %p) owner %s/%s\n", 1891d043de9147df029a98833d0251434f6f2d391bfbsewardj a->deferred_reclaimed_sb, 1892d043de9147df029a98833d0251434f6f2d391bfbsewardj a->clientmem ? "CLIENT" : "VALGRIND", a->name ); 1893d043de9147df029a98833d0251434f6f2d391bfbsewardj } else 1894d043de9147df029a98833d0251434f6f2d391bfbsewardj VG_(debugLog)(1, "mallocfree", 1895a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "deferred_reclaimSuperblock at %p (pszB %7lu) %s " 1896d043de9147df029a98833d0251434f6f2d391bfbsewardj "(prev %p) owner %s/%s\n", 1897d043de9147df029a98833d0251434f6f2d391bfbsewardj sb, sb->n_payload_bytes, 1898d043de9147df029a98833d0251434f6f2d391bfbsewardj (sb->unsplittable ? "unsplittable" : ""), 1899d043de9147df029a98833d0251434f6f2d391bfbsewardj a->deferred_reclaimed_sb, 1900d043de9147df029a98833d0251434f6f2d391bfbsewardj a->clientmem ? "CLIENT" : "VALGRIND", a->name ); 1901d043de9147df029a98833d0251434f6f2d391bfbsewardj 1902d043de9147df029a98833d0251434f6f2d391bfbsewardj if (a->deferred_reclaimed_sb && a->deferred_reclaimed_sb != sb) { 1903d043de9147df029a98833d0251434f6f2d391bfbsewardj // If we are deferring another block that the current block deferred, 1904d043de9147df029a98833d0251434f6f2d391bfbsewardj // then if this block can stil be reclaimed, reclaim it now. 1905d043de9147df029a98833d0251434f6f2d391bfbsewardj // Note that we might have a re-deferred reclaim of the same block 1906d043de9147df029a98833d0251434f6f2d391bfbsewardj // with a sequence: free (causing a deferred reclaim of sb) 1907d043de9147df029a98833d0251434f6f2d391bfbsewardj // alloc (using a piece of memory of the deferred sb) 1908d043de9147df029a98833d0251434f6f2d391bfbsewardj // free of the just alloc-ed block (causing a re-defer). 1909d043de9147df029a98833d0251434f6f2d391bfbsewardj UByte* def_sb_start; 1910d043de9147df029a98833d0251434f6f2d391bfbsewardj UByte* def_sb_end; 1911d043de9147df029a98833d0251434f6f2d391bfbsewardj Superblock* def_sb; 1912d043de9147df029a98833d0251434f6f2d391bfbsewardj Block* b; 1913d043de9147df029a98833d0251434f6f2d391bfbsewardj 1914d043de9147df029a98833d0251434f6f2d391bfbsewardj def_sb = a->deferred_reclaimed_sb; 1915d043de9147df029a98833d0251434f6f2d391bfbsewardj def_sb_start = &def_sb->payload_bytes[0]; 1916d043de9147df029a98833d0251434f6f2d391bfbsewardj def_sb_end = &def_sb->payload_bytes[def_sb->n_payload_bytes - 1]; 1917d043de9147df029a98833d0251434f6f2d391bfbsewardj b = (Block *)def_sb_start; 1918d043de9147df029a98833d0251434f6f2d391bfbsewardj vg_assert (blockSane(a, b)); 1919d043de9147df029a98833d0251434f6f2d391bfbsewardj 1920d043de9147df029a98833d0251434f6f2d391bfbsewardj // Check if the deferred_reclaimed_sb is still reclaimable. 1921d043de9147df029a98833d0251434f6f2d391bfbsewardj // If yes, we will execute the reclaim. 1922d043de9147df029a98833d0251434f6f2d391bfbsewardj if (!is_inuse_block(b)) { 1923d043de9147df029a98833d0251434f6f2d391bfbsewardj // b (at the beginning of def_sb) is not in use. 1924d043de9147df029a98833d0251434f6f2d391bfbsewardj UInt b_listno; 1925d043de9147df029a98833d0251434f6f2d391bfbsewardj SizeT b_bszB, b_pszB; 1926d043de9147df029a98833d0251434f6f2d391bfbsewardj b_bszB = get_bszB(b); 1927d043de9147df029a98833d0251434f6f2d391bfbsewardj b_pszB = bszB_to_pszB(a, b_bszB); 1928d043de9147df029a98833d0251434f6f2d391bfbsewardj if (b + b_bszB-1 == (Block*)def_sb_end) { 1929d043de9147df029a98833d0251434f6f2d391bfbsewardj // b (not in use) covers the full superblock. 1930d043de9147df029a98833d0251434f6f2d391bfbsewardj // => def_sb is still reclaimable 1931d043de9147df029a98833d0251434f6f2d391bfbsewardj // => execute now the reclaim of this def_sb. 1932d043de9147df029a98833d0251434f6f2d391bfbsewardj b_listno = pszB_to_listNo(b_pszB); 1933d043de9147df029a98833d0251434f6f2d391bfbsewardj unlinkBlock( a, b, b_listno ); 1934d043de9147df029a98833d0251434f6f2d391bfbsewardj reclaimSuperblock (a, def_sb); 1935d043de9147df029a98833d0251434f6f2d391bfbsewardj a->deferred_reclaimed_sb = NULL; 1936d043de9147df029a98833d0251434f6f2d391bfbsewardj } 1937d043de9147df029a98833d0251434f6f2d391bfbsewardj } 1938d043de9147df029a98833d0251434f6f2d391bfbsewardj } 1939d043de9147df029a98833d0251434f6f2d391bfbsewardj 1940d043de9147df029a98833d0251434f6f2d391bfbsewardj // sb (possibly NULL) becomes the new deferred reclaimed superblock. 1941d043de9147df029a98833d0251434f6f2d391bfbsewardj a->deferred_reclaimed_sb = sb; 1942d043de9147df029a98833d0251434f6f2d391bfbsewardj} 1943d043de9147df029a98833d0251434f6f2d391bfbsewardj 19440b9d0646949bd382758763664d3bf2d6115993aephilippe/* b must be a free block, of size b_bszB. 19450b9d0646949bd382758763664d3bf2d6115993aephilippe If b is followed by another free block, merge them. 19460b9d0646949bd382758763664d3bf2d6115993aephilippe If b is preceeded by another free block, merge them. 19470b9d0646949bd382758763664d3bf2d6115993aephilippe If the merge results in the superblock being fully free, 19480b9d0646949bd382758763664d3bf2d6115993aephilippe deferred_reclaimSuperblock the superblock. */ 19490b9d0646949bd382758763664d3bf2d6115993aephilippestatic void mergeWithFreeNeighbours (Arena* a, Superblock* sb, 19500b9d0646949bd382758763664d3bf2d6115993aephilippe Block* b, SizeT b_bszB) 1951de4a1d01951937632098a6cda45859afa587a06fsewardj{ 19522d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* sb_start; 19532d5b816a492793741082445c8065dd9bc6298fadnethercote UByte* sb_end; 1954a2578651e8b78da13ae261e06f5890d11195d49dnjn Block* other_b; 19550b9d0646949bd382758763664d3bf2d6115993aephilippe SizeT other_bszB; 19560b9d0646949bd382758763664d3bf2d6115993aephilippe UInt b_listno; 19570b9d0646949bd382758763664d3bf2d6115993aephilippe 19580b9d0646949bd382758763664d3bf2d6115993aephilippe sb_start = &sb->payload_bytes[0]; 19590b9d0646949bd382758763664d3bf2d6115993aephilippe sb_end = &sb->payload_bytes[sb->n_payload_bytes - 1]; 19600b9d0646949bd382758763664d3bf2d6115993aephilippe 19610b9d0646949bd382758763664d3bf2d6115993aephilippe b_listno = pszB_to_listNo(bszB_to_pszB(a, b_bszB)); 19620b9d0646949bd382758763664d3bf2d6115993aephilippe 19630b9d0646949bd382758763664d3bf2d6115993aephilippe // See if this block can be merged with its successor. 19640b9d0646949bd382758763664d3bf2d6115993aephilippe // First test if we're far enough before the superblock's end to possibly 19650b9d0646949bd382758763664d3bf2d6115993aephilippe // have a successor. 19660b9d0646949bd382758763664d3bf2d6115993aephilippe other_b = b + b_bszB; 19670b9d0646949bd382758763664d3bf2d6115993aephilippe if (other_b+min_useful_bszB(a)-1 <= (Block*)sb_end) { 19680b9d0646949bd382758763664d3bf2d6115993aephilippe // Ok, we have a successor, merge if it's not in use. 19690b9d0646949bd382758763664d3bf2d6115993aephilippe other_bszB = get_bszB(other_b); 19700b9d0646949bd382758763664d3bf2d6115993aephilippe if (!is_inuse_block(other_b)) { 19710b9d0646949bd382758763664d3bf2d6115993aephilippe // VG_(printf)( "merge-successor\n"); 19720b9d0646949bd382758763664d3bf2d6115993aephilippe# ifdef DEBUG_MALLOC 19730b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(blockSane(a, other_b)); 19740b9d0646949bd382758763664d3bf2d6115993aephilippe# endif 19750b9d0646949bd382758763664d3bf2d6115993aephilippe unlinkBlock( a, b, b_listno ); 19760b9d0646949bd382758763664d3bf2d6115993aephilippe unlinkBlock( a, other_b, 19770b9d0646949bd382758763664d3bf2d6115993aephilippe pszB_to_listNo(bszB_to_pszB(a,other_bszB)) ); 19780b9d0646949bd382758763664d3bf2d6115993aephilippe b_bszB += other_bszB; 19790b9d0646949bd382758763664d3bf2d6115993aephilippe b_listno = pszB_to_listNo(bszB_to_pszB(a, b_bszB)); 19800b9d0646949bd382758763664d3bf2d6115993aephilippe mkFreeBlock( a, b, b_bszB, b_listno ); 19810b9d0646949bd382758763664d3bf2d6115993aephilippe if (VG_(clo_profile_heap)) 19820b9d0646949bd382758763664d3bf2d6115993aephilippe set_cc(b, "admin.free-2"); 19830b9d0646949bd382758763664d3bf2d6115993aephilippe } 19840b9d0646949bd382758763664d3bf2d6115993aephilippe } else { 19850b9d0646949bd382758763664d3bf2d6115993aephilippe // Not enough space for successor: check that b is the last block 19860b9d0646949bd382758763664d3bf2d6115993aephilippe // ie. there are no unused bytes at the end of the Superblock. 19870b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(other_b-1 == (Block*)sb_end); 19880b9d0646949bd382758763664d3bf2d6115993aephilippe } 19890b9d0646949bd382758763664d3bf2d6115993aephilippe 19900b9d0646949bd382758763664d3bf2d6115993aephilippe // Then see if this block can be merged with its predecessor. 19910b9d0646949bd382758763664d3bf2d6115993aephilippe // First test if we're far enough after the superblock's start to possibly 19920b9d0646949bd382758763664d3bf2d6115993aephilippe // have a predecessor. 19930b9d0646949bd382758763664d3bf2d6115993aephilippe if (b >= (Block*)sb_start + min_useful_bszB(a)) { 19940b9d0646949bd382758763664d3bf2d6115993aephilippe // Ok, we have a predecessor, merge if it's not in use. 19950b9d0646949bd382758763664d3bf2d6115993aephilippe other_b = get_predecessor_block( b ); 19960b9d0646949bd382758763664d3bf2d6115993aephilippe other_bszB = get_bszB(other_b); 19970b9d0646949bd382758763664d3bf2d6115993aephilippe if (!is_inuse_block(other_b)) { 19980b9d0646949bd382758763664d3bf2d6115993aephilippe // VG_(printf)( "merge-predecessor\n"); 19990b9d0646949bd382758763664d3bf2d6115993aephilippe unlinkBlock( a, b, b_listno ); 20000b9d0646949bd382758763664d3bf2d6115993aephilippe unlinkBlock( a, other_b, 20010b9d0646949bd382758763664d3bf2d6115993aephilippe pszB_to_listNo(bszB_to_pszB(a, other_bszB)) ); 20020b9d0646949bd382758763664d3bf2d6115993aephilippe b = other_b; 20030b9d0646949bd382758763664d3bf2d6115993aephilippe b_bszB += other_bszB; 20040b9d0646949bd382758763664d3bf2d6115993aephilippe b_listno = pszB_to_listNo(bszB_to_pszB(a, b_bszB)); 20050b9d0646949bd382758763664d3bf2d6115993aephilippe mkFreeBlock( a, b, b_bszB, b_listno ); 20060b9d0646949bd382758763664d3bf2d6115993aephilippe if (VG_(clo_profile_heap)) 20070b9d0646949bd382758763664d3bf2d6115993aephilippe set_cc(b, "admin.free-3"); 20080b9d0646949bd382758763664d3bf2d6115993aephilippe } 20090b9d0646949bd382758763664d3bf2d6115993aephilippe } else { 20100b9d0646949bd382758763664d3bf2d6115993aephilippe // Not enough space for predecessor: check that b is the first block, 20110b9d0646949bd382758763664d3bf2d6115993aephilippe // ie. there are no unused bytes at the start of the Superblock. 20120b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert((Block*)sb_start == b); 20130b9d0646949bd382758763664d3bf2d6115993aephilippe } 20140b9d0646949bd382758763664d3bf2d6115993aephilippe 20150b9d0646949bd382758763664d3bf2d6115993aephilippe /* If the block b just merged is the only block of the superblock sb, 20160b9d0646949bd382758763664d3bf2d6115993aephilippe then we defer reclaim sb. */ 20170b9d0646949bd382758763664d3bf2d6115993aephilippe if ( ((Block*)sb_start == b) && (b + b_bszB-1 == (Block*)sb_end) ) { 20180b9d0646949bd382758763664d3bf2d6115993aephilippe deferred_reclaimSuperblock (a, sb); 20190b9d0646949bd382758763664d3bf2d6115993aephilippe } 20200b9d0646949bd382758763664d3bf2d6115993aephilippe} 20210b9d0646949bd382758763664d3bf2d6115993aephilippe 20220b9d0646949bd382758763664d3bf2d6115993aephilippevoid VG_(arena_free) ( ArenaId aid, void* ptr ) 20230b9d0646949bd382758763664d3bf2d6115993aephilippe{ 20240b9d0646949bd382758763664d3bf2d6115993aephilippe Superblock* sb; 20252d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b; 20260b9d0646949bd382758763664d3bf2d6115993aephilippe SizeT b_bszB, b_pszB; 20277ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote UInt b_listno; 2028de4a1d01951937632098a6cda45859afa587a06fsewardj Arena* a; 2029de4a1d01951937632098a6cda45859afa587a06fsewardj 203045f4e7c91119c7d01a59f5e827c67841632c9314sewardj ensure_mm_init(aid); 2031de4a1d01951937632098a6cda45859afa587a06fsewardj a = arenaId_to_ArenaP(aid); 2032de4a1d01951937632098a6cda45859afa587a06fsewardj 2033e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn if (ptr == NULL) { 2034e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn return; 2035e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 2036e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 20372d5b816a492793741082445c8065dd9bc6298fadnethercote b = get_payload_block(a, ptr); 2038de4a1d01951937632098a6cda45859afa587a06fsewardj 20393187a4e4b005377e66acfb248ca3b7e4050be3edsewardj /* If this is one of V's areas, check carefully the block we're 20403187a4e4b005377e66acfb248ca3b7e4050be3edsewardj getting back. This picks up simple block-end overruns. */ 20413187a4e4b005377e66acfb248ca3b7e4050be3edsewardj if (aid != VG_AR_CLIENT) 20423187a4e4b005377e66acfb248ca3b7e4050be3edsewardj vg_assert(blockSane(a, b)); 2043de4a1d01951937632098a6cda45859afa587a06fsewardj 2044e6f9e3b9180fd4440f45dc533cc0bf1ec8470aa1njn b_bszB = get_bszB(b); 2045e6f9e3b9180fd4440f45dc533cc0bf1ec8470aa1njn b_pszB = bszB_to_pszB(a, b_bszB); 20462d5b816a492793741082445c8065dd9bc6298fadnethercote sb = findSb( a, b ); 20472d5b816a492793741082445c8065dd9bc6298fadnethercote 20487d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan -= b_pszB; 2049e6f9e3b9180fd4440f45dc533cc0bf1ec8470aa1njn 20503187a4e4b005377e66acfb248ca3b7e4050be3edsewardj /* If this is one of V's areas, fill it up with junk to enhance the 20513187a4e4b005377e66acfb248ca3b7e4050be3edsewardj chances of catching any later reads of it. Note, 0xDD is 20523187a4e4b005377e66acfb248ca3b7e4050be3edsewardj carefully chosen junk :-), in that: (1) 0xDDDDDDDD is an invalid 20533187a4e4b005377e66acfb248ca3b7e4050be3edsewardj and non-word-aligned address on most systems, and (2) 0xDD is a 20543187a4e4b005377e66acfb248ca3b7e4050be3edsewardj value which is unlikely to be generated by the new compressed 20553187a4e4b005377e66acfb248ca3b7e4050be3edsewardj Vbits representation for memcheck. */ 20563187a4e4b005377e66acfb248ca3b7e4050be3edsewardj if (aid != VG_AR_CLIENT) 20573187a4e4b005377e66acfb248ca3b7e4050be3edsewardj VG_(memset)(ptr, 0xDD, (SizeT)b_pszB); 20583187a4e4b005377e66acfb248ca3b7e4050be3edsewardj 2059d043de9147df029a98833d0251434f6f2d391bfbsewardj if (! sb->unsplittable) { 2060d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj // Put this chunk back on a list somewhere. 2061d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj b_listno = pszB_to_listNo(b_pszB); 2062d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj mkFreeBlock( a, b, b_bszB, b_listno ); 2063d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj if (VG_(clo_profile_heap)) 2064d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj set_cc(b, "admin.free-1"); 2065d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 20660b9d0646949bd382758763664d3bf2d6115993aephilippe /* Possibly merge b with its predecessor or successor. */ 20670b9d0646949bd382758763664d3bf2d6115993aephilippe mergeWithFreeNeighbours (a, sb, b, b_bszB); 2068d043de9147df029a98833d0251434f6f2d391bfbsewardj 206972faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Inform that ptr has been released. We give redzone size 207072faf10172c04674ac1e31cf4f7e57be241da7daphilippe // 0 instead of a->rz_szB as proper accessibility is done just after. 207172faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_FREELIKE_BLOCK(ptr, 0)); 207272faf10172c04674ac1e31cf4f7e57be241da7daphilippe 207372faf10172c04674ac1e31cf4f7e57be241da7daphilippe // We need to (re-)establish the minimum accessibility needed 207472faf10172c04674ac1e31cf4f7e57be241da7daphilippe // for free list management. E.g. if block ptr has been put in a free 207572faf10172c04674ac1e31cf4f7e57be241da7daphilippe // list and a neighbour block is released afterwards, the 207672faf10172c04674ac1e31cf4f7e57be241da7daphilippe // "lo" and "hi" portions of the block ptr will be accessed to 207772faf10172c04674ac1e31cf4f7e57be241da7daphilippe // glue the 2 blocks together. 207872faf10172c04674ac1e31cf4f7e57be241da7daphilippe // We could mark the whole block as not accessible, and each time 207972faf10172c04674ac1e31cf4f7e57be241da7daphilippe // transiently mark accessible the needed lo/hi parts. Not done as this 208072faf10172c04674ac1e31cf4f7e57be241da7daphilippe // is quite complex, for very little expected additional bug detection. 208172faf10172c04674ac1e31cf4f7e57be241da7daphilippe // fully unaccessible. Note that the below marks the (possibly) merged 208272faf10172c04674ac1e31cf4f7e57be241da7daphilippe // block, not the block corresponding to the ptr argument. 208372faf10172c04674ac1e31cf4f7e57be241da7daphilippe 208472faf10172c04674ac1e31cf4f7e57be241da7daphilippe // First mark the whole block unaccessible. 208572faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_NOACCESS(b, b_bszB)); 208672faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Then mark the relevant administrative headers as defined. 208772faf10172c04674ac1e31cf4f7e57be241da7daphilippe // No need to mark the heap profile portion as defined, this is not 208872faf10172c04674ac1e31cf4f7e57be241da7daphilippe // used for free blocks. 208972faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_DEFINED(b + hp_overhead_szB(), 209072faf10172c04674ac1e31cf4f7e57be241da7daphilippe sizeof(SizeT) + sizeof(void*))); 209172faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_DEFINED(b + b_bszB 209272faf10172c04674ac1e31cf4f7e57be241da7daphilippe - sizeof(SizeT) - sizeof(void*), 209372faf10172c04674ac1e31cf4f7e57be241da7daphilippe sizeof(SizeT) + sizeof(void*))); 20942d5b816a492793741082445c8065dd9bc6298fadnethercote } else { 20950b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(unsplittableBlockSane(a, sb, b)); 2096d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj 209772faf10172c04674ac1e31cf4f7e57be241da7daphilippe // Inform that ptr has been released. Redzone size value 209872faf10172c04674ac1e31cf4f7e57be241da7daphilippe // is not relevant (so we give 0 instead of a->rz_szB) 209972faf10172c04674ac1e31cf4f7e57be241da7daphilippe // as it is expected that the aspacemgr munmap will be used by 210072faf10172c04674ac1e31cf4f7e57be241da7daphilippe // outer to mark the whole superblock as unaccessible. 210172faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_FREELIKE_BLOCK(ptr, 0)); 210272faf10172c04674ac1e31cf4f7e57be241da7daphilippe 2103d043de9147df029a98833d0251434f6f2d391bfbsewardj // Reclaim immediately the unsplittable superblock sb. 2104d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj reclaimSuperblock (a, sb); 2105de4a1d01951937632098a6cda45859afa587a06fsewardj } 2106de4a1d01951937632098a6cda45859afa587a06fsewardj 2107de4a1d01951937632098a6cda45859afa587a06fsewardj# ifdef DEBUG_MALLOC 2108885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote sanity_check_malloc_arena(aid); 2109de4a1d01951937632098a6cda45859afa587a06fsewardj# endif 2110de4a1d01951937632098a6cda45859afa587a06fsewardj 2111de4a1d01951937632098a6cda45859afa587a06fsewardj} 2112de4a1d01951937632098a6cda45859afa587a06fsewardj 2113de4a1d01951937632098a6cda45859afa587a06fsewardj 2114de4a1d01951937632098a6cda45859afa587a06fsewardj/* 2115de4a1d01951937632098a6cda45859afa587a06fsewardj The idea for malloc_aligned() is to allocate a big block, base, and 2116ad4e979f408239dabbaae955d8ffcb84a51a5c85florian then split it into two parts: frag, which is returned to the free 2117ad4e979f408239dabbaae955d8ffcb84a51a5c85florian pool, and align, which is the bit we're really after. Here's 2118de4a1d01951937632098a6cda45859afa587a06fsewardj a picture. L and H denote the block lower and upper overheads, in 21192d5b816a492793741082445c8065dd9bc6298fadnethercote bytes. The details are gruesome. Note it is slightly complicated 2120de4a1d01951937632098a6cda45859afa587a06fsewardj because the initial request to generate base may return a bigger 2121de4a1d01951937632098a6cda45859afa587a06fsewardj block than we asked for, so it is important to distinguish the base 2122de4a1d01951937632098a6cda45859afa587a06fsewardj request size and the base actual size. 2123de4a1d01951937632098a6cda45859afa587a06fsewardj 2124de4a1d01951937632098a6cda45859afa587a06fsewardj frag_b align_b 2125de4a1d01951937632098a6cda45859afa587a06fsewardj | | 2126de4a1d01951937632098a6cda45859afa587a06fsewardj | frag_p | align_p 2127de4a1d01951937632098a6cda45859afa587a06fsewardj | | | | 2128de4a1d01951937632098a6cda45859afa587a06fsewardj v v v v 2129de4a1d01951937632098a6cda45859afa587a06fsewardj 2130de4a1d01951937632098a6cda45859afa587a06fsewardj +---+ +---+---+ +---+ 2131de4a1d01951937632098a6cda45859afa587a06fsewardj | L |----------------| H | L |---------------| H | 2132de4a1d01951937632098a6cda45859afa587a06fsewardj +---+ +---+---+ +---+ 2133de4a1d01951937632098a6cda45859afa587a06fsewardj 2134de4a1d01951937632098a6cda45859afa587a06fsewardj ^ ^ ^ 2135de4a1d01951937632098a6cda45859afa587a06fsewardj | | : 2136de4a1d01951937632098a6cda45859afa587a06fsewardj | base_p this addr must be aligned 2137de4a1d01951937632098a6cda45859afa587a06fsewardj | 2138de4a1d01951937632098a6cda45859afa587a06fsewardj base_b 2139de4a1d01951937632098a6cda45859afa587a06fsewardj 2140de4a1d01951937632098a6cda45859afa587a06fsewardj . . . . . . . 21412d5b816a492793741082445c8065dd9bc6298fadnethercote <------ frag_bszB -------> . . . 21422d5b816a492793741082445c8065dd9bc6298fadnethercote . <------------- base_pszB_act -----------> . 2143de4a1d01951937632098a6cda45859afa587a06fsewardj . . . . . . . 2144de4a1d01951937632098a6cda45859afa587a06fsewardj 2145de4a1d01951937632098a6cda45859afa587a06fsewardj*/ 214654fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(arena_memalign) ( ArenaId aid, const HChar* cc, 21479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj SizeT req_alignB, SizeT req_pszB ) 2148de4a1d01951937632098a6cda45859afa587a06fsewardj{ 21497ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT base_pszB_req, base_pszB_act, frag_bszB; 21502d5b816a492793741082445c8065dd9bc6298fadnethercote Block *base_b, *align_b; 21512d5b816a492793741082445c8065dd9bc6298fadnethercote UByte *base_p, *align_p; 21527ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT saved_bytes_on_loan; 2153de4a1d01951937632098a6cda45859afa587a06fsewardj Arena* a; 2154de4a1d01951937632098a6cda45859afa587a06fsewardj 215545f4e7c91119c7d01a59f5e827c67841632c9314sewardj ensure_mm_init(aid); 2156de4a1d01951937632098a6cda45859afa587a06fsewardj a = arenaId_to_ArenaP(aid); 2157de4a1d01951937632098a6cda45859afa587a06fsewardj 21587ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote vg_assert(req_pszB < MAX_PSZB); 21592d5b816a492793741082445c8065dd9bc6298fadnethercote 21609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj // You must provide a cost-center name against which to charge 21619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj // this allocation; it isn't optional. 21629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(cc); 21639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 2164f5f6ed1729b2914ff902e16561a6410ee97a5ccephilippe // Check that the requested alignment has a plausible size. 21652d5b816a492793741082445c8065dd9bc6298fadnethercote // Check that the requested alignment seems reasonable; that is, is 21662d5b816a492793741082445c8065dd9bc6298fadnethercote // a power of 2. 21672d5b816a492793741082445c8065dd9bc6298fadnethercote if (req_alignB < VG_MIN_MALLOC_SZB 2168f5f6ed1729b2914ff902e16561a6410ee97a5ccephilippe || req_alignB > 16 * 1024 * 1024 2169717cde5bda18d17792d1994c61b6a27408b4b4a7njn || VG_(log2)( req_alignB ) == -1 /* not a power of 2 */) { 217036b6517cbdf2d7e5470d678a1df7b3c22f75b5a4njn VG_(printf)("VG_(arena_memalign)(%p, %lu, %lu)\n" 217136b6517cbdf2d7e5470d678a1df7b3c22f75b5a4njn "bad alignment value %lu\n" 217236b6517cbdf2d7e5470d678a1df7b3c22f75b5a4njn "(it is too small, too big, or not a power of two)", 217336b6517cbdf2d7e5470d678a1df7b3c22f75b5a4njn a, req_alignB, req_pszB, req_alignB ); 2174717cde5bda18d17792d1994c61b6a27408b4b4a7njn VG_(core_panic)("VG_(arena_memalign)"); 21752d5b816a492793741082445c8065dd9bc6298fadnethercote /*NOTREACHED*/ 2176de4a1d01951937632098a6cda45859afa587a06fsewardj } 21772d5b816a492793741082445c8065dd9bc6298fadnethercote // Paranoid 21782d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(req_alignB % VG_MIN_MALLOC_SZB == 0); 2179de4a1d01951937632098a6cda45859afa587a06fsewardj 2180de4a1d01951937632098a6cda45859afa587a06fsewardj /* Required payload size for the aligned chunk. */ 21812d5b816a492793741082445c8065dd9bc6298fadnethercote req_pszB = align_req_pszB(req_pszB); 2182de4a1d01951937632098a6cda45859afa587a06fsewardj 21832d5b816a492793741082445c8065dd9bc6298fadnethercote /* Payload size to request for the big block that we will split up. */ 21842d5b816a492793741082445c8065dd9bc6298fadnethercote base_pszB_req = req_pszB + min_useful_bszB(a) + req_alignB; 2185de4a1d01951937632098a6cda45859afa587a06fsewardj 2186de4a1d01951937632098a6cda45859afa587a06fsewardj /* Payload ptr for the block we are going to split. Note this 2187de4a1d01951937632098a6cda45859afa587a06fsewardj changes a->bytes_on_loan; we save and restore it ourselves. */ 21887d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj saved_bytes_on_loan = a->stats__bytes_on_loan; 2189d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj { 2190d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj /* As we will split the block given back by VG_(arena_malloc), 2191d043de9147df029a98833d0251434f6f2d391bfbsewardj we have to (temporarily) disable unsplittable for this arena, 2192d043de9147df029a98833d0251434f6f2d391bfbsewardj as unsplittable superblocks cannot be splitted. */ 2193d043de9147df029a98833d0251434f6f2d391bfbsewardj const SizeT save_min_unsplittable_sblock_szB 2194d043de9147df029a98833d0251434f6f2d391bfbsewardj = a->min_unsplittable_sblock_szB; 2195d043de9147df029a98833d0251434f6f2d391bfbsewardj a->min_unsplittable_sblock_szB = MAX_PSZB; 2196d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj base_p = VG_(arena_malloc) ( aid, cc, base_pszB_req ); 2197d043de9147df029a98833d0251434f6f2d391bfbsewardj a->min_unsplittable_sblock_szB = save_min_unsplittable_sblock_szB; 2198d8b9346dd1ac022ca02acaefd6efc6a28129c034sewardj } 21997d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan = saved_bytes_on_loan; 2200de4a1d01951937632098a6cda45859afa587a06fsewardj 22018af1a176e19fbe4d4de1851fef5788d0fcaca265tom /* Give up if we couldn't allocate enough space */ 22028af1a176e19fbe4d4de1851fef5788d0fcaca265tom if (base_p == 0) 22038af1a176e19fbe4d4de1851fef5788d0fcaca265tom return 0; 220472faf10172c04674ac1e31cf4f7e57be241da7daphilippe /* base_p was marked as allocated by VALGRIND_MALLOCLIKE_BLOCK 220572faf10172c04674ac1e31cf4f7e57be241da7daphilippe inside VG_(arena_malloc). We need to indicate it is free, then 220672faf10172c04674ac1e31cf4f7e57be241da7daphilippe we need to mark it undefined to allow the below code to access is. */ 220772faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_FREELIKE_BLOCK(base_p, a->rz_szB)); 220872faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MAKE_MEM_UNDEFINED(base_p, base_pszB_req)); 22098af1a176e19fbe4d4de1851fef5788d0fcaca265tom 2210de4a1d01951937632098a6cda45859afa587a06fsewardj /* Block ptr for the block we are going to split. */ 22112d5b816a492793741082445c8065dd9bc6298fadnethercote base_b = get_payload_block ( a, base_p ); 2212de4a1d01951937632098a6cda45859afa587a06fsewardj 2213de4a1d01951937632098a6cda45859afa587a06fsewardj /* Pointer to the payload of the aligned block we are going to 2214de4a1d01951937632098a6cda45859afa587a06fsewardj return. This has to be suitably aligned. */ 22152d5b816a492793741082445c8065dd9bc6298fadnethercote align_p = align_upwards ( base_b + 2 * overhead_szB_lo(a) 22162d5b816a492793741082445c8065dd9bc6298fadnethercote + overhead_szB_hi(a), 2217de4a1d01951937632098a6cda45859afa587a06fsewardj req_alignB ); 22182d5b816a492793741082445c8065dd9bc6298fadnethercote align_b = get_payload_block(a, align_p); 2219de4a1d01951937632098a6cda45859afa587a06fsewardj 2220de4a1d01951937632098a6cda45859afa587a06fsewardj /* The block size of the fragment we will create. This must be big 2221de4a1d01951937632098a6cda45859afa587a06fsewardj enough to actually create a fragment. */ 22222d5b816a492793741082445c8065dd9bc6298fadnethercote frag_bszB = align_b - base_b; 22232d5b816a492793741082445c8065dd9bc6298fadnethercote 22242d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(frag_bszB >= min_useful_bszB(a)); 2225de4a1d01951937632098a6cda45859afa587a06fsewardj 2226de4a1d01951937632098a6cda45859afa587a06fsewardj /* The actual payload size of the block we are going to split. */ 2227089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn base_pszB_act = get_pszB(a, base_b); 2228de4a1d01951937632098a6cda45859afa587a06fsewardj 22292d5b816a492793741082445c8065dd9bc6298fadnethercote /* Create the fragment block, and put it back on the relevant free list. */ 22302d5b816a492793741082445c8065dd9bc6298fadnethercote mkFreeBlock ( a, base_b, frag_bszB, 22312d5b816a492793741082445c8065dd9bc6298fadnethercote pszB_to_listNo(bszB_to_pszB(a, frag_bszB)) ); 223294c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj if (VG_(clo_profile_heap)) 223394c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj set_cc(base_b, "admin.frag-memalign-1"); 2234de4a1d01951937632098a6cda45859afa587a06fsewardj 2235de4a1d01951937632098a6cda45859afa587a06fsewardj /* Create the aligned block. */ 22362d5b816a492793741082445c8065dd9bc6298fadnethercote mkInuseBlock ( a, align_b, 22372d5b816a492793741082445c8065dd9bc6298fadnethercote base_p + base_pszB_act 22382d5b816a492793741082445c8065dd9bc6298fadnethercote + overhead_szB_hi(a) - (UByte*)align_b ); 223994c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj if (VG_(clo_profile_heap)) 224094c8eb4d79d4d6c0658679ca170ee44d2415b940sewardj set_cc(align_b, cc); 2241de4a1d01951937632098a6cda45859afa587a06fsewardj 2242de4a1d01951937632098a6cda45859afa587a06fsewardj /* Final sanity checks. */ 2243472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn vg_assert( is_inuse_block(get_payload_block(a, align_p)) ); 2244de4a1d01951937632098a6cda45859afa587a06fsewardj 2245089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn vg_assert(req_pszB <= get_pszB(a, get_payload_block(a, align_p))); 2246de4a1d01951937632098a6cda45859afa587a06fsewardj 22477d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan += get_pszB(a, get_payload_block(a, align_p)); 22487d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj if (a->stats__bytes_on_loan > a->stats__bytes_on_loan_max) { 22497d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj a->stats__bytes_on_loan_max = a->stats__bytes_on_loan; 22507d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj } 22517d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj /* a->stats__tot_blocks, a->stats__tot_bytes, a->stats__nsearches 22527d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj are updated by the call to VG_(arena_malloc) just a few lines 22537d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj above. So we don't need to update them here. */ 2254de4a1d01951937632098a6cda45859afa587a06fsewardj 2255de4a1d01951937632098a6cda45859afa587a06fsewardj# ifdef DEBUG_MALLOC 2256885dd9184175039b5ddeff4c2b2b644d5a25ec91nethercote sanity_check_malloc_arena(aid); 2257de4a1d01951937632098a6cda45859afa587a06fsewardj# endif 2258de4a1d01951937632098a6cda45859afa587a06fsewardj 22592d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert( (((Addr)align_p) % req_alignB) == 0 ); 2260b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 226172faf10172c04674ac1e31cf4f7e57be241da7daphilippe INNER_REQUEST(VALGRIND_MALLOCLIKE_BLOCK(align_p, 226272faf10172c04674ac1e31cf4f7e57be241da7daphilippe req_pszB, a->rz_szB, False)); 2263b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 22642d5b816a492793741082445c8065dd9bc6298fadnethercote return align_p; 22652d5b816a492793741082445c8065dd9bc6298fadnethercote} 22662d5b816a492793741082445c8065dd9bc6298fadnethercote 22672d5b816a492793741082445c8065dd9bc6298fadnethercote 22688b140dee891a850c09d27f316df913acc7d7bae7njnSizeT VG_(arena_malloc_usable_size) ( ArenaId aid, void* ptr ) 22692d5b816a492793741082445c8065dd9bc6298fadnethercote{ 22702d5b816a492793741082445c8065dd9bc6298fadnethercote Arena* a = arenaId_to_ArenaP(aid); 22712d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b = get_payload_block(a, ptr); 2272089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn return get_pszB(a, b); 2273de4a1d01951937632098a6cda45859afa587a06fsewardj} 2274de4a1d01951937632098a6cda45859afa587a06fsewardj 2275545380e43e6f1669af91e55bf9840a950db6469fbart 2276545380e43e6f1669af91e55bf9840a950db6469fbart// Implementation of mallinfo(). There is no recent standard that defines 2277545380e43e6f1669af91e55bf9840a950db6469fbart// the behavior of mallinfo(). The meaning of the fields in struct mallinfo 2278545380e43e6f1669af91e55bf9840a950db6469fbart// is as follows: 2279545380e43e6f1669af91e55bf9840a950db6469fbart// 2280545380e43e6f1669af91e55bf9840a950db6469fbart// struct mallinfo { 2281545380e43e6f1669af91e55bf9840a950db6469fbart// int arena; /* total space in arena */ 2282545380e43e6f1669af91e55bf9840a950db6469fbart// int ordblks; /* number of ordinary blocks */ 2283545380e43e6f1669af91e55bf9840a950db6469fbart// int smblks; /* number of small blocks */ 2284545380e43e6f1669af91e55bf9840a950db6469fbart// int hblks; /* number of holding blocks */ 2285545380e43e6f1669af91e55bf9840a950db6469fbart// int hblkhd; /* space in holding block headers */ 2286545380e43e6f1669af91e55bf9840a950db6469fbart// int usmblks; /* space in small blocks in use */ 2287545380e43e6f1669af91e55bf9840a950db6469fbart// int fsmblks; /* space in free small blocks */ 2288545380e43e6f1669af91e55bf9840a950db6469fbart// int uordblks; /* space in ordinary blocks in use */ 2289545380e43e6f1669af91e55bf9840a950db6469fbart// int fordblks; /* space in free ordinary blocks */ 2290545380e43e6f1669af91e55bf9840a950db6469fbart// int keepcost; /* space penalty if keep option */ 2291545380e43e6f1669af91e55bf9840a950db6469fbart// /* is used */ 2292545380e43e6f1669af91e55bf9840a950db6469fbart// }; 2293545380e43e6f1669af91e55bf9840a950db6469fbart// 2294545380e43e6f1669af91e55bf9840a950db6469fbart// The glibc documentation about mallinfo (which is somewhat outdated) can 2295545380e43e6f1669af91e55bf9840a950db6469fbart// be found here: 2296545380e43e6f1669af91e55bf9840a950db6469fbart// http://www.gnu.org/software/libtool/manual/libc/Statistics-of-Malloc.html 2297545380e43e6f1669af91e55bf9840a950db6469fbart// 2298545380e43e6f1669af91e55bf9840a950db6469fbart// See also http://bugs.kde.org/show_bug.cgi?id=160956. 2299545380e43e6f1669af91e55bf9840a950db6469fbart// 2300545380e43e6f1669af91e55bf9840a950db6469fbart// Regarding the implementation of VG_(mallinfo)(): we cannot return the 2301545380e43e6f1669af91e55bf9840a950db6469fbart// whole struct as the library function does, because this is called by a 2302545380e43e6f1669af91e55bf9840a950db6469fbart// client request. So instead we use a pointer to do call by reference. 2303088bfb456af4ad2d1d0962f41e91d029bdec993enjnvoid VG_(mallinfo) ( ThreadId tid, struct vg_mallinfo* mi ) 2304088bfb456af4ad2d1d0962f41e91d029bdec993enjn{ 230576dda8f83b96c657e86df7edf821547b0482f474sewardj UWord i, free_blocks, free_blocks_size; 2306c3c98392eb6c417013dc2d3956ce569022f1def7bart Arena* a = arenaId_to_ArenaP(VG_AR_CLIENT); 2307c3c98392eb6c417013dc2d3956ce569022f1def7bart 2308c3c98392eb6c417013dc2d3956ce569022f1def7bart // Traverse free list and calculate free blocks statistics. 2309c3c98392eb6c417013dc2d3956ce569022f1def7bart // This may seem slow but glibc works the same way. 2310c3c98392eb6c417013dc2d3956ce569022f1def7bart free_blocks_size = free_blocks = 0; 2311c3c98392eb6c417013dc2d3956ce569022f1def7bart for (i = 0; i < N_MALLOC_LISTS; i++) { 2312c3c98392eb6c417013dc2d3956ce569022f1def7bart Block* b = a->freelist[i]; 2313c3c98392eb6c417013dc2d3956ce569022f1def7bart if (b == NULL) continue; 2314c3c98392eb6c417013dc2d3956ce569022f1def7bart for (;;) { 2315c3c98392eb6c417013dc2d3956ce569022f1def7bart free_blocks++; 231676dda8f83b96c657e86df7edf821547b0482f474sewardj free_blocks_size += (UWord)get_pszB(a, b); 2317c3c98392eb6c417013dc2d3956ce569022f1def7bart b = get_next_b(b); 2318c3c98392eb6c417013dc2d3956ce569022f1def7bart if (b == a->freelist[i]) break; 2319c3c98392eb6c417013dc2d3956ce569022f1def7bart } 2320c3c98392eb6c417013dc2d3956ce569022f1def7bart } 2321c3c98392eb6c417013dc2d3956ce569022f1def7bart 2322c3c98392eb6c417013dc2d3956ce569022f1def7bart // We don't have fastbins so smblks & fsmblks are always 0. Also we don't 2323545380e43e6f1669af91e55bf9840a950db6469fbart // have a separate mmap allocator so set hblks & hblkhd to 0. 23247d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj mi->arena = a->stats__bytes_mmaped; 2325545380e43e6f1669af91e55bf9840a950db6469fbart mi->ordblks = free_blocks + VG_(free_queue_length); 2326c3c98392eb6c417013dc2d3956ce569022f1def7bart mi->smblks = 0; 2327c3c98392eb6c417013dc2d3956ce569022f1def7bart mi->hblks = 0; 2328c3c98392eb6c417013dc2d3956ce569022f1def7bart mi->hblkhd = 0; 2329c3c98392eb6c417013dc2d3956ce569022f1def7bart mi->usmblks = 0; 2330c3c98392eb6c417013dc2d3956ce569022f1def7bart mi->fsmblks = 0; 23317d1064a3902f14d3c864ecb2c7cdf12f357a2354sewardj mi->uordblks = a->stats__bytes_on_loan - VG_(free_queue_volume); 2332545380e43e6f1669af91e55bf9840a950db6469fbart mi->fordblks = free_blocks_size + VG_(free_queue_volume); 2333c3c98392eb6c417013dc2d3956ce569022f1def7bart mi->keepcost = 0; // may want some value in here 2334088bfb456af4ad2d1d0962f41e91d029bdec993enjn} 2335de4a1d01951937632098a6cda45859afa587a06fsewardj 2336ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florianSizeT VG_(arena_redzone_size) ( ArenaId aid ) 2337ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian{ 2338ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian ensure_mm_init (VG_AR_CLIENT); 2339ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian /* ensure_mm_init will call arena_init if not yet done. 2340ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian This then ensures that the arena redzone size is properly 2341ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian initialised. */ 2342ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian return arenaId_to_ArenaP(aid)->rz_szB; 2343ac3a1d8cbe5d509107e4dfaa56900c0ff825bf45florian} 234445f4e7c91119c7d01a59f5e827c67841632c9314sewardj 2345de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 2346de4a1d01951937632098a6cda45859afa587a06fsewardj/*--- Services layered on top of malloc/free. ---*/ 2347de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 2348de4a1d01951937632098a6cda45859afa587a06fsewardj 234954fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(arena_calloc) ( ArenaId aid, const HChar* cc, 23509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj SizeT nmemb, SizeT bytes_per_memb ) 2351de4a1d01951937632098a6cda45859afa587a06fsewardj{ 23527ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote SizeT size; 235354fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian void* p; 2354e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 2355926ed47f248e22df1583e431d790002ad10b6c17njn size = nmemb * bytes_per_memb; 2356926ed47f248e22df1583e431d790002ad10b6c17njn vg_assert(size >= nmemb && size >= bytes_per_memb);// check against overflow 23573e88418f808bf2840646504481d6a5be1df16541njn 23589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj p = VG_(arena_malloc) ( aid, cc, size ); 23593e88418f808bf2840646504481d6a5be1df16541njn 2360eb577d7ec674109215260d7ade34320527e45ffbflorian if (p != NULL) 2361eb577d7ec674109215260d7ade34320527e45ffbflorian VG_(memset)(p, 0, size); 2362b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 2363de4a1d01951937632098a6cda45859afa587a06fsewardj return p; 2364de4a1d01951937632098a6cda45859afa587a06fsewardj} 2365de4a1d01951937632098a6cda45859afa587a06fsewardj 2366de4a1d01951937632098a6cda45859afa587a06fsewardj 236754fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(arena_realloc) ( ArenaId aid, const HChar* cc, 23689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj void* ptr, SizeT req_pszB ) 2369de4a1d01951937632098a6cda45859afa587a06fsewardj{ 2370de4a1d01951937632098a6cda45859afa587a06fsewardj Arena* a; 2371089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn SizeT old_pszB; 237254fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian void* p_new; 23732d5b816a492793741082445c8065dd9bc6298fadnethercote Block* b; 2374de4a1d01951937632098a6cda45859afa587a06fsewardj 237545f4e7c91119c7d01a59f5e827c67841632c9314sewardj ensure_mm_init(aid); 2376de4a1d01951937632098a6cda45859afa587a06fsewardj a = arenaId_to_ArenaP(aid); 2377de4a1d01951937632098a6cda45859afa587a06fsewardj 23787ac7f7b2ccfc708851a758e9c8dd43ce7d325a10nethercote vg_assert(req_pszB < MAX_PSZB); 2379de4a1d01951937632098a6cda45859afa587a06fsewardj 2380180f698348d977ff834a0938bfb6703fdcb3eef1njn if (NULL == ptr) { 2381180f698348d977ff834a0938bfb6703fdcb3eef1njn return VG_(arena_malloc)(aid, cc, req_pszB); 2382180f698348d977ff834a0938bfb6703fdcb3eef1njn } 2383180f698348d977ff834a0938bfb6703fdcb3eef1njn 2384180f698348d977ff834a0938bfb6703fdcb3eef1njn if (req_pszB == 0) { 2385180f698348d977ff834a0938bfb6703fdcb3eef1njn VG_(arena_free)(aid, ptr); 2386180f698348d977ff834a0938bfb6703fdcb3eef1njn return NULL; 2387180f698348d977ff834a0938bfb6703fdcb3eef1njn } 2388180f698348d977ff834a0938bfb6703fdcb3eef1njn 23892d5b816a492793741082445c8065dd9bc6298fadnethercote b = get_payload_block(a, ptr); 23902d5b816a492793741082445c8065dd9bc6298fadnethercote vg_assert(blockSane(a, b)); 2391de4a1d01951937632098a6cda45859afa587a06fsewardj 2392472cc7c8f2e4676d1c9f4b93cf7bce0bd1a156dcnjn vg_assert(is_inuse_block(b)); 2393089f51f394a17ed460c10a9f4ba748a0c4efea8dnjn old_pszB = get_pszB(a, b); 2394de4a1d01951937632098a6cda45859afa587a06fsewardj 2395e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn if (req_pszB <= old_pszB) { 2396e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn return ptr; 2397e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 2398e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 23999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj p_new = VG_(arena_malloc) ( aid, cc, req_pszB ); 2400828022a947c7b5c6d162a513f75aff5fe498512enjn 2401b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj VG_(memcpy)(p_new, ptr, old_pszB); 2402de4a1d01951937632098a6cda45859afa587a06fsewardj 2403b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj VG_(arena_free)(aid, ptr); 2404e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 2405de4a1d01951937632098a6cda45859afa587a06fsewardj return p_new; 2406de4a1d01951937632098a6cda45859afa587a06fsewardj} 2407de4a1d01951937632098a6cda45859afa587a06fsewardj 2408de4a1d01951937632098a6cda45859afa587a06fsewardj 24090b9d0646949bd382758763664d3bf2d6115993aephilippevoid VG_(arena_realloc_shrink) ( ArenaId aid, 24100b9d0646949bd382758763664d3bf2d6115993aephilippe void* ptr, SizeT req_pszB ) 24110b9d0646949bd382758763664d3bf2d6115993aephilippe{ 24120b9d0646949bd382758763664d3bf2d6115993aephilippe SizeT req_bszB, frag_bszB, b_bszB; 24130b9d0646949bd382758763664d3bf2d6115993aephilippe Superblock* sb; 24140b9d0646949bd382758763664d3bf2d6115993aephilippe Arena* a; 24150b9d0646949bd382758763664d3bf2d6115993aephilippe SizeT old_pszB; 24160b9d0646949bd382758763664d3bf2d6115993aephilippe Block* b; 24170b9d0646949bd382758763664d3bf2d6115993aephilippe 24180b9d0646949bd382758763664d3bf2d6115993aephilippe ensure_mm_init(aid); 24190b9d0646949bd382758763664d3bf2d6115993aephilippe 24200b9d0646949bd382758763664d3bf2d6115993aephilippe a = arenaId_to_ArenaP(aid); 24210b9d0646949bd382758763664d3bf2d6115993aephilippe b = get_payload_block(a, ptr); 24220b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(blockSane(a, b)); 24230b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(is_inuse_block(b)); 24240b9d0646949bd382758763664d3bf2d6115993aephilippe 24250b9d0646949bd382758763664d3bf2d6115993aephilippe old_pszB = get_pszB(a, b); 24260b9d0646949bd382758763664d3bf2d6115993aephilippe req_pszB = align_req_pszB(req_pszB); 24270b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(old_pszB >= req_pszB); 24280b9d0646949bd382758763664d3bf2d6115993aephilippe if (old_pszB == req_pszB) 24290b9d0646949bd382758763664d3bf2d6115993aephilippe return; 24300b9d0646949bd382758763664d3bf2d6115993aephilippe 24310b9d0646949bd382758763664d3bf2d6115993aephilippe sb = findSb( a, b ); 24320b9d0646949bd382758763664d3bf2d6115993aephilippe if (sb->unsplittable) { 24330b9d0646949bd382758763664d3bf2d6115993aephilippe const UByte* sb_start = &sb->payload_bytes[0]; 24340b9d0646949bd382758763664d3bf2d6115993aephilippe const UByte* sb_end = &sb->payload_bytes[sb->n_payload_bytes - 1]; 24350b9d0646949bd382758763664d3bf2d6115993aephilippe Addr frag; 24360b9d0646949bd382758763664d3bf2d6115993aephilippe 24370b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(unsplittableBlockSane(a, sb, b)); 24380b9d0646949bd382758763664d3bf2d6115993aephilippe 24390b9d0646949bd382758763664d3bf2d6115993aephilippe frag = VG_PGROUNDUP((Addr) sb 24400b9d0646949bd382758763664d3bf2d6115993aephilippe + sizeof(Superblock) + pszB_to_bszB(a, req_pszB)); 24410b9d0646949bd382758763664d3bf2d6115993aephilippe frag_bszB = (Addr)sb_end - frag + 1; 24420b9d0646949bd382758763664d3bf2d6115993aephilippe 24430b9d0646949bd382758763664d3bf2d6115993aephilippe if (frag_bszB >= VKI_PAGE_SIZE) { 24440b9d0646949bd382758763664d3bf2d6115993aephilippe SysRes sres; 24450b9d0646949bd382758763664d3bf2d6115993aephilippe 24460b9d0646949bd382758763664d3bf2d6115993aephilippe a->stats__bytes_on_loan -= old_pszB; 24470b9d0646949bd382758763664d3bf2d6115993aephilippe b_bszB = (UByte*)frag - sb_start; 24480b9d0646949bd382758763664d3bf2d6115993aephilippe shrinkInuseBlock(a, b, b_bszB); 24490b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST 24500b9d0646949bd382758763664d3bf2d6115993aephilippe (VALGRIND_RESIZEINPLACE_BLOCK(ptr, 24510b9d0646949bd382758763664d3bf2d6115993aephilippe old_pszB, 24520b9d0646949bd382758763664d3bf2d6115993aephilippe VG_(arena_malloc_usable_size)(aid, ptr), 24530b9d0646949bd382758763664d3bf2d6115993aephilippe a->rz_szB)); 24540b9d0646949bd382758763664d3bf2d6115993aephilippe /* Have the minimum admin headers needed accessibility. */ 24550b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrSzAccess(a, b)); 24560b9d0646949bd382758763664d3bf2d6115993aephilippe a->stats__bytes_on_loan += bszB_to_pszB(a, b_bszB); 24570b9d0646949bd382758763664d3bf2d6115993aephilippe 24580b9d0646949bd382758763664d3bf2d6115993aephilippe sb->n_payload_bytes -= frag_bszB; 24590b9d0646949bd382758763664d3bf2d6115993aephilippe VG_(debugLog)(1, "mallocfree", 2460a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "shrink superblock %p to (pszB %7lu) " 2461a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "owner %s/%s (munmap-ing %p %7lu)\n", 24620b9d0646949bd382758763664d3bf2d6115993aephilippe sb, sb->n_payload_bytes, 24630b9d0646949bd382758763664d3bf2d6115993aephilippe a->clientmem ? "CLIENT" : "VALGRIND", a->name, 24640b9d0646949bd382758763664d3bf2d6115993aephilippe (void*) frag, frag_bszB); 24650b9d0646949bd382758763664d3bf2d6115993aephilippe if (a->clientmem) { 24660b9d0646949bd382758763664d3bf2d6115993aephilippe Bool need_discard = False; 24670b9d0646949bd382758763664d3bf2d6115993aephilippe sres = VG_(am_munmap_client)(&need_discard, 24680b9d0646949bd382758763664d3bf2d6115993aephilippe frag, 24690b9d0646949bd382758763664d3bf2d6115993aephilippe frag_bszB); 24700b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert (!need_discard); 24710b9d0646949bd382758763664d3bf2d6115993aephilippe } else { 24720b9d0646949bd382758763664d3bf2d6115993aephilippe sres = VG_(am_munmap_valgrind)(frag, 24730b9d0646949bd382758763664d3bf2d6115993aephilippe frag_bszB); 24740b9d0646949bd382758763664d3bf2d6115993aephilippe } 24750b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert2(! sr_isError(sres), "shrink superblock munmap failure\n"); 24760b9d0646949bd382758763664d3bf2d6115993aephilippe a->stats__bytes_mmaped -= frag_bszB; 24770b9d0646949bd382758763664d3bf2d6115993aephilippe 24780b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert(unsplittableBlockSane(a, sb, b)); 24790b9d0646949bd382758763664d3bf2d6115993aephilippe } 24800b9d0646949bd382758763664d3bf2d6115993aephilippe } else { 24810b9d0646949bd382758763664d3bf2d6115993aephilippe req_bszB = pszB_to_bszB(a, req_pszB); 24820b9d0646949bd382758763664d3bf2d6115993aephilippe b_bszB = get_bszB(b); 24830b9d0646949bd382758763664d3bf2d6115993aephilippe frag_bszB = b_bszB - req_bszB; 24840b9d0646949bd382758763664d3bf2d6115993aephilippe if (frag_bszB < min_useful_bszB(a)) 24850b9d0646949bd382758763664d3bf2d6115993aephilippe return; 24860b9d0646949bd382758763664d3bf2d6115993aephilippe 24870b9d0646949bd382758763664d3bf2d6115993aephilippe a->stats__bytes_on_loan -= old_pszB; 24880b9d0646949bd382758763664d3bf2d6115993aephilippe shrinkInuseBlock(a, b, req_bszB); 24890b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST 24900b9d0646949bd382758763664d3bf2d6115993aephilippe (VALGRIND_RESIZEINPLACE_BLOCK(ptr, 24910b9d0646949bd382758763664d3bf2d6115993aephilippe old_pszB, 24920b9d0646949bd382758763664d3bf2d6115993aephilippe VG_(arena_malloc_usable_size)(aid, ptr), 24930b9d0646949bd382758763664d3bf2d6115993aephilippe a->rz_szB)); 24940b9d0646949bd382758763664d3bf2d6115993aephilippe /* Have the minimum admin headers needed accessibility. */ 24950b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrSzAccess(a, b)); 24960b9d0646949bd382758763664d3bf2d6115993aephilippe 24970b9d0646949bd382758763664d3bf2d6115993aephilippe mkFreeBlock(a, &b[req_bszB], frag_bszB, 24980b9d0646949bd382758763664d3bf2d6115993aephilippe pszB_to_listNo(bszB_to_pszB(a, frag_bszB))); 24990b9d0646949bd382758763664d3bf2d6115993aephilippe /* Mark the admin headers as accessible. */ 25000b9d0646949bd382758763664d3bf2d6115993aephilippe INNER_REQUEST(mkBhdrAccess(a, &b[req_bszB])); 25010b9d0646949bd382758763664d3bf2d6115993aephilippe if (VG_(clo_profile_heap)) 25020b9d0646949bd382758763664d3bf2d6115993aephilippe set_cc(&b[req_bszB], "admin.fragmentation-2"); 25030b9d0646949bd382758763664d3bf2d6115993aephilippe /* Possibly merge &b[req_bszB] with its free neighbours. */ 25040b9d0646949bd382758763664d3bf2d6115993aephilippe mergeWithFreeNeighbours(a, sb, &b[req_bszB], frag_bszB); 25050b9d0646949bd382758763664d3bf2d6115993aephilippe 25060b9d0646949bd382758763664d3bf2d6115993aephilippe b_bszB = get_bszB(b); 25070b9d0646949bd382758763664d3bf2d6115993aephilippe a->stats__bytes_on_loan += bszB_to_pszB(a, b_bszB); 25080b9d0646949bd382758763664d3bf2d6115993aephilippe } 25090b9d0646949bd382758763664d3bf2d6115993aephilippe 25100b9d0646949bd382758763664d3bf2d6115993aephilippe vg_assert (blockSane(a, b)); 25110b9d0646949bd382758763664d3bf2d6115993aephilippe# ifdef DEBUG_MALLOC 25120b9d0646949bd382758763664d3bf2d6115993aephilippe sanity_check_malloc_arena(aid); 25130b9d0646949bd382758763664d3bf2d6115993aephilippe# endif 25140b9d0646949bd382758763664d3bf2d6115993aephilippe} 25150b9d0646949bd382758763664d3bf2d6115993aephilippe 25166ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn/* Inline just for the wrapper VG_(strdup) below */ 251719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian__inline__ HChar* VG_(arena_strdup) ( ArenaId aid, const HChar* cc, 251819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian const HChar* s ) 25196ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn{ 25206ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn Int i; 25216ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn Int len; 252219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* res; 25236ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn 25246ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn if (s == NULL) 25256ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn return NULL; 25266ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn 25276ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn len = VG_(strlen)(s) + 1; 25289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res = VG_(arena_malloc) (aid, cc, len); 25296ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn 25306ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn for (i = 0; i < len; i++) 25316ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn res[i] = s[i]; 25326ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn return res; 25336ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn} 25346ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn 25356e4b71339ecdf4accc77e86a892718516a531b0fphilippevoid* VG_(arena_perm_malloc) ( ArenaId aid, SizeT size, Int align ) 25366e4b71339ecdf4accc77e86a892718516a531b0fphilippe{ 25376e4b71339ecdf4accc77e86a892718516a531b0fphilippe Arena* a; 25386e4b71339ecdf4accc77e86a892718516a531b0fphilippe 25396e4b71339ecdf4accc77e86a892718516a531b0fphilippe ensure_mm_init(aid); 25406e4b71339ecdf4accc77e86a892718516a531b0fphilippe a = arenaId_to_ArenaP(aid); 25416e4b71339ecdf4accc77e86a892718516a531b0fphilippe 25426e4b71339ecdf4accc77e86a892718516a531b0fphilippe align = align - 1; 25436e4b71339ecdf4accc77e86a892718516a531b0fphilippe size = (size + align) & ~align; 25446e4b71339ecdf4accc77e86a892718516a531b0fphilippe 25456e4b71339ecdf4accc77e86a892718516a531b0fphilippe if (UNLIKELY(a->perm_malloc_current + size > a->perm_malloc_limit)) { 25466e4b71339ecdf4accc77e86a892718516a531b0fphilippe // Get a superblock, but we will not insert it into the superblock list. 25476e4b71339ecdf4accc77e86a892718516a531b0fphilippe // The superblock structure is not needed, so we will use the full 25486e4b71339ecdf4accc77e86a892718516a531b0fphilippe // memory range of it. This superblock is however counted in the 25496e4b71339ecdf4accc77e86a892718516a531b0fphilippe // mmaped statistics. 25506e4b71339ecdf4accc77e86a892718516a531b0fphilippe Superblock* new_sb = newSuperblock (a, size); 25519293361b6eb2e1590673aac27d88bcb4a293b8b2philippe a->perm_malloc_limit = (Addr)&new_sb->payload_bytes[new_sb->n_payload_bytes - 1]; 25526e4b71339ecdf4accc77e86a892718516a531b0fphilippe 25536e4b71339ecdf4accc77e86a892718516a531b0fphilippe // We do not mind starting allocating from the beginning of the superblock 25546e4b71339ecdf4accc77e86a892718516a531b0fphilippe // as afterwards, we "lose" it as a superblock. 25556e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->perm_malloc_current = (Addr)new_sb; 25566e4b71339ecdf4accc77e86a892718516a531b0fphilippe } 25576e4b71339ecdf4accc77e86a892718516a531b0fphilippe 25586e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__perm_blocks += 1; 25596e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->stats__perm_bytes_on_loan += size; 25606e4b71339ecdf4accc77e86a892718516a531b0fphilippe add_one_block_to_stats (a, size); 25616e4b71339ecdf4accc77e86a892718516a531b0fphilippe 25626e4b71339ecdf4accc77e86a892718516a531b0fphilippe a->perm_malloc_current += size; 25636e4b71339ecdf4accc77e86a892718516a531b0fphilippe return (void*)(a->perm_malloc_current - size); 25646e4b71339ecdf4accc77e86a892718516a531b0fphilippe} 25656ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn 2566de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/ 2567996901a830e8e7c3fd8be8f0c675c71f2b108957nethercote/*--- Tool-visible functions. ---*/ 2568e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*------------------------------------------------------------*/ 2569e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 25702d5b816a492793741082445c8065dd9bc6298fadnethercote// All just wrappers to avoid exposing arenas to tools. 2571e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 2572f5d8e65f2c61c399420cde0afd70204e0c0f7c4cflorian// This function never returns NULL. 257354fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(malloc) ( const HChar* cc, SizeT nbytes ) 2574e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 2575a2968ccb86332489ac050bc194da7e3066770bc5florian return VG_(arena_malloc) ( VG_AR_CORE, cc, nbytes ); 2576e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 2577e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 2578e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnvoid VG_(free) ( void* ptr ) 2579e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 2580a2968ccb86332489ac050bc194da7e3066770bc5florian VG_(arena_free) ( VG_AR_CORE, ptr ); 2581e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 2582e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 258354fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(calloc) ( const HChar* cc, SizeT nmemb, SizeT bytes_per_memb ) 2584e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 2585a2968ccb86332489ac050bc194da7e3066770bc5florian return VG_(arena_calloc) ( VG_AR_CORE, cc, nmemb, bytes_per_memb ); 2586e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 2587e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 258854fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorianvoid* VG_(realloc) ( const HChar* cc, void* ptr, SizeT size ) 2589e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 2590a2968ccb86332489ac050bc194da7e3066770bc5florian return VG_(arena_realloc) ( VG_AR_CORE, cc, ptr, size ); 2591e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 2592e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 259377eb20b3865e7b17c7695c7e7a526b52935f593eflorianvoid VG_(realloc_shrink) ( void* ptr, SizeT size ) 259477eb20b3865e7b17c7695c7e7a526b52935f593eflorian{ 259577eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(arena_realloc_shrink) ( VG_AR_CORE, ptr, size ); 259677eb20b3865e7b17c7695c7e7a526b52935f593eflorian} 259777eb20b3865e7b17c7695c7e7a526b52935f593eflorian 259819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(strdup) ( const HChar* cc, const HChar* s ) 25996ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn{ 2600a2968ccb86332489ac050bc194da7e3066770bc5florian return VG_(arena_strdup) ( VG_AR_CORE, cc, s ); 26016ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn} 26026ba622c16fbe0c0b39f24691a1e10f5d0503bb8anjn 26036e4b71339ecdf4accc77e86a892718516a531b0fphilippevoid* VG_(perm_malloc) ( SizeT size, Int align ) 26046e4b71339ecdf4accc77e86a892718516a531b0fphilippe{ 2605a2968ccb86332489ac050bc194da7e3066770bc5florian return VG_(arena_perm_malloc) ( VG_AR_CORE, size, align ); 26066e4b71339ecdf4accc77e86a892718516a531b0fphilippe} 26076e4b71339ecdf4accc77e86a892718516a531b0fphilippe 260832397c0c26fd49181e87a409ad986b9e1b5b0dfdnjn 2609de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 2610717cde5bda18d17792d1994c61b6a27408b4b4a7njn/*--- end ---*/ 2611de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 2612