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