diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp')
-rw-r--r-- | Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp | 121 |
1 files changed, 54 insertions, 67 deletions
diff --git a/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp index ede8a3643..9c06e7ec2 100644 --- a/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp +++ b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp @@ -26,85 +26,48 @@ #include "config.h" #include "PreciseJumpTargets.h" +#include "InterpreterInlines.h" +#include "JSCInlines.h" +#include "PreciseJumpTargetsInlines.h" + namespace JSC { -template <size_t vectorSize> -static void getJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, Interpreter* interpreter, Instruction* instructionsBegin, unsigned bytecodeOffset, Vector<unsigned, vectorSize>& out) +template <size_t vectorSize, typename Block, typename Instruction> +static void getJumpTargetsForBytecodeOffset(Block* codeBlock, Interpreter* interpreter, Instruction* instructionsBegin, unsigned bytecodeOffset, Vector<unsigned, vectorSize>& out) { - 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_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: + OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset]); + extractStoredJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, [&](int32_t& relativeOffset) { + out.append(bytecodeOffset + relativeOffset); + }); + // op_loop_hint does not have jump target stored in bytecode instructions. + if (opcodeID == op_loop_hint) out.append(bytecodeOffset); - break; - default: - break; - } } -void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out) +enum class ComputePreciseJumpTargetsMode { + FollowCodeBlockClaim, + ForceCompute, +}; + +template<ComputePreciseJumpTargetsMode Mode, typename Block, typename Instruction, size_t vectorSize> +void computePreciseJumpTargetsInternal(Block* codeBlock, Instruction* instructionsBegin, unsigned instructionCount, Vector<unsigned, vectorSize>& out) { ASSERT(out.isEmpty()); // We will derive a superset of the jump targets that the code block thinks it has. // So, if the code block claims there are none, then we are done. - if (!codeBlock->numberOfJumpTargets()) + if (Mode == ComputePreciseJumpTargetsMode::FollowCodeBlockClaim && !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); + OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset]); getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out); bytecodeOffset += opcodeLengths[opcodeID]; } @@ -123,13 +86,37 @@ 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) +void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out) { - Interpreter* interpreter = codeBlock->vm()->interpreter; - Instruction* instructionsBegin = codeBlock->instructions().begin(); - getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out); + computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::FollowCodeBlockClaim>(codeBlock, codeBlock->instructions().begin(), codeBlock->instructions().size(), out); +} + +void computePreciseJumpTargets(CodeBlock* codeBlock, Instruction* instructionsBegin, unsigned instructionCount, Vector<unsigned, 32>& out) +{ + computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::FollowCodeBlockClaim>(codeBlock, instructionsBegin, instructionCount, out); +} + +void computePreciseJumpTargets(UnlinkedCodeBlock* codeBlock, UnlinkedInstruction* instructionsBegin, unsigned instructionCount, Vector<unsigned, 32>& out) +{ + computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::FollowCodeBlockClaim>(codeBlock, instructionsBegin, instructionCount, out); +} + +void recomputePreciseJumpTargets(UnlinkedCodeBlock* codeBlock, UnlinkedInstruction* instructionsBegin, unsigned instructionCount, Vector<unsigned>& out) +{ + computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::ForceCompute>(codeBlock, instructionsBegin, instructionCount, out); +} + +void findJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, Instruction* instructionsBegin, unsigned bytecodeOffset, Vector<unsigned, 1>& out) +{ + getJumpTargetsForBytecodeOffset(codeBlock, codeBlock->vm()->interpreter, instructionsBegin, bytecodeOffset, out); +} + +void findJumpTargetsForBytecodeOffset(UnlinkedCodeBlock* codeBlock, UnlinkedInstruction* instructionsBegin, unsigned bytecodeOffset, Vector<unsigned, 1>& out) +{ + getJumpTargetsForBytecodeOffset(codeBlock, codeBlock->vm()->interpreter, instructionsBegin, bytecodeOffset, out); } } // namespace JSC |