Lines Matching refs:bytecode
5 #include "src/regexp/regexp-bytecode-peephole.h"
52 // Trie-Node for storing bytecode sequences we want to optimize.
55 // Dummy bytecode used when we need to store/return a bytecode but it's not a
56 // valid bytecode in the current context.
59 BytecodeSequenceNode(int bytecode, Zone* zone);
61 BytecodeSequenceNode& FollowedBy(int bytecode);
62 // Marks the end of a sequence and sets optimized bytecode to replace all
64 BytecodeSequenceNode& ReplaceWith(int bytecode);
65 // Maps arguments of bytecodes in the sequence to the optimized bytecode.
67 // bytecode.
70 // bytecode_index_in_sequence: Zero-based index of the referred bytecode
71 // within the sequence (e.g. the bytecode passed to CreateSequence() has
73 // argument_offset: Zero-based offset to the argument within the bytecode
74 // (e.g. the first argument that's not packed with the bytecode has offset 4).
76 // new_argument_byte_length: Length of the argument in the new bytecode
83 // argument of the current bytecode at the specified offset matches the offset
85 // argument_offset: Zero-based offset to the argument within the bytecode
86 // (e.g. the first argument that's not packed with the bytecode has offset 4).
90 // check_byte_offset 0 matches the address of the first bytecode in the
96 // argument of the current bytecode at the specified offset matches the
97 // argument of another bytecode in the sequence.
106 // bytecode_index_in_sequence: Zero-based index of the referred bytecode
107 // within the sequence (e.g. the bytecode passed to CreateSequence() has
109 // argument_offset: Zero-based offset to the argument within the bytecode
110 // (e.g. the first argument that's not packed with the bytecode has offset 4).
117 // node for the actual bytecode sequence.
118 bool CheckArguments(const byte* bytecode, int pc);
120 // replaced with an optimized bytecode).
124 // Returns the optimized bytecode for the node or kDummyBytecode if it is not
127 // Returns the child of the current node matching the given bytecode or
129 BytecodeSequenceNode* Find(int bytecode) const;
176 // Parses bytecode and fills the internal buffer with the potentially
177 // optimized bytecode. Returns true when optimizations were performed, false
179 bool OptimizeBytecode(const byte* bytecode, int length);
180 // Copies the internal bytecode buffer to another buffer. The caller is
188 // Starts a new bytecode sequence.
189 BytecodeSequenceNode& CreateSequence(int bytecode);
190 // Checks for optimization candidates at pc and emits optimized bytecode to
192 int TryOptimizeSequence(const byte* bytecode, int bytecode_length,
194 // Emits optimized bytecode to the internal buffer. start_pc points to the
195 // start of the sequence in bytecode and last_node is the last
197 void EmitOptimization(int start_pc, const byte* bytecode,
200 // Jump source fixups are used to find offsets in the new bytecode that
204 // Jump destination fixups are used to find offsets in the new bytecode that
211 // Updates all jump targets in the new bytecode.
222 void EmitArgument(int start_pc, const byte* bytecode,
229 // Jumps used in old bytecode.
230 // Key: Jump source (offset where destination is stored in old bytecode)
233 // Jumps used in new bytecode.
234 // Key: Jump source (offset where destination is stored in new bytecode)
237 // Number of times a jump destination is used within the bytecode.
238 // Key: Jump destination (offset in old bytecode).
241 // Maps offsets in old bytecode to fixups of sources (delta to new bytecode).
242 // Key: Offset in old bytecode from where the fixup is valid.
243 // Value: Delta to map jump source from old bytecode to new bytecode in bytes.
245 // Maps offsets in old bytecode to fixups of destinations (delta to new
246 // bytecode).
247 // Key: Offset in old bytecode from where the fixup is valid.
248 // Value: Delta to map jump destinations from old bytecode to new bytecode in
263 int32_t GetArgumentValue(const byte* bytecode, int offset, int length) {
266 return GetValue<byte>(bytecode, offset);
268 return GetValue<int16_t>(bytecode, offset);
270 return GetValue<int32_t>(bytecode, offset);
276 BytecodeSequenceNode::BytecodeSequenceNode(int bytecode, Zone* zone)
277 : bytecode_(bytecode),
288 BytecodeSequenceNode& BytecodeSequenceNode::FollowedBy(int bytecode) {
289 DCHECK(0 <= bytecode && bytecode < kRegExpBytecodeCount);
291 if (children_.find(bytecode) == children_.end()) {
293 zone()->New<BytecodeSequenceNode>(bytecode, zone());
300 children_[bytecode] = new_node;
303 return *children_[bytecode];
306 BytecodeSequenceNode& BytecodeSequenceNode::ReplaceWith(int bytecode) {
307 DCHECK(0 <= bytecode && bytecode < kRegExpBytecodeCount);
309 bytecode_replacement_ = bytecode;
389 bool BytecodeSequenceNode::CheckArguments(const byte* bytecode, int pc) {
394 GetArgumentValue(bytecode, pc + check_iter->offset, check_iter->length);
399 bytecode, pc + check_iter->check_offset, check_iter->check_length);
420 BytecodeSequenceNode* BytecodeSequenceNode::Find(int bytecode) const {
421 auto found = children_.find(bytecode);
487 // Sentinel fixups at beginning of bytecode (position -1) so we don't have to
490 // sources/destinations (in the old bytecode) to find them in the new
491 // bytecode. All jump targets are fixed after the new bytecode is fully
494 // Sentinel fixups at end of (old) bytecode so we don't have to check for
501 // Commonly used sequences can be found by creating regexp bytecode traces
507 // first bytecode in this sequence.
522 // first bytecode in this sequence.
538 // first bytecode in this sequence.
559 // first bytecode in this sequence.
577 // first bytecode in this sequence.
592 // bytecode AFTER the whole sequence.
596 // the ADVANCE_CP_AND_GOTO bytecode at the end of the sequence.
600 // jump target of CHECK_GT (i.e. both jump to the first bytecode AFTER the
605 // first bytecode in this sequence.
619 bool RegExpBytecodePeephole::OptimizeBytecode(const byte* bytecode,
625 int replaced_len = TryOptimizeSequence(bytecode, length, old_pc);
630 int bc = bytecode[old_pc];
632 CopyRangeToOutput(bytecode, old_pc, bc_len);
650 BytecodeSequenceNode& RegExpBytecodePeephole::CreateSequence(int bytecode) {
652 DCHECK(0 <= bytecode && bytecode < kRegExpBytecodeCount);
654 return sequences_->FollowedBy(bytecode);
657 int RegExpBytecodePeephole::TryOptimizeSequence(const byte* bytecode,
668 seq_node = seq_node->Find(bytecode[current_pc]);
670 if (!seq_node->CheckArguments(bytecode, start_pc)) break;
673 current_pc += RegExpBytecodeLength(bytecode[current_pc]);
677 EmitOptimization(start_pc, bytecode, *valid_seq_end);
685 int start_pc, const byte* bytecode, const BytecodeSequenceNode& last_node) {
719 EmitArgument(start_pc, bytecode, arg_map);
792 CopyRangeToOutput(bytecode, preserve_from, preserve_length);
868 // offset in the new bytecode.
935 void RegExpBytecodePeephole::EmitArgument(int start_pc, const byte* bytecode,
941 EmitValue(GetValue<byte>(bytecode, arg_pos));
945 EmitValue(GetValue<uint16_t>(bytecode, arg_pos));
949 // the current bytecode, and the remaining 3 bytes are the packed value.
951 // We load 4 bytes from position - 1 and shift out the bytecode.
956 int32_t val = GetValue<int32_t>(bytecode, arg_pos - 1) >> kBitsPerByte;
987 EmitValue(GetValue<uint32_t>(bytecode, arg_pos));
991 EmitValue(GetValue<uint64_t>(bytecode, arg_pos));
994 CopyRangeToOutput(bytecode, arg_pos,
1014 Isolate* isolate, Zone* zone, Handle<String> source, const byte* bytecode,
1017 bool did_optimize = peephole.OptimizeBytecode(bytecode, length);
1023 RegExpBytecodeDisassemble(bytecode, length, source->ToCString().get());