2008-06-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
authorcwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 30 Jun 2008 06:17:01 +0000 (06:17 +0000)
committercwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 30 Jun 2008 06:17:01 +0000 (06:17 +0000)
        Reviewed by Oliver.

        Bug 19821: Merge the instruction pair (less, jfalse)
        <https://bugs.webkit.org/show_bug.cgi?id=19821>

        This is a 2.4% win on SunSpider. I needed to add an ALWAYS_INLINE
        intrinisc to CodeGenerator::rewindBinaryOp() to avoid a massive
        regression in regexp-dna.

        * VM/CodeBlock.cpp:
        (KJS::CodeBlock::dump):
        * VM/CodeGenerator.cpp:
        (KJS::CodeGenerator::rewindBinaryOp):
        (KJS::CodeGenerator::emitJumpIfFalse):
        * VM/Machine.cpp:
        (KJS::Machine::privateExecute):
        * VM/Opcode.cpp:
        (KJS::):
        * VM/Opcode.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@34883 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/VM/CodeBlock.cpp
JavaScriptCore/VM/CodeGenerator.cpp
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/VM/Opcode.cpp
JavaScriptCore/VM/Opcode.h

index 0990b13..a486dda 100644 (file)
@@ -1,3 +1,25 @@
+2008-06-29  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
+
+        Reviewed by Oliver.
+
+        Bug 19821: Merge the instruction pair (less, jfalse)
+        <https://bugs.webkit.org/show_bug.cgi?id=19821>
+        
+        This is a 2.4% win on SunSpider. I needed to add an ALWAYS_INLINE
+        intrinisc to CodeGenerator::rewindBinaryOp() to avoid a massive
+        regression in regexp-dna.
+
+        * VM/CodeBlock.cpp:
+        (KJS::CodeBlock::dump):
+        * VM/CodeGenerator.cpp:
+        (KJS::CodeGenerator::rewindBinaryOp):
+        (KJS::CodeGenerator::emitJumpIfFalse):
+        * VM/Machine.cpp:
+        (KJS::Machine::privateExecute):
+        * VM/Opcode.cpp:
+        (KJS::):
+        * VM/Opcode.h:
+
 2008-06-29  Sam Weinig  <sam@webkit.org>
 
         Fix non-AllInOne builds.
index ff6903a..76894eb 100644 (file)
@@ -488,6 +488,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, jumpTarget(begin, it, offset));
             break;
         }
+        case op_jnless: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, jumpTarget(begin, it, offset));
+            break;
+        }
         case op_loop_if_less: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
index 804780b..9170821 100644 (file)
@@ -429,7 +429,7 @@ void CodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src
     src2Index = instructions().at(size - 1).u.operand;
 }
 
-void CodeGenerator::rewindBinaryOp()
+void ALWAYS_INLINE CodeGenerator::rewindBinaryOp()
 {
     ASSERT(instructions().size() >= 4);
     instructions().shrink(instructions().size() - 4);
@@ -470,6 +470,24 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfTrue(RegisterID* cond, LabelID* tar
 PassRefPtr<LabelID> CodeGenerator::emitJumpIfFalse(RegisterID* cond, LabelID* target)
 {
     ASSERT(target->isForwardLabel());
+    
+    if (m_lastOpcodeID == op_less) {
+        int dstIndex;
+        int src1Index;
+        int src2Index;
+        
+        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
+        
+        if (cond->index() == dstIndex && !cond->refCount()) {
+            rewindBinaryOp();
+            emitOpcode(op_jnless);
+            instructions().append(src1Index);
+            instructions().append(src2Index);
+            instructions().append(target->offsetFrom(instructions().size()));
+            return target;
+        }
+    }
+    
     emitOpcode(op_jfalse);
     instructions().append(cond->index());
     instructions().append(target->offsetFrom(instructions().size()));
index 2f89aa2..45c592b 100644 (file)
@@ -2086,6 +2086,29 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         ++vPC;
         NEXT_OPCODE;
     }
+    BEGIN_OPCODE(op_jnless) {
+        /* jnless src1(r) src2(r) target(offset)
+
+           Checks whether register src1 is less than register src2, as
+           with the ECMAScript '<' operator, and then jumps to offset
+           target from the current instruction, if and only if the 
+           result of the comparison is false.
+        */
+        JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
+        JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
+        int target = (++vPC)->u.operand;
+
+        bool result = jsLess(exec, src1, src2);
+        VM_CHECK_EXCEPTION();
+        
+        if (!result) {
+            vPC += target;
+            NEXT_OPCODE;
+        }
+
+        ++vPC;
+        NEXT_OPCODE;
+    }
     BEGIN_OPCODE(op_new_func) {
         /* new_func dst(r) func(f)
 
index a97ef8a..3d7b252 100644 (file)
@@ -104,6 +104,7 @@ static const char* opcodeNames[] = {
     "jtrue       ",
     "jfalse      ",
     "jless       ",
+    "jnless      ",
     "jmp_scopes  ",
     "loop        ",
     "loop_if_true",
index 688cf0f..d7850e5 100644 (file)
@@ -96,6 +96,7 @@ namespace KJS {
         macro(op_jtrue) \
         macro(op_jfalse) \
         macro(op_jless) \
+        macro(op_jnless) \
         macro(op_jmp_scopes) \
         macro(op_loop) \
         macro(op_loop_if_true) \