Ignore:
Timestamp:
Mar 29, 2013, 12:12:18 PM (12 years ago)
Author:
[email protected]
Message:

Simplified bytecode generation by unforking "condition context" codegen
https://bugs.webkit.org/show_bug.cgi?id=113554

Reviewed by Mark Hahnenberg.

Now, a node that establishes a condition context can always ask its child
nodes to generate into that context.

This has a few advantages:

(*) Removes a bunch of code;

(*) Optimizes a few missed cases like "if (!(x < 2))", "if (!!x)", and

"if (!x
!y)";

(*) Paves the way to removing more opcodes.

  • bytecode/Opcode.h:

(JSC): Separated out the branching opcodes for clarity.

  • bytecompiler/NodesCodegen.cpp:

(JSC::ExpressionNode::emitBytecodeInConditionContext): All expressions
can be emitted in a condition context now -- the default behavior is
to branch based on the expression's value.

(JSC::LogicalNotNode::emitBytecodeInConditionContext):
(JSC::LogicalOpNode::emitBytecodeInConditionContext):
(JSC::ConditionalNode::emitBytecode):
(JSC::IfNode::emitBytecode):
(JSC::IfElseNode::emitBytecode):
(JSC::DoWhileNode::emitBytecode):
(JSC::WhileNode::emitBytecode):
(JSC::ForNode::emitBytecode):

  • parser/Nodes.h:

(JSC::ExpressionNode::isSubtract):
(ExpressionNode):
(LogicalNotNode):
(LogicalOpNode): Removed lots of code for handling expressions
that couldn't generate into a condition context because all expressions
can now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r147184 r147234  
    7474    because the assignment node, "x =", passes r[x] as dst to the number node, "1".
    7575*/
     76
     77void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
     78{
     79    RegisterID* result = generator.emitNode(this);
     80    if (fallThroughMode == FallThroughMeansTrue)
     81        generator.emitJumpIfFalse(result, falseTarget);
     82    else
     83        generator.emitJumpIfTrue(result, trueTarget);
     84}
    7685
    7786// ------------------------------ ThrowableExpressionData --------------------------------
     
    922931// ------------------------------ LogicalNotNode -----------------------------------
    923932
    924 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
    925 {
    926     ASSERT(expr()->hasConditionContextCodegen());
    927 
     933void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
     934{
    928935    // reverse the true and false targets
    929     generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, !fallThroughMeansTrue);
     936    generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
    930937}
    931938
     
    11651172}
    11661173
    1167 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
    1168 {
    1169     if (m_expr1->hasConditionContextCodegen()) {
    1170         RefPtr<Label> afterExpr1 = generator.newLabel();
    1171         if (m_operator == OpLogicalAnd)
    1172             generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, true);
    1173         else
    1174             generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), false);
    1175         generator.emitLabel(afterExpr1.get());
    1176     } else {
    1177         RegisterID* temp = generator.emitNode(m_expr1);
    1178         if (m_operator == OpLogicalAnd)
    1179             generator.emitJumpIfFalse(temp, falseTarget);
    1180         else
    1181             generator.emitJumpIfTrue(temp, trueTarget);
    1182     }
    1183 
    1184     if (m_expr2->hasConditionContextCodegen())
    1185         generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMeansTrue);
    1186     else {
    1187         RegisterID* temp = generator.emitNode(m_expr2);
    1188         if (fallThroughMeansTrue)
    1189             generator.emitJumpIfFalse(temp, falseTarget);
    1190         else
    1191             generator.emitJumpIfTrue(temp, trueTarget);
    1192     }
     1174void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
     1175{
     1176    RefPtr<Label> afterExpr1 = generator.newLabel();
     1177    if (m_operator == OpLogicalAnd)
     1178        generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
     1179    else
     1180        generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
     1181    generator.emitLabel(afterExpr1.get());
     1182
     1183    generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
    11931184}
    11941185
     
    12011192    RefPtr<Label> afterElse = generator.newLabel();
    12021193
    1203     if (m_logical->hasConditionContextCodegen()) {
    1204         RefPtr<Label> beforeThen = generator.newLabel();
    1205         generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true);
    1206         generator.emitLabel(beforeThen.get());
    1207     } else {
    1208         RegisterID* cond = generator.emitNode(m_logical);
    1209         generator.emitJumpIfFalse(cond, beforeElse.get());
    1210     }
     1194    RefPtr<Label> beforeThen = generator.newLabel();
     1195    generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
     1196    generator.emitLabel(beforeThen.get());
    12111197
    12121198    generator.emitNode(newDst.get(), m_expr1);
     
    15441530    RefPtr<Label> afterThen = generator.newLabel();
    15451531
    1546     if (m_condition->hasConditionContextCodegen()) {
    1547         RefPtr<Label> beforeThen = generator.newLabel();
    1548         generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), true);
    1549         generator.emitLabel(beforeThen.get());
    1550     } else {
    1551         RegisterID* cond = generator.emitNode(m_condition);
    1552         generator.emitJumpIfFalse(cond, afterThen.get());
    1553     }
     1532    RefPtr<Label> beforeThen = generator.newLabel();
     1533    generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), FallThroughMeansTrue);
     1534    generator.emitLabel(beforeThen.get());
    15541535
    15551536    generator.emitNode(dst, m_ifBlock);
     
    15691550    RefPtr<Label> afterElse = generator.newLabel();
    15701551
    1571     if (m_condition->hasConditionContextCodegen()) {
    1572         RefPtr<Label> beforeThen = generator.newLabel();
    1573         generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), true);
    1574         generator.emitLabel(beforeThen.get());
    1575     } else {
    1576         RegisterID* cond = generator.emitNode(m_condition);
    1577         generator.emitJumpIfFalse(cond, beforeElse.get());
    1578     }
     1552    RefPtr<Label> beforeThen = generator.newLabel();
     1553    generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
     1554    generator.emitLabel(beforeThen.get());
    15791555
    15801556    generator.emitNode(dst, m_ifBlock);
     
    16061582    generator.emitLabel(scope->continueTarget());
    16071583    generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), charPosition());
    1608     if (m_expr->hasConditionContextCodegen())
    1609         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
    1610     else {
    1611         RegisterID* cond = generator.emitNode(m_expr);
    1612         generator.emitJumpIfTrue(cond, topOfLoop.get());
    1613     }
     1584    generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
    16141585
    16151586    generator.emitLabel(scope->breakTarget());
     
    16251596
    16261597    generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->charPosition());
    1627     if (m_expr->hasConditionContextCodegen())
    1628         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), true);
    1629     else {
    1630         RegisterID* cond = generator.emitNode(m_expr);
    1631         generator.emitJumpIfFalse(cond, scope->breakTarget());
    1632     }
     1598    generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
    16331599
    16341600    generator.emitLabel(topOfLoop.get());
     
    16401606    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
    16411607
    1642     if (m_expr->hasConditionContextCodegen())
    1643         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
    1644     else {
    1645         RegisterID* cond = generator.emitNode(m_expr);
    1646         generator.emitJumpIfTrue(cond, topOfLoop.get());
    1647     }
     1608    generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
    16481609
    16491610    generator.emitLabel(scope->breakTarget());
     
    16651626   
    16661627    RefPtr<Label> topOfLoop = generator.newLabel();
    1667     if (m_expr2) {
    1668         if (m_expr2->hasConditionContextCodegen())
    1669             generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), true);
    1670         else {
    1671             RegisterID* cond = generator.emitNode(m_expr2);
    1672             generator.emitJumpIfFalse(cond, scope->breakTarget());
    1673         }
    1674     }
     1628    if (m_expr2)
     1629        generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
    16751630
    16761631    generator.emitLabel(topOfLoop.get());
     
    16841639        generator.emitNode(generator.ignoredResult(), m_expr3);
    16851640
    1686     if (m_expr2) {
    1687         if (m_expr2->hasConditionContextCodegen())
    1688             generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false);
    1689         else {
    1690             RegisterID* cond = generator.emitNode(m_expr2);
    1691             generator.emitJumpIfTrue(cond, topOfLoop.get());
    1692         }
    1693     } else
     1641    if (m_expr2)
     1642        generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
     1643    else
    16941644        generator.emitJump(topOfLoop.get());
    16951645
Note: See TracChangeset for help on using the changeset viewer.