https://github.com/Unipisa/CMM
Tip revision: 55778ad8b99c136e1886959c1f1333c776df14e1 authored by Giuseppe Attardi on 15 May 1997, 06:24:54 UTC
1.8 -
1.8 -
Tip revision: 55778ad
patch-7
diff -c /home/omega/attardi/posso/cmm/ChangeLog /project/posso/cmm/curr/cmm/ChangeLog
*** /home/omega/attardi/posso/cmm/ChangeLog Thu May 15 08:25:57 1997
--- /project/posso/cmm/curr/cmm/ChangeLog Fri Mar 28 20:20:58 1997
***************
*** 1,18 ****
- Thu May 15 08:24:54 1997 Giuseppe Attardi <attardi@omega>
-
- * cmm.cpp (collect): fixed bug when scavenge() allocates objects
- in page already scanned by the collector. This happens when
- current page contains pointer to large object, whose page gets
- promoted and added to the queue. When this page is scanned,
- objects it contains are moved to the current page, which however
- has been already scanned.
-
- Wed Apr 16 23:09:22 1997 Giuseppe Attardi <attardi@omega>
-
- * memory.cpp: added CmmSVR4DataStart()
-
- * machine.h: use CmmSVR4DataStart for SysV
-
Fri Mar 28 19:45:24 1997 Giuseppe Attardi <attardi@omega>
* cmm.cpp (collect): revised to use roots.begin() and roots.get()
--- 1,3 ----
***************
*** 27,33 ****
promotePage((GCP)*fp++);
}
! * cmm.h (Set): revised (count -> last)
* cmm.cpp (RootAreas): revised to make it similar to Set above
(added begin() and get()). It also clears the new array.
--- 12,18 ----
promotePage((GCP)*fp++);
}
! * cmm.h (Set): revised (no longer uses member count)
* cmm.cpp (RootAreas): revised to make it similar to Set above
(added begin() and get()). It also clears the new array.
diff -c /home/omega/attardi/posso/cmm/cmm.cpp /project/posso/cmm/curr/cmm/cmm.cpp
*** /home/omega/attardi/posso/cmm/cmm.cpp Thu May 15 09:00:51 1997
--- /project/posso/cmm/curr/cmm/cmm.cpp Fri Mar 28 20:04:32 1997
***************
*** 54,60 ****
/* Version tag */
! char* Cmm::version = "CMM 1.8.6";
/*---------------------------------------------------------------------------*
*
--- 54,60 ----
/* Version tag */
! char* Cmm::version = "CMM 1.8.5";
/*---------------------------------------------------------------------------*
*
***************
*** 286,294 ****
public:
RootAreas()
{
- last = 0;
max = 0;
! freed = 0;
entries = NULL;
}
--- 286,293 ----
public:
RootAreas()
{
max = 0;
! free = 0;
entries = NULL;
}
***************
*** 297,349 ****
# define setIncrement 10
int i;
! if (freed)
{
! for (i = 0; i < last; i++)
if (entries[i].addr == NULL)
! {
! freed--;
! break;
! }
}
else
{
! if (last == max)
! {
! RootArea *np;
! max += setIncrement;
! np = ::new RootArea[max];
! for (i = 0; i < last; i++)
! np[i] = entries[i];
! // clear the rest
! for (; i < max; i++)
! np[i].addr = NULL;
! if (entries) ::delete entries;
! entries = np;
! }
! i = last++;
}
entries[i].addr = (GCP)addr;
entries[i].bytes = bytes;
}
!
void erase(void* addr)
{
int i;
!
! for (i = 0; i < last; i++)
if (entries[i].addr == addr)
{
entries[i].addr = NULL;
! freed++;
return;
}
}
!
RootArea* get()
{
// look for a non empty entry
! while (iter < last)
{
if (entries[iter].addr)
return &entries[iter++];
--- 296,345 ----
# define setIncrement 10
int i;
! if (free)
{
! for (i = 0; i < max; i++)
if (entries[i].addr == NULL)
! break;
}
else
{
! RootArea *np;
! int count = max;
! max += setIncrement;
! free = setIncrement;
! np = ::new RootArea[max];
! for (i = 0; i < count; i++)
! np[i] = entries[i];
! // clear the rest
! for (; i < max; i++)
! np[i].addr = NULL;
! if (entries) ::delete entries;
! entries = np;
! i = count;
}
entries[i].addr = (GCP)addr;
entries[i].bytes = bytes;
+ free--;
}
!
void erase(void* addr)
{
int i;
!
! for (i = 0; i < max; i++)
if (entries[i].addr == addr)
{
entries[i].addr = NULL;
! free++;
return;
}
}
!
RootArea* get()
{
// look for a non empty entry
! while (iter < max)
{
if (entries[iter].addr)
return &entries[iter++];
***************
*** 353,366 ****
// No more entries;
return (RootArea*)NULL;
}
!
! void begin() { iter = 0; }
!
! private:
RootArea* entries;
- int last;
int max;
! int freed;
int iter;
};
--- 349,361 ----
// No more entries;
return (RootArea*)NULL;
}
!
! void begin() { iter = 0;}
!
! private:
RootArea* entries;
int max;
! int free;
int iter;
};
***************
*** 399,405 ****
environmentValue(char *name, int &value)
{
char* valuestring = getenv(name);
!
if (valuestring != NULL)
{
value = atoi(valuestring);
--- 394,400 ----
environmentValue(char *name, int &value)
{
char* valuestring = getenv(name);
!
if (valuestring != NULL)
{
value = atoi(valuestring);
***************
*** 416,422 ****
*/
int CmmObject::words()
{
!
register int length = 1;
register int index = WORD_INDEX(this+1);
int shift = BIT_INDEX(this+1);
--- 411,417 ----
*/
int CmmObject::words()
{
!
register int length = 1;
register int index = WORD_INDEX(this+1);
int shift = BIT_INDEX(this+1);
***************
*** 426,432 ****
nextPage += pageGroup[nextPage];
int max = ((int)pageToGCP(nextPage) - (int)this)
/ (bitsPerWord * bytesPerWord);
!
do
{
do
--- 421,427 ----
nextPage += pageGroup[nextPage];
int max = ((int)pageToGCP(nextPage) - (int)this)
/ (bitsPerWord * bytesPerWord);
!
do
{
do
***************
*** 483,489 ****
* shift = 0;
* }
*}
! */
#endif
/*---------------------------------------------------------------------------*
--- 478,484 ----
* shift = 0;
* }
*}
! */
#endif
/*---------------------------------------------------------------------------*
***************
*** 556,577 ****
*---------------------------------------------------------------------------*/
#if !HEADER_SIZE || defined(MARKING)
! # define tableFraction (sizeof(int)*2 /* pageLink, pageHeap */\
! + sizeof(short)*2 /* pageSpace, pageGroup */\
! + wordsPerPage/bitsPerWord*bytesPerWord /* objectMap */\
! + wordsPerPage/bitsPerWord*bytesPerWord) /* liveMap */
#else
! # define tableFraction (sizeof(int)*2 /* pageLink, pageHeap */\
! + sizeof(short)*2 /* pageSpace, pageGroup */\
! + wordsPerPage/bitsPerWord*bytesPerWord) /* objectMap */
#endif
!
void
CmmInit()
{
char *heap;
Page i;
!
/* Log actual heap parameters if from environment or logging */
if ((environmentValue("CMM_MINHEAP", Cmm::minHeap)
| environmentValue("CMM_MAXHEAP", Cmm::maxHeap)
--- 551,572 ----
*---------------------------------------------------------------------------*/
#if !HEADER_SIZE || defined(MARKING)
! # define tableFraction (sizeof(int)*2 /* pageLink, pageHeap */\
! + sizeof(short)*2 /* pageSpace, pageGroup */\
! + wordsPerPage/bitsPerWord*bytesPerWord /* objectMap */\
! + wordsPerPage/bitsPerWord*bytesPerWord) /* liveMap */
#else
! # define tableFraction (sizeof(int)*2 /* pageLink, pageHeap */\
! + sizeof(short)*2 /* pageSpace, pageGroup */\
! + wordsPerPage/bitsPerWord*bytesPerWord) /* objectMap */
#endif
!
void
CmmInit()
{
char *heap;
Page i;
!
/* Log actual heap parameters if from environment or logging */
if ((environmentValue("CMM_MINHEAP", Cmm::minHeap)
| environmentValue("CMM_MAXHEAP", Cmm::maxHeap)
***************
*** 585,595 ****
fprintf(stderr, "***** Cmm(%d, %d, %d, %d, %d, %d, %d, %d)\n",
Cmm::minHeap, Cmm::maxHeap, Cmm::incHeap, Cmm::generational,
Cmm::incPercent, Cmm::gcThreshold, Cmm::flags, Cmm::verbose);
!
/* Allocate heap and side tables. Exit on allocation failure. */
heapSpanPages = totalPages = (Cmm::minHeap + bytesPerPage - 1)/bytesPerPage;
tablePages = (totalPages*tableFraction + bytesPerPage - 1) / bytesPerPage;
!
/* Allocate one block for both the heap and the tables.
* The tables will be recycled into pages at the next collection.
*/
--- 580,590 ----
fprintf(stderr, "***** Cmm(%d, %d, %d, %d, %d, %d, %d, %d)\n",
Cmm::minHeap, Cmm::maxHeap, Cmm::incHeap, Cmm::generational,
Cmm::incPercent, Cmm::gcThreshold, Cmm::flags, Cmm::verbose);
!
/* Allocate heap and side tables. Exit on allocation failure. */
heapSpanPages = totalPages = (Cmm::minHeap + bytesPerPage - 1)/bytesPerPage;
tablePages = (totalPages*tableFraction + bytesPerPage - 1) / bytesPerPage;
!
/* Allocate one block for both the heap and the tables.
* The tables will be recycled into pages at the next collection.
*/
***************
*** 610,616 ****
lastHeapPage = firstHeapPage + heapSpanPages - 1;
firstTablePage = lastHeapPage + 1;
freePages = totalPages;
!
pageSpace = (short *)pageToGCP(firstTablePage);
pageGroup = &pageSpace[totalPages];
pageLink = (Page *)&pageGroup[totalPages];
--- 605,611 ----
lastHeapPage = firstHeapPage + heapSpanPages - 1;
firstTablePage = lastHeapPage + 1;
freePages = totalPages;
!
pageSpace = (short *)pageToGCP(firstTablePage);
pageGroup = &pageSpace[totalPages];
pageLink = (Page *)&pageGroup[totalPages];
***************
*** 619,632 ****
# if !HEADER_SIZE || defined(MARKING)
liveMap = (unsigned long *)&objectMap[totalPages*wordsPerPage/bitsPerWord];
# endif
!
/* The following definitions are safe because these vectors are accessed
only through an address within a page. Instead of using
pageSpace[addr - firstHeapPage]
space is displaced by firstHeapPage so that we can use:
pageSpace[addr]
*/
!
pageSpace = pageSpace - firstHeapPage;
pageLink = pageLink - firstHeapPage;
pageGroup = pageGroup - firstHeapPage;
--- 614,627 ----
# if !HEADER_SIZE || defined(MARKING)
liveMap = (unsigned long *)&objectMap[totalPages*wordsPerPage/bitsPerWord];
# endif
!
/* The following definitions are safe because these vectors are accessed
only through an address within a page. Instead of using
pageSpace[addr - firstHeapPage]
space is displaced by firstHeapPage so that we can use:
pageSpace[addr]
*/
!
pageSpace = pageSpace - firstHeapPage;
pageLink = pageLink - firstHeapPage;
pageGroup = pageGroup - firstHeapPage;
***************
*** 635,641 ****
# if !HEADER_SIZE || defined(MARKING)
liveMap = liveMap - WORD_INDEX(firstHeapPage*bytesPerPage);
# endif
!
/* Initialize tables */
for (i = firstHeapPage ; i <= lastHeapPage ; i++)
pageHeap[i] = NOHEAP;
--- 630,636 ----
# if !HEADER_SIZE || defined(MARKING)
liveMap = liveMap - WORD_INDEX(firstHeapPage*bytesPerPage);
# endif
!
/* Initialize tables */
for (i = firstHeapPage ; i <= lastHeapPage ; i++)
pageHeap[i] = NOHEAP;
***************
*** 644,666 ****
firstFreePage = firstHeapPage;
queueHead = 0;
Cmm::created = true;
!
Cmm::theDefaultHeap->usedPages = 0;
Cmm::theDefaultHeap->stablePages = 0;
Cmm::theDefaultHeap->firstUnusedPage = firstHeapPage;
Cmm::theDefaultHeap->firstReservedPage= firstHeapPage;
Cmm::theDefaultHeap->lastReservedPage = firstHeapPage;
!
# if !HEADER_SIZE
aGcFreeObject = ::new GcFreeObject;
# ifdef DOUBLE_ALIGN_OPTIMIZE
aGcPadObject = ::new GcPadObject;
# endif
# endif
!
// The following initializations are needed by the CmmObject::new
// operator. For this reason they don't use new, but ::new.
!
aCmmObject = ::new CmmObject;
aCmmVarObject = ::new CmmVarObject;
}
--- 639,661 ----
firstFreePage = firstHeapPage;
queueHead = 0;
Cmm::created = true;
!
Cmm::theDefaultHeap->usedPages = 0;
Cmm::theDefaultHeap->stablePages = 0;
Cmm::theDefaultHeap->firstUnusedPage = firstHeapPage;
Cmm::theDefaultHeap->firstReservedPage= firstHeapPage;
Cmm::theDefaultHeap->lastReservedPage = firstHeapPage;
!
# if !HEADER_SIZE
aGcFreeObject = ::new GcFreeObject;
# ifdef DOUBLE_ALIGN_OPTIMIZE
aGcPadObject = ::new GcPadObject;
# endif
# endif
!
// The following initializations are needed by the CmmObject::new
// operator. For this reason they don't use new, but ::new.
!
aCmmObject = ::new CmmObject;
aCmmVarObject = ::new CmmVarObject;
}
***************
*** 682,689 ****
shouldExpandHeap()
{
return (HEAPPERCENT(Cmm::theDefaultHeap->stablePages) >= Cmm::incPercent
! && totalPages < Cmm::maxHeap/bytesPerPage
! && Cmm::incHeap != 0);
}
static bool expandFailed = false;
--- 677,684 ----
shouldExpandHeap()
{
return (HEAPPERCENT(Cmm::theDefaultHeap->stablePages) >= Cmm::incPercent
! && totalPages < Cmm::maxHeap/bytesPerPage
! && Cmm::incHeap != 0);
}
static bool expandFailed = false;
***************
*** 719,754 ****
unsigned long *new_liveMap;
# endif
Page i;
!
short *new_pageSpace;
short *new_pageGroup;
CmmHeap **new_pageHeap;
!
char *new_tables;
int new_tablePages;
char *inc_heap;
bool recycleOldTables = true;
!
/* Check for previous expansion failure */
if (expandFailed) return 0;
!
Page lastTablePage = firstTablePage + tablePages - 1;
!
/* Allocate additional heap and determine page span */
!
#ifndef _WIN32
/* Save the current exception handler for ::new, so we can replace it
! with a dummy one in order to be notified of failure */
savedNewHandler = set_new_handler(dummyNewHandler);
#endif
!
inc_heap = ::new char[inc_totalPages*bytesPerPage + bytesPerPage - 1];
if (inc_heap == NULL) goto fail;
inc_heap = inc_heap + bytesPerPage - 1;
inc_heap -= (Word)inc_heap % bytesPerPage;
inc_firstHeapPage = GCPtoPage(inc_heap);
inc_lastHeapPage = inc_firstHeapPage + inc_totalPages - 1;
!
new_firstHeapPage = MIN(firstHeapPage, inc_firstHeapPage);
new_lastHeapPage = MAX(lastHeapPage, inc_lastHeapPage);
/* Sometimes malloc() (e.g. on Linux ELF) allocates small blocks at
--- 714,749 ----
unsigned long *new_liveMap;
# endif
Page i;
!
short *new_pageSpace;
short *new_pageGroup;
CmmHeap **new_pageHeap;
!
char *new_tables;
int new_tablePages;
char *inc_heap;
bool recycleOldTables = true;
!
/* Check for previous expansion failure */
if (expandFailed) return 0;
!
Page lastTablePage = firstTablePage + tablePages - 1;
!
/* Allocate additional heap and determine page span */
!
#ifndef _WIN32
/* Save the current exception handler for ::new, so we can replace it
! with a dummy one in order to be notified of failure */
savedNewHandler = set_new_handler(dummyNewHandler);
#endif
!
inc_heap = ::new char[inc_totalPages*bytesPerPage + bytesPerPage - 1];
if (inc_heap == NULL) goto fail;
inc_heap = inc_heap + bytesPerPage - 1;
inc_heap -= (Word)inc_heap % bytesPerPage;
inc_firstHeapPage = GCPtoPage(inc_heap);
inc_lastHeapPage = inc_firstHeapPage + inc_totalPages - 1;
!
new_firstHeapPage = MIN(firstHeapPage, inc_firstHeapPage);
new_lastHeapPage = MAX(lastHeapPage, inc_lastHeapPage);
/* Sometimes malloc() (e.g. on Linux ELF) allocates small blocks at
***************
*** 759,765 ****
if (distant(lastHeapPage, firstTablePage)
&& distant(lastTablePage, firstHeapPage))
recycleOldTables = false;
!
if (recycleOldTables)
{
new_firstHeapPage = MIN(new_firstHeapPage, firstTablePage);
--- 754,760 ----
if (distant(lastHeapPage, firstTablePage)
&& distant(lastTablePage, firstHeapPage))
recycleOldTables = false;
!
if (recycleOldTables)
{
new_firstHeapPage = MIN(new_firstHeapPage, firstTablePage);
***************
*** 768,774 ****
}
new_totalPages = totalPages + tablePages + inc_totalPages;
heapSpanPages = new_lastHeapPage - new_firstHeapPage + 1;
!
new_tablePages = (heapSpanPages*tableFraction
+ bytesPerPage - 1) / bytesPerPage;
new_tables = ::new char[new_tablePages*bytesPerPage + bytesPerPage - 1];
--- 763,769 ----
}
new_totalPages = totalPages + tablePages + inc_totalPages;
heapSpanPages = new_lastHeapPage - new_firstHeapPage + 1;
!
new_tablePages = (heapSpanPages*tableFraction
+ bytesPerPage - 1) / bytesPerPage;
new_tables = ::new char[new_tablePages*bytesPerPage + bytesPerPage - 1];
***************
*** 776,782 ****
{
fail:
# ifndef _WIN32
! set_new_handler(savedNewHandler);
# endif
if (inc_heap) ::delete inc_heap;
expandFailed = true;
--- 771,777 ----
{
fail:
# ifndef _WIN32
! set_new_handler(savedNewHandler);
# endif
if (inc_heap) ::delete inc_heap;
expandFailed = true;
***************
*** 796,802 ****
new_liveMap =
(Word *)&new_objectMap[heapSpanPages*wordsPerPage/bitsPerWord];
#endif
!
new_pageSpace = new_pageSpace - new_firstHeapPage;
new_pageLink = new_pageLink - new_firstHeapPage;
new_pageGroup = new_pageGroup - new_firstHeapPage;
--- 791,797 ----
new_liveMap =
(Word *)&new_objectMap[heapSpanPages*wordsPerPage/bitsPerWord];
#endif
!
new_pageSpace = new_pageSpace - new_firstHeapPage;
new_pageLink = new_pageLink - new_firstHeapPage;
new_pageGroup = new_pageGroup - new_firstHeapPage;
***************
*** 805,811 ****
#if !HEADER_SIZE || defined(MARKING)
new_liveMap = new_liveMap - WORD_INDEX(new_firstHeapPage*bytesPerPage);
#endif
!
/* Initialize new side tables */
for (i = inc_firstHeapPage ; i <= inc_lastHeapPage ; i++)
new_pageHeap[i] = NOHEAP;
--- 800,806 ----
#if !HEADER_SIZE || defined(MARKING)
new_liveMap = new_liveMap - WORD_INDEX(new_firstHeapPage*bytesPerPage);
#endif
!
/* Initialize new side tables */
for (i = inc_firstHeapPage ; i <= inc_lastHeapPage ; i++)
new_pageHeap[i] = NOHEAP;
***************
*** 825,831 ****
new_liveMap[i] = liveMap[i];
#endif
}
!
if (recycleOldTables)
{
/* Recycle old tables */
--- 820,826 ----
new_liveMap[i] = liveMap[i];
#endif
}
!
if (recycleOldTables)
{
/* Recycle old tables */
***************
*** 834,843 ****
/* Fill gaps */
Page gapStart = MIN(lastTablePage, inc_lastHeapPage);
Page gap1Start = MIN(lastHeapPage, gapStart);
!
Page gapEnd = MAX(firstTablePage, inc_firstHeapPage);
Page gap2End = MAX(firstHeapPage, gapEnd);
!
Page gap1End = (gapEnd == gap2End) ?
MAX(firstHeapPage, MIN(firstTablePage, inc_firstHeapPage)) : gapEnd;
Page gap2Start = (gapStart == gap1Start) ?
--- 829,838 ----
/* Fill gaps */
Page gapStart = MIN(lastTablePage, inc_lastHeapPage);
Page gap1Start = MIN(lastHeapPage, gapStart);
!
Page gapEnd = MAX(firstTablePage, inc_firstHeapPage);
Page gap2End = MAX(firstHeapPage, gapEnd);
!
Page gap1End = (gapEnd == gap2End) ?
MAX(firstHeapPage, MIN(firstTablePage, inc_firstHeapPage)) : gapEnd;
Page gap2Start = (gapStart == gap1Start) ?
***************
*** 849,855 ****
}
else
::delete (char *)(pageSpace + firstHeapPage); // address of old tables
!
pageSpace = new_pageSpace;
pageLink = new_pageLink;
pageGroup = new_pageGroup;
--- 844,850 ----
}
else
::delete (char *)(pageSpace + firstHeapPage); // address of old tables
!
pageSpace = new_pageSpace;
pageLink = new_pageLink;
pageGroup = new_pageGroup;
***************
*** 865,871 ****
tablePages = new_tablePages;
firstTablePage = GCPtoPage(new_tables);
firstFreePage = inc_firstHeapPage;
!
WHEN_VERBOSE (CMM_STATS,
fprintf(stderr,
"\n***** CMM Heap expanded to %d bytes\n",
--- 860,866 ----
tablePages = new_tablePages;
firstTablePage = GCPtoPage(new_tables);
firstFreePage = inc_firstHeapPage;
!
WHEN_VERBOSE (CMM_STATS,
fprintf(stderr,
"\n***** CMM Heap expanded to %d bytes\n",
***************
*** 887,893 ****
emptyStableSpace(Page end)
{
Page scan;
! if (queueHead == 0) // happens in test3
return;
end = pageLink[end];
while (queueHead != end)
--- 882,888 ----
emptyStableSpace(Page end)
{
Page scan;
! if (queueHead == 0) // happens in test3
return;
end = pageLink[end];
while (queueHead != end)
***************
*** 939,945 ****
promotePage(GCP cp)
{
Page page = GCPtoPage(cp);
!
// Don't promote pages belonging to other heaps.
// (We noticed no benefit by inlining the following test in the caller)
if (page >= firstHeapPage
--- 934,940 ----
promotePage(GCP cp)
{
Page page = GCPtoPage(cp);
!
// Don't promote pages belonging to other heaps.
// (We noticed no benefit by inlining the following test in the caller)
if (page >= firstHeapPage
***************
*** 982,993 ****
basePointer(GCP fp)
{
fp = (GCP) ((int)fp & ~(bytesPerWord-1));
!
register int index = WORD_INDEX(fp);
register int inner = BIT_INDEX(fp);
register Word mask = 1 << inner;
register Word bits = objectMap[index];
!
do
{
do
--- 977,988 ----
basePointer(GCP fp)
{
fp = (GCP) ((int)fp & ~(bytesPerWord-1));
!
register int index = WORD_INDEX(fp);
register int inner = BIT_INDEX(fp);
register Word mask = 1 << inner;
register Word bits = objectMap[index];
!
do
{
do
***************
*** 1033,1042 ****
# if HEADER_SIZE
Ptr header; /* Object header */
# endif
!
/* Verify that the object is a valid pointer and decrement ptr cnt */
WHEN_FLAGS (CMM_TSTOBJ, verifyObject(cp, true); verifyHeader(cp););
!
/* If cell is already forwarded, return forwarding pointer */
# if HEADER_SIZE
header = cp[-HEADER_SIZE];
--- 1028,1037 ----
# if HEADER_SIZE
Ptr header; /* Object header */
# endif
!
/* Verify that the object is a valid pointer and decrement ptr cnt */
WHEN_FLAGS (CMM_TSTOBJ, verifyObject(cp, true); verifyHeader(cp););
!
/* If cell is already forwarded, return forwarding pointer */
# if HEADER_SIZE
header = cp[-HEADER_SIZE];
***************
*** 1052,1058 ****
if (FORWARDED(cp))
return ((GCP)*cp);
# endif
!
/* Move or promote object */
#if HEADER_SIZE
register int words = HEADER_WORDS(header);
--- 1047,1053 ----
if (FORWARDED(cp))
return ((GCP)*cp);
# endif
!
/* Move or promote object */
#if HEADER_SIZE
register int words = HEADER_WORDS(header);
***************
*** 1125,1131 ****
{
GCP p = (GCP)basePointer((GCP)*loc);
page = GCPtoPage(p);
!
if (inside(p)) // in this heap
{
if (inFromSpace(page)) // can be moved
--- 1120,1126 ----
{
GCP p = (GCP)basePointer((GCP)*loc);
page = GCPtoPage(p);
!
if (inside(p)) // in this heap
{
if (inFromSpace(page)) // can be moved
***************
*** 1135,1141 ****
{
assert(inStableSpace(page) || pageSpace[page] == SCANNEDSPACE);
MARK(p);
! if (!(page == scanPage && p > scanPtr)) // scan optimization
// it is not further in the page being scanned
if (SCANNED(page) // or p was not traversed when page was scanned
# if HEADER_SIZE
--- 1130,1136 ----
{
assert(inStableSpace(page) || pageSpace[page] == SCANNEDSPACE);
MARK(p);
! if (!(page == scanPage && p > scanPtr))
// it is not further in the page being scanned
if (SCANNED(page) // or p was not traversed when page was scanned
# if HEADER_SIZE
***************
*** 1165,1217 ****
* middle of collection.
*---------------------------------------------------------------------------*/
- #if HEADER_SIZE
- #define CLOSE_CURRENT_PAGE \
- if (freeWords != 0) { \
- *firstFreeWord = MAKE_HEADER(freeWords, freeSpaceTag); \
- freeWords = 0; }
- #else
- #define CLOSE_CURRENT_PAGE \
- if (freeWords != 0) { \
- *firstFreeWord = *(GCP)aGcFreeObject; \
- SET_OBJECTMAP(firstFreeWord); \
- freeWords = 0; }
- # endif
-
-
void
DefaultHeap::collect()
{
int page; /* Page number while walking page list */
GCP cp, /* Pointers to move constituent objects */
nextcp;
!
// firstFreeWord is seen by the collector: it should not consider it a root.
!
/* Check for heap not yet allocated */
if (!Cmm::created)
{
CmmInit();
return;
}
!
/* Log entry to the collector */
WHEN_VERBOSE (CMM_STATS, {
fprintf(stderr, "***** CMM Collecting - %d%% allocated -> ",
HEAPPERCENT(usedPages));
newlineIfLogging();
});
!
/* Advance space.
* Pages allocated by CmmMove() herein will belong to the StableSpace.
* At the end of collect() we go back to normal.
* Therefore objects moved once by the collector will not be moved again
* until a full collection is enabled by emptyStableSpace().
*/
!
nextSpace = STABLESPACE;
usedPages = stablePages; // start counting in StableSpace
!
# if !HEADER_SIZE || defined(MARKING)
/* Clear the liveMap bitmap */
bzero((char*)&liveMap[WORD_INDEX(firstHeapPage * bytesPerPage)],
--- 1160,1209 ----
* middle of collection.
*---------------------------------------------------------------------------*/
void
DefaultHeap::collect()
{
int page; /* Page number while walking page list */
GCP cp, /* Pointers to move constituent objects */
nextcp;
!
// firstFreeWord is seen by the collector: it should not consider it a root.
!
/* Check for heap not yet allocated */
if (!Cmm::created)
{
CmmInit();
return;
}
!
/* Log entry to the collector */
WHEN_VERBOSE (CMM_STATS, {
fprintf(stderr, "***** CMM Collecting - %d%% allocated -> ",
HEAPPERCENT(usedPages));
newlineIfLogging();
});
!
! /* Allocate rest of the current page */
! if (freeWords != 0) {
! # if HEADER_SIZE
! *firstFreeWord = MAKE_HEADER(freeWords, freeSpaceTag);
! # else
! *firstFreeWord = *(GCP)aGcFreeObject;
! SET_OBJECTMAP(firstFreeWord);
! # endif
! freeWords = 0;
! }
!
/* Advance space.
* Pages allocated by CmmMove() herein will belong to the StableSpace.
* At the end of collect() we go back to normal.
* Therefore objects moved once by the collector will not be moved again
* until a full collection is enabled by emptyStableSpace().
*/
!
nextSpace = STABLESPACE;
usedPages = stablePages; // start counting in StableSpace
!
# if !HEADER_SIZE || defined(MARKING)
/* Clear the liveMap bitmap */
bzero((char*)&liveMap[WORD_INDEX(firstHeapPage * bytesPerPage)],
***************
*** 1224,1250 ****
jmp_buf regs;
GCP fp; /* Pointer for checking the stack */
void CmmExamineStaticArea(GCP, GCP);
!
/* ensure flushing of register caches */
if (_setjmp(regs) == 0) _longjmp(regs, 1);
!
/* Examine the stack: */
# ifdef STACK_GROWS_DOWNWARD
for (fp = (GCP)regs; fp < (GCP)stackBottom; fp++)
# else
! for (fp = (GCP)regs + sizeof(regs); fp > (GCP)stackBottom; fp--)
# endif
! {
! WHEN_VERBOSE (CMM_ROOTLOG, logRoot(fp));
! promotePage((GCP)*fp);
! }
!
/* Examine the static areas: */
WHEN_VERBOSE (CMM_ROOTLOG,
fprintf(stderr, "Static and registered roots:\n"));
!
CmmExamineStaticAreas(CmmExamineStaticArea);
!
/* Examine registered roots: */
roots.begin();
while (RootArea* ra = roots.get())
--- 1216,1242 ----
jmp_buf regs;
GCP fp; /* Pointer for checking the stack */
void CmmExamineStaticArea(GCP, GCP);
!
/* ensure flushing of register caches */
if (_setjmp(regs) == 0) _longjmp(regs, 1);
!
/* Examine the stack: */
# ifdef STACK_GROWS_DOWNWARD
for (fp = (GCP)regs; fp < (GCP)stackBottom; fp++)
# else
! for (fp = (GCP)regs + sizeof(regs); fp > (GCP)stackBottom; fp--)
# endif
! {
! WHEN_VERBOSE (CMM_ROOTLOG, logRoot(fp));
! promotePage((GCP)*fp);
! }
!
/* Examine the static areas: */
WHEN_VERBOSE (CMM_ROOTLOG,
fprintf(stderr, "Static and registered roots:\n"));
!
CmmExamineStaticAreas(CmmExamineStaticArea);
!
/* Examine registered roots: */
roots.begin();
while (RootArea* ra = roots.get())
***************
*** 1253,1259 ****
for (int j = ra->bytes; j > 0; j = j - bytesPerWord)
promotePage((GCP)*fp++);
}
!
/* Examine the uncollected heap: */
/* Should scan all opaque heaps */
if (Cmm::flags & CMM_HEAPROOTS)
--- 1245,1251 ----
for (int j = ra->bytes; j > 0; j = j - bytesPerWord)
promotePage((GCP)*fp++);
}
!
/* Examine the uncollected heap: */
/* Should scan all opaque heaps */
if (Cmm::flags & CMM_HEAPROOTS)
***************
*** 1279,1285 ****
fprintf(stderr, "%d%% locked ", HEAPPERCENT(usedPages));
newlineIfLogging();
});
!
// Sweep across stable pages and move their constituent items.
page = queueHead;
// pages promoted from here should survive this generation:
--- 1271,1277 ----
fprintf(stderr, "%d%% locked ", HEAPPERCENT(usedPages));
newlineIfLogging();
});
!
// Sweep across stable pages and move their constituent items.
page = queueHead;
// pages promoted from here should survive this generation:
***************
*** 1288,1296 ****
{
# ifdef MARKING // pointers to unmarked objects within
SET_SCANNED(page); // this page will have to be traversed
! // recursively by scavenge
! scanPage = page; // scan optimization
! # endif
cp = pageToGCP(page);
WHEN_VERBOSE (CMM_DEBUGLOG, fprintf(stderr, "sweeping 0x%x\n", cp));
GCP nextPage = pageToGCP(page + 1);
--- 1280,1289 ----
{
# ifdef MARKING // pointers to unmarked objects within
SET_SCANNED(page); // this page will have to be traversed
! # ifndef NO_SCAN_OPT
! scanPage = page;
! # endif
! # endif // recursively by scavenge
cp = pageToGCP(page);
WHEN_VERBOSE (CMM_DEBUGLOG, fprintf(stderr, "sweeping 0x%x\n", cp));
GCP nextPage = pageToGCP(page + 1);
***************
*** 1311,1317 ****
# endif
)
{
! scanPtr = cp; // scan optimization
((CmmObject *)(cp + HEADER_SIZE))->traverse();
}
cp = cp + HEADER_WORDS(*cp);
--- 1304,1312 ----
# endif
)
{
! # ifndef NO_SCAN_OPT
! scanPtr = cp;
! # endif
((CmmObject *)(cp + HEADER_SIZE))->traverse();
}
cp = cp + HEADER_WORDS(*cp);
***************
*** 1320,1339 ****
if (MARKED(cp))
# endif
{
! scanPtr = cp; // scan optimization
((CmmObject *)cp)->traverse();
}
cp = cp + ((CmmObject *)cp)->words();
# endif
}
page = pageLink[page];
- if (cp == firstFreeWord && page)
- // close this page if it is the current but not the last in the
- // queue, otherwise new objects might get allocated here
- // which will not be scanned
- CLOSE_CURRENT_PAGE;
}
!
#ifdef MARKING
{
/* Restore scanned pages to STABLESPACE */
--- 1315,1331 ----
if (MARKED(cp))
# endif
{
! # ifndef NO_SCAN_OPT
! scanPtr = cp;
! # endif
((CmmObject *)cp)->traverse();
}
cp = cp + ((CmmObject *)cp)->words();
# endif
}
page = pageLink[page];
}
!
#ifdef MARKING
{
/* Restore scanned pages to STABLESPACE */
***************
*** 1345,1357 ****
}
}
#endif
!
/* Finished, all retained pages are now part of the StableSpace */
fromSpace = fromSpace + 1;
nextSpace = fromSpace; // resume allocating in FromSpace
WHEN_VERBOSE (CMM_STATS,
fprintf(stderr, "%d%% stable.\n", HEAPPERCENT(stablePages)));
!
/* Check for total collection and heap expansion. */
if (Cmm::generational != 0)
{
--- 1337,1349 ----
}
}
#endif
!
/* Finished, all retained pages are now part of the StableSpace */
fromSpace = fromSpace + 1;
nextSpace = fromSpace; // resume allocating in FromSpace
WHEN_VERBOSE (CMM_STATS,
fprintf(stderr, "%d%% stable.\n", HEAPPERCENT(stablePages)));
!
/* Check for total collection and heap expansion. */
if (Cmm::generational != 0)
{
***************
*** 1361,1367 ****
/* Perform a total collection and then expand the heap */
emptyStableSpace(lastStable);
int saveGenerational = Cmm::generational;
!
Cmm::generational = 100;
cp = NULL; // or collect will promote it again
collect();
--- 1353,1359 ----
/* Perform a total collection and then expand the heap */
emptyStableSpace(lastStable);
int saveGenerational = Cmm::generational;
!
Cmm::generational = 100;
cp = NULL; // or collect will promote it again
collect();
***************
*** 1419,1429 ****
Page firstPage; /* Page # of first free page */
int allPages; /* # of pages in the heap */
GCP firstByte; /* address of first free page */
!
allPages = heapSpanPages;
free = 0;
firstPage = firstFreePage;
!
while (allPages--)
{
if (pageHeap[firstFreePage] == NOHEAP)
--- 1411,1421 ----
Page firstPage; /* Page # of first free page */
int allPages; /* # of pages in the heap */
GCP firstByte; /* address of first free page */
!
allPages = heapSpanPages;
free = 0;
firstPage = firstFreePage;
!
while (allPages--)
{
if (pageHeap[firstFreePage] == NOHEAP)
***************
*** 1485,1500 ****
DefaultHeap::getPages(int pages)
{
Page firstPage; /* Page # of first free page */
!
! //#define NEW_GETPAGE bad: grows valla to 29063K
#ifndef NEW_GETPAGE
#define USED2FREE_RATIO 2
! if (fromSpace == nextSpace /* not within CmmMove() */
&& usedPages + pages
> USED2FREE_RATIO * (freePages + reservedPages - usedPages - pages))
collect();
#endif
!
/* Discard any remaining portion of current page */
if (freeWords != 0)
{
--- 1477,1492 ----
DefaultHeap::getPages(int pages)
{
Page firstPage; /* Page # of first free page */
!
! //#define NEW_GETPAGE bad: grows valla to 29063K
#ifndef NEW_GETPAGE
#define USED2FREE_RATIO 2
! if (fromSpace == nextSpace /* not within CmmMove() */
&& usedPages + pages
> USED2FREE_RATIO * (freePages + reservedPages - usedPages - pages))
collect();
#endif
!
/* Discard any remaining portion of current page */
if (freeWords != 0)
{
***************
*** 1596,1609 ****
#define USED2FREE_RATIO 2
#define enoughPagesLeft(pages) (usedPages + pages \
<= USED2FREE_RATIO * (freePages + reservedPages - usedPages - pages))
!
GCP
DefaultHeap::alloc(Word size)
{
GCP object; /* Pointer to the object */
!
size = bytesToWords(size); // add size of header
!
/* Try to allocate from current page */
if (size <= (Word)freeWords)
{
--- 1588,1601 ----
#define USED2FREE_RATIO 2
#define enoughPagesLeft(pages) (usedPages + pages \
<= USED2FREE_RATIO * (freePages + reservedPages - usedPages - pages))
!
GCP
DefaultHeap::alloc(Word size)
{
GCP object; /* Pointer to the object */
!
size = bytesToWords(size); // add size of header
!
/* Try to allocate from current page */
if (size <= (Word)freeWords)
{
***************
*** 1653,1691 ****
* It is allocated at the beginning of next page.
*/
# if HEADER_SIZE
! else if (size > maxHeaderWords)
! {
! fprintf(stderr,
! "\n***** CMM Unable to allocate objects larger than %d bytes\n",
! maxHeaderWords * bytesPerWord - bytesPerWord);
! abort();
! }
# endif
! else
! {
! int pages =
# if HEADER_SIZE && defined(DOUBLE_ALIGN)
! (size + wordsPerPage) / wordsPerPage;
# else
! (size + wordsPerPage - 1) / wordsPerPage;
# endif
#ifdef NEW_GETPAGES
! if (! enoughPagesLeft(pages)) collect();
#endif
! getPages(pages);
! object = firstFreeWord;
! /* No object is allocated in final page after object > 1 page */
! if (freeWords != 0) {
! # if HEADER_SIZE
! *firstFreeWord = MAKE_HEADER(freeWords, freeSpaceTag);
! # else
! *firstFreeWord = *(GCP)aGcFreeObject;
! SET_OBJECTMAP(firstFreeWord);
! # endif
! freeWords = 0;
}
- firstFreeWord = NULL;
- }
ALLOC_SETUP(object, size);
return(object);
}
--- 1645,1683 ----
* It is allocated at the beginning of next page.
*/
# if HEADER_SIZE
! else if (size > maxHeaderWords)
! {
! fprintf(stderr,
! "\n***** CMM Unable to allocate objects larger than %d bytes\n",
! maxHeaderWords * bytesPerWord - bytesPerWord);
! abort();
! }
# endif
! else
! {
! int pages =
# if HEADER_SIZE && defined(DOUBLE_ALIGN)
! (size + wordsPerPage) / wordsPerPage;
# else
! (size + wordsPerPage - 1) / wordsPerPage;
# endif
#ifdef NEW_GETPAGES
! if (! enoughPagesLeft(pages)) collect();
#endif
! getPages(pages);
! object = firstFreeWord;
! /* No object is allocated in final page after object > 1 page */
! if (freeWords != 0) {
! # if HEADER_SIZE
! *firstFreeWord = MAKE_HEADER(freeWords, freeSpaceTag);
! # else
! *firstFreeWord = *(GCP)aGcFreeObject;
! SET_OBJECTMAP(firstFreeWord);
! # endif
! freeWords = 0;
! }
! firstFreeWord = NULL;
}
ALLOC_SETUP(object, size);
return(object);
}
***************
*** 1734,1743 ****
CmmObject::operator new(size_t size, CmmHeap *heap)
{
GCP object = heap->alloc(size);
!
// To avoid problems in GC after new but during constructor
*object = *((GCP)aCmmObject);
!
return (void *)object;
}
--- 1726,1735 ----
CmmObject::operator new(size_t size, CmmHeap *heap)
{
GCP object = heap->alloc(size);
!
// To avoid problems in GC after new but during constructor
*object = *((GCP)aCmmObject);
!
return (void *)object;
}
***************
*** 1762,1771 ****
CmmVarObject::operator new(size_t size, size_t extraSize, CmmHeap *heap)
{
GCP object = heap->alloc(size + extraSize);
!
// To avoid problems in GC after new() but during constructor
*object = *((GCP)aCmmVarObject);
!
return (void *)object;
}
--- 1754,1763 ----
CmmVarObject::operator new(size_t size, size_t extraSize, CmmHeap *heap)
{
GCP object = heap->alloc(size + extraSize);
!
// To avoid problems in GC after new() but during constructor
*object = *((GCP)aCmmVarObject);
!
return (void *)object;
}
***************
*** 1813,1819 ****
Page page = GCPtoPage(cp);
GCP xp = pageToGCP(page); /* Ptr to start of page */
int error = 0;
!
if (page < firstHeapPage) goto fail;
error = 1;
if (page > lastHeapPage) goto fail;
--- 1805,1811 ----
Page page = GCPtoPage(cp);
GCP xp = pageToGCP(page); /* Ptr to start of page */
int error = 0;
!
if (page < firstHeapPage) goto fail;
error = 1;
if (page > lastHeapPage) goto fail;
***************
*** 1858,1864 ****
# endif
Page pagen = GCPtoPage(cp);
int error = 0;
!
if FORWARDED(cp[-HEADER_SIZE]) goto fail;
error = 1;
# if HEADER_SIZE
--- 1850,1856 ----
# endif
Page pagen = GCPtoPage(cp);
int error = 0;
!
if FORWARDED(cp[-HEADER_SIZE]) goto fail;
error = 1;
# if HEADER_SIZE
***************
*** 1909,1926 ****
logRoot(long* fp)
{
Page page = GCPtoPage(fp);
!
if (page < firstHeapPage
|| page > lastHeapPage
|| inFreeSpace(page))
return;
!
int pages = pageGroup[page];
!
if (pages < 0) page += pages;
!
GCP p1, p2 = pageToGCP(page);
!
while (p2 < (GCP)fp)
{
p1 = p2;
--- 1901,1918 ----
logRoot(long* fp)
{
Page page = GCPtoPage(fp);
!
if (page < firstHeapPage
|| page > lastHeapPage
|| inFreeSpace(page))
return;
!
int pages = pageGroup[page];
!
if (pages < 0) page += pages;
!
GCP p1, p2 = pageToGCP(page);
!
while (p2 < (GCP)fp)
{
p1 = p2;
***************
*** 1959,1965 ****
GCP start = pageToGCP(page);
GCP end = pageToGCP(page + 1);
GCP ptr;
!
for (ptr = start; ptr < end; ptr++)
promotePage(ptr);
}
--- 1951,1957 ----
GCP start = pageToGCP(page);
GCP end = pageToGCP(page + 1);
GCP ptr;
!
for (ptr = start; ptr < end; ptr++)
promotePage(ptr);
}
diff -c /home/omega/attardi/posso/cmm/cmm.h /project/posso/cmm/curr/cmm/cmm.h
*** /home/omega/attardi/posso/cmm/cmm.h Wed Apr 16 11:03:01 1997
--- /project/posso/cmm/curr/cmm/cmm.h Fri Mar 28 18:25:29 1997
***************
*** 877,885 ****
public:
Set()
{
- last = 0;
max = 0;
! freed = 0;
entries = NULL;
}
--- 877,885 ----
public:
Set()
{
max = 0;
! free = 0;
! iter = 0;
entries = NULL;
}
***************
*** 888,940 ****
# define setIncrement 10
int i;
! if (freed)
{
! for (i = 0; i < last; i++)
if (entries[i] == NULL)
! {
! freed--;
! break;
! }
}
else
{
! if (last == max)
! {
! T** np;
! max += setIncrement;
! np = ::new T*[max];
! for (i = 0; i < last; i++)
! np[i] = entries[i];
! // clear the rest
! for (; i < max; i++)
! np[i] = NULL;
! if (entries) ::delete entries;
! entries = np;
! }
! i = last++;
}
entries[i] = entry;
}
void erase(T* entry)
{
int i;
! for (i = 0; i < last; i++)
if (entries[i] == entry)
{
entries[i] = NULL;
! freed++;
return;
}
! assert(i < last);
}
T* get()
{
// look for a non empty entry
! while (iter < last)
{
if (entries[iter])
return entries[iter++];
--- 888,937 ----
# define setIncrement 10
int i;
! if (free)
{
! for (i = 0; i < max; i++)
if (entries[i] == NULL)
! break;
}
else
{
! T** np;
! int count = max;
! max += setIncrement;
! free = setIncrement;
! np = ::new T*[max];
! for (i = 0; i < count; i++)
! np[i] = entries[i];
! // clear the rest
! for (; i < max; i++)
! np[i] = NULL;
! if (entries) ::delete entries;
! entries = np;
! i = count;
}
entries[i] = entry;
+ free--;
}
void erase(T* entry)
{
int i;
! for (i = 0; i < max; i++)
if (entries[i] == entry)
{
entries[i] = NULL;
! free++;
return;
}
! assert(i < count);
}
T* get()
{
// look for a non empty entry
! while (iter < max)
{
if (entries[iter])
return entries[iter++];
***************
*** 945,959 ****
return (T*)NULL;
}
! void begin() { iter = 0; }
protected:
T** entries;
private:
- int last;
int max;
! int freed;
int iter;
};
#endif // _CMM_H
--- 942,955 ----
return (T*)NULL;
}
! void begin() { iter = 0;}
protected:
T** entries;
private:
int max;
! int free;
int iter;
};
#endif // _CMM_H
Common subdirectories: /home/omega/attardi/posso/cmm/doc and /project/posso/cmm/curr/cmm/doc
diff -c /home/omega/attardi/posso/cmm/machine.h /project/posso/cmm/curr/cmm/machine.h
*** /home/omega/attardi/posso/cmm/machine.h Wed Apr 16 23:05:25 1997
--- /project/posso/cmm/curr/cmm/machine.h Tue Feb 25 23:07:34 1997
***************
*** 133,140 ****
# define DATASTART USRDATA
#elif defined(__svr4__) || defined(DGUX)
extern int etext;
! extern char * CmmSVR4DataStart(int);
! # define DATASTART CmmSVR4DataStart(0x10000)
#elif defined(hp9000s300)
extern int etext;
# define DATASTART ((((unsigned long)(&etext)) + 0xfff) & ~0xfff)
--- 133,139 ----
# define DATASTART USRDATA
#elif defined(__svr4__) || defined(DGUX)
extern int etext;
! # define DATASTART SVR4DataStart(0x10000)
#elif defined(hp9000s300)
extern int etext;
# define DATASTART ((((unsigned long)(&etext)) + 0xfff) & ~0xfff)
***************
*** 193,197 ****
--- 192,201 ----
extern char etext;
# define DATASTART (&etext)
#endif
+
+ #define SVR4DataStart(max_page_size) \
+ ((unsigned long)(&etext) % max_page_size ? \
+ (unsigned long)(&etext) + max_page_size : \
+ (unsigned long)&etext)
#endif /* ! _MACHINE_H */
diff -c /home/omega/attardi/posso/cmm/memory.cpp /project/posso/cmm/curr/cmm/memory.cpp
*** /home/omega/attardi/posso/cmm/memory.cpp Wed Apr 16 23:11:23 1997
--- /project/posso/cmm/curr/cmm/memory.cpp Thu Nov 28 11:04:38 1996
***************
*** 277,301 ****
# endif
#endif
}
-
- /*---------------------------------------------------------------------------*
- * -- Data Start
- *---------------------------------------------------------------------------*/
-
- #ifdef __svr4__
-
- char *
- CmmSVR4DataStart(int max_page_size)
- {
- Word text_end = ((Word)(&etext) + sizeof(Word) - 1) & ~(sizeof(Word) - 1);
- /* etext rounded to word boundary */
- Word next_page = (text_end + (Word)max_page_size - 1)
- & ~((Word)max_page_size - 1);
- Word page_offset = (text_end & ((Word)max_page_size - 1));
- char * result = (char *)(next_page + page_offset);
- /* Note that this isn't equivalent to just adding
- * max_page_size to &etext if &etext is at a page boundary
- */
- return(result);
- }
- #endif
--- 277,279 ----