OLD | NEW |
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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/log.h" | 10 #include "src/log.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 : NativeRegExpMacroAssembler(zone), | 85 : NativeRegExpMacroAssembler(zone), |
86 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), | 86 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), |
87 mode_(mode), | 87 mode_(mode), |
88 num_registers_(registers_to_save), | 88 num_registers_(registers_to_save), |
89 num_saved_registers_(registers_to_save), | 89 num_saved_registers_(registers_to_save), |
90 entry_label_(), | 90 entry_label_(), |
91 start_label_(), | 91 start_label_(), |
92 success_label_(), | 92 success_label_(), |
93 backtrack_label_(), | 93 backtrack_label_(), |
94 exit_label_() { | 94 exit_label_() { |
95 ASSERT_EQ(0, registers_to_save % 2); | 95 DCHECK_EQ(0, registers_to_save % 2); |
96 __ jmp(&entry_label_); // We'll write the entry code later. | 96 __ jmp(&entry_label_); // We'll write the entry code later. |
97 __ bind(&start_label_); // And then continue from here. | 97 __ bind(&start_label_); // And then continue from here. |
98 } | 98 } |
99 | 99 |
100 | 100 |
101 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { | 101 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { |
102 delete masm_; | 102 delete masm_; |
103 // Unuse labels in case we throw away the assembler without calling GetCode. | 103 // Unuse labels in case we throw away the assembler without calling GetCode. |
104 entry_label_.Unuse(); | 104 entry_label_.Unuse(); |
105 start_label_.Unuse(); | 105 start_label_.Unuse(); |
(...skipping 11 matching lines...) Expand all Loading... |
117 | 117 |
118 | 118 |
119 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { | 119 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { |
120 if (by != 0) { | 120 if (by != 0) { |
121 __ add(edi, Immediate(by * char_size())); | 121 __ add(edi, Immediate(by * char_size())); |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 | 125 |
126 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { | 126 void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { |
127 ASSERT(reg >= 0); | 127 DCHECK(reg >= 0); |
128 ASSERT(reg < num_registers_); | 128 DCHECK(reg < num_registers_); |
129 if (by != 0) { | 129 if (by != 0) { |
130 __ add(register_location(reg), Immediate(by)); | 130 __ add(register_location(reg), Immediate(by)); |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 void RegExpMacroAssemblerIA32::Backtrack() { | 135 void RegExpMacroAssemblerIA32::Backtrack() { |
136 CheckPreemption(); | 136 CheckPreemption(); |
137 // Pop Code* offset from backtrack stack, add Code* and jump to location. | 137 // Pop Code* offset from backtrack stack, add Code* and jump to location. |
138 Pop(ebx); | 138 Pop(ebx); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 BranchOrBacktrack(no_condition, on_no_match); | 275 BranchOrBacktrack(no_condition, on_no_match); |
276 | 276 |
277 __ bind(&success); | 277 __ bind(&success); |
278 // Restore original value before continuing. | 278 // Restore original value before continuing. |
279 __ pop(backtrack_stackpointer()); | 279 __ pop(backtrack_stackpointer()); |
280 // Drop original value of character position. | 280 // Drop original value of character position. |
281 __ add(esp, Immediate(kPointerSize)); | 281 __ add(esp, Immediate(kPointerSize)); |
282 // Compute new value of character position after the matched part. | 282 // Compute new value of character position after the matched part. |
283 __ sub(edi, esi); | 283 __ sub(edi, esi); |
284 } else { | 284 } else { |
285 ASSERT(mode_ == UC16); | 285 DCHECK(mode_ == UC16); |
286 // Save registers before calling C function. | 286 // Save registers before calling C function. |
287 __ push(esi); | 287 __ push(esi); |
288 __ push(edi); | 288 __ push(edi); |
289 __ push(backtrack_stackpointer()); | 289 __ push(backtrack_stackpointer()); |
290 __ push(ebx); | 290 __ push(ebx); |
291 | 291 |
292 static const int argument_count = 4; | 292 static const int argument_count = 4; |
293 __ PrepareCallCFunction(argument_count, ecx); | 293 __ PrepareCallCFunction(argument_count, ecx); |
294 // Put arguments into allocated stack area, last argument highest on stack. | 294 // Put arguments into allocated stack area, last argument highest on stack. |
295 // Parameters are | 295 // Parameters are |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match. | 363 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match. |
364 __ add(edx, esi); // Start of capture. | 364 __ add(edx, esi); // Start of capture. |
365 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match | 365 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match |
366 | 366 |
367 Label loop; | 367 Label loop; |
368 __ bind(&loop); | 368 __ bind(&loop); |
369 if (mode_ == ASCII) { | 369 if (mode_ == ASCII) { |
370 __ movzx_b(eax, Operand(edx, 0)); | 370 __ movzx_b(eax, Operand(edx, 0)); |
371 __ cmpb_al(Operand(ebx, 0)); | 371 __ cmpb_al(Operand(ebx, 0)); |
372 } else { | 372 } else { |
373 ASSERT(mode_ == UC16); | 373 DCHECK(mode_ == UC16); |
374 __ movzx_w(eax, Operand(edx, 0)); | 374 __ movzx_w(eax, Operand(edx, 0)); |
375 __ cmpw_ax(Operand(ebx, 0)); | 375 __ cmpw_ax(Operand(ebx, 0)); |
376 } | 376 } |
377 __ j(not_equal, &fail); | 377 __ j(not_equal, &fail); |
378 // Increment pointers into capture and match string. | 378 // Increment pointers into capture and match string. |
379 __ add(edx, Immediate(char_size())); | 379 __ add(edx, Immediate(char_size())); |
380 __ add(ebx, Immediate(char_size())); | 380 __ add(ebx, Immediate(char_size())); |
381 // Check if we have reached end of match area. | 381 // Check if we have reached end of match area. |
382 __ cmp(ebx, ecx); | 382 __ cmp(ebx, ecx); |
383 __ j(below, &loop); | 383 __ j(below, &loop); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 } | 432 } |
433 BranchOrBacktrack(not_equal, on_not_equal); | 433 BranchOrBacktrack(not_equal, on_not_equal); |
434 } | 434 } |
435 | 435 |
436 | 436 |
437 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd( | 437 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd( |
438 uc16 c, | 438 uc16 c, |
439 uc16 minus, | 439 uc16 minus, |
440 uc16 mask, | 440 uc16 mask, |
441 Label* on_not_equal) { | 441 Label* on_not_equal) { |
442 ASSERT(minus < String::kMaxUtf16CodeUnit); | 442 DCHECK(minus < String::kMaxUtf16CodeUnit); |
443 __ lea(eax, Operand(current_character(), -minus)); | 443 __ lea(eax, Operand(current_character(), -minus)); |
444 if (c == 0) { | 444 if (c == 0) { |
445 __ test(eax, Immediate(mask)); | 445 __ test(eax, Immediate(mask)); |
446 } else { | 446 } else { |
447 __ and_(eax, mask); | 447 __ and_(eax, mask); |
448 __ cmp(eax, c); | 448 __ cmp(eax, c); |
449 } | 449 } |
450 BranchOrBacktrack(not_equal, on_not_equal); | 450 BranchOrBacktrack(not_equal, on_not_equal); |
451 } | 451 } |
452 | 452 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 BranchOrBacktrack(below_equal, on_no_match); | 541 BranchOrBacktrack(below_equal, on_no_match); |
542 } | 542 } |
543 return true; | 543 return true; |
544 } | 544 } |
545 case 'w': { | 545 case 'w': { |
546 if (mode_ != ASCII) { | 546 if (mode_ != ASCII) { |
547 // Table is 128 entries, so all ASCII characters can be tested. | 547 // Table is 128 entries, so all ASCII characters can be tested. |
548 __ cmp(current_character(), Immediate('z')); | 548 __ cmp(current_character(), Immediate('z')); |
549 BranchOrBacktrack(above, on_no_match); | 549 BranchOrBacktrack(above, on_no_match); |
550 } | 550 } |
551 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. | 551 DCHECK_EQ(0, word_character_map[0]); // Character '\0' is not a word char. |
552 ExternalReference word_map = ExternalReference::re_word_character_map(); | 552 ExternalReference word_map = ExternalReference::re_word_character_map(); |
553 __ test_b(current_character(), | 553 __ test_b(current_character(), |
554 Operand::StaticArray(current_character(), times_1, word_map)); | 554 Operand::StaticArray(current_character(), times_1, word_map)); |
555 BranchOrBacktrack(zero, on_no_match); | 555 BranchOrBacktrack(zero, on_no_match); |
556 return true; | 556 return true; |
557 } | 557 } |
558 case 'W': { | 558 case 'W': { |
559 Label done; | 559 Label done; |
560 if (mode_ != ASCII) { | 560 if (mode_ != ASCII) { |
561 // Table is 128 entries, so all ASCII characters can be tested. | 561 // Table is 128 entries, so all ASCII characters can be tested. |
562 __ cmp(current_character(), Immediate('z')); | 562 __ cmp(current_character(), Immediate('z')); |
563 __ j(above, &done); | 563 __ j(above, &done); |
564 } | 564 } |
565 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. | 565 DCHECK_EQ(0, word_character_map[0]); // Character '\0' is not a word char. |
566 ExternalReference word_map = ExternalReference::re_word_character_map(); | 566 ExternalReference word_map = ExternalReference::re_word_character_map(); |
567 __ test_b(current_character(), | 567 __ test_b(current_character(), |
568 Operand::StaticArray(current_character(), times_1, word_map)); | 568 Operand::StaticArray(current_character(), times_1, word_map)); |
569 BranchOrBacktrack(not_zero, on_no_match); | 569 BranchOrBacktrack(not_zero, on_no_match); |
570 if (mode_ != ASCII) { | 570 if (mode_ != ASCII) { |
571 __ bind(&done); | 571 __ bind(&done); |
572 } | 572 } |
573 return true; | 573 return true; |
574 } | 574 } |
575 // Non-standard classes (with no syntactic shorthand) used internally. | 575 // Non-standard classes (with no syntactic shorthand) used internally. |
576 case '*': | 576 case '*': |
577 // Match any character. | 577 // Match any character. |
578 return true; | 578 return true; |
579 case 'n': { | 579 case 'n': { |
580 // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 or 0x2029). | 580 // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 or 0x2029). |
581 // The opposite of '.'. | 581 // The opposite of '.'. |
582 __ mov(eax, current_character()); | 582 __ mov(eax, current_character()); |
583 __ xor_(eax, Immediate(0x01)); | 583 __ xor_(eax, Immediate(0x01)); |
584 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c | 584 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c |
585 __ sub(eax, Immediate(0x0b)); | 585 __ sub(eax, Immediate(0x0b)); |
586 __ cmp(eax, 0x0c - 0x0b); | 586 __ cmp(eax, 0x0c - 0x0b); |
587 if (mode_ == ASCII) { | 587 if (mode_ == ASCII) { |
588 BranchOrBacktrack(above, on_no_match); | 588 BranchOrBacktrack(above, on_no_match); |
589 } else { | 589 } else { |
590 Label done; | 590 Label done; |
591 BranchOrBacktrack(below_equal, &done); | 591 BranchOrBacktrack(below_equal, &done); |
592 ASSERT_EQ(UC16, mode_); | 592 DCHECK_EQ(UC16, mode_); |
593 // Compare original value to 0x2028 and 0x2029, using the already | 593 // Compare original value to 0x2028 and 0x2029, using the already |
594 // computed (current_char ^ 0x01 - 0x0b). I.e., check for | 594 // computed (current_char ^ 0x01 - 0x0b). I.e., check for |
595 // 0x201d (0x2028 - 0x0b) or 0x201e. | 595 // 0x201d (0x2028 - 0x0b) or 0x201e. |
596 __ sub(eax, Immediate(0x2028 - 0x0b)); | 596 __ sub(eax, Immediate(0x2028 - 0x0b)); |
597 __ cmp(eax, 1); | 597 __ cmp(eax, 1); |
598 BranchOrBacktrack(above, on_no_match); | 598 BranchOrBacktrack(above, on_no_match); |
599 __ bind(&done); | 599 __ bind(&done); |
600 } | 600 } |
601 return true; | 601 return true; |
602 } | 602 } |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 RegExpMacroAssembler::IrregexpImplementation | 940 RegExpMacroAssembler::IrregexpImplementation |
941 RegExpMacroAssemblerIA32::Implementation() { | 941 RegExpMacroAssemblerIA32::Implementation() { |
942 return kIA32Implementation; | 942 return kIA32Implementation; |
943 } | 943 } |
944 | 944 |
945 | 945 |
946 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, | 946 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, |
947 Label* on_end_of_input, | 947 Label* on_end_of_input, |
948 bool check_bounds, | 948 bool check_bounds, |
949 int characters) { | 949 int characters) { |
950 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. | 950 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. |
951 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 951 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
952 if (check_bounds) { | 952 if (check_bounds) { |
953 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 953 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
954 } | 954 } |
955 LoadCurrentCharacterUnchecked(cp_offset, characters); | 955 LoadCurrentCharacterUnchecked(cp_offset, characters); |
956 } | 956 } |
957 | 957 |
958 | 958 |
959 void RegExpMacroAssemblerIA32::PopCurrentPosition() { | 959 void RegExpMacroAssemblerIA32::PopCurrentPosition() { |
960 Pop(edi); | 960 Pop(edi); |
961 } | 961 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 __ mov(edi, -by * char_size()); | 1003 __ mov(edi, -by * char_size()); |
1004 // On RegExp code entry (where this operation is used), the character before | 1004 // On RegExp code entry (where this operation is used), the character before |
1005 // the current position is expected to be already loaded. | 1005 // the current position is expected to be already loaded. |
1006 // We have advanced the position, so it's safe to read backwards. | 1006 // We have advanced the position, so it's safe to read backwards. |
1007 LoadCurrentCharacterUnchecked(-1, 1); | 1007 LoadCurrentCharacterUnchecked(-1, 1); |
1008 __ bind(&after_position); | 1008 __ bind(&after_position); |
1009 } | 1009 } |
1010 | 1010 |
1011 | 1011 |
1012 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) { | 1012 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) { |
1013 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! | 1013 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! |
1014 __ mov(register_location(register_index), Immediate(to)); | 1014 __ mov(register_location(register_index), Immediate(to)); |
1015 } | 1015 } |
1016 | 1016 |
1017 | 1017 |
1018 bool RegExpMacroAssemblerIA32::Succeed() { | 1018 bool RegExpMacroAssemblerIA32::Succeed() { |
1019 __ jmp(&success_label_); | 1019 __ jmp(&success_label_); |
1020 return global(); | 1020 return global(); |
1021 } | 1021 } |
1022 | 1022 |
1023 | 1023 |
1024 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg, | 1024 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg, |
1025 int cp_offset) { | 1025 int cp_offset) { |
1026 if (cp_offset == 0) { | 1026 if (cp_offset == 0) { |
1027 __ mov(register_location(reg), edi); | 1027 __ mov(register_location(reg), edi); |
1028 } else { | 1028 } else { |
1029 __ lea(eax, Operand(edi, cp_offset * char_size())); | 1029 __ lea(eax, Operand(edi, cp_offset * char_size())); |
1030 __ mov(register_location(reg), eax); | 1030 __ mov(register_location(reg), eax); |
1031 } | 1031 } |
1032 } | 1032 } |
1033 | 1033 |
1034 | 1034 |
1035 void RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) { | 1035 void RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) { |
1036 ASSERT(reg_from <= reg_to); | 1036 DCHECK(reg_from <= reg_to); |
1037 __ mov(eax, Operand(ebp, kInputStartMinusOne)); | 1037 __ mov(eax, Operand(ebp, kInputStartMinusOne)); |
1038 for (int reg = reg_from; reg <= reg_to; reg++) { | 1038 for (int reg = reg_from; reg <= reg_to; reg++) { |
1039 __ mov(register_location(reg), eax); | 1039 __ mov(register_location(reg), eax); |
1040 } | 1040 } |
1041 } | 1041 } |
1042 | 1042 |
1043 | 1043 |
1044 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { | 1044 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { |
1045 __ mov(eax, backtrack_stackpointer()); | 1045 __ mov(eax, backtrack_stackpointer()); |
1046 __ sub(eax, Operand(ebp, kStackHighEnd)); | 1046 __ sub(eax, Operand(ebp, kStackHighEnd)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 | 1094 |
1095 // Prepare for possible GC. | 1095 // Prepare for possible GC. |
1096 HandleScope handles(isolate); | 1096 HandleScope handles(isolate); |
1097 Handle<Code> code_handle(re_code); | 1097 Handle<Code> code_handle(re_code); |
1098 | 1098 |
1099 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); | 1099 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); |
1100 | 1100 |
1101 // Current string. | 1101 // Current string. |
1102 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); | 1102 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); |
1103 | 1103 |
1104 ASSERT(re_code->instruction_start() <= *return_address); | 1104 DCHECK(re_code->instruction_start() <= *return_address); |
1105 ASSERT(*return_address <= | 1105 DCHECK(*return_address <= |
1106 re_code->instruction_start() + re_code->instruction_size()); | 1106 re_code->instruction_start() + re_code->instruction_size()); |
1107 | 1107 |
1108 Object* result = isolate->stack_guard()->HandleInterrupts(); | 1108 Object* result = isolate->stack_guard()->HandleInterrupts(); |
1109 | 1109 |
1110 if (*code_handle != re_code) { // Return address no longer valid | 1110 if (*code_handle != re_code) { // Return address no longer valid |
1111 int delta = code_handle->address() - re_code->address(); | 1111 int delta = code_handle->address() - re_code->address(); |
1112 // Overwrite the return address on the stack. | 1112 // Overwrite the return address on the stack. |
1113 *return_address += delta; | 1113 *return_address += delta; |
1114 } | 1114 } |
1115 | 1115 |
(...skipping 18 matching lines...) Expand all Loading... |
1134 // If we changed between an ASCII and an UC16 string, the specialized | 1134 // If we changed between an ASCII and an UC16 string, the specialized |
1135 // code cannot be used, and we need to restart regexp matching from | 1135 // code cannot be used, and we need to restart regexp matching from |
1136 // scratch (including, potentially, compiling a new version of the code). | 1136 // scratch (including, potentially, compiling a new version of the code). |
1137 return RETRY; | 1137 return RETRY; |
1138 } | 1138 } |
1139 | 1139 |
1140 // Otherwise, the content of the string might have moved. It must still | 1140 // Otherwise, the content of the string might have moved. It must still |
1141 // be a sequential or external string with the same content. | 1141 // be a sequential or external string with the same content. |
1142 // Update the start and end pointers in the stack frame to the current | 1142 // Update the start and end pointers in the stack frame to the current |
1143 // location (whether it has actually moved or not). | 1143 // location (whether it has actually moved or not). |
1144 ASSERT(StringShape(*subject_tmp).IsSequential() || | 1144 DCHECK(StringShape(*subject_tmp).IsSequential() || |
1145 StringShape(*subject_tmp).IsExternal()); | 1145 StringShape(*subject_tmp).IsExternal()); |
1146 | 1146 |
1147 // The original start address of the characters to match. | 1147 // The original start address of the characters to match. |
1148 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); | 1148 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); |
1149 | 1149 |
1150 // Find the current start address of the same character at the current string | 1150 // Find the current start address of the same character at the current string |
1151 // position. | 1151 // position. |
1152 int start_index = frame_entry<int>(re_frame, kStartIndex); | 1152 int start_index = frame_entry<int>(re_frame, kStartIndex); |
1153 const byte* new_address = StringCharacterPosition(*subject_tmp, | 1153 const byte* new_address = StringCharacterPosition(*subject_tmp, |
1154 start_index + slice_offset); | 1154 start_index + slice_offset); |
(...skipping 11 matching lines...) Expand all Loading... |
1166 // short-circuiting during GC. That will not change start_address but | 1166 // short-circuiting during GC. That will not change start_address but |
1167 // will change pointer inside the subject handle. | 1167 // will change pointer inside the subject handle. |
1168 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1168 frame_entry<const String*>(re_frame, kInputString) = *subject; |
1169 } | 1169 } |
1170 | 1170 |
1171 return 0; | 1171 return 0; |
1172 } | 1172 } |
1173 | 1173 |
1174 | 1174 |
1175 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { | 1175 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { |
1176 ASSERT(register_index < (1<<30)); | 1176 DCHECK(register_index < (1<<30)); |
1177 if (num_registers_ <= register_index) { | 1177 if (num_registers_ <= register_index) { |
1178 num_registers_ = register_index + 1; | 1178 num_registers_ = register_index + 1; |
1179 } | 1179 } |
1180 return Operand(ebp, kRegisterZero - register_index * kPointerSize); | 1180 return Operand(ebp, kRegisterZero - register_index * kPointerSize); |
1181 } | 1181 } |
1182 | 1182 |
1183 | 1183 |
1184 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, | 1184 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, |
1185 Label* on_outside_input) { | 1185 Label* on_outside_input) { |
1186 __ cmp(edi, -cp_offset * char_size()); | 1186 __ cmp(edi, -cp_offset * char_size()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 __ jmp(ebx); | 1220 __ jmp(ebx); |
1221 } | 1221 } |
1222 | 1222 |
1223 | 1223 |
1224 void RegExpMacroAssemblerIA32::SafeCallTarget(Label* name) { | 1224 void RegExpMacroAssemblerIA32::SafeCallTarget(Label* name) { |
1225 __ bind(name); | 1225 __ bind(name); |
1226 } | 1226 } |
1227 | 1227 |
1228 | 1228 |
1229 void RegExpMacroAssemblerIA32::Push(Register source) { | 1229 void RegExpMacroAssemblerIA32::Push(Register source) { |
1230 ASSERT(!source.is(backtrack_stackpointer())); | 1230 DCHECK(!source.is(backtrack_stackpointer())); |
1231 // Notice: This updates flags, unlike normal Push. | 1231 // Notice: This updates flags, unlike normal Push. |
1232 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); | 1232 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); |
1233 __ mov(Operand(backtrack_stackpointer(), 0), source); | 1233 __ mov(Operand(backtrack_stackpointer(), 0), source); |
1234 } | 1234 } |
1235 | 1235 |
1236 | 1236 |
1237 void RegExpMacroAssemblerIA32::Push(Immediate value) { | 1237 void RegExpMacroAssemblerIA32::Push(Immediate value) { |
1238 // Notice: This updates flags, unlike normal Push. | 1238 // Notice: This updates flags, unlike normal Push. |
1239 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); | 1239 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); |
1240 __ mov(Operand(backtrack_stackpointer(), 0), value); | 1240 __ mov(Operand(backtrack_stackpointer(), 0), value); |
1241 } | 1241 } |
1242 | 1242 |
1243 | 1243 |
1244 void RegExpMacroAssemblerIA32::Pop(Register target) { | 1244 void RegExpMacroAssemblerIA32::Pop(Register target) { |
1245 ASSERT(!target.is(backtrack_stackpointer())); | 1245 DCHECK(!target.is(backtrack_stackpointer())); |
1246 __ mov(target, Operand(backtrack_stackpointer(), 0)); | 1246 __ mov(target, Operand(backtrack_stackpointer(), 0)); |
1247 // Notice: This updates flags, unlike normal Pop. | 1247 // Notice: This updates flags, unlike normal Pop. |
1248 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); | 1248 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); |
1249 } | 1249 } |
1250 | 1250 |
1251 | 1251 |
1252 void RegExpMacroAssemblerIA32::CheckPreemption() { | 1252 void RegExpMacroAssemblerIA32::CheckPreemption() { |
1253 // Check for preemption. | 1253 // Check for preemption. |
1254 Label no_preempt; | 1254 Label no_preempt; |
1255 ExternalReference stack_limit = | 1255 ExternalReference stack_limit = |
(...skipping 21 matching lines...) Expand all Loading... |
1277 | 1277 |
1278 | 1278 |
1279 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, | 1279 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, |
1280 int characters) { | 1280 int characters) { |
1281 if (mode_ == ASCII) { | 1281 if (mode_ == ASCII) { |
1282 if (characters == 4) { | 1282 if (characters == 4) { |
1283 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1283 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1284 } else if (characters == 2) { | 1284 } else if (characters == 2) { |
1285 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1285 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1286 } else { | 1286 } else { |
1287 ASSERT(characters == 1); | 1287 DCHECK(characters == 1); |
1288 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1288 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1289 } | 1289 } |
1290 } else { | 1290 } else { |
1291 ASSERT(mode_ == UC16); | 1291 DCHECK(mode_ == UC16); |
1292 if (characters == 2) { | 1292 if (characters == 2) { |
1293 __ mov(current_character(), | 1293 __ mov(current_character(), |
1294 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); | 1294 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); |
1295 } else { | 1295 } else { |
1296 ASSERT(characters == 1); | 1296 DCHECK(characters == 1); |
1297 __ movzx_w(current_character(), | 1297 __ movzx_w(current_character(), |
1298 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); | 1298 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); |
1299 } | 1299 } |
1300 } | 1300 } |
1301 } | 1301 } |
1302 | 1302 |
1303 | 1303 |
1304 #undef __ | 1304 #undef __ |
1305 | 1305 |
1306 #endif // V8_INTERPRETED_REGEXP | 1306 #endif // V8_INTERPRETED_REGEXP |
1307 | 1307 |
1308 }} // namespace v8::internal | 1308 }} // namespace v8::internal |
1309 | 1309 |
1310 #endif // V8_TARGET_ARCH_IA32 | 1310 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |