Mercurial > hg > shenandoah-preopenjdk-archive > openjdk8 > nashorn
changeset 1067:094f0d95ef78
8061955: asm.js idioms result in unnecessarily code emission
Reviewed-by: hannesw, jlaskey
author | attila |
---|---|
date | Fri, 24 Oct 2014 13:25:23 +0200 |
parents | 375a3a3256d0 |
children | 78eb2b415108 |
files | src/jdk/nashorn/internal/codegen/CodeGenerator.java src/jdk/nashorn/internal/codegen/FoldConstants.java src/jdk/nashorn/internal/objects/NativeArray.java src/jdk/nashorn/internal/objects/NativeDataView.java src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java src/jdk/nashorn/internal/objects/NativeUint32Array.java src/jdk/nashorn/internal/runtime/JSType.java src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java |
diffstat | 8 files changed, 54 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Oct 24 13:25:23 2014 +0200 @@ -208,6 +208,8 @@ private static final Type ITERATOR_TYPE = Type.typeFor(ITERATOR_CLASS); private static final Type EXCEPTION_TYPE = Type.typeFor(CompilerConstants.EXCEPTION_PREFIX.type()); + private static final Integer INT_ZERO = Integer.valueOf(0); + /** Constant data & installation. The only reason the compiler keeps this is because it is assigned * by reflection in class installation */ private final Compiler compiler; @@ -3817,7 +3819,12 @@ private void doSHR() { // TODO: make SHR optimistic - method.shr().convert(Type.LONG).load(JSType.MAX_UINT).and(); + method.shr(); + toUint(); + } + + private void toUint() { + JSType.TO_UINT32_I.invoke(method); } private void loadASSIGN_SUB(final BinaryNode binaryNode) { @@ -3879,8 +3886,18 @@ } private void loadBIT_OR(final BinaryNode binaryNode) { - loadBinaryOperands(binaryNode); - method.or(); + // Optimize x|0 to (int)x + if (isRhsZero(binaryNode)) { + loadExpressionAsType(binaryNode.lhs(), Type.INT); + } else { + loadBinaryOperands(binaryNode); + method.or(); + } + } + + private static boolean isRhsZero(final BinaryNode binaryNode) { + final Expression rhs = binaryNode.rhs(); + return rhs instanceof LiteralNode && INT_ZERO.equals(((LiteralNode)rhs).getValue()); } private void loadBIT_XOR(final BinaryNode binaryNode) { @@ -3957,8 +3974,14 @@ } private void loadSHR(final BinaryNode binaryNode) { - loadBinaryOperands(binaryNode); - doSHR(); + // Optimize x >>> 0 to (uint)x + if (isRhsZero(binaryNode)) { + loadExpressionAsType(binaryNode.lhs(), Type.INT); + toUint(); + } else { + loadBinaryOperands(binaryNode); + doSHR(); + } } private void loadSUB(final BinaryNode binaryNode, final TypeBounds resultBounds) {
--- a/src/jdk/nashorn/internal/codegen/FoldConstants.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/codegen/FoldConstants.java Fri Oct 24 13:25:23 2014 +0200 @@ -291,7 +291,7 @@ value = lhs.getNumber() - rhs.getNumber(); break; case SHR: - return LiteralNode.newInstance(token, finish, (lhs.getInt32() >>> rhs.getInt32()) & JSType.MAX_UINT); + return LiteralNode.newInstance(token, finish, JSType.toUint32(lhs.getInt32() >>> rhs.getInt32())); case SAR: return LiteralNode.newInstance(token, finish, lhs.getInt32() >> rhs.getInt32()); case SHL:
--- a/src/jdk/nashorn/internal/objects/NativeArray.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Fri Oct 24 13:25:23 2014 +0200 @@ -33,6 +33,7 @@ import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator; import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT; + import java.lang.invoke.MethodHandle; import java.lang.invoke.SwitchPoint; import java.util.ArrayList; @@ -266,7 +267,7 @@ @Override public Object getLength() { - final long length = getArray().length() & JSType.MAX_UINT; + final long length = JSType.toUint32(getArray().length()); if(length < Integer.MAX_VALUE) { return (int)length; } @@ -476,7 +477,7 @@ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) public static Object length(final Object self) { if (isArray(self)) { - return ((ScriptObject) self).getArray().length() & JSType.MAX_UINT; + return JSType.toUint32(((ScriptObject) self).getArray().length()); } return 0;
--- a/src/jdk/nashorn/internal/objects/NativeDataView.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/objects/NativeDataView.java Fri Oct 24 13:25:23 2014 +0200 @@ -27,6 +27,7 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; + import java.nio.ByteBuffer; import java.nio.ByteOrder; import jdk.nashorn.internal.objects.annotations.Attribute; @@ -432,7 +433,7 @@ @SpecializedFunction public static long getUint32(final Object self, final int byteOffset) { try { - return JSType.MAX_UINT & getBuffer(self, false).getInt(JSType.toInt32(byteOffset)); + return JSType.toUint32(getBuffer(self, false).getInt(JSType.toInt32(byteOffset))); } catch (final IllegalArgumentException iae) { throw rangeError(iae, "dataview.offset"); } @@ -449,7 +450,7 @@ @SpecializedFunction public static long getUint32(final Object self, final int byteOffset, final boolean littleEndian) { try { - return JSType.MAX_UINT & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)); + return JSType.toUint32(getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset))); } catch (final IllegalArgumentException iae) { throw rangeError(iae, "dataview.offset"); }
--- a/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Fri Oct 24 13:25:23 2014 +0200 @@ -74,7 +74,7 @@ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) public static Object length(final Object self) { if (self instanceof ScriptObject) { - return ((ScriptObject)self).getArray().length() & JSType.MAX_UINT; + return JSType.toUint32(((ScriptObject)self).getArray().length()); } return 0;
--- a/src/jdk/nashorn/internal/objects/NativeUint32Array.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/objects/NativeUint32Array.java Fri Oct 24 13:25:23 2014 +0200 @@ -105,7 +105,7 @@ private long getElem(final int index) { try { - return nb.get(index) & JSType.MAX_UINT; + return JSType.toUint32(nb.get(index)); } catch (final IndexOutOfBoundsException e) { throw new ClassCastException(); //force relink - this works for unoptimistic too }
--- a/src/jdk/nashorn/internal/runtime/JSType.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Fri Oct 24 13:25:23 2014 +0200 @@ -115,6 +115,9 @@ /** JavaScript compliant conversion function from double to int32 */ public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class); + /** JavaScript compliant conversion function from int to uint32 */ + public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class); + /** JavaScript compliant conversion function from Object to uint32 */ public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class); @@ -1002,6 +1005,16 @@ } /** + * JavaScript compliant int to uint32 conversion + * + * @param num an int + * @return a uint32 + */ + public static long toUint32(final int num) { + return num & MAX_UINT; + } + + /** * JavaScript compliant Object to uint16 conversion * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer) *
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Thu Oct 23 18:07:16 2014 +0200 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Fri Oct 24 13:25:23 2014 +0200 @@ -182,15 +182,15 @@ } /** - * Convert an index to a long value. This basically amounts to ANDing it - * with {@link JSType#MAX_UINT}, as the maximum array index in JavaScript + * Convert an index to a long value. This basically amounts to converting it into a + * {@link JSType#toUint32(int)} uint32} as the maximum array index in JavaScript * is 0xfffffffe * * @param index index to convert to long form * @return index as uint32 in a long */ public static long toLongIndex(final int index) { - return index & JSType.MAX_UINT; + return JSType.toUint32(index); } /** @@ -201,7 +201,7 @@ * @return index as string */ public static String toKey(final int index) { - return Long.toString(index & JSType.MAX_UINT); + return Long.toString(JSType.toUint32(index)); } }