Source code: Allocator/HeapAllocator.java
1 // HeapAllocator.java, created Tue Feb 27 2:52:57 2001 by joewhaley
2 // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3 // Licensed under the terms of the GNU LGPL; see COPYING for details.
4 package Allocator;
5
6 import java.lang.reflect.Array;
7
8 import Bootstrap.PrimordialClassLoader;
9 import Clazz.jq_Array;
10 import Clazz.jq_Class;
11 import Clazz.jq_ClassFileConstants;
12 import Clazz.jq_Reference;
13 import Clazz.jq_StaticMethod;
14 import Clazz.jq_Type;
15 import Memory.Address;
16 import Memory.HeapAddress;
17 import Memory.Heap.Heap;
18 import Run_Time.SystemInterface;
19 import Util.Assert;
20
21 /**
22 * HeapAllocator
23 *
24 * @author John Whaley <jwhaley@alum.mit.edu>
25 * @version $Id: HeapAllocator.java,v 1.16 2003/05/12 10:04:52 joewhaley Exp $
26 */
27 public abstract class HeapAllocator implements jq_ClassFileConstants {
28
29 //// ABSTRACT METHODS THAT ALLOCATORS NEED TO IMPLEMENT.
30
31 /** Perform initialization for this allocator. This will be called before any other methods.
32 *
33 * @throws OutOfMemoryError if there is not enough memory for initialization
34 */
35 public abstract void init()
36 throws OutOfMemoryError;
37
38 /** Allocate an object with the default alignment.
39 * If the object cannot be allocated due to lack of memory, throws OutOfMemoryError.
40 *
41 * @param size size of object to allocate (including object header), in bytes
42 * @param vtable vtable pointer for new object
43 * @return new uninitialized object
44 * @throws OutOfMemoryError if there is insufficient memory to perform the operation
45 */
46 public abstract Object allocateObject(int size, Object vtable)
47 throws OutOfMemoryError;
48
49 /** Allocate an object such that the first field is 8-byte aligned.
50 * If the object cannot be allocated due to lack of memory, throws OutOfMemoryError.
51 *
52 * @param size size of object to allocate (including object header), in bytes
53 * @param vtable vtable pointer for new object
54 * @return new uninitialized object
55 * @throws OutOfMemoryError if there is insufficient memory to perform the operation
56 */
57 public abstract Object allocateObjectAlign8(int size, Object vtable)
58 throws OutOfMemoryError;
59
60 /** Allocate an array with the default alignment.
61 * If length is negative, throws NegativeArraySizeException.
62 * If the array cannot be allocated due to lack of memory, throws OutOfMemoryError.
63 *
64 * @param length length of new array
65 * @param size size of array to allocate (including array header), in bytes
66 * @param vtable vtable pointer for new array
67 * @return new array
68 * @throws NegativeArraySizeException if length is negative
69 * @throws OutOfMemoryError if there is insufficient memory to perform the operation
70 */
71 public abstract Object allocateArray(int length, int size, Object vtable)
72 throws OutOfMemoryError, NegativeArraySizeException;
73
74 /** Allocate an array such that the elements are 8-byte aligned.
75 * If length is negative, throws NegativeArraySizeException.
76 * If the array cannot be allocated due to lack of memory, throws OutOfMemoryError.
77 *
78 * @param length length of new array
79 * @param size size of array to allocate (including array header), in bytes
80 * @param vtable vtable pointer for new array
81 * @return new array
82 * @throws NegativeArraySizeException if length is negative
83 * @throws OutOfMemoryError if there is insufficient memory to perform the operation
84 */
85 public abstract Object allocateArrayAlign8(int length, int size, Object vtable)
86 throws OutOfMemoryError, NegativeArraySizeException;
87
88 /** Returns an estimate of the amount of free memory available.
89 *
90 * @return bytes of free memory
91 */
92 public abstract int freeMemory();
93
94 /** Returns an estimate of the total memory allocated (both used and unused).
95 *
96 * @return bytes of memory allocated
97 */
98 public abstract int totalMemory();
99
100 /**
101 * Initiate a garbage collection.
102 */
103 public abstract void collect();
104
105 /**
106 * Process a reference to a heap object during garbage collection.
107 */
108 public abstract void processPtrField(Address a);
109
110 //// STATIC, ALLOCATION-RELATED HELPER METHODS.
111
112 /**
113 * Initialize class t and return a new uninitialized object of that type.
114 * If t is not a class type, throw a VerifyError.
115 *
116 * @param t type to initialize and create object of
117 * @return new uninitialized object of type t
118 * @throws VerifyError if t is not a class type
119 */
120 public static Object clsinitAndAllocateObject(jq_Type t)
121 throws VerifyError {
122 if (!t.isClassType())
123 throw new VerifyError();
124 jq_Class k = (jq_Class)t;
125 k.cls_initialize();
126 return k.newInstance();
127 }
128
129 /**
130 * Clone the given object. NOTE: Does not check if the object implements Cloneable.
131 *
132 * @return new clone
133 * @param o object to clone
134 * @throws OutOfMemoryError if there is not enough memory to perform operation
135 */
136 public static Object clone(Object o)
137 throws OutOfMemoryError {
138 jq_Reference t = jq_Reference.getTypeOf(o);
139 if (t.isClassType()) {
140 jq_Class k = (jq_Class)t;
141 Object p = k.newInstance();
142 if (k.getInstanceSize()-ObjectLayout.OBJ_HEADER_SIZE > 0)
143 SystemInterface.mem_cpy(HeapAddress.addressOf(p), HeapAddress.addressOf(o), k.getInstanceSize()-ObjectLayout.OBJ_HEADER_SIZE);
144 return p;
145 } else {
146 Assert._assert(t.isArrayType());
147 jq_Array k = (jq_Array)t;
148 int length = Array.getLength(o);
149 Object p = k.newInstance(length);
150 if (length > 0)
151 SystemInterface.mem_cpy(HeapAddress.addressOf(p), HeapAddress.addressOf(o), k.getInstanceSize(length)-ObjectLayout.ARRAY_HEADER_SIZE);
152 return p;
153 }
154 }
155
156 /**
157 * Handle heap exhaustion.
158 *
159 * @param heap the exhausted heap
160 * @param size number of bytes requested in the failing allocation
161 * @param count the retry count for the failing allocation.
162 */
163 public static void heapExhausted(Heap heap, int size, int count)
164 throws OutOfMemoryError {
165 if (count > 3) outOfMemory();
166 // TODO: trigger GC.
167 }
168
169 private static boolean isOutOfMemory = false;
170 private static final OutOfMemoryError outofmemoryerror = new OutOfMemoryError();
171
172 /**
173 * Called in an out of memory situation.
174 *
175 * @throws OutOfMemoryError always thrown
176 */
177 public static void outOfMemory()
178 throws OutOfMemoryError {
179 if (isOutOfMemory) {
180 SystemInterface.die(-1);
181 }
182 isOutOfMemory = true;
183 SystemInterface.debugwriteln("Out of memory!");
184 throw outofmemoryerror;
185 }
186
187 /**
188 * An object of this class represents a pointer to a heap address.
189 * It is a wrapped version of HeapAddress, so it can be used like
190 * an object.
191 */
192 public static class HeapPointer implements Comparable {
193
194 /** The (actual) address. */
195 private final HeapAddress ip;
196
197 /** Create a new heap pointer.
198 * @param ip heap pointer value
199 */
200 public HeapPointer(HeapAddress ip) { this.ip = ip; }
201
202 /** Extract the address of this heap pointer.
203 * @return address of this heap pointer
204 */
205 public HeapAddress get() { return ip; }
206
207 /** Compare this heap pointer to another heap pointer.
208 * @param that heap pointer to compare against
209 * @return -1 if this ip is before the given ip, 0 if it is equal
210 * to the given ip, 1 if it is after the given ip
211 */
212 public int compareTo(HeapPointer that) {
213 if (this.ip.difference(that.ip) < 0) return -1;
214 if (this.ip.difference(that.ip) > 0) return 1;
215 return 0;
216 }
217
218 /** Compares this heap pointer to the given object.
219 * @param that object to compare to
220 * @return -1 if this is less than, 0 if this is equal, 1 if this
221 * is greater than
222 */
223 public int compareTo(java.lang.Object that) {
224 return compareTo((HeapPointer) that);
225 }
226
227 /** Returns true if this heap pointer refers to the same location
228 * as the given heap pointer, false otherwise.
229 * @param that heap pointer to compare to
230 * @return true if the heap pointers are equal, false otherwise
231 */
232 public boolean equals(HeapPointer that) {
233 return this.ip.difference(that.ip) == 0;
234 }
235
236 /** Compares this heap pointer with the given object.
237 * @param that object to compare with
238 * @return true if these objects are equal, false otherwise
239 */
240 public boolean equals(Object that) {
241 return equals((HeapPointer) that);
242 }
243
244 /** Returns the hash code of this heap pointer.
245 * @return hash code
246 */
247 public int hashCode() { return this.ip.to32BitValue(); }
248
249 /*
250 public static final jq_InstanceField _ip;
251 static {
252 jq_Class k = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("LAllocator/HeapAllocator$HeapPointer;");
253 _ip = k.getOrCreateInstanceField("ip", "I");
254 }
255 */
256 }
257
258 public static final jq_StaticMethod _clsinitAndAllocateObject;
259 static {
260 jq_Class k = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("LAllocator/HeapAllocator;");
261 _clsinitAndAllocateObject = k.getOrCreateStaticMethod("clsinitAndAllocateObject", "(LClazz/jq_Type;)Ljava/lang/Object;");
262 }
263 }