| 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 |