|
From: <sv...@va...> - 2005-09-11 23:00:33
|
Author: sewardj
Date: 2005-09-12 00:00:24 +0100 (Mon, 12 Sep 2005)
New Revision: 4619
Log:
Infrastructure to deal with resizable reservations and resizable
anonymous mappings.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/pub_core_aspacemgr.h
Modified: branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-11 12:48:2=
3 UTC (rev 4618)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-11 23:00:2=
4 UTC (rev 4619)
@@ -1472,16 +1472,6 @@
#define Addr_MAX ((Addr)(-1ULL))
=20
=20
-static HChar* showMovable ( Movable m )
-{
- switch (m) {
- case MoFixed: return "Fixed";
- case MoDownOK: return "MoveD";
- case MoUpOK: return "MoveU";
- default: return "?????";
- }
-}
-
/* Array [0 .. nsegments_used-1] of all mappings. */
/* Sorted by .addr field. */
/* I: len may not be zero. */
@@ -1492,6 +1482,22 @@
static Int nsegments_used =3D 0;
=20
=20
+/* Given a pointer to a seg, tries to figure out which one it is in
+ nsegments[..]. Very paranoid. */
+static Int segAddr_to_index ( NSegment* seg )
+{
+ Int i;
+ if (seg < &nsegments[0] || seg >=3D &nsegments[nsegments_used])
+ return -1;
+ i =3D (seg - &nsegments[0]) / sizeof(NSegment);
+ if (i < 0 || i >=3D nsegments_used)
+ return -1;
+ if (seg =3D=3D &nsegments[i])
+ return i;
+ return -1;
+}
+
+
ULong VG_(aspacem_get_anonsize_total)( void )
{
Int i;
@@ -1689,9 +1695,7 @@
seg->isClient =3D False;
seg->start =3D 0;
seg->end =3D 0;
- seg->moveLo =3D MoFixed;
- seg->moveHi =3D MoFixed;
- seg->maxlen =3D 0;
+ seg->smode =3D SmFixed;
seg->dev =3D 0;
seg->ino =3D 0;
seg->offset =3D 0;
@@ -1722,6 +1726,16 @@
}
}
=20
+static HChar* show_ShrinkMode ( ShrinkMode sm )
+{
+ switch (sm) {
+ case SmLower: return "SmLower";
+ case SmUpper: return "SmUpper";
+ case SmFixed: return "SmFixed";
+ default: return "Sm?????";
+ }
+}
+
static void show_Addr_concisely ( /*OUT*/HChar* buf, Addr aA )
{
HChar* fmt;
@@ -1796,7 +1810,7 @@
case SkResvn:
VG_(debugLog)(
logLevel, "aspacem",
- "%3d: %s %08llx-%08llx %s %c%c%c%c (%s,%s,%llu)\n",
+ "%3d: %s %08llx-%08llx %s %c%c%c%c %s\n",
segNo,
show_seg_kind(seg),
(ULong)seg->start,
@@ -1806,9 +1820,7 @@
seg->hasW ? 'w' : '-',=20
seg->hasX ? 'x' : '-',=20
seg->hasT ? 'T' : '-',=20
- showMovable(seg->moveLo),
- showMovable(seg->moveHi),
-(ULong)seg->maxlen
+ show_ShrinkMode(seg->smode)
);
break;
=20
@@ -2311,6 +2323,149 @@
}
=20
=20
+/* See comment on prototype in pub_core_aspacemgr.h for a description
+ of this. */
+Bool VG_(create_reservation) ( Addr start, SizeT length,=20
+ ShrinkMode smode, SSizeT extra )
+{
+ Int startI, endI;
+ NSegment seg;
+
+ /* start and end, not taking into account the extra space. */
+ Addr start1 =3D start;
+ Addr end1 =3D start + length - 1;
+
+ /* start and end, taking into account the extra space. */
+ Addr start2 =3D start1;
+ Addr end2 =3D end1;
+
+ if (extra < 0) start2 +=3D extra; // this moves it down :-)
+ if (extra > 0) end2 +=3D extra;
+
+ aspacem_assert(VG_IS_PAGE_ALIGNED(start));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(start+length-1));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(start2));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(end2));
+
+ startI =3D find_nsegment_idx( start2 );
+ endI =3D find_nsegment_idx( end2 );
+
+ /* If the start and end points don't fall within the same (free)
+ segment, we're hosed. This does rely on the assumption that all
+ mergeable adjacent segments can be merged, but add_segment()
+ should ensure that. */
+ if (startI !=3D endI)
+ return False;
+
+ if (nsegments[startI].kind !=3D SkFree)
+ return False;
+
+ /* Looks good - make the reservation. */
+ aspacem_assert(nsegments[startI].start <=3D start2);
+ aspacem_assert(end2 <=3D nsegments[startI].end);
+
+ init_nsegment( &seg );
+ seg.kind =3D SkResvn;
+ seg.start =3D start1; /* NB: extra space is not included in the rese=
rvation. */
+ seg.end =3D end1;
+ seg.smode =3D smode;
+ add_segment( &seg );
+ return True;
+}
+
+
+/* See comment on prototype in pub_core_aspacemgr.h for a description
+ of this. */
+Bool VG_(extend_into_adjacent_reservation)( NSegment* seg, SSizeT delta =
)
+{
+ Int segA, segR;
+ UInt prot;
+ SysRes sres;
+
+ /* Find the segment array index for SEG. If the assertion fails it
+ probably means you passed in a bogus SEG. */
+ segA =3D segAddr_to_index( seg );
+ aspacem_assert(segA >=3D 0 && segA < nsegments_used);
+
+ if (nsegments[segA].kind !=3D SkAnon)
+ return False;
+
+ if (delta =3D=3D 0)
+ return True;
+
+ prot =3D (nsegments[segA].hasR ? VKI_PROT_READ : 0)
+ | (nsegments[segA].hasW ? VKI_PROT_WRITE : 0)
+ | (nsegments[segA].hasX ? VKI_PROT_EXEC : 0);
+
+ aspacem_assert(VG_IS_PAGE_ALIGNED(delta<0 ? -delta : delta));
+
+ if (delta > 0) {
+
+ /* Extending the segment forwards. */
+ segR =3D segA+1;
+ if (segR >=3D nsegments_used
+ || nsegments[segR].kind !=3D SkResvn
+ || nsegments[segR].smode !=3D SmLower
+ || nsegments[segR].start !=3D nsegments[segA].end + 1
+ || delta > (nsegments[segR].end - nsegments[segR].start + 1))
+ return False;
+ =20
+ /* Extend the kernel's mapping. */
+ sres =3D do_mmap_NATIVE( nsegments[segR].start, delta,
+ prot,
+ VKI_MAP_FIXED|VKI_MAP_PRIVATE
+ |VKI_MAP_ANONYMOUS, 0, 0 );
+ if (sres.isError)
+ return False; /* kernel bug if this happens? */
+ if (sres.val !=3D nsegments[segR].start) {
+ /* kernel bug if this happens? */
+ do_munmap_NATIVE( sres.val, delta );
+ return False;
+ }
+
+ /* Ok, success with the kernel. Update our structures. */
+ nsegments[segR].start +=3D delta;
+ nsegments[segA].end +=3D delta;
+ aspacem_assert(nsegments[segR].start <=3D nsegments[segR].end);
+
+ } else {
+
+ /* Extending the segment backwards. */
+ delta =3D -delta;
+ aspacem_assert(delta > 0);
+
+ segR =3D segA-1;
+ if (segR < 0
+ || nsegments[segR].kind !=3D SkResvn
+ || nsegments[segR].smode !=3D SmUpper
+ || nsegments[segR].end + 1 !=3D nsegments[segA].start
+ || delta > (nsegments[segR].end - nsegments[segR].start + 1))
+ return False;
+ =20
+ /* Extend the kernel's mapping. */
+ sres =3D do_mmap_NATIVE( nsegments[segA].start-delta, delta,
+ prot,
+ VKI_MAP_FIXED|VKI_MAP_PRIVATE
+ |VKI_MAP_ANONYMOUS, 0, 0 );
+ if (sres.isError)
+ return False; /* kernel bug if this happens? */
+ if (sres.val !=3D nsegments[segA].start-delta) {
+ /* kernel bug if this happens? */
+ do_munmap_NATIVE( sres.val, delta );
+ return False;
+ }
+
+ /* Ok, success with the kernel. Update our structures. */
+ nsegments[segR].end -=3D delta;
+ nsegments[segA].start -=3D delta;
+ aspacem_assert(nsegments[segR].start <=3D nsegments[segR].end);
+
+ }
+
+ return True;
+}
+
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: branches/ASPACEM/coregrind/pub_core_aspacemgr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-11 12:48:23 U=
TC (rev 4618)
+++ branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-11 23:00:24 U=
TC (rev 4619)
@@ -161,17 +161,8 @@
HChar
VgStack[VG_STACK_GUARD_SZB + VG_STACK_ACTIVE_SZB + VG_STACK_GUARD_SZB=
];
=20
-/* Describes the ways in which the ends of a segment may be moved. */
typedef
enum {
- MoFixed, // usual case -- cannot be moved
- MoDownOK, // can be moved to a lower address
- MoUpOK // can be moved to a higher address
- }
- Movable;
-
-typedef
- enum {
SkFree, // unmapped space
SkAnon, // anonymous mapping
SkFile, // mapping to a file
@@ -179,6 +170,14 @@
}
MKind;
=20
+typedef
+ enum {
+ SmLower, // lower end can move up
+ SmFixed, // cannot be shrunk
+ SmUpper // upper end can move down
+ }
+ ShrinkMode;
+
/* Describes a segment. Invariants:
=20
kind =3D=3D SkFree:
@@ -213,10 +212,8 @@
/* Extent (SkFree, SkAnon, SkFile, SkResvn) */
Addr start; // lowest address in range
Addr end; // highest address in range
- /* Resizability (SkAnon, SkResvn only) */
- Movable moveLo; // if yes, can lower end be moved
- Movable moveHi; // if yes, can upper end be moved
- SizeT maxlen; // if yes, what's the max size?
+ /* Shrinkable? (SkResvn only) */
+ ShrinkMode smode;
/* Associated file (SkFile only) */
UInt dev;
UInt ino;
@@ -233,7 +230,7 @@
NSegment;
=20
=20
-/* Takes a pointer to the sp at the time V gained control. This is
+/* Takes a pointer to the SP at the time V gained control. This is
taken to be the highest usable address (more or less). Based on
that (and general consultation of tea leaves, etc) return a
suggested end address for the client's stack. */
@@ -273,7 +270,33 @@
extern SysRes VG_(munmap_client)( Addr base, SizeT length );
=20
extern NSegment* VG_(find_nsegment) ( Addr a );
+extern NSegment* VG_(next_nsegment) ( NSegment* here, Bool fwds );
=20
+/* Create a reservation from START .. START+LENGTH-1, with the given
+ ShrinkMode. When checking whether the reservation can be created,
+ also ensure that at least abs(EXTRA) extra free bytes will remain
+ above (> 0) or below (< 0) the reservation.
+
+ The reservation will only be created if it, plus the extra-zone,
+ falls entirely within a single free segment. The returned Bool
+ indicates whether the creation succeeded. */
+extern=20
+Bool VG_(create_reservation) ( Addr start, SizeT length,=20
+ ShrinkMode smode, SSizeT extra );
+
+
+/* Let SEG be an anonymous mapping. This fn extends the mapping by
+ DELTA bytes, taking the space from a reservation section which must
+ be adjacent. If DELTA is positive, the segment is extended
+ forwards in the address space, and the reservation must be the next
+ one along. If DELTA is negative, the segment is extended backwards
+ in the address space and the reservation must be the previous one.
+ DELTA must be page aligned and must not exceed the size of the
+ reservation segment. */
+extern
+Bool VG_(extend_into_adjacent_reservation) ( NSegment* seg, SSizeT delta=
);
+
+
#endif // __PUB_CORE_ASPACEMGR_H
=20
/*--------------------------------------------------------------------*/
|