Changeset 37417 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Oct 8, 2008, 3:53:13 AM (17 years ago)
Author:
[email protected]
Message:

2008-10-08 Maciej Stachowiak <[email protected]>

Reviewed by Oliver Hunt.

Re-landing the following fix with the crashing bug in it fixed (r37405):


  • optimize away multiplication by constant 1.0


2.3% speedup on v8 RayTrace benchmark

Apparently it's not uncommon for JavaScript code to multiply by
constant 1.0 in the mistaken belief that this converts integer to
floating point and that there is any operational difference.

  • VM/CTI.cpp: (JSC::CTI::privateCompileMainPass): Optimize to_jsnumber for case where parameter is already number. (JSC::CTI::privateCompileSlowCases): ditto
  • VM/Machine.cpp: (JSC::Machine::privateExecute): ditto
  • kjs/grammar.y: (makeMultNode): Transform as follows: +FOO * BAR ==> FOO * BAR FOO * +BAR ==> FOO * BAR FOO * 1 ==> +FOO 1 * FOO ==> +FOO (makeDivNode): Transform as follows: +FOO / BAR ==> FOO / BAR FOO / +BAR ==> FOO / BAR (makeSubNode): Transform as follows: +FOO - BAR ==> FOO - BAR FOO - +BAR ==> FOO - BAR
  • kjs/nodes.h: (JSC::ExpressionNode::stripUnaryPlus): Helper for above grammar.y changes (JSC::UnaryPlusNode::stripUnaryPlus): ditto
Location:
trunk/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r37415 r37417  
     12008-10-08  Maciej Stachowiak  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Re-landing the following fix with the crashing bug in it fixed (r37405):
     6       
     7        - optimize away multiplication by constant 1.0
     8       
     9        2.3% speedup on v8 RayTrace benchmark
     10
     11        Apparently it's not uncommon for JavaScript code to multiply by
     12        constant 1.0 in the mistaken belief that this converts integer to
     13        floating point and that there is any operational difference.
     14
     15        * VM/CTI.cpp:
     16        (JSC::CTI::privateCompileMainPass): Optimize to_jsnumber for
     17        case where parameter is already number.
     18        (JSC::CTI::privateCompileSlowCases): ditto
     19        * VM/Machine.cpp:
     20        (JSC::Machine::privateExecute): ditto
     21        * kjs/grammar.y:
     22        (makeMultNode): Transform as follows:
     23        +FOO * BAR ==> FOO * BAR
     24        FOO * +BAR ==> FOO * BAR
     25        FOO * 1 ==> +FOO
     26        1 * FOO ==> +FOO
     27        (makeDivNode): Transform as follows:
     28        +FOO / BAR ==> FOO / BAR
     29        FOO / +BAR ==> FOO / BAR
     30        (makeSubNode): Transform as follows:
     31        +FOO - BAR ==> FOO - BAR
     32        FOO - +BAR ==> FOO - BAR
     33        * kjs/nodes.h:
     34        (JSC::ExpressionNode::stripUnaryPlus): Helper for above
     35        grammar.y changes
     36        (JSC::UnaryPlusNode::stripUnaryPlus): ditto
     37
    1382008-10-08  Maciej Stachowiak  <[email protected]>
    239
  • trunk/JavaScriptCore/VM/CTI.cpp

    r37408 r37417  
    17681768        }
    17691769        case op_to_jsnumber: {
    1770             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
    1771             emitCall(i, Machine::cti_op_to_jsnumber);
     1770            emitGetArg(instruction[i + 2].u.operand, X86::eax);
     1771           
     1772            m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
     1773            X86Assembler::JmpSrc wasImmediate = m_jit.emitUnlinkedJnz();
     1774
     1775            emitJumpSlowCaseIfNotJSCell(X86::eax, i);
     1776
     1777            m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
     1778            m_jit.cmpl_i32m(NumberType, OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::ecx);
     1779           
     1780            m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
     1781           
     1782            m_jit.link(wasImmediate, m_jit.label());
     1783
    17721784            emitPutResult(instruction[i + 1].u.operand);
    17731785            i += 3;
     
    25192531            break;
    25202532        }
     2533        case op_to_jsnumber: {
     2534            m_jit.link(iter->from, m_jit.label());
     2535            m_jit.link(iter->from, m_jit.label());
     2536
     2537            emitPutArg(X86::eax, 0);
     2538            emitCall(i, Machine::cti_op_to_jsnumber);
     2539
     2540            emitPutResult(instruction[i + 1].u.operand);
     2541            i += 3;
     2542            break;
     2543        }
    25212544
    25222545        default:
  • trunk/JavaScriptCore/VM/Machine.cpp

    r37408 r37417  
    18161816        int dst = (++vPC)->u.operand;
    18171817        int src = (++vPC)->u.operand;
    1818         JSValue* result = r[src].jsValue(exec)->toJSNumber(exec);
    1819         VM_CHECK_EXCEPTION();
    1820 
    1821         r[dst] = result;
     1818
     1819        JSValue* srcVal = r[src].jsValue(exec);
     1820
     1821        if (LIKELY(JSImmediate::isNumber(srcVal) || static_cast<JSCell*>(srcVal)->structureID()->typeInfo().type() == NumberType)) {
     1822            r[dst] = r[src];
     1823        } else {
     1824            JSValue* result = srcVal->toJSNumber(exec);
     1825            VM_CHECK_EXCEPTION();
     1826            r[dst] = result;
     1827        }
    18221828
    18231829        ++vPC;
  • trunk/JavaScriptCore/kjs/grammar.y

    r37408 r37417  
    14251425static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    14261426{
     1427    expr1 = expr1->stripUnaryPlus();
     1428    expr2 = expr2->stripUnaryPlus();
     1429
    14271430    if (expr1->isNumber() && expr2->isNumber())
    14281431        return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
     1432
     1433    if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
     1434        return new UnaryPlusNode(GLOBAL_DATA, expr2);
     1435
     1436    if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
     1437        return new UnaryPlusNode(GLOBAL_DATA, expr1);
     1438
    14291439    return new MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
    14301440}
     
    14321442static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    14331443{
     1444    expr1 = expr1->stripUnaryPlus();
     1445    expr2 = expr2->stripUnaryPlus();
     1446
    14341447    if (expr1->isNumber() && expr2->isNumber())
    14351448        return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
     
    14461459static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    14471460{
     1461    expr1 = expr1->stripUnaryPlus();
     1462    expr2 = expr2->stripUnaryPlus();
     1463
    14481464    if (expr1->isNumber() && expr2->isNumber())
    14491465        return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
  • trunk/JavaScriptCore/kjs/nodes.h

    r37408 r37417  
    227227        virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
    228228
     229        virtual ExpressionNode* stripUnaryPlus() { return this; }
     230
    229231        ResultType resultDescriptor() const JSC_FAST_CALL { return m_resultDesc; }
    230232
     
    11791181        {
    11801182        }
     1183
     1184        virtual ExpressionNode* stripUnaryPlus() { return m_expr.get(); }
    11811185
    11821186        virtual OpcodeID opcode() const JSC_FAST_CALL { return op_to_jsnumber; }
Note: See TracChangeset for help on using the changeset viewer.