Commit f303611f authored by ggaren@apple.com's avatar ggaren@apple.com

Cleaned up pre/post inc/dec in bytecode

https://bugs.webkit.org/show_bug.cgi?id=115222

Reviewed by Filip Pizlo.

Source/JavaScriptCore: 

A few related changes here:

(*) Removed post_inc and post_dec. The two-result form was awkward to
reason about. Being explicit about the intermediate mov and to_number
reduces DFG overhead, removes some fragile ASSERTs from the DFG, and
fixes a const bug. Plus, we get to blow away 262 lines of code.

(*) Renamed pre_inc and pre_dec to inc and dec, since there's only one
version now.

(*) Renamed to_jsnumber to to_number, to match the ECMA name.

(*) Tightened up the codegen and runtime support for to_number.


* JavaScriptCore.order: Order!

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Opcode.h:
(JSC::padOpcodeName):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitInc):
(JSC::BytecodeGenerator::emitDec):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitToNumber):
(BytecodeGenerator): Removed post_inc and post_dec.

* bytecompiler/NodesCodegen.cpp:
(JSC::emitPreIncOrDec): Updated for rename.

(JSC::emitPostIncOrDec): Issue an explicit mov and to_number when needed.
These are rare, and they boil away in the DFG.

(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve): For const, use an explicit mov instead
of any special forms. This fixes a bug where we would do string
add/subtract instead of number.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_inc):
(JSC::JIT::emitSlow_op_inc):
(JSC::JIT::emit_op_dec):
(JSC::JIT::emitSlow_op_dec):
* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_inc):
(JSC::JIT::emitSlow_op_inc):
(JSC::JIT::emit_op_dec):
(JSC::JIT::emitSlow_op_dec): Removed post_inc/dec, and updated for renames.

* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_number):
(JSC::JIT::emitSlow_op_to_number): Removed a test for number cells. There's
no such thing!

* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_to_number): Use LowestTag to avoid making assumptions
about the lowest valued tag.

(JSC::JIT::emitSlow_op_to_number): Updated for renames.

* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/NodeConstructors.h:
(JSC::UnaryPlusNode::UnaryPlusNode): Removed post_inc/dec, and updated for renames.

* runtime/Operations.cpp:
(JSC::jsIsObjectType): Removed a test for number cells. There's
no such thing!

LayoutTests: 

* fast/js/const-expected.txt:
* fast/js/resources/const.js: Added tests for some const cases we used
to get wrong.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@149247 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b2cfbae4
2013-04-25 Geoffrey Garen <ggaren@apple.com>
Cleaned up pre/post inc/dec in bytecode
https://bugs.webkit.org/show_bug.cgi?id=115222
Reviewed by Filip Pizlo.
* fast/js/const-expected.txt:
* fast/js/resources/const.js: Added tests for some const cases we used
to get wrong.
2013-04-26 Geoffrey Garen <ggaren@apple.com>
Re-landing <http://trac.webkit.org/changeset/148999>
......
......@@ -55,6 +55,15 @@ PASS tryCatch1Result is 5
PASS tryCatch2Result is 5
PASS with1Result is 5
PASS with2Result is 5
PASS PASS: ++x should be 2 and is.
PASS PASS: --x should be 0 and is.
PASS PASS: x should be 1 and is.
PASS PASS: x++ should be 1 and is.
PASS PASS: x should be 1 and is.
PASS PASS: ++x should be 2 and is.
PASS PASS: x should be 1 and is.
PASS PASS: x++ should be 1 and is.
PASS PASS: x should be 1 and is.
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -160,3 +160,31 @@ with1Result = with1();
shouldBe("with1Result", "5");
with2Result = with2();
shouldBe("with2Result", "5");
(function () {
function shouldBe(aDescription, a, b)
{
if (a === b) {
testPassed("PASS: " + aDescription + " should be " + b + " and is.");
return;
}
testFailed("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
}
(function() {
const x = "1";
shouldBe("++x", ++x, 2);
shouldBe("--x", --x, 0);
shouldBe("x", x, "1");
shouldBe("x++", x++, 1);
shouldBe("x", x, "1");
})();
(function() {
const x = 1;
shouldBe("++x", ++x, 2);
shouldBe("x", x, 1);
shouldBe("x++", x++, 1);
shouldBe("x", x, 1);
})();
})();
2013-04-25 Geoffrey Garen <ggaren@apple.com>
Cleaned up pre/post inc/dec in bytecode
https://bugs.webkit.org/show_bug.cgi?id=115222
Reviewed by Filip Pizlo.
A few related changes here:
(*) Removed post_inc and post_dec. The two-result form was awkward to
reason about. Being explicit about the intermediate mov and to_number
reduces DFG overhead, removes some fragile ASSERTs from the DFG, and
fixes a const bug. Plus, we get to blow away 262 lines of code.
(*) Renamed pre_inc and pre_dec to inc and dec, since there's only one
version now.
(*) Renamed to_jsnumber to to_number, to match the ECMA name.
(*) Tightened up the codegen and runtime support for to_number.
* JavaScriptCore.order: Order!
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Opcode.h:
(JSC::padOpcodeName):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitInc):
(JSC::BytecodeGenerator::emitDec):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitToNumber):
(BytecodeGenerator): Removed post_inc and post_dec.
* bytecompiler/NodesCodegen.cpp:
(JSC::emitPreIncOrDec): Updated for rename.
(JSC::emitPostIncOrDec): Issue an explicit mov and to_number when needed.
These are rare, and they boil away in the DFG.
(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve): For const, use an explicit mov instead
of any special forms. This fixes a bug where we would do string
add/subtract instead of number.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_inc):
(JSC::JIT::emitSlow_op_inc):
(JSC::JIT::emit_op_dec):
(JSC::JIT::emitSlow_op_dec):
* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_inc):
(JSC::JIT::emitSlow_op_inc):
(JSC::JIT::emit_op_dec):
(JSC::JIT::emitSlow_op_dec): Removed post_inc/dec, and updated for renames.
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_number):
(JSC::JIT::emitSlow_op_to_number): Removed a test for number cells. There's
no such thing!
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_to_number): Use LowestTag to avoid making assumptions
about the lowest valued tag.
(JSC::JIT::emitSlow_op_to_number): Updated for renames.
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/NodeConstructors.h:
(JSC::UnaryPlusNode::UnaryPlusNode): Removed post_inc/dec, and updated for renames.
* runtime/Operations.cpp:
(JSC::jsIsObjectType): Removed a test for number cells. There's
no such thing!
2013-04-27 Julien Brianceau <jbrianceau@nds.com>
REGRESSION(r149114): cache flush for SH4 arch may flush an extra page.
......
......@@ -889,7 +889,7 @@ __ZN3JSC3JIT11emit_op_jmpEPNS_11InstructionE
__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE
__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_13TrustedImmPtrE
__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii
__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE
__ZN3JSC3JIT15emit_op_incEPNS_11InstructionE
__ZN3JSC3JIT16emitTimeoutCheckEv
__ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE
__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
......@@ -897,7 +897,7 @@ __ZN3JSC9JITThunks7ctiStubEPNS_12VMEPFNS_21MacroAssemblerCodePtrES2_PNS_14Execut
__ZN3WTF9HashTableIPFN3JSC21MacroAssemblerCodePtrEPNS1_12VMEPNS1_14ExecutablePoolEESt4pairIS8_S2_ENS_18PairFirstExtractorISA_EENS_7PtrHashIS8_EENS_14PairHashTraitsINS_10HashTraitsIS8_EENSG_IS2_EEEESH_E6expandEv
__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12VMEPNS_14ExecutablePoolE
__ZN3JSC21roundUpAllocationSizeEmm
__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC3JIT19emitSlow_op_incEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC12X86Assembler7movq_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE
__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_
......@@ -1359,9 +1359,9 @@ __ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE
_cti_op_load_varargs
__ZN3WTF13tryFastCallocEmm
__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE
__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE
__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE
_cti_op_pre_dec
__ZN3JSC3JIT15emit_op_decEPNS_11InstructionE
__ZN3JSC3JIT19emitSlow_op_decEPNS_11InstructionERPNS_13SlowCaseEntryE
_cti_op_dec
__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j
__ZN3JSC5Lexer19getUnicodeCharacterEv
__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateE
......@@ -1433,8 +1433,6 @@ __ZN3WTF10StringImpl7replaceEtPS0_
__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_16ReturnAddressPtrEb
_cti_op_put_by_id_fail
__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_
__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE
__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSCL23createPrototypePropertyERNS_12VMEPNS_14JSGlobalObjectEPNS_10JSFunctionE
__ZNK3JSC8NullNode6isNullEv
__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE
......@@ -1617,8 +1615,6 @@ __ZN3WTF6VectorItLm64EE18tryReserveCapacityEm
__ZN3JSC16globalFuncEscapeEPNS_9ExecStateE
__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_
__ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE
__ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
__ZN3JSC9ExecState19arrayPrototypeTableEPS0_
......@@ -1818,9 +1814,9 @@ __ZNK3JSC18PropertyDescriptor8writableEv
__ZNK3JSC18PropertyDescriptor10enumerableEv
__ZNK3JSC18PropertyDescriptor12configurableEv
__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
__ZN3JSC3JIT19emit_op_to_jsnumberEPNS_11InstructionE
__ZN3JSC3JIT23emitSlow_op_to_jsnumberEPNS_11InstructionERPNS_13SlowCaseEntryE
_cti_op_to_jsnumber
__ZN3JSC3JIT19emit_op_to_numberEPNS_11InstructionE
__ZN3JSC3JIT23emitSlow_op_to_numberEPNS_11InstructionERPNS_13SlowCaseEntryE
_cti_op_to_number
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toNumberEPNS_9ExecStateE
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE9classNameEv
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toStringEPNS_9ExecStateE
......@@ -1933,7 +1929,7 @@ __ZN3JSC15globalFuncIsNaNEPNS_9ExecStateE
_cti_op_is_object
__ZN3JSC14jsIsObjectTypeENS_7JSValueE
__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateE
_cti_op_pre_inc
_cti_op_inc
__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateE
__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateE
__ZN3JSC7JSArray3popEv
......@@ -1973,8 +1969,6 @@ __ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
__ZN3JSC15DateConstructor11getCallDataERNS_8CallDataE
__ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
_cti_op_post_inc
_cti_op_post_dec
__ZN3JSC10ASTBuilder18makeBitwiseNotNodeEPNS_14ExpressionNodeE
__ZN3JSC3JIT14emit_op_bitnotEPNS_11InstructionE
__ZN3JSC3JIT18emitSlow_op_bitnotEPNS_11InstructionERPNS_13SlowCaseEntryE
......
......@@ -837,26 +837,18 @@ void CodeBlock::dumpBytecode(PrintStream& out, ExecState* exec, const Instructio
printBinaryOp(out, exec, location, it, "greatereq");
break;
}
case op_pre_inc: {
case op_inc: {
int r0 = (++it)->u.operand;
out.printf("[%4d] pre_inc\t\t %s", location, registerName(exec, r0).data());
break;
}
case op_pre_dec: {
case op_dec: {
int r0 = (++it)->u.operand;
out.printf("[%4d] pre_dec\t\t %s", location, registerName(exec, r0).data());
break;
}
case op_post_inc: {
printUnaryOp(out, exec, location, it, "post_inc");
break;
}
case op_post_dec: {
printUnaryOp(out, exec, location, it, "post_dec");
break;
}
case op_to_jsnumber: {
printUnaryOp(out, exec, location, it, "to_jsnumber");
case op_to_number: {
printUnaryOp(out, exec, location, it, "to_number");
break;
}
case op_negate: {
......
......@@ -67,11 +67,9 @@ namespace JSC {
macro(op_greater, 4) \
macro(op_greatereq, 4) \
\
macro(op_pre_inc, 2) \
macro(op_pre_dec, 2) \
macro(op_post_inc, 3) \
macro(op_post_dec, 3) \
macro(op_to_jsnumber, 3) \
macro(op_inc, 2) \
macro(op_dec, 2) \
macro(op_to_number, 3) \
macro(op_negate, 3) \
macro(op_add, 5) \
macro(op_mul, 5) \
......
......@@ -1016,36 +1016,20 @@ RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, R
return dst;
}
RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
{
emitOpcode(op_pre_inc);
emitOpcode(op_inc);
instructions().append(srcDst->index());
return srcDst;
}
RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
{
emitOpcode(op_pre_dec);
emitOpcode(op_dec);
instructions().append(srcDst->index());
return srcDst;
}
RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
{
emitOpcode(op_post_inc);
instructions().append(dst->index());
instructions().append(srcDst->index());
return dst;
}
RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
{
emitOpcode(op_post_dec);
instructions().append(dst->index());
instructions().append(srcDst->index());
return dst;
}
RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
{
emitOpcode(opcodeID);
......
......@@ -445,11 +445,9 @@ namespace JSC {
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); }
RegisterID* emitPreInc(RegisterID* srcDst);
RegisterID* emitPreDec(RegisterID* srcDst);
RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_number, dst, src); }
RegisterID* emitInc(RegisterID* srcDst);
RegisterID* emitDec(RegisterID* srcDst);
void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target);
RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
......
......@@ -601,16 +601,18 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
// ------------------------------ PostfixNode ----------------------------------
static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
{
return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
}
static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
{
if (srcDst == dst)
return generator.emitToJSNumber(dst, srcDst);
return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
if (dst == srcDst)
return generator.emitToNumber(generator.finalDestination(dst), srcDst);
RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
emitIncOrDec(generator, srcDst, oper);
return generator.moveToDestinationIfNeeded(dst, tmp.get());
}
RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
......@@ -624,12 +626,12 @@ RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* d
ResolveResult resolveResult = generator.resolve(ident);
if (RegisterID* local = resolveResult.local()) {
if (RefPtr<RegisterID> local = resolveResult.local()) {
if (resolveResult.isReadOnly()) {
generator.emitReadOnlyExceptionIfNeeded();
return generator.emitToJSNumber(generator.finalDestination(dst), local);
local = generator.emitMove(generator.tempDestination(dst), local.get());
}
return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
return emitPostIncOrDec(generator, generator.finalDestination(dst), local.get(), m_operator);
}
if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
......@@ -805,22 +807,18 @@ RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* ds
const Identifier& ident = resolve->identifier();
ResolveResult resolveResult = generator.resolve(ident);
if (RegisterID* local = resolveResult.local()) {
if (RefPtr<RegisterID> local = resolveResult.local()) {
if (resolveResult.isReadOnly()) {
generator.emitReadOnlyExceptionIfNeeded();
if (dst == generator.ignoredResult())
return generator.emitToJSNumber(generator.newTemporary(), local);
RefPtr<RegisterID> r0 = generator.emitLoad(generator.tempDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
return generator.moveToDestinationIfNeeded(dst, r0.get());
local = generator.emitMove(generator.tempDestination(dst), local.get());
}
emitPreIncOrDec(generator, local, m_operator);
return generator.moveToDestinationIfNeeded(dst, local);
emitIncOrDec(generator, local.get(), m_operator);
return generator.moveToDestinationIfNeeded(dst, local.get());
}
if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
RefPtr<RegisterID> propDst = generator.emitGetStaticVar(generator.tempDestination(dst), resolveResult, ident);
emitPreIncOrDec(generator, propDst.get(), m_operator);
emitIncOrDec(generator, propDst.get(), m_operator);
generator.emitPutStaticVar(resolveResult, ident, propDst.get());
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
......@@ -829,7 +827,7 @@ RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* ds
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
NonlocalResolveInfo resolveVerifier;
RefPtr<RegisterID> base = generator.emitResolveWithBaseForPut(generator.newTemporary(), propDst.get(), resolveResult, ident, resolveVerifier);
emitPreIncOrDec(generator, propDst.get(), m_operator);
emitIncOrDec(generator, propDst.get(), m_operator);
generator.emitPutToBase(base.get(), ident, propDst.get(), resolveVerifier);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
......@@ -847,7 +845,7 @@ RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* ds
generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
emitPreIncOrDec(generator, value, m_operator);
emitIncOrDec(generator, value, m_operator);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutByVal(base.get(), property.get(), value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
......@@ -865,7 +863,7 @@ RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
emitPreIncOrDec(generator, value, m_operator);
emitIncOrDec(generator, value, m_operator);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base.get(), ident, value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
......
......@@ -2196,35 +2196,18 @@ bool ByteCodeParser::parseBlock(unsigned limit)
// === Increment/Decrement opcodes ===
case op_pre_inc: {
case op_inc: {
unsigned srcDst = currentInstruction[1].u.operand;
Node* op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
NEXT_OPCODE(op_pre_inc);
NEXT_OPCODE(op_inc);
}
case op_post_inc: {
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
ASSERT(result != srcDst); // Required for assumptions we make during OSR.
Node* op = get(srcDst);
setPair(result, op, srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
NEXT_OPCODE(op_post_inc);
}
case op_pre_dec: {
case op_dec: {
unsigned srcDst = currentInstruction[1].u.operand;
Node* op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithSub, op, one())));
NEXT_OPCODE(op_pre_dec);
}
case op_post_dec: {
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
Node* op = get(srcDst);
setPair(result, op, srcDst, makeSafe(addToGraph(ArithSub, op, one())));
NEXT_OPCODE(op_post_dec);
NEXT_OPCODE(op_dec);
}
// === Arithmetic operations ===
......@@ -3377,10 +3360,10 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_typeof);
}
case op_to_jsnumber: {
case op_to_number: {
set(currentInstruction[1].u.operand,
addToGraph(Identity, Edge(get(currentInstruction[2].u.operand), NumberUse)));
NEXT_OPCODE(op_to_jsnumber);
NEXT_OPCODE(op_to_number);
}
default:
......
......@@ -95,10 +95,8 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_rshift:
case op_lshift:
case op_urshift:
case op_pre_inc:
case op_post_inc:
case op_pre_dec:
case op_post_dec:
case op_inc:
case op_dec:
case op_add:
case op_sub:
case op_negate:
......@@ -183,7 +181,7 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_put_to_base_variable:
case op_put_to_base:
case op_typeof:
case op_to_jsnumber:
case op_to_number:
return CanCompile;
case op_call_varargs:
......
......@@ -290,10 +290,8 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_not)
DEFINE_OP(op_nstricteq)
DEFINE_OP(op_pop_scope)
DEFINE_OP(op_post_dec)
DEFINE_OP(op_post_inc)
DEFINE_OP(op_pre_dec)
DEFINE_OP(op_pre_inc)
DEFINE_OP(op_dec)
DEFINE_OP(op_inc)
DEFINE_OP(op_profile_did_call)
DEFINE_OP(op_profile_will_call)
DEFINE_OP(op_push_name_scope)
......@@ -346,7 +344,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_tear_off_arguments)
DEFINE_OP(op_throw)
DEFINE_OP(op_throw_static_error)
DEFINE_OP(op_to_jsnumber)
DEFINE_OP(op_to_number)
DEFINE_OP(op_to_primitive)
DEFINE_OP(op_get_scoped_var)
......@@ -470,10 +468,8 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_new_object)
DEFINE_SLOWCASE_OP(op_not)
DEFINE_SLOWCASE_OP(op_nstricteq)
DEFINE_SLOWCASE_OP(op_post_dec)
DEFINE_SLOWCASE_OP(op_post_inc)
DEFINE_SLOWCASE_OP(op_pre_dec)
DEFINE_SLOWCASE_OP(op_pre_inc)
DEFINE_SLOWCASE_OP(op_dec)
DEFINE_SLOWCASE_OP(op_inc)
case op_put_by_id_out_of_line:
case op_put_by_id_transition_direct:
case op_put_by_id_transition_normal:
......@@ -486,7 +482,7 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_urshift)
DEFINE_SLOWCASE_OP(op_stricteq)
DEFINE_SLOWCASE_OP(op_sub)
DEFINE_SLOWCASE_OP(op_to_jsnumber)
DEFINE_SLOWCASE_OP(op_to_number)
DEFINE_SLOWCASE_OP(op_to_primitive)
case op_resolve_global_property:
......
......@@ -709,10 +709,8 @@ namespace JSC {
void emit_op_not(Instruction*);
void emit_op_nstricteq(Instruction*);
void emit_op_pop_scope(Instruction*);
void emit_op_post_dec(Instruction*);
void emit_op_post_inc(Instruction*);
void emit_op_pre_dec(Instruction*);
void emit_op_pre_inc(Instruction*);
void emit_op_dec(Instruction*);
void emit_op_inc(Instruction*);
void emit_op_profile_did_call(Instruction*);
void emit_op_profile_will_call(Instruction*);
void emit_op_push_name_scope(Instruction*);
......@@ -744,7 +742,7 @@ namespace JSC {
void emit_op_tear_off_arguments(Instruction*);
void emit_op_throw(Instruction*);
void emit_op_throw_static_error(Instruction*);
void emit_op_to_jsnumber(Instruction*);
void emit_op_to_number(Instruction*);
void emit_op_to_primitive(Instruction*);
void emit_op_unexpected_load(Instruction*);
void emit_op_urshift(Instruction*);
......@@ -789,17 +787,15 @@ namespace JSC {
void emitSlow_op_new_object(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_init_global_const_check(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
......
......@@ -629,65 +629,7 @@ void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEnt
}
}
void JIT::emit_op_post_inc(Instruction* currentInstruction)
{
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
if (canBeOptimizedOrInlined())
killLastResultRegister();
}
void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
linkSlowCase(iter);
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_post_inc);
stubCall.addArgument(regT0);
stubCall.addArgument(Imm32(srcDst));
stubCall.call(result);
}
void JIT::emit_op_post_dec(Instruction* currentInstruction)
{
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
if (canBeOptimizedOrInlined())
killLastResultRegister();
}
void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
linkSlowCase(iter);
linkSlowCase(iter);