src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java

Thu, 17 Oct 2013 17:33:16 +0200

author
hannesw
date
Thu, 17 Oct 2013 17:33:16 +0200
changeset 633
a2065f67857c
parent 482
0ad00ae4fec6
child 952
6d5471a497fb
child 963
e2497b11a021
permissions
-rw-r--r--

8026701: Array.prototype.splice is slow on dense arrays
Reviewed-by: lagergren, sundar, jlaskey

jlaskey@3 1 /*
jlaskey@7 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
jlaskey@3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jlaskey@3 4 *
jlaskey@3 5 * This code is free software; you can redistribute it and/or modify it
jlaskey@3 6 * under the terms of the GNU General Public License version 2 only, as
jlaskey@3 7 * published by the Free Software Foundation. Oracle designates this
jlaskey@3 8 * particular file as subject to the "Classpath" exception as provided
jlaskey@3 9 * by Oracle in the LICENSE file that accompanied this code.
jlaskey@3 10 *
jlaskey@3 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jlaskey@3 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jlaskey@3 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jlaskey@3 14 * version 2 for more details (a copy is included in the LICENSE file that
jlaskey@3 15 * accompanied this code).
jlaskey@3 16 *
jlaskey@3 17 * You should have received a copy of the GNU General Public License version
jlaskey@3 18 * 2 along with this work; if not, write to the Free Software Foundation,
jlaskey@3 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jlaskey@3 20 *
jlaskey@3 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jlaskey@3 22 * or visit www.oracle.com if you need additional information or have any
jlaskey@3 23 * questions.
jlaskey@3 24 */
jlaskey@3 25
jlaskey@3 26 package jdk.nashorn.internal.runtime.arrays;
jlaskey@3 27
jlaskey@3 28 import java.util.Arrays;
jlaskey@3 29 import jdk.nashorn.internal.runtime.JSType;
jlaskey@3 30 import jdk.nashorn.internal.runtime.ScriptRuntime;
jlaskey@3 31
jlaskey@3 32 /**
jlaskey@3 33 * Implementation of {@link ArrayData} as soon as an Object has been
jlaskey@3 34 * written to the array
jlaskey@3 35 */
jlaskey@3 36 final class ObjectArrayData extends ArrayData {
jlaskey@3 37
jlaskey@3 38 /**
jlaskey@3 39 * The wrapped array
jlaskey@3 40 */
jlaskey@3 41 private Object[] array;
jlaskey@3 42
jlaskey@3 43 /**
jlaskey@3 44 * Constructor
jlaskey@3 45 * @param array an int array
jlaskey@3 46 * @param length a length, not necessarily array.length
jlaskey@3 47 */
jlaskey@3 48 ObjectArrayData(final Object array[], final int length) {
jlaskey@3 49 super(length);
hannesw@482 50 assert array.length >= length;
jlaskey@3 51 this.array = array;
hannesw@482 52 }
hannesw@482 53
hannesw@482 54 @Override
hannesw@482 55 public ArrayData copy() {
hannesw@482 56 return new ObjectArrayData(array.clone(), (int) length());
jlaskey@3 57 }
jlaskey@3 58
jlaskey@3 59 @Override
jlaskey@3 60 public Object[] asObjectArray() {
jlaskey@3 61 return Arrays.copyOf(array, (int) length());
jlaskey@3 62 }
jlaskey@3 63
jlaskey@3 64 @Override
jlaskey@3 65 public ArrayData convert(final Class<?> type) {
jlaskey@3 66 return this;
jlaskey@3 67 }
jlaskey@3 68
jlaskey@3 69 @Override
jlaskey@3 70 public void shiftLeft(final int by) {
jlaskey@3 71 System.arraycopy(array, by, array, 0, array.length - by);
jlaskey@3 72 }
jlaskey@3 73
jlaskey@3 74 @Override
jlaskey@3 75 public ArrayData shiftRight(final int by) {
jlaskey@3 76 final ArrayData newData = ensure(by + length() - 1);
jlaskey@3 77 if (newData != this) {
jlaskey@3 78 newData.shiftRight(by);
jlaskey@3 79 return newData;
jlaskey@3 80 }
jlaskey@3 81 System.arraycopy(array, 0, array, by, array.length - by);
jlaskey@3 82 return this;
jlaskey@3 83 }
jlaskey@3 84
jlaskey@3 85 @Override
jlaskey@3 86 public ArrayData ensure(final long safeIndex) {
jlaskey@3 87 if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
jlaskey@3 88 return new SparseArrayData(this, safeIndex + 1);
jlaskey@3 89 }
jlaskey@3 90
jlaskey@3 91 int newLength = array.length;
jlaskey@3 92
jlaskey@3 93 while (newLength <= safeIndex) {
jlaskey@3 94 newLength = ArrayData.nextSize(newLength);
jlaskey@3 95 }
jlaskey@3 96
jlaskey@3 97 if (array.length <= safeIndex) {
jlaskey@3 98 array = Arrays.copyOf(array, newLength);
jlaskey@3 99 Arrays.fill(array, (int) length(), newLength, ScriptRuntime.UNDEFINED);
jlaskey@3 100 }
jlaskey@3 101
jlaskey@3 102 setLength(safeIndex + 1);
jlaskey@3 103
jlaskey@3 104 return this;
jlaskey@3 105 }
jlaskey@3 106
jlaskey@3 107 @Override
jlaskey@3 108 public ArrayData shrink(final long newLength) {
jlaskey@3 109 Arrays.fill(array, (int) newLength, array.length, ScriptRuntime.UNDEFINED);
jlaskey@3 110 return this;
jlaskey@3 111 }
jlaskey@3 112
jlaskey@3 113 @Override
jlaskey@3 114 public ArrayData set(final int index, final Object value, final boolean strict) {
jlaskey@3 115 array[index] = value;
jlaskey@3 116 setLength(Math.max(index + 1, length()));
jlaskey@3 117 return this;
jlaskey@3 118 }
jlaskey@3 119
jlaskey@3 120 @Override
jlaskey@3 121 public ArrayData set(final int index, final int value, final boolean strict) {
jlaskey@3 122 array[index] = value;
jlaskey@3 123 setLength(Math.max(index + 1, length()));
jlaskey@3 124 return this;
jlaskey@3 125 }
jlaskey@3 126
jlaskey@3 127 @Override
jlaskey@3 128 public ArrayData set(final int index, final long value, final boolean strict) {
jlaskey@3 129 array[index] = value;
jlaskey@3 130 setLength(Math.max(index + 1, length()));
jlaskey@3 131 return this;
jlaskey@3 132 }
jlaskey@3 133
jlaskey@3 134 @Override
jlaskey@3 135 public ArrayData set(final int index, final double value, final boolean strict) {
jlaskey@3 136 array[index] = value;
jlaskey@3 137 setLength(Math.max(index + 1, length()));
jlaskey@3 138 return this;
jlaskey@3 139 }
jlaskey@3 140
jlaskey@3 141 @Override
jlaskey@368 142 public ArrayData setEmpty(final int index) {
jlaskey@368 143 array[index] = ScriptRuntime.EMPTY;
jlaskey@368 144 return this;
jlaskey@368 145 }
jlaskey@368 146
jlaskey@368 147 @Override
jlaskey@368 148 public ArrayData setEmpty(final long lo, final long hi) {
lagergren@405 149 Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, Integer.MAX_VALUE), ScriptRuntime.EMPTY);
jlaskey@368 150 return this;
jlaskey@368 151 }
jlaskey@368 152
jlaskey@368 153 @Override
jlaskey@3 154 public int getInt(final int index) {
jlaskey@3 155 return JSType.toInt32(array[index]);
jlaskey@3 156 }
jlaskey@3 157
jlaskey@3 158 @Override
jlaskey@3 159 public long getLong(final int index) {
jlaskey@3 160 return JSType.toLong(array[index]);
jlaskey@3 161 }
jlaskey@3 162
jlaskey@3 163 @Override
jlaskey@3 164 public double getDouble(final int index) {
jlaskey@3 165 return JSType.toNumber(array[index]);
jlaskey@3 166 }
jlaskey@3 167
jlaskey@3 168 @Override
jlaskey@3 169 public Object getObject(final int index) {
jlaskey@3 170 return array[index];
jlaskey@3 171 }
jlaskey@3 172
jlaskey@3 173 @Override
jlaskey@3 174 public boolean has(final int index) {
jlaskey@3 175 return 0 <= index && index < length();
jlaskey@3 176 }
jlaskey@3 177
jlaskey@3 178 @Override
jlaskey@3 179 public ArrayData delete(final int index) {
jlaskey@368 180 setEmpty(index);
jlaskey@3 181 return new DeletedRangeArrayFilter(this, index, index);
jlaskey@3 182 }
jlaskey@3 183
jlaskey@3 184 @Override
jlaskey@3 185 public ArrayData delete(final long fromIndex, final long toIndex) {
jlaskey@368 186 setEmpty(fromIndex, toIndex);
jlaskey@3 187 return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
jlaskey@3 188 }
jlaskey@3 189
jlaskey@3 190 @Override
jlaskey@3 191 public Object pop() {
jlaskey@3 192 if (length() == 0) {
jlaskey@3 193 return ScriptRuntime.UNDEFINED;
jlaskey@3 194 }
jlaskey@3 195
jlaskey@3 196 final int newLength = (int) (length() - 1);
jlaskey@3 197 final Object elem = array[newLength];
jlaskey@368 198 setEmpty(newLength);
jlaskey@3 199 setLength(newLength);
jlaskey@3 200 return elem;
jlaskey@3 201 }
jlaskey@3 202
jlaskey@3 203 @Override
jlaskey@3 204 public ArrayData slice(final long from, final long to) {
jlaskey@3 205 final long start = from < 0 ? (from + length()) : from;
jlaskey@3 206 final long newLength = to - start;
jlaskey@3 207 return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
jlaskey@3 208 }
hannesw@633 209
hannesw@633 210 @Override
hannesw@633 211 public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
hannesw@633 212 final long oldLength = length();
hannesw@633 213 final long newLength = oldLength - removed + added;
hannesw@633 214 if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
hannesw@633 215 throw new UnsupportedOperationException();
hannesw@633 216 }
hannesw@633 217 final ArrayData returnValue = (removed == 0) ?
hannesw@633 218 EMPTY_ARRAY : new ObjectArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
hannesw@633 219
hannesw@633 220 if (newLength != oldLength) {
hannesw@633 221 final Object[] newArray;
hannesw@633 222
hannesw@633 223 if (newLength > array.length) {
hannesw@633 224 newArray = new Object[ArrayData.nextSize((int)newLength)];
hannesw@633 225 System.arraycopy(array, 0, newArray, 0, start);
hannesw@633 226 } else {
hannesw@633 227 newArray = array;
hannesw@633 228 }
hannesw@633 229
hannesw@633 230 System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed));
hannesw@633 231 array = newArray;
hannesw@633 232 setLength(newLength);
hannesw@633 233 }
hannesw@633 234
hannesw@633 235 return returnValue;
hannesw@633 236 }
jlaskey@3 237 }

mercurial