ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

MemorySegment.hpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Kernel RexxMemorysegment.hpp */
40 /* */
41 /* Primitive MemorySegment class definitions */
42 /* */
43 /******************************************************************************/
44 
45 #ifndef Included_MemorySegment
46 #define Included_MemorySegment
47 
48 #include "stddef.h"
49 #include "DeadObject.hpp"
50 #include "Interpreter.hpp"
51 
52 #define MemorySegmentOverhead (sizeof(MemorySegmentHeader))
53 #define MemorySegmentPoolOverhead (sizeof(MemorySegmentPoolHeader))
54 
55 #ifdef __REXX64__
56 // default size for a segment allocation, we go larger on 64-bit
57 #define SegmentSize (256*1024*2)
58 /* our threshold for moving to a larger block allocation scheme */
59 #define LargeBlockThreshold 8192
60 #else
61 /* default size for a segment allocation */
62 #define SegmentSize (256*1024)
63 /* our threshold for moving to a larger block allocation scheme */
64 #define LargeBlockThreshold 4096
65 #endif
66 /* Minimum size segment we'll allow */
67 #define MinimumSegmentSize (SegmentSize/2)
68 /* amount of usable space in a minimum sized segment */
69 #define MinimumSegmentDeadSpace (MinimumSegmentSize - MemorySegmentOverhead)
70 /* default size for a larger segment allocation */
71 #define LargeSegmentSize (SegmentSize * 4)
72 /* allocation available in a default segment */
73 #define SegmentDeadSpace (SegmentSize - MemorySegmentOverhead)
74 /* allocation request for the recovery segment */
75 #define RecoverSegmentSize ((SegmentSize/2) - MemorySegmentOverhead)
76 /* space available in a larger allocation. */
77 #define LargeSegmentDeadSpace (LargeSegmentSize - MemorySegmentOverhead)
78 
79 #define InitialNormalSegmentSpace ((LargeSegmentSize * 8) - MemorySegmentOverhead)
80 
81 #define LargestNormalSegmentSize (LargeObjectMinSize - (1024 * 1024) - MemorySegmentOverhead)
82 
83 
84 /* Our threshold for deciding we're thrashing the garbage */
85 /* collector. We'll always just extend memory if we're below this */
86 /* request threshold. */
87 #define MemoryThrashingThreshold 4
88 
89 /* map an object length to an allocation deadpool. NOTE: this */
90 /* assumes the length has already been rounded to ObjectGrain! */
91 #define LengthToDeadPool(l) ((l)/ObjectGrain)
92 
93 /* map a dead pool index to the size of blocks held in the pool */
94 #define DeadPoolToLength(d) ((d)*ObjectGrain)
95 /* index of first dead free chain. We start with the previous */
96 /* chain, as older tokenized images can contain objects smaller */
97 /* than our minimum. If these are garbage collected individually, */
98 /* we need a place to put them. */
99 #define FirstDeadPool (LengthToDeadPool(MinimumObjectSize) - 1)
100 /* The largest size element we'll keep in a subpool */
101 #define LargestSubpool 512
102 /* The index of the last subpool dead chain */
103 #define LastDeadPool LengthToDeadPool(LargestSubpool)
104 /* number of free chains (we index zero based, so we need to */
105 /* allocate one additional pool) */
106 #define DeadPools LastDeadPool + 1
107 
108 /* the threshold to trigger expansion of the normal segment set. */
109 #define NormalMemoryExpansionThreshold .30
110 /* The point where we consider releasing segments */
111 #define NormalMemoryContractionThreshold .70
112 
113 /* the sanity check point where we don't force automatic expansion */
114 /* of the normal heap */
115 #define MaxDeadObjectSpace 1000000
116 
117 /* This rounds to segment sized chunks, not taking the overhead into account. */
118 inline size_t roundSegmentBoundary(size_t n) { return RXROUNDUP(n, SegmentSize); }
119 
120 
121 class RexxMemory;
122 
123 /* A segment of heap memory. A MemorySegment will be associated */
124 /* with a particular MemorySegmentSet, which implements the */
125 /* suballocation rules. */
127  friend class MemorySegmentSet;
128  friend class NormalSegmentSet;
129  friend class LargeSegmentSet;
130  friend class OldSegmentSet;
131  friend class RexxMemory;
132 
133  protected:
134  size_t segmentSize; /* size of the segment */
135  size_t liveObjects; /* number of live objects in segment */
136  MemorySegment *next; /* next segment in the chain */
137  MemorySegment *previous; /* previous segment in the chain */
138 };
139 
140 /* A segment of heap memory. A MemorySegment will be associated */
141 /* with a particular MemorySegmentSet, which implements the */
142 /* suballocation rules. */
144  friend class MemorySegmentSet;
145  friend class NormalSegmentSet;
146  friend class LargeSegmentSet;
147  friend class OldSegmentSet;
148  friend class RexxMemory;
149 
150  public:
151  inline void *operator new(size_t size, void *segment) { return segment; }
152  inline void operator delete(void *) { }
153  inline void operator delete(void *, void *) { }
154 
155  inline MemorySegment(size_t segSize) {
156  segmentSize = segSize - sizeof(MemorySegmentHeader);
157  }
158  /* Following is a static constructor, called during RexxMemory */
159  /* initialization */
160  inline MemorySegment() {
161  segmentSize = 0;
162  /* Chain this segment to itself. */
163  next = this;
164  previous = this;
165  }
166 
168  newSegment->next = this->next;
169  newSegment->previous = this;
170  this->next->previous = newSegment;
171  this->next = newSegment;
172  };
173 
175  newSegment->next = this;
176  newSegment->previous = this->previous;
177  this->previous->next = newSegment;
178  this->previous = newSegment;
179  };
180 
181  inline void remove() {
182  this->next->previous = this->previous;
183  this->previous->next = this->next;
184  }
185 
186  inline void removeAll() {
187  firstObject()->remove();
188  remove();
189  }
190 
191  inline bool isInSegment(RexxObject * object) {
192  return (((char *)object >= segmentStart) && ((char *)object <= segmentStart + segmentSize));
193  }
194 
195  inline DeadObject *createDeadObject() { return new ((void *)segmentStart) DeadObject(segmentSize); }
196 
198  inline void combine(MemorySegment *nextSegment) { segmentSize += nextSegment->segmentSize + MemorySegmentOverhead; }
199  inline void shrink(size_t delta) { segmentSize -= delta; }
200  inline bool isAdjacentTo(MemorySegment *seg) { return end() == (char *)seg; }
201  inline bool isLastBlock(char *addr, size_t length) { return (addr + length) == end(); }
202  inline bool isFirstBlock(char *addr) { return addr == start(); }
203 
204  inline size_t size() { return segmentSize; }
205  inline size_t realSize() { return segmentSize + MemorySegmentOverhead; }
206  inline char *start() { return segmentStart; }
207  inline char *end() { return segmentStart + segmentSize; }
208  inline bool isReal() { return segmentSize != 0; }
209  inline bool isEmpty() { return liveObjects == 0; }
210  void dump(const char *owner, size_t counter, FILE *keyfile, FILE *dumpfile);
213  void gatherObjectStats(MemoryStats *memStats, SegmentStats *stats);
214  void markAllObjects();
215 
216  public:
217  char segmentStart[8]; /* start of the object data */
218 };
219 
220 
221 
222 
223 /* A set of memory segments. This manages the access to a pool of */
224 /* memory segments allocated for different uses by RexxMemory. */
225 /* This is a subclass of MemorySegment because the MemorySegmentSet */
226 /* object is also the anchor element for the segment chaining. */
228  friend class RexxMemory;
229 
230  public:
232  /* the memory segment mimic for anchoring the pool */
233  MemorySegmentSet(RexxMemory *memObject, SegmentSetID id, const char *setName) {
234  /* Chain this segment to itself. */
235  owner = id;
236  count = 0;
237  /* keep the link back to the memory object that provides */
238  /* us services. */
239  this->memory = memObject;
240  this->name = setName;
241  }
242  /* the default constructor */
244  /* Chain this segment to itself. */
246  count = 0;
247  /* The link to the memory object will need to be established later */
248  memory = NULL;
249  }
250 
251  virtual ~MemorySegmentSet() { ; }
252  inline void *operator new(size_t size, void *segment) { return segment; }
253  inline void operator delete(void * size) { }
254  inline void operator delete(void * size, void *segment) { }
255 
256  /* Following is a static constructor, called during */
257  /* RexxMemeory initialization */
258 
259  inline void removeSegment(MemorySegment *segment) {
260  /* remove both the segment, and any blocks on the dead */
261  /* chains. */
262  segment->remove();
263  count--;
264  }
265 
266  inline void removeSegmentAndStorage(MemorySegment *segment) {
267  /* remove both the segment, and any blocks on the dead */
268  /* chains. */
269  segment->removeAll();
270  count--;
271  }
272 
273  inline void add(MemorySegment *segment) {
274  anchor.insertBefore(segment);
275  count++;
276  }
277 
278  inline MemorySegment *first() {
279  if (anchor.next->isReal()) {
280  return anchor.next;
281  }
282  else {
283  return NULL;
284  }
285  }
286 
287  inline MemorySegment *next(MemorySegment *segment) {
288  if (segment->next->isReal()) {
289  return segment->next;
290  }
291  else {
292  return NULL;
293  }
294  }
295 
296  inline bool isInSegmentSet(RexxObject *object) {
297  MemorySegment *segment = first();
298  while (segment != NULL) {
299  if (segment->isInSegment(object)) {
300  return true;
301  }
302  segment = next(segment);
303  }
304  return false;
305  }
306 
307 
308  void dumpSegments(FILE *keyfile, FILE *dumpfile);
309  void addSegment(MemorySegment *segment, bool createDeadObject = 1);
310  void sweep();
311  inline bool is(SegmentSetID id) { return owner == id; }
312  void gatherStats(MemoryStats *memStats, SegmentStats *stats);
313 
314 
315  virtual void dumpMemoryProfile(FILE *outfile);
316  virtual DeadObject *donateObject(size_t allocationLength);
317  virtual MemorySegment *donateSegment(size_t allocationLength);
318 
319  protected:
320 
321  virtual void collectEmptySegments();
322  virtual void addDeadObject(DeadObject *object);
323  virtual void addDeadObject(char *object, size_t length);
324  RexxObject *splitDeadObject(DeadObject *object, size_t allocationLength, size_t splitMinimum);
325  void insertSegment(MemorySegment *segment);
326  MemorySegment *findEmptySegment(size_t allocationLength);
327  MemorySegment *splitSegment(size_t allocationLength);
328  void mergeSegments(size_t allocationLength);
330  virtual size_t suggestMemoryExpansion();
331  virtual size_t suggestMemoryContraction();
332  virtual void prepareForSweep();
333  virtual void completeSweepOperation();
336  void adjustMemorySize();
337  void releaseEmptySegments(size_t releaseSize);
338  void releaseSegment(MemorySegment *segment);
339  bool newSegment(size_t requestLength, size_t minimumLength);
340 
341  virtual MemorySegment *allocateSegment(size_t requestLength, size_t minimumLength);
342  inline float freeMemoryPercentage() {return (float)deadObjectBytes/(float)(deadObjectBytes + liveObjectBytes); }
343  inline size_t totalFreeMemory() { return liveObjectBytes + deadObjectBytes; }
344  /* This rounds a size into an even segment multiple, taking the */
345  /* segment overhead into account. */
346  inline size_t calculateSegmentAllocation(size_t n) {
347  size_t size = roundSegmentBoundary(n) - MemorySegmentOverhead;
348  /* this could be true if our size is larger than can fit into a */
349  /* segment once the overhead is considered. If we can't fit, */
350  /* we go over by a segment. */
351  if (size < n) {
352  size += SegmentSize;
353  }
354  return size;
355  }
356  void addSegments(size_t requiredSpace);
357  MemorySegment *getSegment(size_t requestLength, size_t minimumLength);
358  void activateEmptySegments();
359 
360  inline void validateObject(size_t bytes)
361  {
362  #ifdef CHECKOREFS
363  /* is object invalid size? */
364  if (!IsValidSize(bytes)) {
365  /* Yes, this is not good. Exit */
366  /* Critical Section and report */
367  /* unrecoverable error. */
368  Interpreter::logicError("Bad object detected during Garbage Collection, unable to continue");
369  }
370  #endif
371  }
372 
373 
374 
375  MemorySegment anchor; /* the anchor for our active segment chain */
376  MemorySegment emptySegments; /* our empty segment chain (used for reserves) */
377  size_t count; /* the number of elements in the pool */
378  size_t liveObjectBytes; /* bytes allocation to live objects */
379  size_t deadObjectBytes; /* bytes consumed by dead objects */
380  SegmentSetID owner; /* the owner of this segment */
381  const char *name; /* character identifier for debugging/profiling */
382  RexxMemory *memory; /* the hosting memory object */
383 };
384 
385 
387 {
388  public:
389 
390  /* the default constructor */
393  virtual ~NormalSegmentSet() { ; }
394  virtual void dumpMemoryProfile(FILE *outfile);
395  inline RexxObject *allocateObject(size_t allocationLength)
396  {
397  DeadObject *newObject;
398  size_t targetPool;
399  size_t realLength;
400 
401  /* Calculate the dead chain. Note that if this is larger than */
402  /* the largest subpool, the for() loop test below will fail, */
403  /* causing this to drop down to the large block allocation */
404  /* logic. This eliminates an additional check against the */
405  /* large size. */
406  targetPool = LengthToDeadPool(allocationLength);
407 
408  if (targetPool < DeadPools) {
409 
410  /* pick up the last successful one */
411  size_t currentDead = lastUsedSubpool[targetPool];
412  /* loop through the small pool chains looking for a block. */
413  /* We only go up to the largest blocks as a last resort to */
414  /* reduce the fragmentation. */
415  while (currentDead < DeadPools) {
416  /* See if the chain has an object. Once we get an */
417  /* object, we return this directly. We accept over */
418  /* allocations when then come from the subpool chain. */
419  /* Since this is such a heavily hit path, we don't want */
420  /* to absorb the overhead of attempting to split the */
421  /* blocks. For the majority of over allocations, we */
422  /* can't split anyway. When we do split, the result is */
423  /* a very small fragment. */
424  newObject = subpools[currentDead].getFirstSingle();
425  if (newObject != OREF_NULL) {
426  /* Record the success. Next time around, */
427  /* allocations will come directly here. */
428  lastUsedSubpool[targetPool] = currentDead;
429  /* we have a block. Now see if we got this from a */
430  /* higher level chain and have enough room to */
431  /* subdivide into a small block. */
432  /* Convert this from a dead object into a real one of the */
433  /* given size. */
434  return (RexxObject *)newObject;
435  }
436 
437  currentDead++;
438 
439  while (currentDead < DeadPools)
440  {
441  if (lastUsedSubpool[currentDead] < DeadPools)
442  {
443  // this pool might be redirected already, so
444  // pick up the index of where it's redirected to.
445  currentDead = lastUsedSubpool[currentDead];
446  lastUsedSubpool[targetPool] = currentDead;
447  break;
448  }
449  currentDead++;
450  }
451  }
452  /* we've gone all the way to the end without finding */
453  /* anything. Cause the next allocation to skip directly to */
454  /* the large chain. */
455  lastUsedSubpool[targetPool] = DeadPools;
456  }
457  /* Nope, go through the LARGEDEAD object looking for the 1st */
458  /* one we can use either our object is too big for all the */
459  /* small chains, or the small chains are depleted.... */
460  /* Go through the LARGEDEAD object looking for the 1st */
461  /* one we can use either our object is too big for all the */
462  /* small chains, or the small chains are depleted.... */
463  newObject = largeDead.findFit(allocationLength, &realLength);
464  if (newObject != NULL) { /* did we find an object? */
465  size_t deadLength = realLength - allocationLength;
466  /* remainder too small or this is a very large request */
467  /* is the remainder two small to reuse? */
468  if (deadLength < MinimumObjectSize) {
469  /* Convert this from a dead object into a real one of the */
470  /* given size. */
471  return (RexxObject *)newObject;
472  }
473  else {
474  /* potentially split this object into a smaller unit so we */
475  /* can reuse the remainder. */
476  return splitNormalDeadObject(newObject, allocationLength, deadLength);
477  }
478  }
479  return OREF_NULL;
480  }
481 
482  RexxObject *handleAllocationFailure(size_t allocationLength);
483  virtual DeadObject *donateObject(size_t allocationLength);
484  void getInitialSet();
485  virtual size_t suggestMemoryExpansion();
486  virtual size_t suggestMemoryContraction();
487 
488  protected:
489  virtual void addDeadObject(DeadObject *object);
490  virtual void addDeadObject(char *object, size_t length);
491  virtual void prepareForSweep();
492  void completeSweepOperation();
493 
494  private:
495 
496  inline size_t mapLengthToDeadPool(size_t length) { return length/ObjectGrain; }
497  RexxObject *findLargeDeadObject(size_t allocationLength);
498  inline size_t recommendedMemorySize() { return (size_t)((float)liveObjectBytes/(1.0 - NormalMemoryExpansionThreshold)); }
499  inline size_t recommendedMaximumMemorySize() { return (size_t)((float)liveObjectBytes/(1.0 - NormalMemoryContractionThreshold)); }
500  void checkObjectOverlap(DeadObject *obj);
501  RexxObject *findObject(size_t allocationLength);
502  inline RexxObject *splitNormalDeadObject(DeadObject *object, size_t allocationLength, size_t deadLength)
503  {
504  /* we need to keep all of these sizes as ObjectGrain multiples, */
505  /* so round it down...the allocation will get all of the extra. */
506  /* deadLength = rounddown(deadLength, ObjectGrain);
507  allocationLength is rounded, deadLength might be
508  an ungrained object size from old tokenized format */
509 
510  /* Yes, so pull new object out of the front of the dead */
511  /* object, adjust the size of the Dead object. We want */
512  /* to use the front rather than the back so that if we */
513  /* hit the need to split a segment because of low memory */
514  /* conditions, we increase the probability that we'll be */
515  /* able to use the end of the segment. */
516  DeadObject *largeObject = (DeadObject *)(((char *)object) + allocationLength);
517  /* if the length is larger than the biggest subpool we */
518  /* maintain, we add this to the large block list. */
519  if (deadLength > LargestSubpool) {
520  /* ideally, we'd like to add this sorted by size, but */
521  /* this is called so frequently, attempting to sort */
522  /* degrades performance by about 10%. */
523  largeDead.add(new (largeObject) DeadObject(deadLength));
524  }
525  else {
526  /* calculate the dead chain */
527  /* and add that to the appropriate chain */
528  size_t deadChain = LengthToDeadPool(deadLength);
529  subpools[deadChain].addSingle(new (largeObject) DeadObject(deadLength));
530  /* we can mark this subpool as having items again */
531  lastUsedSubpool[deadChain] = deadChain;
532  }
533  /* Convert this from a dead object into a real one of the */
534  /* given size. */
535  ((RexxObject *)object)->setObjectSize(allocationLength);
536  return (RexxObject *)object;
537  }
538 
539  DeadObjectPool largeDead; /* the set of large dead objects */
540  DeadObjectPool subpools[DeadPools]; /* our set of allocation subpools */
541  size_t lastUsedSubpool[DeadPools + 1];/* a look-aside index to tell us what pool to use for a given size */
542  MemorySegment *recoverSegment; /* our last-ditch memory segment */
543 };
544 
545 
547 {
548  public:
549 
550  /* the default constructor */
553  virtual ~LargeSegmentSet() { ; }
554  virtual void dumpMemoryProfile(FILE *outfile);
555  RexxObject *handleAllocationFailure(size_t allocationLength);
556  inline RexxObject *allocateObject(size_t allocationLength)
557  {
558  DeadObject *largeObject;
559 
560  /* go through the LARGEDEAD object looking for the 1st one we can */
561  /* use either our object is too big for all the small chains, or */
562  /* the small chain are depleted.... */
563  largeObject = deadCache.findBestFit(allocationLength);
564  /* did we find an object? */
565  if (largeObject != NULL) {
566  /* remember the successful request */
567  requests++;
568  /* split and prepare this object for use */
569  return splitDeadObject(largeObject, allocationLength, LargeAllocationUnit);
570  }
571  return OREF_NULL; /* we couldn't get this */
572  }
573 
574  virtual DeadObject *donateObject(size_t allocationLength);
575 
576 protected:
577 
578  virtual void addDeadObject(DeadObject *object);
579  virtual void addDeadObject(char *object, size_t length);
580  virtual MemorySegment *allocateSegment(size_t requestLength, size_t minimumLength);
581  void expandOrCollect(size_t allocationLength);
582  void expandSegmentSet(size_t allocationLength);
583  virtual void prepareForSweep();
584  void completeSweepOperation();
585 
586  private:
587 
588  RexxObject *findObject(size_t allocationLength);
589 
590  DeadObjectPool deadCache; /* the set of large dead objects */
591  size_t requests; /* requests since last gc cycle. */
592  size_t smallestObject; // the smallest object in the set
593  size_t largestObject; // the largest object in the set
594 };
595 
596 
598 {
599  public:
600 
601  /* the default constructor */
604  virtual ~OldSpaceSegmentSet() { ; }
605  RexxObject *allocateObject(size_t allocationLength);
606 
607  void markOldSpaceObjects();
608 
609  protected:
610  virtual void addDeadObject(DeadObject *object);
611  virtual void addDeadObject(char *object, size_t length);
612  RexxObject *findObject(size_t allocationLength);
613 
614  private:
615  DeadObjectPool deadCache; /* the set of objects on the old dead chain */
616 };
617 
618 #endif
MemorySegment::MemorySegment
MemorySegment(size_t segSize)
Definition: MemorySegment.hpp:155
MemorySegment::removeAll
void removeAll()
Definition: MemorySegment.hpp:186
DeadObject
Definition: DeadObject.hpp:59
MemorySegmentSet::dumpSegments
void dumpSegments(FILE *keyfile, FILE *dumpfile)
Definition: MemorySegment.cpp:120
MemorySegmentSet::insertSegment
void insertSegment(MemorySegment *segment)
NormalSegmentSet::handleAllocationFailure
RexxObject * handleAllocationFailure(size_t allocationLength)
Definition: MemorySegment.cpp:1263
DeadPools
#define DeadPools
Definition: MemorySegment.hpp:106
SegmentStats
Definition: MemoryStats.hpp:68
MemorySegment::insertBefore
void insertBefore(MemorySegment *newSegment)
Definition: MemorySegment.hpp:174
MemorySegmentSet::addSegments
void addSegments(size_t requiredSpace)
Definition: MemorySegment.cpp:956
MemorySegmentSet::donateSegment
virtual MemorySegment * donateSegment(size_t allocationLength)
Definition: MemorySegment.cpp:558
RexxMemory
Definition: RexxMemory.hpp:169
DeadObjectPool::addSingle
void addSingle(DeadObject *obj)
Definition: DeadObject.hpp:262
DeadObjectPool::getFirstSingle
DeadObject * getFirstSingle()
Definition: DeadObject.hpp:270
NormalSegmentSet::mapLengthToDeadPool
size_t mapLengthToDeadPool(size_t length)
Definition: MemorySegment.hpp:496
MemorySegment::shrink
void shrink(size_t delta)
Definition: MemorySegment.hpp:199
MemorySegment::OldSegmentSet
friend class OldSegmentSet
Definition: MemorySegment.hpp:147
MemorySegmentSet::deadObjectBytes
size_t deadObjectBytes
Definition: MemorySegment.hpp:379
DeadObject.hpp
MemorySegmentSet::calculateSegmentAllocation
size_t calculateSegmentAllocation(size_t n)
Definition: MemorySegment.hpp:346
OldSpaceSegmentSet::~OldSpaceSegmentSet
virtual ~OldSpaceSegmentSet()
Definition: MemorySegment.hpp:604
MemorySegmentSet::SegmentSetID
SegmentSetID
Definition: MemorySegment.hpp:231
MemorySegment::combine
void combine(MemorySegment *nextSegment)
Definition: MemorySegment.hpp:198
MemorySegment::isAdjacentTo
bool isAdjacentTo(MemorySegment *seg)
Definition: MemorySegment.hpp:200
MemorySegmentSet::MemorySegmentSet
MemorySegmentSet()
Definition: MemorySegment.hpp:243
MemorySegmentSet::addDeadObject
virtual void addDeadObject(DeadObject *object)
Definition: MemorySegment.cpp:350
LargestSubpool
#define LargestSubpool
Definition: MemorySegment.hpp:101
MemorySegmentSet::SET_OLDSPACE
Definition: MemorySegment.hpp:231
LargeSegmentSet
Definition: MemorySegment.hpp:546
LargeAllocationUnit
#define LargeAllocationUnit
Definition: RexxMemory.hpp:76
NormalSegmentSet::~NormalSegmentSet
virtual ~NormalSegmentSet()
Definition: MemorySegment.hpp:393
OldSpaceSegmentSet::OldSpaceSegmentSet
OldSpaceSegmentSet()
Definition: MemorySegment.hpp:602
ObjectGrain
#define ObjectGrain
Definition: RexxMemory.hpp:74
NormalSegmentSet::lastUsedSubpool
size_t lastUsedSubpool[((512)/ObjectGrain)+1+1]
Definition: MemorySegment.hpp:541
LargeSegmentSet::prepareForSweep
virtual void prepareForSweep()
Definition: MemorySegment.cpp:1030
RexxMemory::newSegment
MemorySegment * newSegment(size_t requestLength, size_t minLength)
Definition: RexxMemory.cpp:713
MemorySegmentSet::allocateSegment
virtual MemorySegment * allocateSegment(size_t requestLength, size_t minimumLength)
Definition: MemorySegment.cpp:249
DeadObjectPool::findBestFit
DeadObject * findBestFit(size_t length)
Definition: DeadObject.cpp:66
MemorySegmentSet::count
size_t count
Definition: MemorySegment.hpp:377
MemorySegmentSet::SET_LARGEBLOCK
Definition: MemorySegment.hpp:231
OldSpaceSegmentSet::deadCache
DeadObjectPool deadCache
Definition: MemorySegment.hpp:615
LargeSegmentSet::expandOrCollect
void expandOrCollect(size_t allocationLength)
Definition: MemorySegment.cpp:1473
MemorySegmentSet::activateEmptySegments
void activateEmptySegments()
Definition: MemorySegment.cpp:310
MemorySegmentSet::splitDeadObject
RexxObject * splitDeadObject(DeadObject *object, size_t allocationLength, size_t splitMinimum)
Definition: MemorySegment.cpp:1190
MemorySegmentSet::add
void add(MemorySegment *segment)
Definition: MemorySegment.hpp:273
MemorySegmentHeader::segmentSize
size_t segmentSize
Definition: MemorySegment.hpp:134
MemorySegmentHeader
Definition: MemorySegment.hpp:126
MemorySegmentSet::isInSegmentSet
bool isInSegmentSet(RexxObject *object)
Definition: MemorySegment.hpp:296
LargeSegmentSet::allocateObject
RexxObject * allocateObject(size_t allocationLength)
Definition: MemorySegment.hpp:556
MemorySegmentSet::validateObject
void validateObject(size_t bytes)
Definition: MemorySegment.hpp:360
MemorySegmentSet::collectEmptySegments
virtual void collectEmptySegments()
Definition: MemorySegment.cpp:1181
NormalSegmentSet
Definition: MemorySegment.hpp:386
MemorySegmentSet::MemorySegmentSet
MemorySegmentSet(RexxMemory *memObject, SegmentSetID id, const char *setName)
Definition: MemorySegment.hpp:233
LargeSegmentSet::LargeSegmentSet
LargeSegmentSet()
Definition: MemorySegment.hpp:551
LargeSegmentSet::findObject
RexxObject * findObject(size_t allocationLength)
Definition: MemorySegment.cpp:1320
LargeSegmentSet::expandSegmentSet
void expandSegmentSet(size_t allocationLength)
Definition: MemorySegment.cpp:1700
MemorySegmentOverhead
#define MemorySegmentOverhead
Definition: MemorySegment.hpp:52
MemorySegmentSet::is
bool is(SegmentSetID id)
Definition: MemorySegment.hpp:311
OldSpaceSegmentSet::addDeadObject
virtual void addDeadObject(DeadObject *object)
Definition: MemorySegment.cpp:369
MemorySegmentSet::adjustMemorySize
void adjustMemorySize()
Definition: MemorySegment.cpp:872
MemorySegmentSet::suggestMemoryContraction
virtual size_t suggestMemoryContraction()
Definition: MemorySegment.cpp:831
LargeSegmentSet::addDeadObject
virtual void addDeadObject(DeadObject *object)
Definition: MemorySegment.cpp:359
MemorySegment::segmentStart
char segmentStart[8]
Definition: MemorySegment.hpp:217
RXROUNDUP
#define RXROUNDUP(n, to)
Definition: RexxCore.h:208
Interpreter.hpp
OldSpaceSegmentSet
Definition: MemorySegment.hpp:597
MemorySegmentSet::largestEmptySegment
MemorySegment * largestEmptySegment()
Definition: MemorySegment.cpp:1451
NormalSegmentSet::subpools
DeadObjectPool subpools[((512)/ObjectGrain)+1]
Definition: MemorySegment.hpp:540
LargeSegmentSet::smallestObject
size_t smallestObject
Definition: MemorySegment.hpp:592
MemorySegment::markAllObjects
void markAllObjects()
Definition: MemorySegment.cpp:1773
IsValidSize
#define IsValidSize(s)
Definition: RexxMemory.hpp:93
NormalSegmentSet::suggestMemoryExpansion
virtual size_t suggestMemoryExpansion()
Definition: MemorySegment.cpp:786
roundSegmentBoundary
size_t roundSegmentBoundary(size_t n)
Definition: MemorySegment.hpp:118
MemorySegment
Definition: MemorySegment.hpp:143
MemorySegmentSet::owner
SegmentSetID owner
Definition: MemorySegment.hpp:380
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
NormalSegmentSet::getInitialSet
void getInitialSet()
Definition: MemorySegment.cpp:239
MemorySegmentSet::largestActiveSegment
MemorySegment * largestActiveSegment()
Definition: MemorySegment.cpp:1429
LargeSegmentSet::allocateSegment
virtual MemorySegment * allocateSegment(size_t requestLength, size_t minimumLength)
Definition: MemorySegment.cpp:258
MemorySegment::realSize
size_t realSize()
Definition: MemorySegment.hpp:205
MemorySegmentSet::completeSweepOperation
virtual void completeSweepOperation()
Definition: MemorySegment.cpp:1046
MemorySegment::isEmpty
bool isEmpty()
Definition: MemorySegment.hpp:209
MemorySegmentSet::newSegment
bool newSegment(size_t requestLength, size_t minimumLength)
Definition: MemorySegment.cpp:332
MemorySegmentSet::first
MemorySegment * first()
Definition: MemorySegment.hpp:278
LargeSegmentSet::~LargeSegmentSet
virtual ~LargeSegmentSet()
Definition: MemorySegment.hpp:553
MemorySegmentSet::memory
RexxMemory * memory
Definition: MemorySegment.hpp:382
NormalSegmentSet::largeDead
DeadObjectPool largeDead
Definition: MemorySegment.hpp:539
MemorySegmentSet::splitSegment
MemorySegment * splitSegment(size_t allocationLength)
Definition: MemorySegment.cpp:578
MemorySegment::createDeadObject
DeadObject * createDeadObject()
Definition: MemorySegment.hpp:195
MemorySegment::isInSegment
bool isInSegment(RexxObject *object)
Definition: MemorySegment.hpp:191
MemorySegmentSet::suggestMemoryExpansion
virtual size_t suggestMemoryExpansion()
Definition: MemorySegment.cpp:817
MemorySegmentSet::mergeSegments
void mergeSegments(size_t allocationLength)
Definition: MemorySegment.cpp:1533
MemorySegment::firstObject
DeadObject * firstObject()
Definition: MemorySegment.hpp:197
MemorySegmentSet::dumpMemoryProfile
virtual void dumpMemoryProfile(FILE *outfile)
Definition: MemorySegment.cpp:134
MemorySegmentSet::~MemorySegmentSet
virtual ~MemorySegmentSet()
Definition: MemorySegment.hpp:251
NormalSegmentSet::NormalSegmentSet
NormalSegmentSet()
Definition: MemorySegment.hpp:391
MemoryStats
Definition: MemoryStats.hpp:97
MemorySegment::remove
void remove()
Definition: MemorySegment.hpp:181
MemorySegmentSet::emptySegments
MemorySegment emptySegments
Definition: MemorySegment.hpp:376
OldSpaceSegmentSet::markOldSpaceObjects
void markOldSpaceObjects()
Definition: MemorySegment.cpp:1796
LargeSegmentSet::deadCache
DeadObjectPool deadCache
Definition: MemorySegment.hpp:590
LargeSegmentSet::largestObject
size_t largestObject
Definition: MemorySegment.hpp:593
NormalSegmentSet::splitNormalDeadObject
RexxObject * splitNormalDeadObject(DeadObject *object, size_t allocationLength, size_t deadLength)
Definition: MemorySegment.hpp:502
MemorySegment::isReal
bool isReal()
Definition: MemorySegment.hpp:208
SegmentSize
#define SegmentSize
Definition: MemorySegment.hpp:62
OldSpaceSegmentSet::findObject
RexxObject * findObject(size_t allocationLength)
Definition: MemorySegment.cpp:1381
NormalSegmentSet::suggestMemoryContraction
virtual size_t suggestMemoryContraction()
Definition: MemorySegment.cpp:844
LargeSegmentSet::dumpMemoryProfile
virtual void dumpMemoryProfile(FILE *outfile)
Definition: MemorySegment.cpp:142
NormalSegmentSet::findLargeDeadObject
RexxObject * findLargeDeadObject(size_t allocationLength)
Definition: MemorySegment.cpp:1230
MemorySegmentHeader::previous
MemorySegment * previous
Definition: MemorySegment.hpp:137
MemorySegmentSet::donateObject
virtual DeadObject * donateObject(size_t allocationLength)
Definition: MemorySegment.cpp:518
MinimumObjectSize
#define MinimumObjectSize
Definition: RexxMemory.hpp:85
MemorySegment::gatherObjectStats
void gatherObjectStats(MemoryStats *memStats, SegmentStats *stats)
Definition: MemorySegment.cpp:104
MemorySegmentSet::getSegment
MemorySegment * getSegment(size_t requestLength, size_t minimumLength)
Definition: MemorySegment.cpp:267
NormalSegmentSet::recoverSegment
MemorySegment * recoverSegment
Definition: MemorySegment.hpp:542
MemorySegmentSet::sweep
void sweep()
Definition: MemorySegment.cpp:1106
MemorySegment::firstDeadObject
DeadObject * firstDeadObject()
Definition: MemorySegment.cpp:89
MemorySegmentSet::totalFreeMemory
size_t totalFreeMemory()
Definition: MemorySegment.hpp:343
MemorySegment::lastDeadObject
DeadObject * lastDeadObject()
Definition: MemorySegment.cpp:62
NormalSegmentSet::addDeadObject
virtual void addDeadObject(DeadObject *object)
Definition: MemorySegment.cpp:379
MemorySegmentSet::SET_UNINITIALIZED
Definition: MemorySegment.hpp:231
MemorySegmentSet::combineEmptySegments
void combineEmptySegments(MemorySegment *front, MemorySegment *back)
Definition: MemorySegment.cpp:1672
MemorySegment::MemorySegment
MemorySegment()
Definition: MemorySegment.hpp:160
NormalSegmentSet::completeSweepOperation
void completeSweepOperation()
Definition: MemorySegment.cpp:1054
DeadObjectPool
Definition: DeadObject.hpp:131
DeadObjectPool::add
void add(DeadObject *obj)
Definition: DeadObject.hpp:161
MemorySegmentSet::releaseSegment
void releaseSegment(MemorySegment *segment)
Definition: MemorySegment.cpp:947
MemorySegmentSet::prepareForSweep
virtual void prepareForSweep()
Definition: MemorySegment.cpp:1003
MemorySegmentHeader::liveObjects
size_t liveObjects
Definition: MemorySegment.hpp:135
MemorySegmentSet::next
MemorySegment * next(MemorySegment *segment)
Definition: MemorySegment.hpp:287
NormalSegmentSet::findObject
RexxObject * findObject(size_t allocationLength)
Definition: MemorySegment.cpp:1252
DeadObject::remove
void remove()
Definition: DeadObject.hpp:101
MemorySegment::isLastBlock
bool isLastBlock(char *addr, size_t length)
Definition: MemorySegment.hpp:201
MemorySegment::isFirstBlock
bool isFirstBlock(char *addr)
Definition: MemorySegment.hpp:202
MemorySegmentSet::removeSegmentAndStorage
void removeSegmentAndStorage(MemorySegment *segment)
Definition: MemorySegment.hpp:266
NormalSegmentSet::allocateObject
RexxObject * allocateObject(size_t allocationLength)
Definition: MemorySegment.hpp:395
OldSpaceSegmentSet::allocateObject
RexxObject * allocateObject(size_t allocationLength)
Definition: MemorySegment.cpp:1401
MemorySegment::start
char * start()
Definition: MemorySegment.hpp:206
MemorySegmentHeader::OldSegmentSet
friend class OldSegmentSet
Definition: MemorySegment.hpp:130
MemorySegment::dump
void dump(const char *owner, size_t counter, FILE *keyfile, FILE *dumpfile)
Definition: MemorySegment.cpp:48
MemorySegmentHeader::next
MemorySegment * next
Definition: MemorySegment.hpp:136
LargeSegmentSet::donateObject
virtual DeadObject * donateObject(size_t allocationLength)
Definition: MemorySegment.cpp:543
LargeSegmentSet::completeSweepOperation
void completeSweepOperation()
Definition: MemorySegment.cpp:1093
MemorySegmentSet::liveObjectBytes
size_t liveObjectBytes
Definition: MemorySegment.hpp:378
NormalSegmentSet::checkObjectOverlap
void checkObjectOverlap(DeadObject *obj)
Definition: MemorySegment.cpp:170
NormalSegmentSet::donateObject
virtual DeadObject * donateObject(size_t allocationLength)
Definition: MemorySegment.cpp:530
MemorySegment::end
char * end()
Definition: MemorySegment.hpp:207
MemorySegment::size
size_t size()
Definition: MemorySegment.hpp:204
LargeSegmentSet::handleAllocationFailure
RexxObject * handleAllocationFailure(size_t allocationLength)
Definition: MemorySegment.cpp:1331
NormalMemoryExpansionThreshold
#define NormalMemoryExpansionThreshold
Definition: MemorySegment.hpp:109
LargeSegmentSet::requests
size_t requests
Definition: MemorySegment.hpp:591
MemorySegmentSet::anchor
MemorySegment anchor
Definition: MemorySegment.hpp:375
NormalSegmentSet::prepareForSweep
virtual void prepareForSweep()
Definition: MemorySegment.cpp:1013
MemorySegmentSet::gatherStats
void gatherStats(MemoryStats *memStats, SegmentStats *stats)
Definition: MemorySegment.cpp:1756
MemorySegmentSet::name
const char * name
Definition: MemorySegment.hpp:381
Interpreter::logicError
static void logicError(const char *desc)
Definition: Interpreter.cpp:553
MemorySegment::insertAfter
void insertAfter(MemorySegment *newSegment)
Definition: MemorySegment.hpp:167
MemorySegmentSet
Definition: MemorySegment.hpp:227
MemorySegmentSet::removeSegment
void removeSegment(MemorySegment *segment)
Definition: MemorySegment.hpp:259
MemorySegmentSet::findEmptySegment
MemorySegment * findEmptySegment(size_t allocationLength)
Definition: MemorySegment.cpp:289
NormalSegmentSet::recommendedMemorySize
size_t recommendedMemorySize()
Definition: MemorySegment.hpp:498
NormalSegmentSet::recommendedMaximumMemorySize
size_t recommendedMaximumMemorySize()
Definition: MemorySegment.hpp:499
MemorySegmentSet::releaseEmptySegments
void releaseEmptySegments(size_t releaseSize)
Definition: MemorySegment.cpp:915
NormalSegmentSet::dumpMemoryProfile
virtual void dumpMemoryProfile(FILE *outfile)
Definition: MemorySegment.cpp:153
MemorySegmentSet::addSegment
void addSegment(MemorySegment *segment, bool createDeadObject=1)
Definition: MemorySegment.cpp:473
RexxObject
Definition: ObjectClass.hpp:311
LengthToDeadPool
#define LengthToDeadPool(l)
Definition: MemorySegment.hpp:91
MemorySegmentSet::SET_NORMAL
Definition: MemorySegment.hpp:231
DeadObjectPool::findFit
DeadObject * findFit(size_t length)
Definition: DeadObject.hpp:193
MemorySegmentSet::freeMemoryPercentage
float freeMemoryPercentage()
Definition: MemorySegment.hpp:342
NormalMemoryContractionThreshold
#define NormalMemoryContractionThreshold
Definition: MemorySegment.hpp:111