Title: [167646] trunk/Source/_javascript_Core
Revision
167646
Author
[email protected]
Date
2014-04-21 19:58:00 -0700 (Mon, 21 Apr 2014)

Log Message

Switch statements that skip the baseline JIT should work
https://bugs.webkit.org/show_bug.cgi?id=131965

Reviewed by Mark Hahnenberg.

* bytecode/JumpTable.h:
(JSC::SimpleJumpTable::ensureCTITable):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
* tests/stress/inline-llint-with-switch.js: Added.
(foo):
(bar):
(test):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (167645 => 167646)


--- trunk/Source/_javascript_Core/ChangeLog	2014-04-22 02:16:53 UTC (rev 167645)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-04-22 02:58:00 UTC (rev 167646)
@@ -1,3 +1,25 @@
+2014-04-21  Filip Pizlo  <[email protected]>
+
+        Switch statements that skip the baseline JIT should work
+        https://bugs.webkit.org/show_bug.cgi?id=131965
+
+        Reviewed by Mark Hahnenberg.
+
+        * bytecode/JumpTable.h:
+        (JSC::SimpleJumpTable::ensureCTITable):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_switch_imm):
+        (JSC::JIT::emit_op_switch_char):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_switch_imm):
+        (JSC::JIT::emit_op_switch_char):
+        * tests/stress/inline-llint-with-switch.js: Added.
+        (foo):
+        (bar):
+        (test):
+
 2014-04-21  Mark Hahnenberg  <[email protected]>
 
         Arguments objects shouldn't need a destructor

Modified: trunk/Source/_javascript_Core/bytecode/JumpTable.h (167645 => 167646)


--- trunk/Source/_javascript_Core/bytecode/JumpTable.h	2014-04-22 02:16:53 UTC (rev 167645)
+++ trunk/Source/_javascript_Core/bytecode/JumpTable.h	2014-04-22 02:58:00 UTC (rev 167646)
@@ -94,6 +94,12 @@
         }
 
 #if ENABLE(JIT)
+        void ensureCTITable()
+        {
+            ASSERT(ctiOffsets.isEmpty() || ctiOffsets.size() == branchOffsets.size());
+            ctiOffsets.grow(branchOffsets.size());
+        }
+        
         inline CodeLocationLabel ctiForValue(int32_t value)
         {
             if (value >= min && static_cast<uint32_t>(value - min) < ctiOffsets.size())

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (167645 => 167646)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2014-04-22 02:16:53 UTC (rev 167645)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2014-04-22 02:58:00 UTC (rev 167646)
@@ -4947,6 +4947,7 @@
     SwitchData* data, GPRReg value, GPRReg scratch)
 {
     SimpleJumpTable& table = m_jit.codeBlock()->switchJumpTable(data->switchTableIndex);
+    table.ensureCTITable();
     m_jit.sub32(Imm32(table.min), value);
     addBranch(
         m_jit.branch32(JITCompiler::AboveOrEqual, value, Imm32(table.ctiOffsets.size())),

Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (167645 => 167646)


--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp	2014-04-22 02:16:53 UTC (rev 167645)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp	2014-04-22 02:58:00 UTC (rev 167646)
@@ -646,7 +646,7 @@
     // create jump table for switch destinations, track this switch statement.
     SimpleJumpTable* jumpTable = &m_codeBlock->switchJumpTable(tableIndex);
     m_switches.append(SwitchRecord(jumpTable, m_bytecodeOffset, defaultOffset, SwitchRecord::Immediate));
-    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+    jumpTable->ensureCTITable();
 
     emitGetVirtualRegister(scrutinee, regT0);
     callOperation(operationSwitchImmWithUnknownKeyType, regT0, tableIndex);
@@ -662,7 +662,7 @@
     // create jump table for switch destinations, track this switch statement.
     SimpleJumpTable* jumpTable = &m_codeBlock->switchJumpTable(tableIndex);
     m_switches.append(SwitchRecord(jumpTable, m_bytecodeOffset, defaultOffset, SwitchRecord::Character));
-    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+    jumpTable->ensureCTITable();
 
     emitGetVirtualRegister(scrutinee, regT0);
     callOperation(operationSwitchCharWithUnknownKeyType, regT0, tableIndex);

Modified: trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (167645 => 167646)


--- trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp	2014-04-22 02:16:53 UTC (rev 167645)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp	2014-04-22 02:58:00 UTC (rev 167646)
@@ -933,7 +933,7 @@
     // create jump table for switch destinations, track this switch statement.
     SimpleJumpTable* jumpTable = &m_codeBlock->switchJumpTable(tableIndex);
     m_switches.append(SwitchRecord(jumpTable, m_bytecodeOffset, defaultOffset, SwitchRecord::Immediate));
-    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+    jumpTable->ensureCTITable();
 
     emitLoad(scrutinee, regT1, regT0);
     callOperation(operationSwitchImmWithUnknownKeyType, regT1, regT0, tableIndex);
@@ -949,7 +949,7 @@
     // create jump table for switch destinations, track this switch statement.
     SimpleJumpTable* jumpTable = &m_codeBlock->switchJumpTable(tableIndex);
     m_switches.append(SwitchRecord(jumpTable, m_bytecodeOffset, defaultOffset, SwitchRecord::Character));
-    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+    jumpTable->ensureCTITable();
 
     emitLoad(scrutinee, regT1, regT0);
     callOperation(operationSwitchCharWithUnknownKeyType, regT1, regT0, tableIndex);

Added: trunk/Source/_javascript_Core/tests/stress/inline-llint-with-switch.js (0 => 167646)


--- trunk/Source/_javascript_Core/tests/stress/inline-llint-with-switch.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/inline-llint-with-switch.js	2014-04-22 02:58:00 UTC (rev 167646)
@@ -0,0 +1,43 @@
+function foo(i) {
+    switch (i) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+        return 42;
+    default:
+        return "error";
+    }
+}
+
+function bar(p) {
+    if (p)
+        return foo(effectful42() - 42);
+    else
+        return 42;
+}
+
+noInline(bar);
+
+function test(p) {
+    var result = bar(p);
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+// Make sure that the call to foo() looks like it has happened.
+for (var i = 0; i < 2; ++i)
+    test(true);
+
+// Warm up bar and cause inlining, but make sure that foo() doesn't get DFG'd.
+for (var i = 0; i < 10000; ++i)
+    test(false);
+
+// And finally test the switch statement.
+test(true);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to