Mercurial > hg > graal-jvmci-8
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DynamicObjectBasic.java Tue Nov 18 23:19:43 2014 +0100 @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.object.basic; + +import java.lang.annotation.*; + +import com.oracle.truffle.api.object.*; +import com.oracle.truffle.object.*; +import com.oracle.truffle.object.basic.BasicLocations.*; + +public class DynamicObjectBasic extends DynamicObjectImpl { + @Retention(RetentionPolicy.RUNTIME) + protected @interface DynamicField { + } + + @DynamicField private long primitive1; + @DynamicField private long primitive2; + @DynamicField private long primitive3; + @DynamicField private Object object1; + @DynamicField private Object object2; + @DynamicField private Object object3; + @DynamicField private Object object4; + private Object[] objext; + private long[] primext; + + public DynamicObjectBasic(Shape shape) { + super(shape); + } + + @Override + protected final void initialize(Shape shape) { + assert getObjectStore(shape) == null; + int capacity = ((ShapeImpl) shape).getObjectArrayCapacity(); + if (capacity != 0) { + this.setObjectStore(new Object[capacity], shape); + } + if (((ShapeImpl) shape).getPrimitiveArrayCapacity() != 0) { + this.setPrimitiveStore(new long[((ShapeImpl) shape).getPrimitiveArrayCapacity()], shape); + } + } + + /** + * Simpler version of {@link #resizeObjectStore} when the object is only increasing in size. + */ + @Override + protected final void growObjectStore(Shape oldShape, Shape newShape) { + int oldObjectArrayCapacity = ((ShapeImpl) oldShape).getObjectArrayCapacity(); + int newObjectArrayCapacity = ((ShapeImpl) newShape).getObjectArrayCapacity(); + if (oldObjectArrayCapacity != newObjectArrayCapacity) { + growObjectStoreIntl(oldObjectArrayCapacity, newObjectArrayCapacity, oldShape); + } + } + + private void growObjectStoreIntl(int oldObjectArrayCapacity, int newObjectArrayCapacity, Shape newShape) { + Object[] newObjectStore = new Object[newObjectArrayCapacity]; + if (oldObjectArrayCapacity != 0) { + // monotonic growth assumption + assert oldObjectArrayCapacity < newObjectArrayCapacity; + Object[] oldObjectStore = this.getObjectStore(newShape); + for (int i = 0; i < oldObjectArrayCapacity; ++i) { + newObjectStore[i] = oldObjectStore[i]; + } + } + this.setObjectStore(newObjectStore, newShape); + } + + /** + * Simpler version of {@link #resizePrimitiveStore} when the object is only increasing in size. + */ + @Override + protected final void growPrimitiveStore(Shape oldShape, Shape newShape) { + assert ((ShapeImpl) newShape).hasPrimitiveArray(); + int oldPrimitiveCapacity = oldShape.getPrimitiveArrayCapacity(); + int newPrimitiveCapacity = newShape.getPrimitiveArrayCapacity(); + if (newPrimitiveCapacity == 0) { + // due to obsolescence, we might have to reserve an empty primitive array slot + this.setPrimitiveStore(null, newShape); + } else if (oldPrimitiveCapacity != newPrimitiveCapacity) { + growPrimitiveStoreIntl(oldPrimitiveCapacity, newPrimitiveCapacity, oldShape); + } + } + + private void growPrimitiveStoreIntl(int oldPrimitiveCapacity, int newPrimitiveCapacity, Shape newShape) { + long[] newPrimitiveArray = new long[newPrimitiveCapacity]; + if (oldPrimitiveCapacity != 0) { + // primitive array can shrink due to type changes + long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); + for (int i = 0; i < Math.min(oldPrimitiveCapacity, newPrimitiveCapacity); ++i) { + newPrimitiveArray[i] = oldPrimitiveArray[i]; + } + } + this.setPrimitiveStore(newPrimitiveArray, newShape); + } + + @Override + protected final void resizeObjectStore(Shape oldShape, Shape newShape) { + Object[] newObjectStore = null; + int destinationCapacity = newShape.getObjectArrayCapacity(); + if (destinationCapacity != 0) { + newObjectStore = new Object[destinationCapacity]; + int sourceCapacity = oldShape.getObjectArrayCapacity(); + if (sourceCapacity != 0) { + Object[] oldObjectStore = getObjectStore(newShape); + for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { + newObjectStore[i] = oldObjectStore[i]; + } + } + } + this.setObjectStore(newObjectStore, newShape); + } + + private Object[] getObjectStore(@SuppressWarnings("unused") Shape currentShape) { + return objext; + } + + private void setObjectStore(Object[] newArray, @SuppressWarnings("unused") Shape currentShape) { + objext = newArray; + } + + private long[] getPrimitiveStore(@SuppressWarnings("unused") Shape currentShape) { + return primext; + } + + private void setPrimitiveStore(long[] newArray, @SuppressWarnings("unused") Shape currentShape) { + primext = newArray; + } + + @Override + protected final void resizePrimitiveStore(Shape oldShape, Shape newShape) { + assert newShape.hasPrimitiveArray(); + long[] newPrimitiveArray = null; + int destinationCapacity = newShape.getPrimitiveArrayCapacity(); + if (destinationCapacity != 0) { + newPrimitiveArray = new long[destinationCapacity]; + int sourceCapacity = oldShape.getPrimitiveArrayCapacity(); + if (sourceCapacity != 0) { + long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); + for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { + newPrimitiveArray[i] = oldPrimitiveArray[i]; + } + } + } + this.setPrimitiveStore(newPrimitiveArray, newShape); + } + + /** + * Check whether fast transition is valid. + * + * @see #setShapeAndGrow + */ + @SuppressWarnings("unused") + private boolean checkSetShape(Shape oldShape, Shape newShape) { + Shape currentShape = getShape(); + assert oldShape != newShape : "Wrong old shape assumption?"; + assert newShape != currentShape : "Redundant shape change? shape=" + currentShape; + assert oldShape == currentShape || oldShape.getParent() == currentShape : "Out-of-order shape change?" + "\nparentShape=" + currentShape + "\noldShape=" + oldShape + "\nnewShape=" + newShape; + return true; + } + + /** + * Check whether the extension arrays are in accordance with the description in the shape. + */ + @Override + protected final boolean checkExtensionArrayInvariants(Shape newShape) { + assert getShape() == newShape; + assert (getObjectStore(newShape) == null && newShape.getObjectArrayCapacity() == 0) || + (getObjectStore(newShape) != null && getObjectStore(newShape).length == newShape.getObjectArrayCapacity()); + if (newShape.hasPrimitiveArray()) { + assert (getPrimitiveStore(newShape) == null && newShape.getPrimitiveArrayCapacity() == 0) || + (getPrimitiveStore(newShape) != null && getPrimitiveStore(newShape).length == newShape.getPrimitiveArrayCapacity()); + } + return true; + } + + @Override + protected final DynamicObject cloneWithShape(Shape currentShape) { + assert this.getShape() == currentShape; + final DynamicObjectBasic clone = (DynamicObjectBasic) super.clone(); + if (this.getObjectStore(currentShape) != null) { + clone.setObjectStore(this.getObjectStore(currentShape).clone(), currentShape); + } + if (currentShape.hasPrimitiveArray() && this.getPrimitiveStore(currentShape) != null) { + clone.setPrimitiveStore(this.getPrimitiveStore(currentShape).clone(), currentShape); + } + return clone; + } + + protected final void reshape(ShapeImpl newShape) { + reshapeCount.inc(); + + ShapeImpl oldShape = getShape(); + ShapeImpl commonAncestor = ShapeImpl.findCommonAncestor(oldShape, newShape); + if (ObjectStorageOptions.TraceReshape) { + int limit = 150; + System.out.printf("RESHAPE\nOLD %s\nNEW %s\nLCA %s\nDIFF %s\n---\n", oldShape.toStringLimit(limit), newShape.toStringLimit(limit), commonAncestor.toStringLimit(limit), + ShapeImpl.diff(oldShape, newShape)); + } + + DynamicObject original = this.cloneWithShape(oldShape); + setShapeAndGrow(oldShape, newShape); + assert !((newShape.hasPrimitiveArray() && newShape.getPrimitiveArrayCapacity() == 0)) || getPrimitiveStore(newShape) == null; + copyProperties(original, commonAncestor); + assert checkExtensionArrayInvariants(newShape); + } + + static final SimpleObjectFieldLocation[] OBJECT_FIELD_LOCATIONS; + static final SimpleLongFieldLocation[] PRIMITIVE_FIELD_LOCATIONS; + + static final SimpleObjectFieldLocation OBJECT_ARRAY_LOCATION; + static final SimpleObjectFieldLocation PRIMITIVE_ARRAY_LOCATION; + + static { + int index; + + index = 0; + PRIMITIVE_FIELD_LOCATIONS = new SimpleLongFieldLocation[]{new SimpleLongFieldLocation(index++) { + @Override + public long getLong(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).primitive1; + } + + @Override + public void setLongInternal(DynamicObject store, long value) { + ((DynamicObjectBasic) store).primitive1 = value; + } + }, new SimpleLongFieldLocation(index++) { + @Override + public long getLong(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).primitive2; + } + + @Override + public void setLongInternal(DynamicObject store, long value) { + ((DynamicObjectBasic) store).primitive2 = value; + } + }, new SimpleLongFieldLocation(index++) { + @Override + public long getLong(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).primitive3; + } + + @Override + public void setLongInternal(DynamicObject store, long value) { + ((DynamicObjectBasic) store).primitive3 = value; + } + }}; + + index = 0; + OBJECT_FIELD_LOCATIONS = new SimpleObjectFieldLocation[]{new SimpleObjectFieldLocation(index++) { + @Override + public Object get(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).object1; + } + + @Override + public void setInternal(DynamicObject store, Object value) { + ((DynamicObjectBasic) store).object1 = value; + } + }, new SimpleObjectFieldLocation(index++) { + @Override + public Object get(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).object2; + } + + @Override + public void setInternal(DynamicObject store, Object value) { + ((DynamicObjectBasic) store).object2 = value; + } + }, new SimpleObjectFieldLocation(index++) { + @Override + public Object get(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).object3; + } + + @Override + public void setInternal(DynamicObject store, Object value) { + ((DynamicObjectBasic) store).object3 = value; + } + }, new SimpleObjectFieldLocation(index++) { + @Override + public Object get(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).object4; + } + + @Override + public void setInternal(DynamicObject store, Object value) { + ((DynamicObjectBasic) store).object4 = value; + } + }}; + + OBJECT_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { + @Override + public Object[] get(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).objext; + } + + @Override + public void setInternal(DynamicObject store, Object value) { + ((DynamicObjectBasic) store).objext = (Object[]) value; + } + }; + + PRIMITIVE_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { + @Override + public long[] get(DynamicObject store, boolean condition) { + return ((DynamicObjectBasic) store).primext; + } + + @Override + public void setInternal(DynamicObject store, Object value) { + ((DynamicObjectBasic) store).primext = (long[]) value; + } + }; + } +}