]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecode/PreciseJumpTargets.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / PreciseJumpTargets.cpp
index 0cdf51a984b70f98b6f772a68ee5e22da54154e0..6bba492124dc4341b8d4d39562fff77dc7d1cd24 100644 (file)
 #include "config.h"
 #include "PreciseJumpTargets.h"
 
+#include "JSCInlines.h"
+
 namespace JSC {
 
-static void addSimpleSwitchTargets(SimpleJumpTable& jumpTable, unsigned bytecodeOffset, Vector<unsigned, 32>& out)
+template <size_t vectorSize>
+static void getJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, Interpreter* interpreter, Instruction* instructionsBegin, unsigned bytecodeOffset, Vector<unsigned, vectorSize>& out)
 {
-    for (unsigned i = jumpTable.branchOffsets.size(); i--;)
-        out.append(bytecodeOffset + jumpTable.branchOffsets[i]);
+    OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
+    Instruction* current = instructionsBegin + bytecodeOffset;
+    switch (opcodeID) {
+    case op_jmp:
+        out.append(bytecodeOffset + current[1].u.operand);
+        break;
+    case op_jtrue:
+    case op_jfalse:
+    case op_jeq_null:
+    case op_jneq_null:
+        out.append(bytecodeOffset + current[2].u.operand);
+        break;
+    case op_jneq_ptr:
+    case op_jless:
+    case op_jlesseq:
+    case op_jgreater:
+    case op_jgreatereq:
+    case op_jnless:
+    case op_jnlesseq:
+    case op_jngreater:
+    case op_jngreatereq:
+        out.append(bytecodeOffset + current[3].u.operand);
+        break;
+    case op_switch_imm:
+    case op_switch_char: {
+        SimpleJumpTable& table = codeBlock->switchJumpTable(current[1].u.operand);
+        for (unsigned i = table.branchOffsets.size(); i--;)
+            out.append(bytecodeOffset + table.branchOffsets[i]);
+        out.append(bytecodeOffset + current[2].u.operand);
+        break;
+    }
+    case op_switch_string: {
+        StringJumpTable& table = codeBlock->stringSwitchJumpTable(current[1].u.operand);
+        StringJumpTable::StringOffsetTable::iterator iter = table.offsetTable.begin();
+        StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
+        for (; iter != end; ++iter)
+            out.append(bytecodeOffset + iter->value.branchOffset);
+        out.append(bytecodeOffset + current[2].u.operand);
+        break;
+    }
+    case op_check_has_instance:
+        out.append(bytecodeOffset + current[4].u.operand);
+        break;
+    case op_loop_hint:
+        out.append(bytecodeOffset);
+        break;
+    default:
+        break;
+    }
 }
 
 void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
@@ -51,60 +101,7 @@ void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
     unsigned instructionCount = codeBlock->instructions().size();
     for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount;) {
         OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
-        Instruction* current = instructionsBegin + bytecodeOffset;
-        switch (opcodeID) {
-        case op_jmp:
-            out.append(bytecodeOffset + current[1].u.operand);
-            break;
-        case op_jtrue:
-        case op_jfalse:
-        case op_jeq_null:
-        case op_jneq_null:
-            out.append(bytecodeOffset + current[2].u.operand);
-            break;
-        case op_jneq_ptr:
-        case op_jless:
-        case op_jlesseq:
-        case op_jgreater:
-        case op_jgreatereq:
-        case op_jnless:
-        case op_jnlesseq:
-        case op_jngreater:
-        case op_jngreatereq:
-            out.append(bytecodeOffset + current[3].u.operand);
-            break;
-        case op_switch_imm:
-            addSimpleSwitchTargets(codeBlock->immediateSwitchJumpTable(current[1].u.operand), bytecodeOffset, out);
-            out.append(bytecodeOffset + current[2].u.operand);
-            break;
-        case op_switch_char:
-            addSimpleSwitchTargets(codeBlock->characterSwitchJumpTable(current[1].u.operand), bytecodeOffset, out);
-            out.append(bytecodeOffset + current[2].u.operand);
-            break;
-        case op_switch_string: {
-            StringJumpTable& table = codeBlock->stringSwitchJumpTable(current[1].u.operand);
-            StringJumpTable::StringOffsetTable::iterator iter = table.offsetTable.begin();
-            StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
-            for (; iter != end; ++iter)
-                out.append(bytecodeOffset + iter->value.branchOffset);
-            out.append(bytecodeOffset + current[2].u.operand);
-            break;
-        }
-        case op_get_pnames:
-            out.append(bytecodeOffset + current[5].u.operand);
-            break;
-        case op_next_pname:
-            out.append(bytecodeOffset + current[6].u.operand);
-            break;
-        case op_check_has_instance:
-            out.append(bytecodeOffset + current[4].u.operand);
-            break;
-        case op_loop_hint:
-            out.append(bytecodeOffset);
-            break;
-        default:
-            break;
-        }
+        getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out);
         bytecodeOffset += opcodeLengths[opcodeID];
     }
     
@@ -124,5 +121,12 @@ void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
     out.resize(toIndex);
 }
 
+void findJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, Vector<unsigned, 1>& out)
+{
+    Interpreter* interpreter = codeBlock->vm()->interpreter;
+    Instruction* instructionsBegin = codeBlock->instructions().begin();
+    getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out);
+}
+
 } // namespace JSC