summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp')
-rw-r--r--Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp125
1 files changed, 65 insertions, 60 deletions
diff --git a/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
index b789da104..e2cb00048 100644
--- a/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
+++ b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
@@ -24,15 +24,62 @@
*/
#include "config.h"
-#include "JSCellInlines.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:
+ case op_save: // The jump of op_save is purely for calculating liveness.
+ 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_loop_hint:
+ out.append(bytecodeOffset);
+ break;
+ default:
+ break;
+ }
}
void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
@@ -44,68 +91,18 @@ void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
if (!codeBlock->numberOfJumpTargets())
return;
- for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;)
+ for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;) {
out.append(codeBlock->exceptionHandler(i).target);
-
+ out.append(codeBlock->exceptionHandler(i).start);
+ out.append(codeBlock->exceptionHandler(i).end);
+ }
+
Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
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];
}
@@ -123,6 +120,14 @@ void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
lastValue = value;
}
out.resize(toIndex);
+ out.shrinkToFit();
+}
+
+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