regexp-macro-assembler-arm.h 9.27 KB
Newer Older
1
// Copyright 2012 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_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_
#define V8_REGEXP_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_
7

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

12 13
namespace v8 {
namespace internal {
14

lrn@chromium.org's avatar
lrn@chromium.org committed
15

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

lrn@chromium.org's avatar
lrn@chromium.org committed
59 60 61 62 63 64
  // Checks whether the given offset from the current position is before
  // the end of the string.
  virtual void CheckPosition(int cp_offset, Label* on_outside_input);
  virtual bool CheckSpecialCharacterClass(uc16 type,
                                          Label* on_no_match);
  virtual void Fail();
65
  virtual Handle<HeapObject> GetCode(Handle<String> source);
lrn@chromium.org's avatar
lrn@chromium.org committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
  virtual void GoTo(Label* label);
  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
  virtual void IfRegisterEqPos(int reg, Label* if_eq);
  virtual IrregexpImplementation Implementation();
  virtual void LoadCurrentCharacter(int cp_offset,
                                    Label* on_end_of_input,
                                    bool check_bounds = true,
                                    int characters = 1);
  virtual void PopCurrentPosition();
  virtual void PopRegister(int register_index);
  virtual void PushBacktrack(Label* label);
  virtual void PushCurrentPosition();
  virtual void PushRegister(int register_index,
                            StackCheckFlag check_stack_limit);
  virtual void ReadCurrentPositionFromRegister(int reg);
  virtual void ReadStackPointerFromRegister(int reg);
83
  virtual void SetCurrentPositionFromEnd(int by);
lrn@chromium.org's avatar
lrn@chromium.org committed
84
  virtual void SetRegister(int register_index, int to);
85
  virtual bool Succeed();
lrn@chromium.org's avatar
lrn@chromium.org committed
86 87 88
  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
  virtual void ClearRegisters(int reg_from, int reg_to);
  virtual void WriteStackPointerToRegister(int reg);
89
  virtual bool CanReadUnaligned();
lrn@chromium.org's avatar
lrn@chromium.org committed
90 91 92 93 94 95 96

  // Called from RegExp if the stack-guard is triggered.
  // If the code object is relocated, the return address is fixed before
  // returning.
  static int CheckStackGuardState(Address* return_address,
                                  Code* re_code,
                                  Address re_frame);
97

lrn@chromium.org's avatar
lrn@chromium.org committed
98 99 100 101 102 103 104 105 106
 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.
  // Register 4..11.
  static const int kStoredRegisters = kFramePointer;
  // Return address (stored from link register, read into pc on return).
  static const int kReturnAddress = kStoredRegisters + 8 * kPointerSize;
107
  static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
lrn@chromium.org's avatar
lrn@chromium.org committed
108
  // Stack parameters placed by caller.
109
  static const int kRegisterOutput = kSecondaryReturnAddress + kPointerSize;
110 111
  static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
  static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
112
  static const int kDirectCall = kStackHighEnd + kPointerSize;
113
  static const int kIsolate = kDirectCall + kPointerSize;
lrn@chromium.org's avatar
lrn@chromium.org committed
114 115 116 117 118 119 120 121 122

  // 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.
123
  static const int kSuccessfulCaptures = kInputString - kPointerSize;
124
  static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize;
lrn@chromium.org's avatar
lrn@chromium.org committed
125
  // First register address. Following registers are below it on the stack.
126
  static const int kRegisterZero = kStringStartMinusOne - kPointerSize;
lrn@chromium.org's avatar
lrn@chromium.org committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

  // Initial size of code buffer.
  static const size_t kRegExpCodeSize = 1024;

  static const int kBacktrackConstantPoolSize = 4;

  // Load a number of characters at the given offset from the
  // current position, into the current-character register.
  void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);

  // 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);

  // 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.
  inline Register current_input_offset() { return r6; }

  // The register containing the current character after LoadCurrentCharacter.
  inline Register current_character() { return r7; }

  // Register holding address of the end of the input string.
  inline Register end_of_input_address() { return r10; }

  // Register holding the frame address. Local variables, parameters and
  // regexp registers are addressed relative to this.
  inline Register frame_pointer() { return fp; }

  // The register containing the backtrack stack top. Provides a meaningful
  // name to the register.
  inline Register backtrack_stackpointer() { return r8; }

  // Register holding pointer to the current code object.
  inline Register code_pointer() { return r5; }

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

  // Equivalent to a conditional branch to the label, unless the label
  // is NULL, in which case it is a conditional Backtrack.
  void BranchOrBacktrack(Condition condition, Label* to);

  // 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 = al);
  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);

192
  Isolate* isolate() const { return masm_->isolate(); }
lrn@chromium.org's avatar
lrn@chromium.org committed
193 194 195

  MacroAssembler* masm_;

196
  // Which mode to generate code for (Latin1 or UC16).
lrn@chromium.org's avatar
lrn@chromium.org committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
  Mode mode_;

  // 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)
  int num_saved_registers_;

  // 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_;
};

216
#endif  // V8_INTERPRETED_REGEXP
lrn@chromium.org's avatar
lrn@chromium.org committed
217 218


219 220
}  // namespace internal
}  // namespace v8
221

222
#endif  // V8_REGEXP_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_