New function VG_(am_mmap_client_heap) which swallows

VG_(am_set_segment_isCH_if_SkAnonC).
Rename VG_(am_set_segment_hasT_if_client_segment) to
VG_(am_set_segment_hasT) passing in an address (because that function
cannot possible take a pointer to a *const* segment). Also assert that
the segment containing the address is a client segment. Everything else
is a bug.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14993
This commit is contained in:
Florian Krohm 2015-03-07 23:01:14 +00:00
parent f85702628a
commit a016e927bb
4 changed files with 38 additions and 56 deletions

View File

@ -2568,6 +2568,23 @@ SysRes VG_(am_shared_mmap_file_float_valgrind)
fd, offset );
}
/* Convenience wrapper around VG_(am_mmap_anon_float_client) which also
marks the segment as containing the client heap. This is for the benefit
of the leak checker which needs to be able to identify such segments
so as not to use them as sources of roots during leak checks. */
SysRes VG_(am_mmap_client_heap) ( SizeT length, Int prot )
{
SysRes res = VG_(am_mmap_anon_float_client)(length, prot);
if (! sr_isError(res)) {
Addr addr = sr_Res(res);
Int ix = find_nsegment_idx(addr);
nsegments[ix].isCH = True;
}
return res;
}
/* --- --- munmap helper --- --- */
static
@ -2684,33 +2701,15 @@ Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len )
return True;
}
/* 'seg' must have been obtained from VG_(am_find_nsegment), and still valid.
If it denotes a SkAnonC (anonymous client mapping) area, set the .isCH
(is-client-heap) flag for that area. Otherwise do nothing.
(Bizarre interface so that the same code works for both Linux and
AIX and does not impose inefficiencies on the Linux version.) */
void VG_(am_set_segment_isCH_if_SkAnonC)( const NSegment* seg )
/* Set the 'hasT' bit on the segment containing ADDR indicating that
translations have or may have been taken from this segment. ADDR is
expected to belong to a client segment. */
void VG_(am_set_segment_hasT)( Addr addr )
{
aspacem_assert(seg != NULL);
Int i = segAddr_to_index( seg );
if (nsegments[i].kind == SkAnonC) {
nsegments[i].isCH = True;
} else {
aspacem_assert(nsegments[i].isCH == False);
}
}
/* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the
segment's hasT bit (has-cached-code) if this is a client segment,
i.e. SkFileC, SkAnonC, or SkShmC. */
void VG_(am_set_segment_hasT_if_client_segment)( const NSegment* seg )
{
aspacem_assert(seg != NULL);
Int i = segAddr_to_index( seg );
if (nsegments[i].kind == SkAnonC || nsegments[i].kind == SkFileC ||
nsegments[i].kind == SkShmC) {
nsegments[i].hasT = True;
}
Int i = find_nsegment_idx(addr);
SegKind kind = nsegments[i].kind;
aspacem_assert(kind == SkAnonC || kind == SkFileC || kind == SkShmC);
nsegments[i].hasT = True;
}

View File

@ -853,15 +853,11 @@ Superblock* newSuperblock ( Arena* a, SizeT cszB )
if (a->clientmem) {
// client allocation -- return 0 to client if it fails
sres = VG_(am_mmap_anon_float_client)
sres = VG_(am_mmap_client_heap)
( cszB, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC );
if (sr_isError(sres))
return 0;
sb = (Superblock*)(Addr)sr_Res(sres);
// Mark this segment as containing client heap. The leak
// checker needs to be able to identify such segments so as not
// to use them as sources of roots during leak checks.
VG_(am_set_segment_isCH_if_SkAnonC)( VG_(am_find_nsegment)( (Addr)sb ) );
} else {
// non-client allocation -- abort if it fails
sres = VG_(am_mmap_anon_float_valgrind)( cszB );

View File

@ -1765,21 +1765,12 @@ Bool VG_(translate) ( ThreadId tid,
vg_assert(tres.n_sc_extents >= 0 && tres.n_sc_extents <= 3);
vg_assert(tmpbuf_used <= N_TMPBUF);
vg_assert(tmpbuf_used > 0);
/* Tell aspacem of all segments that have had translations taken
from them. Optimisation: don't re-look up vge.base[0] since seg
should already point to it. */
vg_assert( vge.base[0] == addr );
/* set 'translations taken from this segment' flag */
VG_(am_set_segment_hasT_if_client_segment)( seg );
} /* END new scope specially for 'seg' */
for (i = 1; i < vge.n_used; i++) {
NSegment const* seg
= VG_(am_find_nsegment)( vge.base[i] );
/* set 'translations taken from this segment' flag */
VG_(am_set_segment_hasT_if_client_segment)( seg );
/* Tell aspacem of all segments that have had translations taken
from them. */
for (i = 0; i < vge.n_used; i++) {
VG_(am_set_segment_hasT)( vge.base[i] );
}
/* Copy data at trans_addr into the translation cache. */

View File

@ -231,6 +231,10 @@ extern SysRes VG_(am_mmap_file_float_valgrind)
extern SysRes VG_(am_shared_mmap_file_float_valgrind)
( SizeT length, UInt prot, Int fd, Off64T offset );
/* Convenience wrapper around VG_(am_mmap_anon_float_client) which also
marks the segment as containing the client heap. */
extern SysRes VG_(am_mmap_client_heap) ( SizeT length, Int prot );
/* Unmap the given address range and update the segment array
accordingly. This fails if the range isn't valid for the client.
If *need_discard is True after a successful return, the caller
@ -245,18 +249,10 @@ extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
suitable segment. */
extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len );
/* 'seg' must be NULL or have been obtained from
VG_(am_find_nsegment), and still valid. If non-NULL, and if it
denotes a SkAnonC (anonymous client mapping) area, set the .isCH
(is-client-heap) flag for that area. Otherwise do nothing.
(Bizarre interface so that the same code works for both Linux and
AIX and does not impose inefficiencies on the Linux version.) */
extern void VG_(am_set_segment_isCH_if_SkAnonC)( const NSegment* seg );
/* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the
segment's hasT bit (has-cached-code) if this is a client segment,
i.e. SkFileC, SkAnonC, or SkShmC. */
extern void VG_(am_set_segment_hasT_if_client_segment)( const NSegment* );
/* Set the 'hasT' bit on the segment containing ADDR indicating that
translations have or may have been taken from this segment. ADDR is
expected to belong to a client segment. */
extern void VG_(am_set_segment_hasT)( Addr addr );
/* --- --- --- reservations --- --- --- */