From 4a28db15e8f24572628806945250a9c565840f86 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Tue, 9 Apr 2019 13:07:45 +0000 Subject: [PATCH] Bug 1535137 - Store JSOP_DOUBLE literals inline r=jandem Replace the unaligned uint32_t index with the encoded double value. The double values are already being copied again before use, so an unaligned uint64_t load directly to double seems a more direct strategy. This also avoids needed to manage the allocation of the consts table. Differential Revision: https://phabricator.services.mozilla.com/D23396 --HG-- extra : moz-landing-system : lando --- js/src/frontend/BytecodeEmitter.cpp | 19 ++++++++++++++----- js/src/frontend/BytecodeEmitter.h | 1 + js/src/jit/BaselineCompiler.cpp | 14 ++++++++++---- js/src/jit/IonBuilder.cpp | 3 +++ js/src/vm/BytecodeUtil.cpp | 12 +++++++++--- js/src/vm/BytecodeUtil.h | 12 +++++++++++- js/src/vm/Interpreter.cpp | 9 +-------- js/src/vm/Opcodes.h | 4 ++-- 8 files changed, 51 insertions(+), 23 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 28fff1e5eafc..7a5202284cd1 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2011,6 +2011,19 @@ bool BytecodeEmitter::emitCallIncDec(UnaryNode* incDec) { return emitUint16Operand(JSOP_THROWMSG, JSMSG_BAD_LEFTSIDE_OF_ASS); } +bool BytecodeEmitter::emitDouble(double d) { + ptrdiff_t offset; + if (!emitCheck(JSOP_DOUBLE, 9, &offset)) { + return false; + } + + jsbytecode* code = this->code(offset); + code[0] = jsbytecode(JSOP_DOUBLE); + SET_DOUBLE(code, d); + updateDepth(offset); + return true; +} + bool BytecodeEmitter::emitNumberOp(double dval) { int32_t ival; if (NumberIsInt32(dval, &ival)) { @@ -2045,11 +2058,7 @@ bool BytecodeEmitter::emitNumberOp(double dval) { return true; } - if (!numberList.append(DoubleValue(dval))) { - return false; - } - - return emitIndex32(JSOP_DOUBLE, numberList.length() - 1); + return emitDouble(dval); } /* diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index 38354e1ebd5a..7d4c9e93d2f9 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -556,6 +556,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter { // Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand. MOZ_MUST_USE bool emitN(JSOp op, size_t extra, ptrdiff_t* offset = nullptr); + MOZ_MUST_USE bool emitDouble(double dval); MOZ_MUST_USE bool emitNumberOp(double dval); MOZ_MUST_USE bool emitBigIntOp(BigInt* bigint); diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 59c9bc9bbdac..df29b82c8f09 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2163,7 +2163,7 @@ bool BaselineCodeGen::emit_JSOP_RESUMEINDEX() { template <> bool BaselineCompilerCodeGen::emit_JSOP_DOUBLE() { - frame.push(handler.script()->getConst(GET_UINT32_INDEX(handler.pc()))); + frame.push(DoubleValue(GET_DOUBLE(handler.pc()))); return true; } @@ -2172,9 +2172,15 @@ bool BaselineInterpreterCodeGen::emit_JSOP_DOUBLE() { MOZ_CRASH("NYI: interpreter JSOP_DOUBLE"); } -template -bool BaselineCodeGen::emit_JSOP_BIGINT() { - return emit_JSOP_DOUBLE(); +template <> +bool BaselineCompilerCodeGen::emit_JSOP_BIGINT() { + frame.push(handler.script()->getConst(GET_UINT32_INDEX(handler.pc()))); + return true; +} + +template <> +bool BaselineInterpreterCodeGen::emit_JSOP_BIGINT() { + MOZ_CRASH("NYI: interpreter JSOP_BIGINT"); } template <> diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index f0cb43262384..e7f570baf18a 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1967,6 +1967,9 @@ AbortReasonOr IonBuilder::inspectOpcode(JSOp op) { return jsop_compare(op); case JSOP_DOUBLE: + pushConstant(DoubleValue(GET_DOUBLE(pc))); + return Ok(); + case JSOP_BIGINT: pushConstant(info().getConst(pc)); return Ok(); diff --git a/js/src/vm/BytecodeUtil.cpp b/js/src/vm/BytecodeUtil.cpp index 3e5c6c89316b..6b4e31244bfc 100644 --- a/js/src/vm/BytecodeUtil.cpp +++ b/js/src/vm/BytecodeUtil.cpp @@ -1474,8 +1474,15 @@ static unsigned Disassemble1(JSContext* cx, HandleScript script, jsbytecode* pc, break; } - case JOF_BIGINT: case JOF_DOUBLE: { + double d = GET_DOUBLE(pc); + if (!sp->jsprintf(" %lf", d)) { + return 0; + } + break; + } + + case JOF_BIGINT: { RootedValue v(cx, script->getConst(GET_UINT32_INDEX(pc))); UniqueChars bytes = ToDisassemblySource(cx, v); if (!bytes) { @@ -2012,8 +2019,7 @@ bool ExpressionDecompiler::decompilePC(jsbytecode* pc, uint8_t defIndex) { return write("CONSTRUCTOR"); case JSOP_DOUBLE: - return sprinter.printf( - "%lf", script->getConst(GET_UINT32_INDEX(pc)).toDouble()); + return sprinter.printf("%lf", GET_DOUBLE(pc)); case JSOP_EXCEPTION: return write("EXCEPTION"); diff --git a/js/src/vm/BytecodeUtil.h b/js/src/vm/BytecodeUtil.h index a7e8700db10b..930b860ff04a 100644 --- a/js/src/vm/BytecodeUtil.h +++ b/js/src/vm/BytecodeUtil.h @@ -57,7 +57,7 @@ enum { JOF_ATOM = 14, /* uint32_t constant index */ JOF_OBJECT = 15, /* uint32_t object index */ JOF_REGEXP = 16, /* uint32_t regexp index */ - JOF_DOUBLE = 17, /* uint32_t index for double value */ + JOF_DOUBLE = 17, /* inline double value */ JOF_SCOPE = 18, /* uint32_t scope index */ JOF_CODE_OFFSET = 19, /* int32_t bytecode offset */ JOF_ICINDEX = 20, /* uint32_t IC index */ @@ -163,6 +163,16 @@ static MOZ_ALWAYS_INLINE void SET_UINT32(jsbytecode* pc, uint32_t u) { mozilla::NativeEndian::copyAndSwapToLittleEndian(pc + 1, &u, 1); } +static MOZ_ALWAYS_INLINE double GET_DOUBLE(const jsbytecode* pc) { + double result; + mozilla::NativeEndian::copyAndSwapFromLittleEndian(&result, pc + 1, 1); + return result; +} + +static MOZ_ALWAYS_INLINE void SET_DOUBLE(jsbytecode* pc, double d) { + mozilla::NativeEndian::copyAndSwapToLittleEndian(pc + 1, &d, 1); +} + static MOZ_ALWAYS_INLINE int32_t GET_INT32(const jsbytecode* pc) { return static_cast(GET_UINT32(pc)); } diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 78043d36f96a..9a2117faeddc 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1786,9 +1786,6 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_CALLER bool Interpret(JSContext* cx, COUNT_COVERAGE_PC(REGS.pc); \ JS_END_MACRO -#define LOAD_DOUBLE(PCOFF, dbl) \ - ((dbl) = script->getConst(GET_UINT32_INDEX(REGS.pc + (PCOFF))).toDouble()) - #define SET_SCRIPT(s) \ JS_BEGIN_MACRO \ script = (s); \ @@ -3269,11 +3266,7 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_CALLER bool Interpret(JSContext* cx, CASE(JSOP_INT32) { PUSH_INT32(GET_INT32(REGS.pc)); } END_CASE(JSOP_INT32) - CASE(JSOP_DOUBLE) { - double dbl; - LOAD_DOUBLE(0, dbl); - PUSH_DOUBLE(dbl); - } + CASE(JSOP_DOUBLE) { PUSH_DOUBLE(GET_DOUBLE(REGS.pc)); } END_CASE(JSOP_DOUBLE) CASE(JSOP_STRING) { PUSH_STRING(script->getAtom(REGS.pc)); } diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index d3b261855c7d..ff56f4566e37 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -616,10 +616,10 @@ * * Category: Literals * Type: Constants - * Operands: uint32_t constIndex + * Operands: double literal * Stack: => val */ \ - MACRO(JSOP_DOUBLE, 60, "double", NULL, 5, 0, 1, JOF_DOUBLE) \ + MACRO(JSOP_DOUBLE, 60, "double", NULL, 9, 0, 1, JOF_DOUBLE) \ /* * Pushes string constant onto the stack. *