+2013-03-28 Geoffrey Garen <ggaren@apple.com>
+
+ Simplified the bytecode by removing op_loop and op_loop_if_*
+ https://bugs.webkit.org/show_bug.cgi?id=113548
+
+ Reviewed by Filip Pizlo.
+
+ Regular jumps will suffice.
+
+ These opcodes are identical to branches, except they also do timeout
+ checking. That style of timeout checking has been broken for a long
+ time, and when we add back timeout checking, it won't use these opcodes.
+
+ * JavaScriptCore.order:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/PreciseJumpTargets.cpp:
+ (JSC::computePreciseJumpTargets):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitJump):
+ (JSC::BytecodeGenerator::emitJumpIfTrue):
+ (JSC::BytecodeGenerator::emitJumpIfFalse):
+ * 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):
+ (JSC):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
2013-03-28 Geoffrey Garen <ggaren@apple.com>
Simplified the bytecode by removing op_jmp_scopes
__ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_
__ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE
__ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC3JIT22emit_op_loop_if_lesseqEPNS_11InstructionE
-__ZN3JSC3JIT26emitSlow_op_loop_if_lesseqEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
__ZN3JSC9ExecState19arrayPrototypeTableEPS0_
__ZN3JSC20StrictEvalActivationD1Ev
__ZN3JSC27StrictModeTypeErrorFunctionD1Ev
__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
-_cti_op_loop_if_lesseq
__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E
__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E
__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDEi
out.printf("[%4d] jmp\t\t %d(->%d)", location, offset, location + offset);
break;
}
- case op_loop: {
- int offset = (++it)->u.operand;
- out.printf("[%4d] loop\t\t %d(->%d)", location, offset, location + offset);
- break;
- }
case op_jtrue: {
printConditionalJump(out, exec, begin, it, location, "jtrue");
break;
}
- case op_loop_if_true: {
- printConditionalJump(out, exec, begin, it, location, "loop_if_true");
- break;
- }
- case op_loop_if_false: {
- printConditionalJump(out, exec, begin, it, location, "loop_if_false");
- break;
- }
case op_jfalse: {
printConditionalJump(out, exec, begin, it, location, "jfalse");
break;
out.printf("[%4d] jngreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
- case op_loop_if_less: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- out.printf("[%4d] loop_if_less\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
- case op_loop_if_lesseq: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- out.printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
- case op_loop_if_greater: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- out.printf("[%4d] loop_if_greater\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
- case op_loop_if_greatereq: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- out.printf("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
case op_loop_hint: {
out.printf("[%4d] loop_hint", location);
break;
macro(op_jnlesseq, 4) \
macro(op_jngreater, 4) \
macro(op_jngreatereq, 4) \
- macro(op_loop, 2) \
- macro(op_loop_if_true, 3) \
- macro(op_loop_if_false, 3) \
- macro(op_loop_if_less, 4) \
- macro(op_loop_if_lesseq, 4) \
- macro(op_loop_if_greater, 4) \
- macro(op_loop_if_greatereq, 4) \
macro(op_loop_hint, 1) \
macro(op_switch_imm, 4) \
macro(op_switch_char, 4) \
Instruction* current = instructionsBegin + bytecodeOffset;
switch (opcodeID) {
case op_jmp:
- case op_loop:
out.append(bytecodeOffset + current[1].u.operand);
break;
case op_jtrue:
case op_jfalse:
case op_jeq_null:
case op_jneq_null:
- case op_loop_if_true:
- case op_loop_if_false:
out.append(bytecodeOffset + current[2].u.operand);
break;
case op_jneq_ptr:
case op_jnlesseq:
case op_jngreater:
case op_jngreatereq:
- case op_loop_if_less:
- case op_loop_if_lesseq:
- case op_loop_if_greater:
- case op_loop_if_greatereq:
out.append(bytecodeOffset + current[3].u.operand);
break;
case op_switch_imm:
PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
{
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jmp : op_loop);
+ emitOpcode(op_jmp);
instructions().append(target->bind(begin, instructions().size()));
return target;
}
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jless : op_loop_if_less);
+ emitOpcode(op_jless);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
+ emitOpcode(op_jlesseq);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jgreater : op_loop_if_greater);
+ emitOpcode(op_jgreater);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jgreatereq : op_loop_if_greatereq);
+ emitOpcode(op_jgreatereq);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
+ emitOpcode(op_jtrue);
instructions().append(cond->index());
instructions().append(target->bind(begin, instructions().size()));
return target;
rewindUnaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
+ emitOpcode(op_jtrue);
instructions().append(srcIndex);
instructions().append(target->bind(begin, instructions().size()));
return target;
}
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false);
+ emitOpcode(op_jfalse);
instructions().append(cond->index());
instructions().append(target->bind(begin, instructions().size()));
return target;
LAST_OPCODE(op_jmp);
}
- case op_loop: {
- unsigned relativeOffset = currentInstruction[1].u.operand;
- addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
- LAST_OPCODE(op_loop);
- }
-
- case op_jtrue:
- case op_loop_if_true: {
+ case op_jtrue: {
unsigned relativeOffset = currentInstruction[2].u.operand;
Node* condition = get(currentInstruction[1].u.operand);
if (canFold(condition)) {
LAST_OPCODE(op_jtrue);
}
- case op_jfalse:
- case op_loop_if_false: {
+ case op_jfalse: {
unsigned relativeOffset = currentInstruction[2].u.operand;
Node* condition = get(currentInstruction[1].u.operand);
if (canFold(condition)) {
LAST_OPCODE(op_jneq_null);
}
- case op_jless:
- case op_loop_if_less: {
+ case op_jless: {
unsigned relativeOffset = currentInstruction[3].u.operand;
Node* op1 = get(currentInstruction[1].u.operand);
Node* op2 = get(currentInstruction[2].u.operand);
LAST_OPCODE(op_jless);
}
- case op_jlesseq:
- case op_loop_if_lesseq: {
+ case op_jlesseq: {
unsigned relativeOffset = currentInstruction[3].u.operand;
Node* op1 = get(currentInstruction[1].u.operand);
Node* op2 = get(currentInstruction[2].u.operand);
LAST_OPCODE(op_jlesseq);
}
- case op_jgreater:
- case op_loop_if_greater: {
+ case op_jgreater: {
unsigned relativeOffset = currentInstruction[3].u.operand;
Node* op1 = get(currentInstruction[1].u.operand);
Node* op2 = get(currentInstruction[2].u.operand);
LAST_OPCODE(op_jgreater);
}
- case op_jgreatereq:
- case op_loop_if_greatereq: {
+ case op_jgreatereq: {
unsigned relativeOffset = currentInstruction[3].u.operand;
Node* op1 = get(currentInstruction[1].u.operand);
Node* op2 = get(currentInstruction[2].u.operand);
case op_init_global_const:
case op_init_global_const_check:
case op_jmp:
- case op_loop:
case op_jtrue:
case op_jfalse:
- case op_loop_if_true:
- case op_loop_if_false:
case op_jeq_null:
case op_jneq_null:
case op_jless:
case op_jngreater:
case op_jngreatereq:
case op_loop_hint:
- case op_loop_if_less:
- case op_loop_if_lesseq:
- case op_loop_if_greater:
- case op_loop_if_greatereq:
case op_ret:
case op_end:
case op_call_put_result:
DEFINE_OP(op_jngreater)
DEFINE_OP(op_jngreatereq)
DEFINE_OP(op_jtrue)
- DEFINE_OP(op_loop)
DEFINE_OP(op_loop_hint)
- DEFINE_OP(op_loop_if_less)
- DEFINE_OP(op_loop_if_lesseq)
- DEFINE_OP(op_loop_if_greater)
- DEFINE_OP(op_loop_if_greatereq)
- DEFINE_OP(op_loop_if_true)
- DEFINE_OP(op_loop_if_false)
DEFINE_OP(op_lshift)
DEFINE_OP(op_mod)
DEFINE_OP(op_mov)
DEFINE_SLOWCASE_OP(op_jngreater)
DEFINE_SLOWCASE_OP(op_jngreatereq)
DEFINE_SLOWCASE_OP(op_jtrue)
- DEFINE_SLOWCASE_OP(op_loop_if_less)
- DEFINE_SLOWCASE_OP(op_loop_if_lesseq)
- DEFINE_SLOWCASE_OP(op_loop_if_greater)
- DEFINE_SLOWCASE_OP(op_loop_if_greatereq)
- DEFINE_SLOWCASE_OP(op_loop_if_true)
- DEFINE_SLOWCASE_OP(op_loop_if_false)
DEFINE_SLOWCASE_OP(op_lshift)
DEFINE_SLOWCASE_OP(op_mod)
DEFINE_SLOWCASE_OP(op_mul)
void emit_op_jngreater(Instruction*);
void emit_op_jngreatereq(Instruction*);
void emit_op_jtrue(Instruction*);
- void emit_op_loop(Instruction*);
void emit_op_loop_hint(Instruction*);
- void emit_op_loop_if_less(Instruction*);
- void emit_op_loop_if_lesseq(Instruction*);
- void emit_op_loop_if_greater(Instruction*);
- void emit_op_loop_if_greatereq(Instruction*);
- void emit_op_loop_if_true(Instruction*);
- void emit_op_loop_if_false(Instruction*);
void emit_op_lshift(Instruction*);
void emit_op_mod(Instruction*);
void emit_op_mov(Instruction*);
void emitSlow_op_jngreater(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jngreatereq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_greater(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_greatereq(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_false(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&);
#endif
} JIT_CLASS_ALIGNMENT;
- inline void JIT::emit_op_loop(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jmp(currentInstruction);
- }
-
inline void JIT::emit_op_loop_hint(Instruction*)
{
emitOptimizationCheck(LoopOptimizationCheck);
}
- inline void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jtrue(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jtrue(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_false(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jfalse(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jfalse(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jless(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jless(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jlesseq(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jlesseq(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_greater(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jgreater(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_greater(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jgreater(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_greatereq(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jgreatereq(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_greatereq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jgreatereq(currentInstruction, iter);
- }
-
} // namespace JSC
#endif // ENABLE(JIT)
dispatch(5)
-_llint_op_loop_if_true:
- traceExecution()
- jumpTrueOrFalse(
- macro (value, target) btinz value, target end,
- _llint_slow_path_jtrue)
-
-
_llint_op_jtrue:
traceExecution()
jumpTrueOrFalse(
_llint_slow_path_jtrue)
-_llint_op_loop_if_false:
- traceExecution()
- jumpTrueOrFalse(
- macro (value, target) btiz value, target end,
- _llint_slow_path_jfalse)
-
-
_llint_op_jfalse:
traceExecution()
jumpTrueOrFalse(
_llint_slow_path_jfalse)
-_llint_op_loop_if_less:
- traceExecution()
- compare(
- macro (left, right, target) bilt left, right, target end,
- macro (left, right, target) bdlt left, right, target end,
- _llint_slow_path_jless)
-
-
_llint_op_jless:
traceExecution()
compare(
_llint_slow_path_jnless)
-_llint_op_loop_if_greater:
- traceExecution()
- compare(
- macro (left, right, target) bigt left, right, target end,
- macro (left, right, target) bdgt left, right, target end,
- _llint_slow_path_jgreater)
-
-
_llint_op_jgreater:
traceExecution()
compare(
_llint_slow_path_jngreater)
-_llint_op_loop_if_lesseq:
- traceExecution()
- compare(
- macro (left, right, target) bilteq left, right, target end,
- macro (left, right, target) bdlteq left, right, target end,
- _llint_slow_path_jlesseq)
-
-
_llint_op_jlesseq:
traceExecution()
compare(
_llint_slow_path_jnlesseq)
-_llint_op_loop_if_greatereq:
- traceExecution()
- compare(
- macro (left, right, target) bigteq left, right, target end,
- macro (left, right, target) bdgteq left, right, target end,
- _llint_slow_path_jgreatereq)
-
-
_llint_op_jgreatereq:
traceExecution()
compare(
dispatch(5)
-_llint_op_loop:
- traceExecution()
- dispatchBranch(4[PC])
-
-
_llint_op_jmp:
traceExecution()
dispatchBranch(4[PC])
dispatch(5)
-_llint_op_loop:
- traceExecution()
- dispatchIntIndirect(1)
-
-
_llint_op_jmp:
traceExecution()
dispatchIntIndirect(1)