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

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

Issue 11608: * Added tests for regexp-macro-assembler-ia32. (Closed)
Patch Set: Created 12 years 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
« no previous file with comments | « src/regexp-macro-assembler-ia32.h ('k') | test/cctest/cctest.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 17 matching lines...) Expand all
28 #include <string.h> 28 #include <string.h>
29 #include "v8.h" 29 #include "v8.h"
30 #include "log.h" 30 #include "log.h"
31 #include "ast.h" 31 #include "ast.h"
32 #include "macro-assembler.h" 32 #include "macro-assembler.h"
33 #include "regexp-macro-assembler-ia32.h" 33 #include "regexp-macro-assembler-ia32.h"
34 34
35 namespace v8 { namespace internal { 35 namespace v8 { namespace internal {
36 /* 36 /*
37 * This assembler uses the following register assignment convention 37 * This assembler uses the following register assignment convention
38 * - edx : current character, or kEndOfInput if current position is not 38 * - edx : current character. Must be loaded using LoadCurrentCharacter
39 * inside string. The kEndOfInput value is greater than 0xffff, 39 * before using any of the dispatch methods.
40 * so any tests that don't check whether the current position
41 * is inside the correct range should retain bits above the
42 * 15th in their computations, and fail if the value is too
43 * great.
44 * - edi : current position in input, as negative offset from end of string. 40 * - edi : current position in input, as negative offset from end of string.
41 * NOTICE: This is the byte offset, not the character offset!
Erik Corry 2008/11/25 12:39:11 No shouting :-)
45 * - esi : end of input (points to byte after last character in input). 42 * - esi : end of input (points to byte after last character in input).
46 * - ebp : points to the location above the registers on the stack, 43 * - ebp : points to the location above the registers on the stack,
47 * as if by the "enter <register_count>" opcode. 44 * as if by the "enter <register_count>" opcode.
48 * - esp : points to tip of backtracking stack. 45 * - esp : points to tip of backtracking stack.
49 * 46 *
50 * The registers eax, ebx and ecx are free to use for computations. 47 * The registers eax, ebx and ecx are free to use for computations.
51 * 48 *
52 * Each call to a public method should retain this convention. 49 * Each call to a public method should retain this convention.
53 * The stack will have the following structure: 50 * The stack will have the following structure:
54 * - int* capture_array (int[num_saved_registers_], for output). 51 * - int* capture_array (int[num_saved_registers_], for output).
55 * - end of input (index of end of string, relative to *string_base) 52 * - end of input (index of end of string, relative to *string_base)
56 * - start of input (index of first character in string, relative 53 * - start of input (index of first character in string, relative
57 * to *string_base) 54 * to *string_base)
58 * - void** string_base (location of a handle containing the string) 55 * - void** string_base (location of a handle containing the string)
59 * - return address 56 * - return address
60 * - backup of esi 57 * - backup of esi
61 * - backup of edi 58 * - backup of edi
62 * ebp-> - old ebp 59 * ebp-> - old ebp
63 * - register 0 ebp[-4] 60 * - register 0 ebp[-4] (Only positions must be stored in the first
64 * - register 1 ebp[-8] 61 * - register 1 ebp[-8] num_saved_registers_ registers)
65 * - ... 62 * - ...
66 * 63 *
67 * The data before ebp must be placed there by the calling code, e.g., 64 * The first num_saved_registers_ registers are initialized to point to
68 * by calling the code as cast to: 65 * "character -1" in the string (i.e., char_size() bytes before the first
66 * character of the string). The remaining registers are starts out as garbage.
Erik Corry 2008/11/25 12:39:11 this sentence are not parse
67 *
68 * The data up to the return address must be placed there by the calling
69 * code, e.g., by calling the code as cast to:
69 * bool (*match)(String** string_base, 70 * bool (*match)(String** string_base,
70 * int start_offset, 71 * int start_offset,
71 * int end_offset, 72 * int end_offset,
72 * int* capture_output_array) 73 * int* capture_output_array)
73 */ 74 */
74 75
75 #define __ masm_-> 76 #define __ masm_->
76 77
77 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32( 78 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
78 Mode mode, 79 Mode mode,
79 int registers_to_save, 80 int registers_to_save,
80 bool ignore_case) 81 bool ignore_case)
Erik Corry 2008/11/25 12:39:11 ignore_case is unused and likely to remain so.
Lasse Reichstein 2008/11/25 13:05:47 I see that the CheckNotBackReferenceCaseIndependen
81 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), 82 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
82 constants_(kRegExpConstantsSize), 83 constants_(kRegExpConstantsSize),
83 mode_(mode), 84 mode_(mode),
84 num_registers_(registers_to_save), 85 num_registers_(registers_to_save),
85 num_saved_registers_(registers_to_save), 86 num_saved_registers_(registers_to_save),
86 ignore_case_(ignore_case), 87 ignore_case_(ignore_case),
87 entry_label_(), 88 entry_label_(),
88 start_label_(), 89 start_label_(),
89 success_label_(), 90 success_label_(),
90 exit_label_(), 91 exit_label_(),
(...skipping 10 matching lines...) Expand all
101 start_label_.Unuse(); 102 start_label_.Unuse();
102 success_label_.Unuse(); 103 success_label_.Unuse();
103 exit_label_.Unuse(); 104 exit_label_.Unuse();
104 } 105 }
105 106
106 107
107 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { 108 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
108 ASSERT(by > 0); 109 ASSERT(by > 0);
109 Label inside_string; 110 Label inside_string;
110 __ add(Operand(edi), Immediate(by * char_size())); 111 __ add(Operand(edi), Immediate(by * char_size()));
111 __ j(below, &inside_string);
112 Backtrack();
113
114 __ bind(&inside_string);
115 } 112 }
116 113
117 114
118 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { 115 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) {
119 ASSERT(reg >= 0); 116 ASSERT(reg >= 0);
120 ASSERT(reg < num_registers_); 117 ASSERT(reg < num_registers_);
121 __ add(register_location(reg), Immediate(by)); 118 __ add(register_location(reg), Immediate(by));
122 } 119 }
123 120
124 121
125 void RegExpMacroAssemblerIA32::Backtrack() { 122 void RegExpMacroAssemblerIA32::Backtrack() {
126 __ pop(ecx); 123 __ pop(ecx);
127 __ add(Operand(ecx), Immediate(self_)); 124 __ add(Operand(ecx), Immediate(self_));
128 __ jmp(Operand(ecx)); 125 __ jmp(Operand(ecx));
129 } 126 }
130 127
131 128
132 void RegExpMacroAssemblerIA32::Bind(Label* label) { 129 void RegExpMacroAssemblerIA32::Bind(Label* label) {
133 __ bind(label); 130 __ bind(label);
134 } 131 }
135 132
136 void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start, 133 void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
137 Label* bitmap, 134 Label* bitmap,
138 Label* on_zero) { 135 Label* on_zero) {
136 UNREACHABLE();
139 ReadCurrentChar(eax); 137 ReadCurrentChar(eax);
140 __ sub(Operand(eax), Immediate(start)); 138 __ sub(Operand(eax), Immediate(start));
141 __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits. 139 __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits.
142 BranchOrBacktrack(greater_equal, on_zero); 140 BranchOrBacktrack(greater_equal, on_zero);
143 __ mov(ebx, eax); 141 __ mov(ebx, eax);
144 __ shr(ebx, 3); 142 __ shr(ebx, 3);
145 // TODO(lrn): Where is the bitmap stored? Pass the bitmap as argument instead. 143 // TODO(lrn): Where is the bitmap stored? Pass the bitmap as argument instead.
146 // __ mov(ecx, position_of_bitmap); 144 // __ mov(ecx, position_of_bitmap);
147 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0)); 145 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0));
148 __ and_(eax, (1<<3)-1); 146 __ and_(eax, (1<<3)-1);
(...skipping 17 matching lines...) Expand all
166 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { 164 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) {
167 __ cmp(edx, limit); 165 __ cmp(edx, limit);
168 BranchOrBacktrack(less, on_less); 166 BranchOrBacktrack(less, on_less);
169 } 167 }
170 168
171 169
172 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str, 170 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str,
173 int cp_offset, 171 int cp_offset,
174 Label* on_failure) { 172 Label* on_failure) {
175 int byte_length = str.length() * char_size(); 173 int byte_length = str.length() * char_size();
176 int start_offset = cp_offset * char_size(); 174 int byte_offset = cp_offset * char_size();
177 __ mov(ebx, edi); 175 __ mov(ebx, edi);
178 __ add(Operand(ebx), Immediate(start_offset + byte_length)); 176 __ add(Operand(ebx), Immediate(byte_offset + byte_length));
179 BranchOrBacktrack(greater_equal, on_failure); 177 BranchOrBacktrack(greater_equal, on_failure);
180 178
181 ArraySlice constant_buffer = constants_.GetBuffer(str.length(), char_size()); 179 ArraySlice constant_buffer = constants_.GetBuffer(str.length(), char_size());
182 for (int i = 0; i < str.length(); i++) { 180 if (mode_ == ASCII) {
183 if (mode_ == ASCII) { 181 for (int i = 0; i < str.length(); i++) {
184 constant_buffer.at<char>(i) = static_cast<char>(str[i]); 182 constant_buffer.at<char>(i) = static_cast<char>(str[i]);
185 } else {
186 memcpy(constant_buffer.location<void>(),
187 str.start(),
188 str.length() * sizeof(uc16));
189 } 183 }
184 } else {
185 memcpy(constant_buffer.location<void>(),
186 str.start(),
187 str.length() * sizeof(uc16));
190 } 188 }
191 189
192 __ mov(eax, edi); 190 __ mov(eax, edi);
193 __ mov(ebx, esi); 191 __ mov(ebx, esi);
194 __ lea(edi, Operand(esi, edi, times_1, start_offset)); 192 __ lea(edi, Operand(esi, edi, times_1, byte_offset));
195 LoadConstantBufferAddress(esi, &constant_buffer); 193 LoadConstantBufferAddress(esi, &constant_buffer);
196 __ mov(ecx, str.length()); 194 __ mov(ecx, str.length());
197 if (mode_ == ASCII) { 195 if (mode_ == ASCII) {
198 __ rep_cmpsb(); 196 __ rep_cmpsb();
199 } else { 197 } else {
200 ASSERT(mode_ == UC16); 198 ASSERT(mode_ == UC16);
201 __ rep_cmpsw(); 199 __ rep_cmpsw();
202 } 200 }
203 __ mov(esi, ebx); 201 __ mov(esi, ebx);
204 __ mov(edi, eax); 202 __ mov(edi, eax);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 305
308 void RegExpMacroAssemblerIA32::DispatchByteMap( 306 void RegExpMacroAssemblerIA32::DispatchByteMap(
309 uc16 start, 307 uc16 start,
310 Label* byte_map, 308 Label* byte_map,
311 const Vector<Label*>& destinations) { 309 const Vector<Label*>& destinations) {
312 Label fallthrough; 310 Label fallthrough;
313 ReadCurrentChar(eax); 311 ReadCurrentChar(eax);
314 __ sub(Operand(eax), Immediate(start)); 312 __ sub(Operand(eax), Immediate(start));
315 __ cmp(eax, 64); // FIXME: 64 = size of map. Found somehow?? 313 __ cmp(eax, 64); // FIXME: 64 = size of map. Found somehow??
316 __ j(greater_equal, &fallthrough); 314 __ j(greater_equal, &fallthrough);
317 // FIXME: ecx must hold address of map 315 // TODO(lrn): ecx must hold address of map
318 __ movzx_b(eax, Operand(ecx, eax, times_1, 0)); 316 __ movzx_b(eax, Operand(ecx, eax, times_1, 0));
319 // jump table: jump to destinations[eax]; 317 // jump table: jump to destinations[eax];
320 318
321 __ bind(&fallthrough); 319 __ bind(&fallthrough);
322 } 320 }
323 321
324 322
325 323
326 void RegExpMacroAssemblerIA32::DispatchHighByteMap( 324 void RegExpMacroAssemblerIA32::DispatchHighByteMap(
327 byte start, 325 byte start,
328 Label* byte_map, 326 Label* byte_map,
329 const Vector<Label*>& destinations) { 327 const Vector<Label*>& destinations) {
328 UNREACHABLE();
329
330 Label fallthrough; 330 Label fallthrough;
331 ReadCurrentChar(eax); 331 ReadCurrentChar(eax);
332 __ shr(eax, 8); 332 __ shr(eax, 8);
333 __ sub(Operand(eax), Immediate(start)); 333 __ sub(Operand(eax), Immediate(start));
334 __ cmp(eax, destinations.length() - start); 334 __ cmp(eax, destinations.length() - start);
335 __ j(greater_equal, &fallthrough); 335 __ j(greater_equal, &fallthrough);
336 336
337 // TODO(lrn) jumptable: jump to destinations[eax] 337 // TODO(lrn) jumptable: jump to destinations[eax]
338 __ bind(&fallthrough); 338 __ bind(&fallthrough);
339 } 339 }
340 340
341 341
342 void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) { 342 void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
343 UNREACHABLE(); // Has no use. 343 UNREACHABLE(); // Has no use.
344 } 344 }
345 345
346 346
347 void RegExpMacroAssemblerIA32::Fail() { 347 void RegExpMacroAssemblerIA32::Fail() {
348 __ mov(eax, 0); 348 __ xor_(eax, Operand(eax)); // zero eax.
349 __ jmp(&exit_label_); 349 __ jmp(&exit_label_);
350 } 350 }
351 351
352 352
353 Handle<Object> RegExpMacroAssemblerIA32::GetCode() { 353 Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
354 // Finalize code - write the entry point code now we know how many 354 // Finalize code - write the entry point code now we know how many
355 // registers we need. 355 // registers we need.
356 356
357 // Entry code: 357 // Entry code:
358 __ bind(&entry_label_); 358 __ bind(&entry_label_);
359 __ push(esi); 359 __ push(esi);
360 __ push(edi); 360 __ push(edi);
361 __ enter(Immediate(num_registers_ * sizeof(uint32_t))); 361 __ enter(Immediate(num_registers_ * sizeof(uint32_t)));
362 __ mov(esi, Operand(ebp, kInputEndOffset)); 362 __ mov(esi, Operand(ebp, kInputEndOffset));
363 __ mov(edi, Operand(ebp, kInputStartOffset)); 363 __ mov(edi, Operand(ebp, kInputStartOffset));
364 __ sub(edi, Operand(esi)); 364 __ sub(edi, Operand(esi));
365 __ mov(edx, Operand(ebp, kInputBuffer)); 365 __ mov(edx, Operand(ebp, kInputBuffer));
366 __ mov(edx, Operand(edx, 0)); 366 __ mov(edx, Operand(edx, 0));
367 __ add(esi, Operand(edx)); 367 __ add(esi, Operand(edx));
368 if (num_saved_registers_ > 0) {
369 // Fill saved registers with initial value = start offset - 1
370 __ mov(ecx, -num_saved_registers_);
371 __ mov(eax, Operand(edi));
372 if (char_size() == 1) {
373 __ dec(eax);
Erik Corry 2008/11/25 12:39:11 I think dec is deprecated for performance reasons
374 } else {
375 __ sub(Operand(eax), Immediate(2));
376 }
377 Label init_loop;
378 __ bind(&init_loop);
379 __ mov(Operand(ebp, ecx, times_4, +0), eax);
380 __ inc(ecx);
381 __ j(not_equal, &init_loop);
382 }
368 __ jmp(&start_label_); 383 __ jmp(&start_label_);
369 384
370 // Exit code: 385 // Exit code:
371 __ bind(&success_label_); 386 __ bind(&success_label_);
372 __ mov(ebx, Operand(ebp, kRegisterOutput)); 387 if (num_saved_registers_ > 0) {
373 __ mov(ecx, Operand(ebp, kInputEndOffset)); 388 // copy captures to output
374 __ sub(ecx, Operand(ebp, kInputStartOffset)); 389 __ mov(ebx, Operand(ebp, kRegisterOutput));
375 for (int i = 0; i < num_saved_registers_; i++) { 390 __ mov(ecx, Operand(ebp, kInputEndOffset));
376 __ mov(eax, register_location(i)); 391 __ sub(ecx, Operand(ebp, kInputStartOffset));
377 __ sub(eax, Operand(ecx)); // Convert to index from start, not end. 392 for (int i = 0; i < num_saved_registers_; i++) {
378 __ mov(Operand(ebx, i * sizeof(int32_t)), eax); 393 __ mov(eax, register_location(i));
394 __ add(eax, Operand(ecx)); // Convert to index from start, not end.
395 if (char_size() == 2) {
396 __ shr(eax);
397 }
398 __ mov(Operand(ebx, i * sizeof(int32_t)), eax);
399 }
379 } 400 }
380 // copy captures to output
381 __ mov(eax, Immediate(1)); 401 __ mov(eax, Immediate(1));
382 402
383 __ bind(&exit_label_); 403 __ bind(&exit_label_);
384 __ leave(); 404 __ leave();
385 __ pop(edi); 405 __ pop(edi);
386 __ pop(esi); 406 __ pop(esi);
387 __ ret(0); 407 __ ret(0);
388 408
389 CodeDesc code_desc; 409 CodeDesc code_desc;
390 masm_->GetCode(&code_desc); 410 masm_->GetCode(&code_desc);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 RegExpMacroAssemblerIA32::Implementation() { 445 RegExpMacroAssemblerIA32::Implementation() {
426 return kIA32Implementation; 446 return kIA32Implementation;
427 } 447 }
428 448
429 449
430 450
431 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, 451 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
432 Label* on_end_of_input) { 452 Label* on_end_of_input) {
433 ASSERT(cp_offset >= 0); 453 ASSERT(cp_offset >= 0);
434 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 454 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
435 __ cmp(edi, -cp_offset); 455 __ cmp(edi, -cp_offset * char_size());
436 BranchOrBacktrack(less_equal, on_end_of_input); 456 BranchOrBacktrack(greater_equal, on_end_of_input);
437 ReadChar(edx, cp_offset); 457 ReadChar(edx, cp_offset);
438 } 458 }
439 459
440 460
441 void RegExpMacroAssemblerIA32::PopCurrentPosition() { 461 void RegExpMacroAssemblerIA32::PopCurrentPosition() {
442 __ pop(edi); 462 __ pop(edi);
443 } 463 }
444 464
445 465
446 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { 466 void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
447 RecordRegister(register_index); 467 RecordRegister(register_index);
448 __ pop(register_location(register_index)); 468 __ pop(register_location(register_index));
449 } 469 }
450 470
451 471
452 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) { 472 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) {
453 // Check for preemption first. 473 // CheckStackLimit(); // Not ready yet.
454 Label no_preempt;
455 Label retry_preempt;
456 // Check for preemption.
457 ExternalReference stack_limit =
458 ExternalReference::address_of_stack_guard_limit();
459 __ cmp(esp, Operand::StaticVariable(stack_limit));
460 __ j(above, &no_preempt);
461
462 __ push(edi); // Current position.
463 __ push(edx); // Current character.
464 // Restore original edi, esi.
465 __ mov(edi, Operand(ebp, kBackup_edi));
466 __ mov(esi, Operand(ebp, kBackup_esi));
467
468 __ bind(&retry_preempt);
469 // simulate stack for Runtime call.
470 __ push(Immediate(0)); // Dummy receiver
471 __ CallRuntime(Runtime::kStackGuard, 0);
472 __ cmp(esp, Operand::StaticVariable(stack_limit));
473 __ j(below_equal, &retry_preempt);
474
475 __ pop(edx);
476 __ pop(edi);
477 __ mov(esi, Operand(ebp, kInputBuffer));
478 __ mov(esi, Operand(esi, 0));
479 __ add(esi, Operand(ebp, kInputEndOffset));
480
481 __ bind(&no_preempt);
482
483 Label cont;
484 __ push(label, RelocInfo::NONE); 474 __ push(label, RelocInfo::NONE);
485 } 475 }
486 476
487 477
488 void RegExpMacroAssemblerIA32::PushCurrentPosition() { 478 void RegExpMacroAssemblerIA32::PushCurrentPosition() {
489 __ push(edi); 479 __ push(edi);
490 } 480 }
491 481
492 482
493 void RegExpMacroAssemblerIA32::PushRegister(int register_index) { 483 void RegExpMacroAssemblerIA32::PushRegister(int register_index) {
494 __ push(register_location(register_index)); 484 __ push(register_location(register_index));
495 } 485 }
496 486
497 487
498 void RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(int reg) { 488 void RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(int reg) {
499 __ mov(edi, register_location(reg)); 489 __ mov(edi, register_location(reg));
500 } 490 }
501 491
502 492
503 void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) { 493 void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) {
504 __ mov(esp, register_location(reg)); 494 __ mov(esp, register_location(reg));
505 } 495 }
506 496
507 497
508 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) { 498 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
499 ASSERT(register_index >= num_saved_registers_); // Reserved for positions!
Erik Corry 2008/11/25 12:39:11 We might want to use this instruction on capture p
Lasse Reichstein 2008/11/25 13:05:47 It won't work for positions, as currently implemen
509 RecordRegister(register_index); 500 RecordRegister(register_index);
510 __ mov(register_location(register_index), Immediate(to)); 501 __ mov(register_location(register_index), Immediate(to));
511 } 502 }
512 503
513 504
514 void RegExpMacroAssemblerIA32::Succeed() { 505 void RegExpMacroAssemblerIA32::Succeed() {
515 __ jmp(&success_label_); 506 __ jmp(&success_label_);
516 } 507 }
517 508
518 509
519 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister( 510 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(
520 int register_index) { 511 int register_index) {
512 RecordRegister(register_index);
521 __ mov(register_location(register_index), edi); 513 __ mov(register_location(register_index), edi);
522 } 514 }
523 515
524 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { 516 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
525 __ mov(register_location(reg), esp); 517 __ mov(register_location(reg), esp);
526 } 518 }
527 519
528 520
529 // Private methods: 521 // Private methods:
530 522
(...skipping 11 matching lines...) Expand all
542 534
543 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, 535 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
544 Label* to) { 536 Label* to) {
545 if (condition < 0) { // No condition 537 if (condition < 0) { // No condition
546 if (to == NULL) { 538 if (to == NULL) {
547 Backtrack(); 539 Backtrack();
548 return; 540 return;
549 } 541 }
550 __ jmp(to); 542 __ jmp(to);
551 return; 543 return;
552 } else if (to == NULL) { 544 }
545 if (to == NULL) {
553 Label skip; 546 Label skip;
554 __ j(NegateCondition(condition), &skip); 547 __ j(NegateCondition(condition), &skip);
555 Backtrack(); 548 Backtrack();
556 __ bind(&skip); 549 __ bind(&skip);
557 return; 550 return;
558 } 551 }
559 __ j(condition, to); 552 __ j(condition, to);
560 } 553 }
561 554
562 555
563 void RegExpMacroAssemblerIA32::Canonicalize(Register reg) { 556 void RegExpMacroAssemblerIA32::Canonicalize(Register reg) {
564 if (mode_ == ASCII) { 557 if (mode_ == ASCII) {
565 Label end; 558 Label end;
566 __ cmp(Operand(reg), Immediate('a')); 559 __ cmp(Operand(reg), Immediate('a'));
567 __ j(below, &end); 560 __ j(below, &end);
568 __ cmp(Operand(reg), Immediate('z')); 561 __ cmp(Operand(reg), Immediate('z'));
569 __ j(above, &end); 562 __ j(above, &end);
570 __ sub(Operand(reg), Immediate('a' - 'A')); 563 __ sub(Operand(reg), Immediate('a' - 'A'));
571 __ bind(&end); 564 __ bind(&end);
572 return; 565 return;
573 } 566 }
574 ASSERT(mode_ == UC16); 567 ASSERT(mode_ == UC16);
575 // TODO(lrn): Use some tables. 568 // TODO(lrn): Use some tables.
576 } 569 }
577 570
578 571
572 void RegExpMacroAssemblerIA32::CheckStackLimit() {
573 if (FLAG_check_stack) {
574 // Check for preemption first.
575 Label no_preempt;
576 Label retry_preempt;
577 // Check for preemption.
578 ExternalReference stack_guard_limit =
579 ExternalReference::address_of_stack_guard_limit();
580 __ cmp(esp, Operand::StaticVariable(stack_guard_limit));
581 __ j(above, &no_preempt, taken);
Erik Corry 2008/11/25 12:39:11 This needs to be moved out of line at some point (
582
583 __ push(edi); // Current position.
584 __ push(edx); // Current character.
585 // Restore original edi, esi.
586 __ mov(edi, Operand(ebp, kBackup_edi));
587 __ mov(esi, Operand(ebp, kBackup_esi));
588
589 __ bind(&retry_preempt);
590 // simulate stack for Runtime call.
591 __ push(eax);
592 __ push(Immediate(Smi::FromInt(0))); // Dummy receiver
593 __ CallRuntime(Runtime::kStackGuard, 1);
594 __ pop(eax);
595
596 __ cmp(esp, Operand::StaticVariable(stack_guard_limit));
597 __ j(below_equal, &retry_preempt);
598
599 __ pop(edx);
600 __ pop(edi);
601 __ mov(esi, Operand(ebp, kInputBuffer));
602 __ mov(esi, Operand(esi, 0));
603 __ add(esi, Operand(ebp, kInputEndOffset));
604
605 __ bind(&no_preempt);
606 }
607 }
608
609
579 void RegExpMacroAssemblerIA32::RecordRegister(int register_index) { 610 void RegExpMacroAssemblerIA32::RecordRegister(int register_index) {
580 if (register_index >= num_registers_) { 611 if (register_index >= num_registers_) {
581 num_registers_ = register_index + 1; 612 num_registers_ = register_index + 1;
582 } 613 }
583 } 614 }
584 615
585 616
586 void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) { 617 void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) {
587 if (mode_ == ASCII) { 618 if (mode_ == ASCII) {
588 __ movzx_b(destination, Operand(esi, edi, times_1, offset)); 619 __ movzx_b(destination, Operand(esi, edi, times_1, offset));
(...skipping 10 matching lines...) Expand all
599 630
600 631
601 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, 632 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg,
602 ArraySlice* buffer) { 633 ArraySlice* buffer) {
603 __ mov(reg, buffer->array()); 634 __ mov(reg, buffer->array());
604 __ add(Operand(reg), Immediate(buffer->base_offset())); 635 __ add(Operand(reg), Immediate(buffer->base_offset()));
605 } 636 }
606 637
607 #undef __ 638 #undef __
608 }} 639 }}
OLDNEW
« no previous file with comments | « src/regexp-macro-assembler-ia32.h ('k') | test/cctest/cctest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698