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