diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-11-27 14:49:40 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-01-09 13:52:26 +0000 |
commit | 4eaf4a002b9832838bf9dd7a2eaf0c6b29d2060c (patch) | |
tree | a625c905f9913264ef0d3300337c84a3cd8a3918 /src/qml/jit/qv4assembler.cpp | |
parent | e3f7da72ac5b4540f88bb5cbd91a4917ba84334a (diff) |
Optimize inc/dec operations
Change-Id: I3e1fa464e380a40b610bbc339bdbc272ebc863d1
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/jit/qv4assembler.cpp')
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 87 |
1 files changed, 63 insertions, 24 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 956ee76623..fdb795be92 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -61,6 +61,7 @@ namespace JIT { #define callHelper(x) PlatformAssemblerCommon::callRuntime(#x, reinterpret_cast<void *>(&x)) const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer; +const int IsIntegerConvertible_Shift = QV4::Value::IsIntegerConvertible_Shift; static ReturnedValue toNumberHelper(ReturnedValue v) { @@ -630,7 +631,12 @@ struct PlatformAssembler64 : PlatformAssemblerCommon { PlatformAssemblerCommon::callRuntime(functionName, funcPtr); if (dest == Assembler::ResultInAccumulator) - move(ReturnValueRegister, AccumulatorRegister); + saveReturnValueInAccumulator(); + } + + void saveReturnValueInAccumulator() + { + move(ReturnValueRegister, AccumulatorRegister); } void loadUndefined(RegisterID dest = AccumulatorRegister) @@ -716,7 +722,7 @@ struct PlatformAssembler64 : PlatformAssemblerCommon move(AccumulatorRegister, registerForArg(0)); callHelper(toNumberHelper); - move(ReturnValueRegister, AccumulatorRegister); + saveReturnValueInAccumulator(); isNumber.link(this); } @@ -740,7 +746,7 @@ struct PlatformAssembler64 : PlatformAssemblerCommon pushAligned(lhsTarget); move(AccumulatorRegister, registerForArg(0)); callHelper(toInt32Helper); - move(ReturnValueRegister, AccumulatorRegister); + saveReturnValueInAccumulator(); popAligned(lhsTarget); isInt.link(this); @@ -862,8 +868,8 @@ struct PlatformAssembler64 : PlatformAssemblerCommon Jump unopIntPath(std::function<Jump(void)> fastPath) { - urshift64(AccumulatorRegister, TrustedImm32(32), ScratchRegister); - Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister); + urshift64(AccumulatorRegister, TrustedImm32(IsIntegerConvertible_Shift), ScratchRegister); + Jump accNotIntConvertible = branch32(NotEqual, TrustedImm32(1), ScratchRegister); // both integer Jump failure = fastPath(); @@ -872,10 +878,16 @@ struct PlatformAssembler64 : PlatformAssemblerCommon // all other cases if (failure.isSet()) failure.link(this); - accNotInt.link(this); + accNotIntConvertible.link(this); return done; } + + void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall) + { + passAsArg(AccumulatorRegister, 0); + doCall(); + } }; typedef PlatformAssembler64 PlatformAssembler; @@ -888,10 +900,14 @@ struct PlatformAssembler32 : PlatformAssemblerCommon Assembler::CallResultDestination dest) { PlatformAssemblerCommon::callRuntime(functionName, funcPtr); - if (dest == Assembler::ResultInAccumulator) { - move(ReturnValueRegisterValue, AccumulatorRegisterValue); - move(ReturnValueRegisterTag, AccumulatorRegisterTag); - } + if (dest == Assembler::ResultInAccumulator) + saveReturnValueInAccumulator(); + } + + void saveReturnValueInAccumulator() + { + move(ReturnValueRegisterValue, AccumulatorRegisterValue); + move(ReturnValueRegisterTag, AccumulatorRegisterTag); } void loadUndefined() @@ -979,8 +995,7 @@ struct PlatformAssembler32 : PlatformAssemblerCommon } callRuntime("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper), Assembler::ResultInAccumulator); - move(ReturnValueRegisterValue, AccumulatorRegisterValue); - move(ReturnValueRegisterTag, AccumulatorRegisterTag); + saveReturnValueInAccumulator(); if (ArgInRegCount < 2) addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); @@ -1243,6 +1258,20 @@ struct PlatformAssembler32 : PlatformAssemblerCommon return done; } + + void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall) + { + if (ArgInRegCount < 2) { + push(AccumulatorRegisterTag); + push(AccumulatorRegisterValue); + } else { + move(AccumulatorRegisterValue, registerForArg(0)); + move(AccumulatorRegisterTag, registerForArg(1)); + } + doCall(); + if (ArgInRegCount < 2) + addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); + } }; typedef PlatformAssembler32 PlatformAssembler; @@ -1467,9 +1496,14 @@ void Assembler::ucompl() pasm()->setAccumulatorTag(IntegerTag); } -static ReturnedValue incHelper(const Value &v) +static ReturnedValue incHelper(const Value v) { - return Encode(v.toNumber() + 1.); + double d; + if (Q_LIKELY(v.isDouble())) + d = v.doubleValue(); + else + d = v.toNumberImpl(); + return Encode(d + 1.); } void Assembler::inc() @@ -1484,19 +1518,24 @@ void Assembler::inc() }); // slow path: - saveAccumulatorInFrame(); - prepareCallWithArgCount(1); - passAccumulatorAsArg(0); - IN_JIT_GENERATE_RUNTIME_CALL(incHelper, ResultInAccumulator); + pasm()->callWithAccumulatorByValueAsFirstArgument([this]() { + pasm()->callHelper(incHelper); + pasm()->saveReturnValueInAccumulator(); + }); checkException(); // done. done.link(pasm()); } -static ReturnedValue decHelper(const Value &v) +static ReturnedValue decHelper(const Value v) { - return Encode(v.toNumber() - 1.); + double d; + if (Q_LIKELY(v.isDouble())) + d = v.doubleValue(); + else + d = v.toNumberImpl(); + return Encode(d - 1.); } void Assembler::dec() @@ -1511,10 +1550,10 @@ void Assembler::dec() }); // slow path: - saveAccumulatorInFrame(); - prepareCallWithArgCount(1); - passAccumulatorAsArg(0); - IN_JIT_GENERATE_RUNTIME_CALL(decHelper, ResultInAccumulator); + pasm()->callWithAccumulatorByValueAsFirstArgument([this]() { + pasm()->callHelper(decHelper); + pasm()->saveReturnValueInAccumulator(); + }); checkException(); // done. |