regexp-macro-assembler-mips.h 10.1 KB
Newer Older
1
// Copyright 2011 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#ifndef V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
#define V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
7

8
#include "src/codegen/macro-assembler.h"
9
#include "src/regexp/regexp-macro-assembler.h"
10

11 12 13
namespace v8 {
namespace internal {

14 15
class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
    : public NativeRegExpMacroAssembler {
16
 public:
17 18
  RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, Mode mode,
                           int registers_to_save);
19 20 21 22 23 24 25 26 27 28 29 30
  ~RegExpMacroAssemblerMIPS() override;
  int stack_limit_slack() override;
  void AdvanceCurrentPosition(int by) override;
  void AdvanceRegister(int reg, int by) override;
  void Backtrack() override;
  void Bind(Label* label) override;
  void CheckAtStart(int cp_offset, Label* on_at_start) override;
  void CheckCharacter(uint32_t c, Label* on_equal) override;
  void CheckCharacterAfterAnd(uint32_t c, uint32_t mask,
                              Label* on_equal) override;
  void CheckCharacterGT(base::uc16 limit, Label* on_greater) override;
  void CheckCharacterLT(base::uc16 limit, Label* on_less) override;
31 32
  // A "greedy loop" is a loop that is both greedy and with a simple
  // body. It has a particularly simple implementation.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
  void CheckGreedyLoop(Label* on_tos_equals_current_position) override;
  void CheckNotAtStart(int cp_offset, Label* on_not_at_start) override;
  void CheckNotBackReference(int start_reg, bool read_backward,
                             Label* on_no_match) override;
  void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
                                       bool unicode,
                                       Label* on_no_match) override;
  void CheckNotCharacter(uint32_t c, Label* on_not_equal) override;
  void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask,
                                 Label* on_not_equal) override;
  void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus,
                                      base::uc16 mask,
                                      Label* on_not_equal) override;
  void CheckCharacterInRange(base::uc16 from, base::uc16 to,
                             Label* on_in_range) override;
  void CheckCharacterNotInRange(base::uc16 from, base::uc16 to,
                                Label* on_not_in_range) override;
50 51 52 53
  bool CheckCharacterInRangeArray(const ZoneList<CharacterRange>* ranges,
                                  Label* on_in_range) override;
  bool CheckCharacterNotInRangeArray(const ZoneList<CharacterRange>* ranges,
                                     Label* on_not_in_range) override;
54
  void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) override;
55

56 57
  // Checks whether the given offset from the current position is before
  // the end of the string.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  void CheckPosition(int cp_offset, Label* on_outside_input) override;
  bool CheckSpecialCharacterClass(StandardCharacterSet type,
                                  Label* on_no_match) override;
  void Fail() override;
  Handle<HeapObject> GetCode(Handle<String> source) override;
  void GoTo(Label* label) override;
  void IfRegisterGE(int reg, int comparand, Label* if_ge) override;
  void IfRegisterLT(int reg, int comparand, Label* if_lt) override;
  void IfRegisterEqPos(int reg, Label* if_eq) override;
  IrregexpImplementation Implementation() override;
  void LoadCurrentCharacterUnchecked(int cp_offset,
                                     int character_count) override;
  void PopCurrentPosition() override;
  void PopRegister(int register_index) override;
  void PushBacktrack(Label* label) override;
  void PushCurrentPosition() override;
  void PushRegister(int register_index,
                    StackCheckFlag check_stack_limit) override;
  void ReadCurrentPositionFromRegister(int reg) override;
  void ReadStackPointerFromRegister(int reg) override;
  void SetCurrentPositionFromEnd(int by) override;
  void SetRegister(int register_index, int to) override;
  bool Succeed() override;
  void WriteCurrentPositionToRegister(int reg, int cp_offset) override;
  void ClearRegisters(int reg_from, int reg_to) override;
  void WriteStackPointerToRegister(int reg) override;
  bool CanReadUnaligned() const override;
85 86 87 88

  // Called from RegExp if the stack-guard is triggered.
  // If the code object is relocated, the return address is fixed before
  // returning.
89 90
  // {raw_code} is an Address because this is called via ExternalReference.
  static int CheckStackGuardState(Address* return_address, Address raw_code,
91
                                  Address re_frame);
92

93 94 95 96 97 98 99 100 101
 private:
  // Offsets from frame_pointer() of function parameters and stored registers.
  static const int kFramePointer = 0;

  // Above the frame pointer - Stored registers and stack passed parameters.
  static const int kStoredRegisters = kFramePointer;
  // Return address (stored from link register, read into pc on return).
  static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
  // Stack frame header.
102
  static const int kStackFrameHeader = kReturnAddress;
103
  // Stack parameters placed by caller.
104
  static const int kRegisterOutput = kStackFrameHeader + 20;
105
  static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
106
  static const int kDirectCall = kNumOutputRegisters + kPointerSize;
107 108 109 110 111 112 113 114 115 116
  static const int kIsolate = kDirectCall + kPointerSize;

  // Below the frame pointer.
  // Register parameters stored by setup code.
  static const int kInputEnd = kFramePointer - kPointerSize;
  static const int kInputStart = kInputEnd - kPointerSize;
  static const int kStartIndex = kInputStart - kPointerSize;
  static const int kInputString = kStartIndex - kPointerSize;
  // When adding local variables remember to push space for them in
  // the frame in GetCode.
117
  static const int kSuccessfulCaptures = kInputString - kPointerSize;
118
  static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize;
119
  static const int kBacktrackCount = kStringStartMinusOne - kSystemPointerSize;
120 121 122 123 124 125
  // Stores the initial value of the regexp stack pointer in a
  // position-independent representation (in case the regexp stack grows and
  // thus moves).
  static const int kRegExpStackBasePointer =
      kBacktrackCount - kSystemPointerSize;

126
  // First register address. Following registers are below it on the stack.
127
  static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
128 129

  // Initial size of code buffer.
130
  static const int kRegExpCodeSize = 1024;
131

132 133 134
  void PushCallerSavedRegisters();
  void PopCallerSavedRegisters();

135 136 137 138 139 140 141 142
  // Check whether preemption has been requested.
  void CheckPreemption();

  // Check whether we are exceeding the stack limit on the backtrack stack.
  void CheckStackLimit();

  // Generate a call to CheckStackGuardState.
  void CallCheckStackGuardState(Register scratch);
143
  void CallIsCharacterInRangeArray(const ZoneList<CharacterRange>* ranges);
144 145 146 147 148 149

  // The ebp-relative location of a regexp register.
  MemOperand register_location(int register_index);

  // Register holding the current input position as negative offset from
  // the end of the string.
150
  static constexpr Register current_input_offset() { return t2; }
151 152

  // The register containing the current character after LoadCurrentCharacter.
153
  static constexpr Register current_character() { return t3; }
154 155

  // Register holding address of the end of the input string.
156
  static constexpr Register end_of_input_address() { return t6; }
157 158 159

  // Register holding the frame address. Local variables, parameters and
  // regexp registers are addressed relative to this.
160
  static constexpr Register frame_pointer() { return fp; }
161 162 163

  // The register containing the backtrack stack top. Provides a meaningful
  // name to the register.
164
  static constexpr Register backtrack_stackpointer() { return t4; }
165 166

  // Register holding pointer to the current code object.
167
  static constexpr Register code_pointer() { return t1; }
168

169
  // Byte size of chars in the string to match (decided by the Mode argument).
170
  inline int char_size() const { return static_cast<int>(mode_); }
171 172

  // Equivalent to a conditional branch to the label, unless the label
173
  // is nullptr, in which case it is a conditional Backtrack.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
  void BranchOrBacktrack(Label* to,
                         Condition condition,
                         Register rs,
                         const Operand& rt);

  // Call and return internally in the generated code in a way that
  // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
  inline void SafeCall(Label* to,
                       Condition cond,
                       Register rs,
                       const Operand& rt);
  inline void SafeReturn();
  inline void SafeCallTarget(Label* name);

  // Pushes the value of a register on the backtrack stack. Decrements the
  // stack pointer by a word size and stores the register's value there.
  inline void Push(Register source);

  // Pops a value from the backtrack stack. Reads the word at the stack pointer
  // and increments it by a word size.
  inline void Pop(Register target);

196 197 198 199 200
  void LoadRegExpStackPointerFromMemory(Register dst);
  void StoreRegExpStackPointerToMemory(Register src, Register scratch);
  void PushRegExpBasePointer(Register scratch1, Register scratch2);
  void PopRegExpBasePointer(Register scratch1, Register scratch2);

201
  Isolate* isolate() const { return masm_->isolate(); }
202

203 204
  const std::unique_ptr<MacroAssembler> masm_;
  const NoRootArrayScope no_root_array_scope_;
205

206
  // Which mode to generate code for (Latin1 or UC16).
207
  const Mode mode_;
208 209 210 211 212

  // One greater than maximal register index actually used.
  int num_registers_;

  // Number of registers to output at the end (the saved registers
213
  // are always 0..num_saved_registers_-1).
214
  const int num_saved_registers_;
215 216 217 218 219 220 221 222 223

  // Labels used internally.
  Label entry_label_;
  Label start_label_;
  Label success_label_;
  Label backtrack_label_;
  Label exit_label_;
  Label check_preempt_label_;
  Label stack_overflow_label_;
224
  Label internal_failure_label_;
225
  Label fallback_label_;
226 227
};

228 229
}  // namespace internal
}  // namespace v8
230

231
#endif  // V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_