StackClass.cpp
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 */
40 /* */
41 /* Primitive Stack Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StackClass.hpp"
47 
49  size_t _size) /* elements in the stack */
50 /******************************************************************************/
51 /* Function: Initialize a primitive stack. */
52 /******************************************************************************/
53 {
54  this->clearObject(); /* clear entire stack */
55  this->size = _size; /* set the size */
56  this->top = 0; /* and we're set at the top */
57 }
58 
59 
61  size_t _size) /* elements in the stack */
62 /******************************************************************************/
63 /* Function: Initialize a primitive stack early in memory set up */
64 /******************************************************************************/
65 {
66  this->clearObject(); /* clear entire stack */
67  this->size = _size; /* set the size */
68  this->top = 0; /* and we're set at the top */
69 }
70 
71 void RexxStack::live(size_t liveMark)
72 /******************************************************************************/
73 /* Function: Normal garbage collection live marking */
74 /******************************************************************************/
75 {
76  RexxObject **rp;
77 
78  for (rp = this->stack; rp < this->stack+this->stackSize(); rp++)
79  {
80  memory_mark(*rp);
81  }
82 }
83 
84 void RexxStack::liveGeneral(int reason)
85 /******************************************************************************/
86 /* Function: Generalized object marking */
87 /******************************************************************************/
88 {
89  RexxObject **rp;
90 
91  for (rp = this->stack; rp < this->stack+this->stackSize(); rp++)
92  {
94  }
95 }
96 
97 
99 /******************************************************************************/
100 /* Function: Flatten an object */
101 /******************************************************************************/
102 {
104  for (size_t i=0; i < this->stackSize(); i++ )
105  {
106  flatten_reference(newThis->stack[i], envelope);
107  }
109 }
110 
112 /******************************************************************************/
113 /* Function: Get a specific stack element */
114 /******************************************************************************/
115 {
116  if (pos < this->stackSize())
117  {
118  return *(this->stack+(this->stackSize()+this->top-pos)%this->stackSize());
119  }
120  else
121  {
122  return OREF_NULL;
123  }
124 }
125 
127 /******************************************************************************/
128 /* Function: Pop an element from the stack */
129 /******************************************************************************/
130 {
131  RexxObject *object = *(this->stack + this->top); /* get the new item */
132  /* needed by memory_alloc */
133  OrefSet(this, *(this->stack+this->top), OREF_NULL);
134  decrementTop(); /* move the top pointer (and potentially wrap) */
135  return object; /* return the object */
136 }
137 
139 /******************************************************************************/
140 /* Function: Get top stack element, which is removed from the stack */
141 /* */
142 /* This "fast pop" method doesn't null out the popped stack entry and can */
143 /* therefore leave spurious object references in the stack. It is used by */
144 /* memory_collect for mobj.livestack, where speed is of the essence and the */
145 /* spurious references have no effect. */
146 /******************************************************************************/
147 {
148  RexxObject *object = *(this->stack + this->top); /* get the top item */
149  decrementTop(); /* move the top pointer (and potentially wrap) */
150  return object; /* return the object */
151 }
152 
153 void *RexxStack::operator new(
154  size_t size, /* Object size */
155  size_t stksize, /* stack size */
156  bool temporary ) /* this is a temporary one */
157 /******************************************************************************/
158 /* Function: Create a new translator object */
159 /******************************************************************************/
160 {
161  RexxObject *newObject; /* the new atack */
162 
163  if (!temporary) /* normal stack object? */
164  {
165  /* Get new object */
166  newObject = new_object(size + ((stksize-1) * sizeof(RexxObject *)), T_Stack);
167  }
168  else
169  {
170  /* Get new object */
171  newObject = memoryObject.temporaryObject(size + ((stksize-1) * sizeof(RexxObject *)));
172  /* set the behaviour */
173  newObject->setBehaviour(TheStackBehaviour);
174  }
175  return newObject; /* return the new object */
176 }
177 
178 
180  size_t _size, /* elements in the stack */
181  size_t aSize) /* size to allocate! */
182  : RexxStack(_size)
183 /******************************************************************************/
184 /* Function: Initialize a primitive stack. */
185 /******************************************************************************/
186 {
187  this->allocSize = aSize;
188 }
189 
191  size_t _size, /* elements in the stack */
192  size_t aSize) /* size to allocate */
193 /******************************************************************************/
194 /* Function: Initialize a primitive stack early in memory set up */
195 /******************************************************************************/
196 {
197  this->clearObject(); /* clear entire stack */
198  this->size = _size; /* set the size */
199  this->top = 0; /* set the element to the top */
200  this->allocSize = aSize;
201 }
202 
203 void *RexxSaveStack::operator new(
204  size_t size, /* Object size */
205  size_t allocSize ) /* size to allocate */
206 /******************************************************************************/
207 /* Function: Create a new translator object */
208 /******************************************************************************/
209 {
210  /* Get new object */
211  return new_object(size + ((allocSize-1) * sizeof(RexxObject *)), T_Stack);
212 }
213 
215  size_t newSize) /* new size to use */
216 /******************************************************************************/
217 /* Function: Extend the usable size of the save stack */
218 /******************************************************************************/
219 {
220  if (newSize < this->allocSize)
221  {
222  this->size = newSize;
223  }
224 }
225 
227  RexxObject *element, /* object to remove from save stack */
228  bool search) /* search through whole savestack? */
229 {
230  size_t i;
231 
232  /* I remember top element so that this operation is not disturbed by */
233  /* another thread pushing something onto the savestack */
234 
235  /* first check top element */
236  i = this->top;
237 
238  if (this->stack[i] == element)
239  {
240  this->stack[i] = OREF_NULL;
241  if (i == this->top)
242  {
243  this->top--;
244  }
245  }
246  else
247  {
248  /* not top element, search it if requested */
249  if (search)
250  {
251  for (i=0; i<this->size; i++)
252  {
253  if (this->stack[i] == element)
254  {
255  this->stack[i] = OREF_NULL;
256  break;
257  }
258  }
259  }
260  }
261 }
262 
263 #define SAVE_THRESHOLD 5
264 
265 void RexxSaveStack::live(size_t liveMark)
266 /******************************************************************************/
267 /* Function: Normal garbage collection live marking */
268 /******************************************************************************/
269 {
270  RexxObject **rp;
271 
272  for (rp = this->stack; rp < this->stack+this->stackSize(); rp++)
273  {
274  RexxObject *thisObject = *rp; /* get the next object in the stack */
275  if (thisObject == OREF_NULL)
276  {
277  continue; /* an empty entry? just go on */
278  }
279  /* if the object has already been marked, */
280  else if (thisObject->isObjectMarked(liveMark))
281  {
282  *rp = OREF_NULL; /* we can clear this out now, rather than keeping it in the stack */
283  }
284  else
285  {
286  /* this is an object we need to keep alive, but we'll only */
287  /* do this for one GC cycle. We'll clear this out now, to */
288  /* make sure we don't keep this pinned longer than */
289  /* necessary. */
290  memory_mark(*rp);
291  *rp = OREF_NULL;
292  }
293  }
294 }
295 
@ T_Stack
#define TheStackBehaviour
#define OREF_NULL
Definition: RexxCore.h:60
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
RexxMemory memoryObject
Definition: RexxMemory.cpp:85
#define memory_mark(oref)
Definition: RexxMemory.hpp:445
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:431
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:493
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:446
#define cleanUpFlatten
Definition: RexxMemory.hpp:479
#define setUpFlatten(type)
Definition: RexxMemory.hpp:473
void setBehaviour(RexxBehaviour *b)
bool isObjectMarked(size_t markword)
RexxObject * temporaryObject(size_t size)
void remove(RexxObject *, bool search=false)
Definition: StackClass.cpp:226
void extend(size_t)
Definition: StackClass.cpp:214
size_t allocSize
Definition: StackClass.hpp:97
void live(size_t)
Definition: StackClass.cpp:265
RexxSaveStack(size_t, size_t)
Definition: StackClass.cpp:179
void init(size_t, size_t)
Definition: StackClass.cpp:190
void init(size_t)
Definition: StackClass.cpp:60
void live(size_t)
Definition: StackClass.cpp:71
void flatten(RexxEnvelope *)
Definition: StackClass.cpp:98
void liveGeneral(int reason)
Definition: StackClass.cpp:84
RexxObject * fpop()
Definition: StackClass.cpp:138
void decrementTop()
Definition: StackClass.hpp:75
size_t size
Definition: StackClass.hpp:80
RexxObject * stack[1]
Definition: StackClass.hpp:82
size_t stackSize()
Definition: StackClass.hpp:73
RexxObject * pop()
Definition: StackClass.cpp:126
RexxStack(RESTORETYPE restoreType)
Definition: StackClass.hpp:55
size_t top
Definition: StackClass.hpp:81
RexxObject * get(size_t pos)
Definition: StackClass.cpp:111