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

Side by Side Diff: src/regexp/arm/regexp-macro-assembler-arm.cc

Issue 1451373003: Revert of Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/regexp/arm/regexp-macro-assembler-arm.h" 7 #include "src/regexp/arm/regexp-macro-assembler-arm.h"
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/log.h" 10 #include "src/log.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 * - fp[32] return address (lr). 51 * - fp[32] return address (lr).
52 * - fp[28] old frame pointer (r11). 52 * - fp[28] old frame pointer (r11).
53 * - fp[0..24] backup of registers r4..r10. 53 * - fp[0..24] backup of registers r4..r10.
54 * --- frame pointer ---- 54 * --- frame pointer ----
55 * - fp[-4] end of input (address of end of string). 55 * - fp[-4] end of input (address of end of string).
56 * - fp[-8] start of input (address of first character in string). 56 * - fp[-8] start of input (address of first character in string).
57 * - fp[-12] start index (character index of start). 57 * - fp[-12] start index (character index of start).
58 * - fp[-16] void* input_string (location of a handle containing the string). 58 * - fp[-16] void* input_string (location of a handle containing the string).
59 * - fp[-20] success counter (only for global regexps to count matches). 59 * - fp[-20] success counter (only for global regexps to count matches).
60 * - fp[-24] Offset of location before start of input (effectively character 60 * - fp[-24] Offset of location before start of input (effectively character
61 * string start - 1). Used to initialize capture registers to a 61 * position -1). Used to initialize capture registers to a
62 * non-position. 62 * non-position.
63 * - fp[-28] At start (if 1, we are starting at the start of the 63 * - fp[-28] At start (if 1, we are starting at the start of the
64 * string, otherwise 0) 64 * string, otherwise 0)
65 * - fp[-32] register 0 (Only positions must be stored in the first 65 * - fp[-32] register 0 (Only positions must be stored in the first
66 * - register 1 num_saved_registers_ registers) 66 * - register 1 num_saved_registers_ registers)
67 * - ... 67 * - ...
68 * - register num_registers-1 68 * - register num_registers-1
69 * --- sp --- 69 * --- sp ---
70 * 70 *
71 * The first num_saved_registers_ registers are initialized to point to 71 * The first num_saved_registers_ registers are initialized to point to
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 169 }
170 170
171 171
172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { 172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) {
173 __ cmp(current_character(), Operand(limit)); 173 __ cmp(current_character(), Operand(limit));
174 BranchOrBacktrack(gt, on_greater); 174 BranchOrBacktrack(gt, on_greater);
175 } 175 }
176 176
177 177
178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { 178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
179 __ ldr(r1, MemOperand(frame_pointer(), kStringStartMinusOne)); 179 Label not_at_start;
180 __ add(r0, current_input_offset(), Operand(-char_size())); 180 // Did we start the match at the start of the string at all?
181 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
182 __ cmp(r0, Operand::Zero());
183 BranchOrBacktrack(ne, &not_at_start);
184
185 // If we did, are we still at the start of the input?
186 __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
187 __ add(r0, end_of_input_address(), Operand(current_input_offset()));
181 __ cmp(r0, r1); 188 __ cmp(r0, r1);
182 BranchOrBacktrack(eq, on_at_start); 189 BranchOrBacktrack(eq, on_at_start);
190 __ bind(&not_at_start);
183 } 191 }
184 192
185 193
186 void RegExpMacroAssemblerARM::CheckNotAtStart(int cp_offset, 194 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) {
187 Label* on_not_at_start) { 195 // Did we start the match at the start of the string at all?
188 __ ldr(r1, MemOperand(frame_pointer(), kStringStartMinusOne)); 196 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
189 __ add(r0, current_input_offset(), 197 __ cmp(r0, Operand::Zero());
190 Operand(-char_size() + cp_offset * char_size())); 198 BranchOrBacktrack(ne, on_not_at_start);
199 // If we did, are we still at the start of the input?
200 __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
201 __ add(r0, end_of_input_address(), Operand(current_input_offset()));
191 __ cmp(r0, r1); 202 __ cmp(r0, r1);
192 BranchOrBacktrack(ne, on_not_at_start); 203 BranchOrBacktrack(ne, on_not_at_start);
193 } 204 }
194 205
195 206
196 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { 207 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) {
197 __ cmp(current_character(), Operand(limit)); 208 __ cmp(current_character(), Operand(limit));
198 BranchOrBacktrack(lt, on_less); 209 BranchOrBacktrack(lt, on_less);
199 } 210 }
200 211
201 212
202 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { 213 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) {
203 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); 214 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0));
204 __ cmp(current_input_offset(), r0); 215 __ cmp(current_input_offset(), r0);
205 __ add(backtrack_stackpointer(), 216 __ add(backtrack_stackpointer(),
206 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); 217 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq);
207 BranchOrBacktrack(eq, on_equal); 218 BranchOrBacktrack(eq, on_equal);
208 } 219 }
209 220
210 221
211 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( 222 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
212 int start_reg, bool read_backward, Label* on_no_match) { 223 int start_reg,
224 Label* on_no_match) {
213 Label fallthrough; 225 Label fallthrough;
214 __ ldr(r0, register_location(start_reg)); // Index of start of capture 226 __ ldr(r0, register_location(start_reg)); // Index of start of capture
215 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture 227 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
216 __ sub(r1, r1, r0, SetCC); // Length of capture. 228 __ sub(r1, r1, r0, SetCC); // Length of capture.
217 229
218 // At this point, the capture registers are either both set or both cleared. 230 // If length is zero, either the capture is empty or it is not participating.
219 // If the capture length is zero, then the capture is either empty or cleared. 231 // In either case succeed immediately.
220 // Fall through in both cases.
221 __ b(eq, &fallthrough); 232 __ b(eq, &fallthrough);
222 233
223 // Check that there are enough characters left in the input. 234 // Check that there are enough characters left in the input.
224 if (read_backward) { 235 __ cmn(r1, Operand(current_input_offset()));
225 __ ldr(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); 236 BranchOrBacktrack(gt, on_no_match);
226 __ add(r3, r3, r1);
227 __ cmp(current_input_offset(), r3);
228 BranchOrBacktrack(le, on_no_match);
229 } else {
230 __ cmn(r1, Operand(current_input_offset()));
231 BranchOrBacktrack(gt, on_no_match);
232 }
233 237
234 if (mode_ == LATIN1) { 238 if (mode_ == LATIN1) {
235 Label success; 239 Label success;
236 Label fail; 240 Label fail;
237 Label loop_check; 241 Label loop_check;
238 242
239 // r0 - offset of start of capture 243 // r0 - offset of start of capture
240 // r1 - length of capture 244 // r1 - length of capture
241 __ add(r0, r0, end_of_input_address()); 245 __ add(r0, r0, Operand(end_of_input_address()));
242 __ add(r2, end_of_input_address(), current_input_offset()); 246 __ add(r2, end_of_input_address(), Operand(current_input_offset()));
243 if (read_backward) { 247 __ add(r1, r0, Operand(r1));
244 __ sub(r2, r2, r1); // Offset by length when matching backwards.
245 }
246 __ add(r1, r0, r1);
247 248
248 // r0 - Address of start of capture. 249 // r0 - Address of start of capture.
249 // r1 - Address of end of capture 250 // r1 - Address of end of capture
250 // r2 - Address of current input position. 251 // r2 - Address of current input position.
251 252
252 Label loop; 253 Label loop;
253 __ bind(&loop); 254 __ bind(&loop);
254 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); 255 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex));
255 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); 256 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex));
256 __ cmp(r4, r3); 257 __ cmp(r4, r3);
(...skipping 18 matching lines...) Expand all
275 __ cmp(r0, r1); 276 __ cmp(r0, r1);
276 __ b(lt, &loop); 277 __ b(lt, &loop);
277 __ jmp(&success); 278 __ jmp(&success);
278 279
279 __ bind(&fail); 280 __ bind(&fail);
280 BranchOrBacktrack(al, on_no_match); 281 BranchOrBacktrack(al, on_no_match);
281 282
282 __ bind(&success); 283 __ bind(&success);
283 // Compute new value of character position after the matched part. 284 // Compute new value of character position after the matched part.
284 __ sub(current_input_offset(), r2, end_of_input_address()); 285 __ sub(current_input_offset(), r2, end_of_input_address());
285 if (read_backward) {
286 __ ldr(r0, register_location(start_reg)); // Index of start of capture
287 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
288 __ add(current_input_offset(), current_input_offset(), r0);
289 __ sub(current_input_offset(), current_input_offset(), r1);
290 }
291 } else { 286 } else {
292 DCHECK(mode_ == UC16); 287 DCHECK(mode_ == UC16);
293 int argument_count = 4; 288 int argument_count = 4;
294 __ PrepareCallCFunction(argument_count, r2); 289 __ PrepareCallCFunction(argument_count, r2);
295 290
296 // r0 - offset of start of capture 291 // r0 - offset of start of capture
297 // r1 - length of capture 292 // r1 - length of capture
298 293
299 // Put arguments into arguments registers. 294 // Put arguments into arguments registers.
300 // Parameters are 295 // Parameters are
301 // r0: Address byte_offset1 - Address captured substring's start. 296 // r0: Address byte_offset1 - Address captured substring's start.
302 // r1: Address byte_offset2 - Address of current character position. 297 // r1: Address byte_offset2 - Address of current character position.
303 // r2: size_t byte_length - length of capture in bytes(!) 298 // r2: size_t byte_length - length of capture in bytes(!)
304 // r3: Isolate* isolate 299 // r3: Isolate* isolate
305 300
306 // Address of start of capture. 301 // Address of start of capture.
307 __ add(r0, r0, Operand(end_of_input_address())); 302 __ add(r0, r0, Operand(end_of_input_address()));
308 // Length of capture. 303 // Length of capture.
309 __ mov(r2, Operand(r1)); 304 __ mov(r2, Operand(r1));
310 // Save length in callee-save register for use on return. 305 // Save length in callee-save register for use on return.
311 __ mov(r4, Operand(r1)); 306 __ mov(r4, Operand(r1));
312 // Address of current input position. 307 // Address of current input position.
313 __ add(r1, current_input_offset(), end_of_input_address()); 308 __ add(r1, current_input_offset(), Operand(end_of_input_address()));
314 if (read_backward) {
315 __ sub(r1, r1, r4);
316 }
317 // Isolate. 309 // Isolate.
318 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); 310 __ mov(r3, Operand(ExternalReference::isolate_address(isolate())));
319 311
320 { 312 {
321 AllowExternalCallThatCantCauseGC scope(masm_); 313 AllowExternalCallThatCantCauseGC scope(masm_);
322 ExternalReference function = 314 ExternalReference function =
323 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 315 ExternalReference::re_case_insensitive_compare_uc16(isolate());
324 __ CallCFunction(function, argument_count); 316 __ CallCFunction(function, argument_count);
325 } 317 }
326 318
327 // Check if function returned non-zero for success or zero for failure. 319 // Check if function returned non-zero for success or zero for failure.
328 __ cmp(r0, Operand::Zero()); 320 __ cmp(r0, Operand::Zero());
329 BranchOrBacktrack(eq, on_no_match); 321 BranchOrBacktrack(eq, on_no_match);
330 322 // On success, increment position by length of capture.
331 // On success, advance position by length of capture. 323 __ add(current_input_offset(), current_input_offset(), Operand(r4));
332 if (read_backward) {
333 __ sub(current_input_offset(), current_input_offset(), r4);
334 } else {
335 __ add(current_input_offset(), current_input_offset(), r4);
336 }
337 } 324 }
338 325
339 __ bind(&fallthrough); 326 __ bind(&fallthrough);
340 } 327 }
341 328
342 329
343 void RegExpMacroAssemblerARM::CheckNotBackReference(int start_reg, 330 void RegExpMacroAssemblerARM::CheckNotBackReference(
344 bool read_backward, 331 int start_reg,
345 Label* on_no_match) { 332 Label* on_no_match) {
346 Label fallthrough; 333 Label fallthrough;
347 Label success; 334 Label success;
348 335
349 // Find length of back-referenced capture. 336 // Find length of back-referenced capture.
350 __ ldr(r0, register_location(start_reg)); 337 __ ldr(r0, register_location(start_reg));
351 __ ldr(r1, register_location(start_reg + 1)); 338 __ ldr(r1, register_location(start_reg + 1));
352 __ sub(r1, r1, r0, SetCC); // Length to check. 339 __ sub(r1, r1, r0, SetCC); // Length to check.
353 340 // Succeed on empty capture (including no capture).
354 // At this point, the capture registers are either both set or both cleared.
355 // If the capture length is zero, then the capture is either empty or cleared.
356 // Fall through in both cases.
357 __ b(eq, &fallthrough); 341 __ b(eq, &fallthrough);
358 342
359 // Check that there are enough characters left in the input. 343 // Check that there are enough characters left in the input.
360 if (read_backward) { 344 __ cmn(r1, Operand(current_input_offset()));
361 __ ldr(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); 345 BranchOrBacktrack(gt, on_no_match);
362 __ add(r3, r3, r1);
363 __ cmp(current_input_offset(), r3);
364 BranchOrBacktrack(lt, on_no_match);
365 } else {
366 __ cmn(r1, Operand(current_input_offset()));
367 BranchOrBacktrack(gt, on_no_match);
368 }
369 346
370 // r0 - offset of start of capture 347 // Compute pointers to match string and capture string
371 // r1 - length of capture 348 __ add(r0, r0, Operand(end_of_input_address()));
372 __ add(r0, r0, end_of_input_address()); 349 __ add(r2, end_of_input_address(), Operand(current_input_offset()));
373 __ add(r2, end_of_input_address(), current_input_offset()); 350 __ add(r1, r1, Operand(r0));
374 if (read_backward) {
375 __ sub(r2, r2, r1); // Offset by length when matching backwards.
376 }
377 __ add(r1, r0, r1);
378 351
379 Label loop; 352 Label loop;
380 __ bind(&loop); 353 __ bind(&loop);
381 if (mode_ == LATIN1) { 354 if (mode_ == LATIN1) {
382 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); 355 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex));
383 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); 356 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex));
384 } else { 357 } else {
385 DCHECK(mode_ == UC16); 358 DCHECK(mode_ == UC16);
386 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); 359 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex));
387 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); 360 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex));
388 } 361 }
389 __ cmp(r3, r4); 362 __ cmp(r3, r4);
390 BranchOrBacktrack(ne, on_no_match); 363 BranchOrBacktrack(ne, on_no_match);
391 __ cmp(r0, r1); 364 __ cmp(r0, r1);
392 __ b(lt, &loop); 365 __ b(lt, &loop);
393 366
394 // Move current character position to position after match. 367 // Move current character position to position after match.
395 __ sub(current_input_offset(), r2, end_of_input_address()); 368 __ sub(current_input_offset(), r2, end_of_input_address());
396 if (read_backward) {
397 __ ldr(r0, register_location(start_reg)); // Index of start of capture
398 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
399 __ add(current_input_offset(), current_input_offset(), r0);
400 __ sub(current_input_offset(), current_input_offset(), r1);
401 }
402
403 __ bind(&fallthrough); 369 __ bind(&fallthrough);
404 } 370 }
405 371
406 372
407 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, 373 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c,
408 Label* on_not_equal) { 374 Label* on_not_equal) {
409 __ cmp(current_character(), Operand(c)); 375 __ cmp(current_character(), Operand(c));
410 BranchOrBacktrack(ne, on_not_equal); 376 BranchOrBacktrack(ne, on_not_equal);
411 } 377 }
412 378
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 // Order here should correspond to order of offset constants in header file. 596 // Order here should correspond to order of offset constants in header file.
631 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | 597 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() |
632 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); 598 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit();
633 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); 599 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit();
634 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); 600 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit());
635 // Set frame pointer in space for it if this is not a direct call 601 // Set frame pointer in space for it if this is not a direct call
636 // from generated code. 602 // from generated code.
637 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); 603 __ add(frame_pointer(), sp, Operand(4 * kPointerSize));
638 __ mov(r0, Operand::Zero()); 604 __ mov(r0, Operand::Zero());
639 __ push(r0); // Make room for success counter and initialize it to 0. 605 __ push(r0); // Make room for success counter and initialize it to 0.
640 __ push(r0); // Make room for "string start - 1" constant. 606 __ push(r0); // Make room for "position - 1" constant (value is irrelevant).
641 // Check if we have space on the stack for registers. 607 // Check if we have space on the stack for registers.
642 Label stack_limit_hit; 608 Label stack_limit_hit;
643 Label stack_ok; 609 Label stack_ok;
644 610
645 ExternalReference stack_limit = 611 ExternalReference stack_limit =
646 ExternalReference::address_of_stack_limit(isolate()); 612 ExternalReference::address_of_stack_limit(isolate());
647 __ mov(r0, Operand(stack_limit)); 613 __ mov(r0, Operand(stack_limit));
648 __ ldr(r0, MemOperand(r0)); 614 __ ldr(r0, MemOperand(r0));
649 __ sub(r0, sp, r0, SetCC); 615 __ sub(r0, sp, r0, SetCC);
650 // Handle it if the stack pointer is already below the stack limit. 616 // Handle it if the stack pointer is already below the stack limit.
(...skipping 23 matching lines...) Expand all
674 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); 640 __ ldr(r0, MemOperand(frame_pointer(), kInputStart));
675 // Find negative length (offset of start relative to end). 641 // Find negative length (offset of start relative to end).
676 __ sub(current_input_offset(), r0, end_of_input_address()); 642 __ sub(current_input_offset(), r0, end_of_input_address());
677 // Set r0 to address of char before start of the input string 643 // Set r0 to address of char before start of the input string
678 // (effectively string position -1). 644 // (effectively string position -1).
679 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); 645 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
680 __ sub(r0, current_input_offset(), Operand(char_size())); 646 __ sub(r0, current_input_offset(), Operand(char_size()));
681 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); 647 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0));
682 // Store this value in a local variable, for use when clearing 648 // Store this value in a local variable, for use when clearing
683 // position registers. 649 // position registers.
684 __ str(r0, MemOperand(frame_pointer(), kStringStartMinusOne)); 650 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
685 651
686 // Initialize code pointer register 652 // Initialize code pointer register
687 __ mov(code_pointer(), Operand(masm_->CodeObject())); 653 __ mov(code_pointer(), Operand(masm_->CodeObject()));
688 654
689 Label load_char_start_regexp, start_regexp; 655 Label load_char_start_regexp, start_regexp;
690 // Load newline if index is at start, previous character otherwise. 656 // Load newline if index is at start, previous character otherwise.
691 __ cmp(r1, Operand::Zero()); 657 __ cmp(r1, Operand::Zero());
692 __ b(ne, &load_char_start_regexp); 658 __ b(ne, &load_char_start_regexp);
693 __ mov(current_character(), Operand('\n'), LeaveCC, eq); 659 __ mov(current_character(), Operand('\n'), LeaveCC, eq);
694 __ jmp(&start_regexp); 660 __ jmp(&start_regexp);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 // Check whether we have enough room for another set of capture results. 744 // Check whether we have enough room for another set of capture results.
779 __ cmp(r1, Operand(num_saved_registers_)); 745 __ cmp(r1, Operand(num_saved_registers_));
780 __ b(lt, &return_r0); 746 __ b(lt, &return_r0);
781 747
782 __ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters)); 748 __ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters));
783 // Advance the location for output. 749 // Advance the location for output.
784 __ add(r2, r2, Operand(num_saved_registers_ * kPointerSize)); 750 __ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
785 __ str(r2, MemOperand(frame_pointer(), kRegisterOutput)); 751 __ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
786 752
787 // Prepare r0 to initialize registers with its value in the next run. 753 // Prepare r0 to initialize registers with its value in the next run.
788 __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne)); 754 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
789 755
790 if (global_with_zero_length_check()) { 756 if (global_with_zero_length_check()) {
791 // Special case for zero-length matches. 757 // Special case for zero-length matches.
792 // r4: capture start index 758 // r4: capture start index
793 __ cmp(current_input_offset(), r4); 759 __ cmp(current_input_offset(), r4);
794 // Not a zero-length match, restart. 760 // Not a zero-length match, restart.
795 __ b(ne, &load_char_start_regexp); 761 __ b(ne, &load_char_start_regexp);
796 // Offset from the end is zero if we already reached the end. 762 // Offset from the end is zero if we already reached the end.
797 __ cmp(current_input_offset(), Operand::Zero()); 763 __ cmp(current_input_offset(), Operand::Zero());
798 __ b(eq, &exit_label_); 764 __ b(eq, &exit_label_);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 RegExpMacroAssembler::IrregexpImplementation 885 RegExpMacroAssembler::IrregexpImplementation
920 RegExpMacroAssemblerARM::Implementation() { 886 RegExpMacroAssemblerARM::Implementation() {
921 return kARMImplementation; 887 return kARMImplementation;
922 } 888 }
923 889
924 890
925 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, 891 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset,
926 Label* on_end_of_input, 892 Label* on_end_of_input,
927 bool check_bounds, 893 bool check_bounds,
928 int characters) { 894 int characters) {
895 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
929 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 896 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
930 if (check_bounds) { 897 if (check_bounds) {
931 if (cp_offset >= 0) { 898 CheckPosition(cp_offset + characters - 1, on_end_of_input);
932 CheckPosition(cp_offset + characters - 1, on_end_of_input);
933 } else {
934 CheckPosition(cp_offset, on_end_of_input);
935 }
936 } 899 }
937 LoadCurrentCharacterUnchecked(cp_offset, characters); 900 LoadCurrentCharacterUnchecked(cp_offset, characters);
938 } 901 }
939 902
940 903
941 void RegExpMacroAssemblerARM::PopCurrentPosition() { 904 void RegExpMacroAssemblerARM::PopCurrentPosition() {
942 Pop(current_input_offset()); 905 Pop(current_input_offset());
943 } 906 }
944 907
945 908
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 __ str(current_input_offset(), register_location(reg)); 976 __ str(current_input_offset(), register_location(reg));
1014 } else { 977 } else {
1015 __ add(r0, current_input_offset(), Operand(cp_offset * char_size())); 978 __ add(r0, current_input_offset(), Operand(cp_offset * char_size()));
1016 __ str(r0, register_location(reg)); 979 __ str(r0, register_location(reg));
1017 } 980 }
1018 } 981 }
1019 982
1020 983
1021 void RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) { 984 void RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) {
1022 DCHECK(reg_from <= reg_to); 985 DCHECK(reg_from <= reg_to);
1023 __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne)); 986 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
1024 for (int reg = reg_from; reg <= reg_to; reg++) { 987 for (int reg = reg_from; reg <= reg_to; reg++) {
1025 __ str(r0, register_location(reg)); 988 __ str(r0, register_location(reg));
1026 } 989 }
1027 } 990 }
1028 991
1029 992
1030 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) { 993 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) {
1031 __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd)); 994 __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd));
1032 __ sub(r0, backtrack_stackpointer(), r1); 995 __ sub(r0, backtrack_stackpointer(), r1);
1033 __ str(r0, register_location(reg)); 996 __ str(r0, register_location(reg));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 if (num_registers_ <= register_index) { 1062 if (num_registers_ <= register_index) {
1100 num_registers_ = register_index + 1; 1063 num_registers_ = register_index + 1;
1101 } 1064 }
1102 return MemOperand(frame_pointer(), 1065 return MemOperand(frame_pointer(),
1103 kRegisterZero - register_index * kPointerSize); 1066 kRegisterZero - register_index * kPointerSize);
1104 } 1067 }
1105 1068
1106 1069
1107 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, 1070 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset,
1108 Label* on_outside_input) { 1071 Label* on_outside_input) {
1109 if (cp_offset >= 0) { 1072 __ cmp(current_input_offset(), Operand(-cp_offset * char_size()));
1110 __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); 1073 BranchOrBacktrack(ge, on_outside_input);
1111 BranchOrBacktrack(ge, on_outside_input);
1112 } else {
1113 __ ldr(r1, MemOperand(frame_pointer(), kStringStartMinusOne));
1114 __ add(r0, current_input_offset(), Operand(cp_offset * char_size()));
1115 __ cmp(r0, r1);
1116 BranchOrBacktrack(le, on_outside_input);
1117 }
1118 } 1074 }
1119 1075
1120 1076
1121 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, 1077 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition,
1122 Label* to) { 1078 Label* to) {
1123 if (condition == al) { // Unconditional. 1079 if (condition == al) { // Unconditional.
1124 if (to == NULL) { 1080 if (to == NULL) {
1125 Backtrack(); 1081 Backtrack();
1126 return; 1082 return;
1127 } 1083 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 1188
1233 1189
1234 #undef __ 1190 #undef __
1235 1191
1236 #endif // V8_INTERPRETED_REGEXP 1192 #endif // V8_INTERPRETED_REGEXP
1237 1193
1238 } // namespace internal 1194 } // namespace internal
1239 } // namespace v8 1195 } // namespace v8
1240 1196
1241 #endif // V8_TARGET_ARCH_ARM 1197 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/regexp/arm/regexp-macro-assembler-arm.h ('k') | src/regexp/arm64/regexp-macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698