Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: src/regexp-macro-assembler-ia32.h

Issue 17416: * Move irregexp backtrack stack to external memory area, instead of the system stack. (Closed)
Patch Set: Added explicit stack check requests to push operations. Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 20 matching lines...) Expand all
31 namespace v8 { namespace internal { 31 namespace v8 { namespace internal {
32 32
33 class RegExpMacroAssemblerIA32: public RegExpMacroAssembler { 33 class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
34 public: 34 public:
35 // Type of input string to generate code for. 35 // Type of input string to generate code for.
36 enum Mode { ASCII = 1, UC16 = 2 }; 36 enum Mode { ASCII = 1, UC16 = 2 };
37 enum Result { EXCEPTION = -1, FAILURE = 0, SUCCESS = 1 }; 37 enum Result { EXCEPTION = -1, FAILURE = 0, SUCCESS = 1 };
38 38
39 RegExpMacroAssemblerIA32(Mode mode, int registers_to_save); 39 RegExpMacroAssemblerIA32(Mode mode, int registers_to_save);
40 virtual ~RegExpMacroAssemblerIA32(); 40 virtual ~RegExpMacroAssemblerIA32();
41 virtual int stack_limit();
41 virtual void AdvanceCurrentPosition(int by); 42 virtual void AdvanceCurrentPosition(int by);
42 virtual void AdvanceRegister(int reg, int by); 43 virtual void AdvanceRegister(int reg, int by);
43 virtual void Backtrack(); 44 virtual void Backtrack();
44 virtual void Bind(Label* label); 45 virtual void Bind(Label* label);
45 virtual void CheckBitmap(uc16 start, Label* bitmap, Label* on_zero); 46 virtual void CheckBitmap(uc16 start, Label* bitmap, Label* on_zero);
46 virtual void CheckCharacter(uint32_t c, Label* on_equal); 47 virtual void CheckCharacter(uint32_t c, Label* on_equal);
47 virtual void CheckCharacterAfterAnd(uint32_t c, 48 virtual void CheckCharacterAfterAnd(uint32_t c,
48 uint32_t mask, 49 uint32_t mask,
49 Label* on_equal); 50 Label* on_equal);
50 virtual void CheckCharacterGT(uc16 limit, Label* on_greater); 51 virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
51 virtual void CheckCharacterLT(uc16 limit, Label* on_less); 52 virtual void CheckCharacterLT(uc16 limit, Label* on_less);
52 virtual void CheckCharacters(Vector<const uc16> str, 53 virtual void CheckCharacters(Vector<const uc16> str,
53 int cp_offset, 54 int cp_offset,
54 Label* on_failure, 55 Label* on_failure,
55 bool check_end_of_string); 56 bool check_end_of_string);
57 // A "greedy loop" is a loop that is both greedy and with a simple
58 // body. It has a particularly simple implementation.
56 virtual void CheckGreedyLoop(Label* on_tos_equals_current_position); 59 virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
57 virtual void CheckNotAtStart(Label* on_not_at_start); 60 virtual void CheckNotAtStart(Label* on_not_at_start);
58 virtual void CheckNotBackReference(int start_reg, Label* on_no_match); 61 virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
59 virtual void CheckNotBackReferenceIgnoreCase(int start_reg, 62 virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
60 Label* on_no_match); 63 Label* on_no_match);
61 virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal); 64 virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal);
62 virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal); 65 virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal);
63 virtual void CheckNotCharacterAfterAnd(uint32_t c, 66 virtual void CheckNotCharacterAfterAnd(uint32_t c,
64 uint32_t mask, 67 uint32_t mask,
65 Label* on_not_equal); 68 Label* on_not_equal);
(...skipping 21 matching lines...) Expand all
87 virtual void IfRegisterGE(int reg, int comparand, Label* if_ge); 90 virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
88 virtual void IfRegisterLT(int reg, int comparand, Label* if_lt); 91 virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
89 virtual void IfRegisterEqPos(int reg, Label* if_eq); 92 virtual void IfRegisterEqPos(int reg, Label* if_eq);
90 virtual IrregexpImplementation Implementation(); 93 virtual IrregexpImplementation Implementation();
91 virtual void LoadCurrentCharacter(int cp_offset, 94 virtual void LoadCurrentCharacter(int cp_offset,
92 Label* on_end_of_input, 95 Label* on_end_of_input,
93 bool check_bounds = true, 96 bool check_bounds = true,
94 int characters = 1); 97 int characters = 1);
95 virtual void PopCurrentPosition(); 98 virtual void PopCurrentPosition();
96 virtual void PopRegister(int register_index); 99 virtual void PopRegister(int register_index);
97 virtual void PushBacktrack(Label* label); 100 virtual void PushBacktrack(Label* label, StackCheckFlag check_stack_limit);
98 virtual void PushCurrentPosition(); 101 virtual void PushCurrentPosition(StackCheckFlag check_stack_limit);
99 virtual void PushRegister(int register_index); 102 virtual void PushRegister(int register_index,
103 StackCheckFlag check_stack_limit);
100 virtual void ReadCurrentPositionFromRegister(int reg); 104 virtual void ReadCurrentPositionFromRegister(int reg);
101 virtual void ReadStackPointerFromRegister(int reg); 105 virtual void ReadStackPointerFromRegister(int reg);
102 virtual void SetRegister(int register_index, int to); 106 virtual void SetRegister(int register_index, int to);
103 virtual void Succeed(); 107 virtual void Succeed();
104 virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); 108 virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
105 virtual void WriteStackPointerToRegister(int reg); 109 virtual void WriteStackPointerToRegister(int reg);
106 110
107 template <typename T> 111 static Result Execute(Code* code,
108 static inline Result Execute(Code* code, 112 Address* input,
109 T** input, 113 int start_offset,
110 int start_offset, 114 int end_offset,
111 int end_offset, 115 int* output,
112 int* output, 116 bool at_start);
113 bool at_start) {
114 typedef int (*matcher)(T**, int, int, int*, int);
115 matcher matcher_func = FUNCTION_CAST<matcher>(code->entry());
116 int at_start_val = at_start ? 1 : 0;
117 int result = matcher_func(input,
118 start_offset,
119 end_offset,
120 output,
121 at_start_val);
122 return (result < 0) ? EXCEPTION : (result ? SUCCESS : FAILURE);
123 }
124 117
125 private: 118 private:
126 // Offsets from ebp of arguments to function. 119 // Offsets from ebp of arguments to function and stored registers.
127 static const int kBackup_ebx = sizeof(uint32_t); 120 static const int kBackup_ebx = sizeof(uint32_t);
128 static const int kBackup_edi = kBackup_ebx + sizeof(uint32_t); 121 static const int kBackup_edi = kBackup_ebx + sizeof(uint32_t);
129 static const int kBackup_esi = kBackup_edi + sizeof(uint32_t); 122 static const int kBackup_esi = kBackup_edi + sizeof(uint32_t);
130 static const int kReturn_eip = kBackup_esi + sizeof(uint32_t); 123 static const int kReturn_eip = kBackup_esi + sizeof(uint32_t);
131 static const int kInputBuffer = kReturn_eip + sizeof(uint32_t); 124 static const int kInputBuffer = kReturn_eip + sizeof(uint32_t);
132 static const int kInputStartOffset = kInputBuffer + sizeof(uint32_t); 125 static const int kInputStartOffset = kInputBuffer + sizeof(uint32_t);
133 static const int kInputEndOffset = kInputStartOffset + sizeof(uint32_t); 126 static const int kInputEndOffset = kInputStartOffset + sizeof(uint32_t);
134 static const int kRegisterOutput = kInputEndOffset + sizeof(uint32_t); 127 static const int kRegisterOutput = kInputEndOffset + sizeof(uint32_t);
135 static const int kAtStart = kRegisterOutput + sizeof(uint32_t); 128 static const int kAtStart = kRegisterOutput + sizeof(uint32_t);
129 static const int kStackHighEnd = kAtStart + sizeof(uint32_t);
136 130
137 // Initial size of code buffer. 131 // Initial size of code buffer.
138 static const size_t kRegExpCodeSize = 1024; 132 static const size_t kRegExpCodeSize = 1024;
139 // Initial size of constant buffers allocated during compilation. 133 // Initial size of constant buffers allocated during compilation.
140 static const int kRegExpConstantsSize = 256; 134 static const int kRegExpConstantsSize = 256;
141 // Only unroll loops up to this length. TODO(lrn): Actually use this. 135 // Only unroll loops up to this length.
142 static const int kMaxInlineStringTests = 32; 136 static const int kMaxInlineStringTests = 32;
143 137
144 // Compares two-byte strings case insensitively. 138 // Compares two-byte strings case insensitively.
139 // Called from generated RegExp code.
145 static int CaseInsensitiveCompareUC16(uc16** buffer, 140 static int CaseInsensitiveCompareUC16(uc16** buffer,
146 int byte_offset1, 141 int byte_offset1,
147 int byte_offset2, 142 int byte_offset2,
148 size_t byte_length); 143 size_t byte_length);
149 144
145 // Adds code that loads the character at the given offset from the
146 // current position, into the current-character register.
150 void LoadCurrentCharacterUnchecked(int cp_offset, int characters); 147 void LoadCurrentCharacterUnchecked(int cp_offset, int characters);
151 148
152 // Adds code that checks whether preemption has been requested 149 // Adds code that checks whether preemption has been requested.
153 // (and checks if we have hit the stack limit too). 150 void CheckPreemption();
151
152 // Adds code that checks whether we are exceeding the stack limit
153 // on the backtrack stack.
154 void CheckStackLimit(); 154 void CheckStackLimit();
155 155
156 // Called from RegExp if the stack-guard is triggered. 156 // Called from RegExp if the stack-guard is triggered.
157 // If the code object is relocated, the return address is fixed before 157 // If the code object is relocated, the return address is fixed before
158 // returning. 158 // returning.
159 static int CheckStackGuardState(Address return_address, Code* re_code); 159 static int CheckStackGuardState(Address return_address, Code* re_code);
160 160
161 // Called from RegExp if the backtrack stack limit is hit.
162 // Tries to expand the stack. Returns the new stack-top pointer if
163 // successful, or 0 if unable to grow the stack.
164 // This function must not trigger a garbage collection.
165 static Address GrowStack(Address stack_top);
166
161 // Checks whether the given offset from the current position is before 167 // Checks whether the given offset from the current position is before
162 // the end of the string. 168 // the end of the string.
163 void CheckPosition(int cp_offset, Label* on_outside_input); 169 void CheckPosition(int cp_offset, Label* on_outside_input);
164 170
165 // The ebp-relative location of a regexp register. 171 // The ebp-relative location of a regexp register.
166 Operand register_location(int register_index); 172 Operand register_location(int register_index);
167 173
168 // The register containing the current character after LoadCurrentCharacter. 174 // The register containing the current character after LoadCurrentCharacter.
169 Register current_character(); 175 inline Register current_character() { return edx; }
176
177 // The register containing the backtrack stack top. Provides a meaningful
178 // name to the register.
179 inline Register backtrack_stackpointer() { return ecx; }
170 180
171 // Byte size of chars in the string to match (decided by the Mode argument) 181 // Byte size of chars in the string to match (decided by the Mode argument)
172 size_t char_size(); 182 inline size_t char_size() { return static_cast<size_t>(mode_); }
173 183
174 // Equivalent to a conditional branch to the label, unless the label 184 // Equivalent to a conditional branch to the label, unless the label
175 // is NULL, in which case it is a conditional Backtrack. 185 // is NULL, in which case it is a conditional Backtrack.
176 void BranchOrBacktrack(Condition condition, Label* to); 186 void BranchOrBacktrack(Condition condition, Label* to, Hint hint = no_hint);
177 187
178 // Load the address of a "constant buffer" (a slice of a byte array) 188 // Load the address of a "constant buffer" (a slice of a byte array)
179 // into a register. The address is computed from the ByteArray* address 189 // into a register. The address is computed from the ByteArray* address
180 // and an offset. Uses no extra registers. 190 // and an offset. Uses no extra registers.
181 void LoadConstantBufferAddress(Register reg, ArraySlice* buffer); 191 void LoadConstantBufferAddress(Register reg, ArraySlice* buffer);
182 192
183 // Call and return internally in the generated code in a way that 193 // Call and return internally in the generated code in a way that
184 // is GC-safe (i.e., doesn't leave absolute code addresses on the stack) 194 // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
185 void SafeCall(Label* to); 195 inline void SafeCall(Label* to);
186 void SafeReturn(); 196 inline void SafeReturn();
197
198 // Pushes the value of a register on the backtrack stack. Decrements the
199 // stack pointer (ecx) by a word size and stores the register's value there.
200 inline void Push(Register source);
201
202 // Pushes a value on the backtrack stack. Decrements the stack pointer (ecx)
203 // by a word size and stores the value there.
204 inline void Push(Immediate value);
205
206 // Pops a value from the backtrack stack. Reads the word at the stack pointer
207 // (ecx) and increments it by a word size.
208 inline void Pop(Register target);
187 209
188 // Before calling a C-function from generated code, align arguments on stack. 210 // Before calling a C-function from generated code, align arguments on stack.
189 // After aligning the frame, arguments must be stored in esp[0], esp[4], 211 // After aligning the frame, arguments must be stored in esp[0], esp[4],
190 // etc., not pushed. The argument count assumes all arguments are word sized. 212 // etc., not pushed. The argument count assumes all arguments are word sized.
191 void FrameAlign(int num_arguments); 213 // Some compilers/platforms require the stack to be aligned when calling
214 // C++ code.
215 inline void FrameAlign(int num_arguments);
216
192 // Calls a C function and cleans up the space for arguments allocated 217 // Calls a C function and cleans up the space for arguments allocated
193 // by FrameAlign. The called function is not allowed to trigger a garbage 218 // by FrameAlign. The called function is not allowed to trigger a garbage
194 // collection, since that might move the code and invalidate the return 219 // collection, since that might move the code and invalidate the return
195 // address 220 // address (unless this is somehow accounted for).
196 void CallCFunction(Address function_address, int num_arguments); 221 inline void CallCFunction(Address function_address, int num_arguments);
197 222
198 MacroAssembler* masm_; 223 MacroAssembler* masm_;
224
199 // Constant buffer provider. Allocates external storage for storing 225 // Constant buffer provider. Allocates external storage for storing
200 // constants. 226 // constants.
201 ByteArrayProvider constants_; 227 ByteArrayProvider constants_;
228
202 // Which mode to generate code for (ASCII or UTF16). 229 // Which mode to generate code for (ASCII or UTF16).
203 Mode mode_; 230 Mode mode_;
231
204 // One greater than maximal register index actually used. 232 // One greater than maximal register index actually used.
205 int num_registers_; 233 int num_registers_;
234
206 // Number of registers to output at the end (the saved registers 235 // Number of registers to output at the end (the saved registers
207 // are always 0..num_saved_registers_-1) 236 // are always 0..num_saved_registers_-1)
208 int num_saved_registers_; 237 int num_saved_registers_;
238
209 // Labels used internally. 239 // Labels used internally.
210 Label entry_label_; 240 Label entry_label_;
211 Label start_label_; 241 Label start_label_;
212 Label success_label_; 242 Label success_label_;
213 Label backtrack_label_; 243 Label backtrack_label_;
214 Label exit_label_; 244 Label exit_label_;
215 Label check_preempt_label_; 245 Label check_preempt_label_;
246 Label stack_overflow_label_;
247
216 // Handle used to represent the generated code object itself. 248 // Handle used to represent the generated code object itself.
217 Handle<Object> self_; 249 Handle<Object> self_;
218 }; 250 };
219 251
220 }} // namespace v8::internal 252 }} // namespace v8::internal
221 253
222 #endif /* REGEXP_MACRO_ASSEMBLER_IA32_H_ */ 254 #endif /* REGEXP_MACRO_ASSEMBLER_IA32_H_ */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698