Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DynamicObjectBasic.java @ 18408:2c3666f44855
Truffle: initial commit of object API implementation
author | Andreas Woess <andreas.woess@jku.at> |
---|---|
date | Tue, 18 Nov 2014 23:19:43 +0100 |
parents | |
children | b1530a6cce8c |
comparison
equal
deleted
inserted
replaced
18407:f439fdb137a3 | 18408:2c3666f44855 |
---|---|
1 /* | |
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.truffle.object.basic; | |
24 | |
25 import java.lang.annotation.*; | |
26 | |
27 import com.oracle.truffle.api.object.*; | |
28 import com.oracle.truffle.object.*; | |
29 import com.oracle.truffle.object.basic.BasicLocations.*; | |
30 | |
31 public class DynamicObjectBasic extends DynamicObjectImpl { | |
32 @Retention(RetentionPolicy.RUNTIME) | |
33 protected @interface DynamicField { | |
34 } | |
35 | |
36 @DynamicField private long primitive1; | |
37 @DynamicField private long primitive2; | |
38 @DynamicField private long primitive3; | |
39 @DynamicField private Object object1; | |
40 @DynamicField private Object object2; | |
41 @DynamicField private Object object3; | |
42 @DynamicField private Object object4; | |
43 private Object[] objext; | |
44 private long[] primext; | |
45 | |
46 public DynamicObjectBasic(Shape shape) { | |
47 super(shape); | |
48 } | |
49 | |
50 @Override | |
51 protected final void initialize(Shape shape) { | |
52 assert getObjectStore(shape) == null; | |
53 int capacity = ((ShapeImpl) shape).getObjectArrayCapacity(); | |
54 if (capacity != 0) { | |
55 this.setObjectStore(new Object[capacity], shape); | |
56 } | |
57 if (((ShapeImpl) shape).getPrimitiveArrayCapacity() != 0) { | |
58 this.setPrimitiveStore(new long[((ShapeImpl) shape).getPrimitiveArrayCapacity()], shape); | |
59 } | |
60 } | |
61 | |
62 /** | |
63 * Simpler version of {@link #resizeObjectStore} when the object is only increasing in size. | |
64 */ | |
65 @Override | |
66 protected final void growObjectStore(Shape oldShape, Shape newShape) { | |
67 int oldObjectArrayCapacity = ((ShapeImpl) oldShape).getObjectArrayCapacity(); | |
68 int newObjectArrayCapacity = ((ShapeImpl) newShape).getObjectArrayCapacity(); | |
69 if (oldObjectArrayCapacity != newObjectArrayCapacity) { | |
70 growObjectStoreIntl(oldObjectArrayCapacity, newObjectArrayCapacity, oldShape); | |
71 } | |
72 } | |
73 | |
74 private void growObjectStoreIntl(int oldObjectArrayCapacity, int newObjectArrayCapacity, Shape newShape) { | |
75 Object[] newObjectStore = new Object[newObjectArrayCapacity]; | |
76 if (oldObjectArrayCapacity != 0) { | |
77 // monotonic growth assumption | |
78 assert oldObjectArrayCapacity < newObjectArrayCapacity; | |
79 Object[] oldObjectStore = this.getObjectStore(newShape); | |
80 for (int i = 0; i < oldObjectArrayCapacity; ++i) { | |
81 newObjectStore[i] = oldObjectStore[i]; | |
82 } | |
83 } | |
84 this.setObjectStore(newObjectStore, newShape); | |
85 } | |
86 | |
87 /** | |
88 * Simpler version of {@link #resizePrimitiveStore} when the object is only increasing in size. | |
89 */ | |
90 @Override | |
91 protected final void growPrimitiveStore(Shape oldShape, Shape newShape) { | |
92 assert ((ShapeImpl) newShape).hasPrimitiveArray(); | |
93 int oldPrimitiveCapacity = oldShape.getPrimitiveArrayCapacity(); | |
94 int newPrimitiveCapacity = newShape.getPrimitiveArrayCapacity(); | |
95 if (newPrimitiveCapacity == 0) { | |
96 // due to obsolescence, we might have to reserve an empty primitive array slot | |
97 this.setPrimitiveStore(null, newShape); | |
98 } else if (oldPrimitiveCapacity != newPrimitiveCapacity) { | |
99 growPrimitiveStoreIntl(oldPrimitiveCapacity, newPrimitiveCapacity, oldShape); | |
100 } | |
101 } | |
102 | |
103 private void growPrimitiveStoreIntl(int oldPrimitiveCapacity, int newPrimitiveCapacity, Shape newShape) { | |
104 long[] newPrimitiveArray = new long[newPrimitiveCapacity]; | |
105 if (oldPrimitiveCapacity != 0) { | |
106 // primitive array can shrink due to type changes | |
107 long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); | |
108 for (int i = 0; i < Math.min(oldPrimitiveCapacity, newPrimitiveCapacity); ++i) { | |
109 newPrimitiveArray[i] = oldPrimitiveArray[i]; | |
110 } | |
111 } | |
112 this.setPrimitiveStore(newPrimitiveArray, newShape); | |
113 } | |
114 | |
115 @Override | |
116 protected final void resizeObjectStore(Shape oldShape, Shape newShape) { | |
117 Object[] newObjectStore = null; | |
118 int destinationCapacity = newShape.getObjectArrayCapacity(); | |
119 if (destinationCapacity != 0) { | |
120 newObjectStore = new Object[destinationCapacity]; | |
121 int sourceCapacity = oldShape.getObjectArrayCapacity(); | |
122 if (sourceCapacity != 0) { | |
123 Object[] oldObjectStore = getObjectStore(newShape); | |
124 for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { | |
125 newObjectStore[i] = oldObjectStore[i]; | |
126 } | |
127 } | |
128 } | |
129 this.setObjectStore(newObjectStore, newShape); | |
130 } | |
131 | |
132 private Object[] getObjectStore(@SuppressWarnings("unused") Shape currentShape) { | |
133 return objext; | |
134 } | |
135 | |
136 private void setObjectStore(Object[] newArray, @SuppressWarnings("unused") Shape currentShape) { | |
137 objext = newArray; | |
138 } | |
139 | |
140 private long[] getPrimitiveStore(@SuppressWarnings("unused") Shape currentShape) { | |
141 return primext; | |
142 } | |
143 | |
144 private void setPrimitiveStore(long[] newArray, @SuppressWarnings("unused") Shape currentShape) { | |
145 primext = newArray; | |
146 } | |
147 | |
148 @Override | |
149 protected final void resizePrimitiveStore(Shape oldShape, Shape newShape) { | |
150 assert newShape.hasPrimitiveArray(); | |
151 long[] newPrimitiveArray = null; | |
152 int destinationCapacity = newShape.getPrimitiveArrayCapacity(); | |
153 if (destinationCapacity != 0) { | |
154 newPrimitiveArray = new long[destinationCapacity]; | |
155 int sourceCapacity = oldShape.getPrimitiveArrayCapacity(); | |
156 if (sourceCapacity != 0) { | |
157 long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); | |
158 for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { | |
159 newPrimitiveArray[i] = oldPrimitiveArray[i]; | |
160 } | |
161 } | |
162 } | |
163 this.setPrimitiveStore(newPrimitiveArray, newShape); | |
164 } | |
165 | |
166 /** | |
167 * Check whether fast transition is valid. | |
168 * | |
169 * @see #setShapeAndGrow | |
170 */ | |
171 @SuppressWarnings("unused") | |
172 private boolean checkSetShape(Shape oldShape, Shape newShape) { | |
173 Shape currentShape = getShape(); | |
174 assert oldShape != newShape : "Wrong old shape assumption?"; | |
175 assert newShape != currentShape : "Redundant shape change? shape=" + currentShape; | |
176 assert oldShape == currentShape || oldShape.getParent() == currentShape : "Out-of-order shape change?" + "\nparentShape=" + currentShape + "\noldShape=" + oldShape + "\nnewShape=" + newShape; | |
177 return true; | |
178 } | |
179 | |
180 /** | |
181 * Check whether the extension arrays are in accordance with the description in the shape. | |
182 */ | |
183 @Override | |
184 protected final boolean checkExtensionArrayInvariants(Shape newShape) { | |
185 assert getShape() == newShape; | |
186 assert (getObjectStore(newShape) == null && newShape.getObjectArrayCapacity() == 0) || | |
187 (getObjectStore(newShape) != null && getObjectStore(newShape).length == newShape.getObjectArrayCapacity()); | |
188 if (newShape.hasPrimitiveArray()) { | |
189 assert (getPrimitiveStore(newShape) == null && newShape.getPrimitiveArrayCapacity() == 0) || | |
190 (getPrimitiveStore(newShape) != null && getPrimitiveStore(newShape).length == newShape.getPrimitiveArrayCapacity()); | |
191 } | |
192 return true; | |
193 } | |
194 | |
195 @Override | |
196 protected final DynamicObject cloneWithShape(Shape currentShape) { | |
197 assert this.getShape() == currentShape; | |
198 final DynamicObjectBasic clone = (DynamicObjectBasic) super.clone(); | |
199 if (this.getObjectStore(currentShape) != null) { | |
200 clone.setObjectStore(this.getObjectStore(currentShape).clone(), currentShape); | |
201 } | |
202 if (currentShape.hasPrimitiveArray() && this.getPrimitiveStore(currentShape) != null) { | |
203 clone.setPrimitiveStore(this.getPrimitiveStore(currentShape).clone(), currentShape); | |
204 } | |
205 return clone; | |
206 } | |
207 | |
208 protected final void reshape(ShapeImpl newShape) { | |
209 reshapeCount.inc(); | |
210 | |
211 ShapeImpl oldShape = getShape(); | |
212 ShapeImpl commonAncestor = ShapeImpl.findCommonAncestor(oldShape, newShape); | |
213 if (ObjectStorageOptions.TraceReshape) { | |
214 int limit = 150; | |
215 System.out.printf("RESHAPE\nOLD %s\nNEW %s\nLCA %s\nDIFF %s\n---\n", oldShape.toStringLimit(limit), newShape.toStringLimit(limit), commonAncestor.toStringLimit(limit), | |
216 ShapeImpl.diff(oldShape, newShape)); | |
217 } | |
218 | |
219 DynamicObject original = this.cloneWithShape(oldShape); | |
220 setShapeAndGrow(oldShape, newShape); | |
221 assert !((newShape.hasPrimitiveArray() && newShape.getPrimitiveArrayCapacity() == 0)) || getPrimitiveStore(newShape) == null; | |
222 copyProperties(original, commonAncestor); | |
223 assert checkExtensionArrayInvariants(newShape); | |
224 } | |
225 | |
226 static final SimpleObjectFieldLocation[] OBJECT_FIELD_LOCATIONS; | |
227 static final SimpleLongFieldLocation[] PRIMITIVE_FIELD_LOCATIONS; | |
228 | |
229 static final SimpleObjectFieldLocation OBJECT_ARRAY_LOCATION; | |
230 static final SimpleObjectFieldLocation PRIMITIVE_ARRAY_LOCATION; | |
231 | |
232 static { | |
233 int index; | |
234 | |
235 index = 0; | |
236 PRIMITIVE_FIELD_LOCATIONS = new SimpleLongFieldLocation[]{new SimpleLongFieldLocation(index++) { | |
237 @Override | |
238 public long getLong(DynamicObject store, boolean condition) { | |
239 return ((DynamicObjectBasic) store).primitive1; | |
240 } | |
241 | |
242 @Override | |
243 public void setLongInternal(DynamicObject store, long value) { | |
244 ((DynamicObjectBasic) store).primitive1 = value; | |
245 } | |
246 }, new SimpleLongFieldLocation(index++) { | |
247 @Override | |
248 public long getLong(DynamicObject store, boolean condition) { | |
249 return ((DynamicObjectBasic) store).primitive2; | |
250 } | |
251 | |
252 @Override | |
253 public void setLongInternal(DynamicObject store, long value) { | |
254 ((DynamicObjectBasic) store).primitive2 = value; | |
255 } | |
256 }, new SimpleLongFieldLocation(index++) { | |
257 @Override | |
258 public long getLong(DynamicObject store, boolean condition) { | |
259 return ((DynamicObjectBasic) store).primitive3; | |
260 } | |
261 | |
262 @Override | |
263 public void setLongInternal(DynamicObject store, long value) { | |
264 ((DynamicObjectBasic) store).primitive3 = value; | |
265 } | |
266 }}; | |
267 | |
268 index = 0; | |
269 OBJECT_FIELD_LOCATIONS = new SimpleObjectFieldLocation[]{new SimpleObjectFieldLocation(index++) { | |
270 @Override | |
271 public Object get(DynamicObject store, boolean condition) { | |
272 return ((DynamicObjectBasic) store).object1; | |
273 } | |
274 | |
275 @Override | |
276 public void setInternal(DynamicObject store, Object value) { | |
277 ((DynamicObjectBasic) store).object1 = value; | |
278 } | |
279 }, new SimpleObjectFieldLocation(index++) { | |
280 @Override | |
281 public Object get(DynamicObject store, boolean condition) { | |
282 return ((DynamicObjectBasic) store).object2; | |
283 } | |
284 | |
285 @Override | |
286 public void setInternal(DynamicObject store, Object value) { | |
287 ((DynamicObjectBasic) store).object2 = value; | |
288 } | |
289 }, new SimpleObjectFieldLocation(index++) { | |
290 @Override | |
291 public Object get(DynamicObject store, boolean condition) { | |
292 return ((DynamicObjectBasic) store).object3; | |
293 } | |
294 | |
295 @Override | |
296 public void setInternal(DynamicObject store, Object value) { | |
297 ((DynamicObjectBasic) store).object3 = value; | |
298 } | |
299 }, new SimpleObjectFieldLocation(index++) { | |
300 @Override | |
301 public Object get(DynamicObject store, boolean condition) { | |
302 return ((DynamicObjectBasic) store).object4; | |
303 } | |
304 | |
305 @Override | |
306 public void setInternal(DynamicObject store, Object value) { | |
307 ((DynamicObjectBasic) store).object4 = value; | |
308 } | |
309 }}; | |
310 | |
311 OBJECT_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { | |
312 @Override | |
313 public Object[] get(DynamicObject store, boolean condition) { | |
314 return ((DynamicObjectBasic) store).objext; | |
315 } | |
316 | |
317 @Override | |
318 public void setInternal(DynamicObject store, Object value) { | |
319 ((DynamicObjectBasic) store).objext = (Object[]) value; | |
320 } | |
321 }; | |
322 | |
323 PRIMITIVE_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { | |
324 @Override | |
325 public long[] get(DynamicObject store, boolean condition) { | |
326 return ((DynamicObjectBasic) store).primext; | |
327 } | |
328 | |
329 @Override | |
330 public void setInternal(DynamicObject store, Object value) { | |
331 ((DynamicObjectBasic) store).primext = (long[]) value; | |
332 } | |
333 }; | |
334 } | |
335 } |