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

5 6
#ifndef V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_H_
#define V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_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 int64_t CheckStackGuardState(Address* return_address, Address raw_code,
91
                                      Address re_frame);
92 93 94 95 96 97 98 99 100 101 102

  void print_regexp_frame_constants();

 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).

103
  // TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp.
104

105
  static const int kReturnAddress = kStoredRegisters + 9 * kSystemPointerSize;
106
  // Stack frame header.
107
  static const int kStackFrameHeader = kReturnAddress;
108 109 110

  // Below the frame pointer.
  // Register parameters stored by setup code.
111 112 113 114 115 116 117 118
  static const int kIsolate = kFramePointer - kSystemPointerSize;
  static const int kDirectCall = kIsolate - kSystemPointerSize;
  static const int kNumOutputRegisters = kDirectCall - kSystemPointerSize;
  static const int kRegisterOutput = kNumOutputRegisters - kSystemPointerSize;
  static const int kInputEnd = kRegisterOutput - kSystemPointerSize;
  static const int kInputStart = kInputEnd - kSystemPointerSize;
  static const int kStartIndex = kInputStart - kSystemPointerSize;
  static const int kInputString = kStartIndex - kSystemPointerSize;
119 120
  // When adding local variables remember to push space for them in
  // the frame in GetCode.
121 122 123
  static const int kSuccessfulCaptures = kInputString - kSystemPointerSize;
  static const int kStringStartMinusOne =
      kSuccessfulCaptures - kSystemPointerSize;
124
  static const int kBacktrackCount = kStringStartMinusOne - kSystemPointerSize;
125 126 127 128 129 130
  // 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;

131
  // First register address. Following registers are below it on the stack.
132
  static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
133 134

  // Initial size of code buffer.
135
  static const int kRegExpCodeSize = 1024;
136

137 138 139
  void PushCallerSavedRegisters();
  void PopCallerSavedRegisters();

140 141 142 143 144 145 146 147 148
  // 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);
149
  void CallIsCharacterInRangeArray(const ZoneList<CharacterRange>* ranges);
150 151 152 153 154 155

  // 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.
156
  static constexpr Register current_input_offset() { return s2; }
157 158

  // The register containing the current character after LoadCurrentCharacter.
159
  static constexpr Register current_character() { return s5; }
160 161

  // Register holding address of the end of the input string.
162
  static constexpr Register end_of_input_address() { return s6; }
163 164 165

  // Register holding the frame address. Local variables, parameters and
  // regexp registers are addressed relative to this.
166
  static constexpr Register frame_pointer() { return fp; }
167 168 169

  // The register containing the backtrack stack top. Provides a meaningful
  // name to the register.
170
  static constexpr Register backtrack_stackpointer() { return s7; }
171 172

  // Register holding pointer to the current code object.
173
  static constexpr Register code_pointer() { return s1; }
174 175

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

  // Equivalent to a conditional branch to the label, unless the label
179
  // is nullptr, in which case it is a conditional Backtrack.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
  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);

202 203
  void LoadRegExpStackPointerFromMemory(Register dst);
  void StoreRegExpStackPointerToMemory(Register src, Register scratch);
204 205
  void PushRegExpBasePointer(Register stack_pointer, Register scratch);
  void PopRegExpBasePointer(Register stack_pointer_out, Register scratch);
206

207 208
  Isolate* isolate() const { return masm_->isolate(); }

209 210
  const std::unique_ptr<MacroAssembler> masm_;
  const NoRootArrayScope no_root_array_scope_;
211

212
  // Which mode to generate code for (Latin1 or UC16).
213
  const Mode mode_;
214 215 216 217 218 219

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

  // Number of registers to output at the end (the saved registers
  // are always 0..num_saved_registers_-1).
220
  const int num_saved_registers_;
221 222 223 224 225 226 227 228 229 230

  // 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_;
  Label internal_failure_label_;
231
  Label fallback_label_;
232 233
};

234 235
}  // namespace internal
}  // namespace v8
236

237
#endif  // V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_H_