Mercurial > hg > graal-compiler
view graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/BaseArrayStore.java @ 13514:0fbee3eb71f0
Ruby: import project.
author | Chris Seaton <chris.seaton@oracle.com> |
---|---|
date | Mon, 06 Jan 2014 17:12:09 +0000 |
parents | |
children |
line wrap: on
line source
/* * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This * code is released under a tri EPL/GPL/LGPL license. You can use it, * redistribute it and/or modify it under the terms of the: * * Eclipse Public License version 1.0 * GNU General Public License version 2 * GNU Lesser General Public License version 2.1 */ package com.oracle.truffle.ruby.runtime.core.array; /** * Contains implementations of as much of the array stores that we could easily share. Much of the * rest depends on static types in method signatures, so is lexically almost the same, but isn't the * same in type, and as the whole point is to avoid boxing, we can't use Java's generics. */ public abstract class BaseArrayStore implements ArrayStore { protected int capacity; protected int size; @Override public int size() { return size; } /** * Set a range in the array to be another range. You must ensure that the otherValues array is * of the same type as your values array. */ protected void setRangeArrayMatchingTypes(int normalisedBegin, int normalisedExclusiveEnd, Object otherValues, int otherSize) { // Is the range the whole array? if (normalisedBegin == 0 && normalisedExclusiveEnd == size) { // Do we already have enough space? if (otherSize <= capacity) { // Copy to our existing array. final Object values = getValuesArrayObject(); System.arraycopy(otherValues, 0, values, 0, otherSize); } else { // Create a new copy of their array. setCapacityWithNewArray(otherSize); final Object values = getValuesArrayObject(); System.arraycopy(otherValues, 0, values, 0, otherSize); } size = otherSize; } else { final int rangeLength = normalisedExclusiveEnd - normalisedBegin; // Create extra space - might be negative if the new range is shorter, or zero. final int extraSpaceNeeded = otherSize - rangeLength; if (extraSpaceNeeded > 0) { createSpace(normalisedBegin, extraSpaceNeeded); } else if (extraSpaceNeeded < 0) { deleteSpace(normalisedBegin, -extraSpaceNeeded); } // Copy across the new values. final Object values = getValuesArrayObject(); System.arraycopy(otherValues, 0, values, normalisedBegin, otherSize); } } protected void createSpace(int normalisedBegin, int count) { /* * Is this space at the end or in the middle? */ if (normalisedBegin == size) { createSpaceAtEnd(count); } else { /* * Create space in the middle - is the array already big enough? */ final int elementsToMove = size - normalisedBegin; if (size + count > capacity) { /* * The array isn't big enough. We don't want to use Arrays.copyOf because that will * do wasted copying of the elements we are about to move. However - is * Arrays.copyOf clever enough to see that only one instance of Array is using the * block and use realloc, potentially avoiding a malloc and winning? */ final Object values = getValuesArrayObject(); setCapacityWithNewArray(ArrayUtilities.capacityFor(size + count)); final Object newValues = getValuesArrayObject(); System.arraycopy(values, 0, newValues, 0, normalisedBegin); System.arraycopy(values, normalisedBegin, newValues, normalisedBegin + count, elementsToMove); } else { /* * The array is already big enough - we can copy elements already in the array to * make space. */ final Object values = getValuesArrayObject(); System.arraycopy(values, normalisedBegin, values, normalisedBegin + count, elementsToMove); } size += count; } } protected void createSpaceAtEnd(int count) { /* * Create space at the end - we can do this by creating a copy of the array if needed. */ if (size + count > capacity) { setCapacityByCopying(ArrayUtilities.capacityFor(size + count)); } size += count; } protected void deleteSpace(int normalisedBegin, int count) { final Object values = getValuesArrayObject(); final int elementsToMove = size - normalisedBegin - count; if (elementsToMove > 0) { System.arraycopy(values, normalisedBegin + count, values, normalisedBegin, elementsToMove); } size -= count; } protected abstract void setCapacityByCopying(int newCapacity); protected abstract void setCapacityWithNewArray(int newCapacity); protected abstract Object getValuesArrayObject(); @Override public boolean equals(ArrayStore other) { for (int n = 0; n < size; n++) { if (!other.get(n).equals(get(n))) { return false; } } return true; } }