| 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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
| 8 | 8 |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/log.h" | 10 #include "src/log.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), | 103 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), |
| 104 mode_(mode), | 104 mode_(mode), |
| 105 num_registers_(registers_to_save), | 105 num_registers_(registers_to_save), |
| 106 num_saved_registers_(registers_to_save), | 106 num_saved_registers_(registers_to_save), |
| 107 entry_label_(), | 107 entry_label_(), |
| 108 start_label_(), | 108 start_label_(), |
| 109 success_label_(), | 109 success_label_(), |
| 110 backtrack_label_(), | 110 backtrack_label_(), |
| 111 exit_label_(), | 111 exit_label_(), |
| 112 internal_failure_label_() { | 112 internal_failure_label_() { |
| 113 ASSERT_EQ(0, registers_to_save % 2); | 113 DCHECK_EQ(0, registers_to_save % 2); |
| 114 __ jmp(&entry_label_); // We'll write the entry code later. | 114 __ jmp(&entry_label_); // We'll write the entry code later. |
| 115 // If the code gets too big or corrupted, an internal exception will be | 115 // If the code gets too big or corrupted, an internal exception will be |
| 116 // raised, and we will exit right away. | 116 // raised, and we will exit right away. |
| 117 __ bind(&internal_failure_label_); | 117 __ bind(&internal_failure_label_); |
| 118 __ li(v0, Operand(FAILURE)); | 118 __ li(v0, Operand(FAILURE)); |
| 119 __ Ret(); | 119 __ Ret(); |
| 120 __ bind(&start_label_); // And then continue from here. | 120 __ bind(&start_label_); // And then continue from here. |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 142 | 142 |
| 143 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { | 143 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { |
| 144 if (by != 0) { | 144 if (by != 0) { |
| 145 __ Addu(current_input_offset(), | 145 __ Addu(current_input_offset(), |
| 146 current_input_offset(), Operand(by * char_size())); | 146 current_input_offset(), Operand(by * char_size())); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { | 151 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { |
| 152 ASSERT(reg >= 0); | 152 DCHECK(reg >= 0); |
| 153 ASSERT(reg < num_registers_); | 153 DCHECK(reg < num_registers_); |
| 154 if (by != 0) { | 154 if (by != 0) { |
| 155 __ lw(a0, register_location(reg)); | 155 __ lw(a0, register_location(reg)); |
| 156 __ Addu(a0, a0, Operand(by)); | 156 __ Addu(a0, a0, Operand(by)); |
| 157 __ sw(a0, register_location(reg)); | 157 __ sw(a0, register_location(reg)); |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 void RegExpMacroAssemblerMIPS::Backtrack() { | 162 void RegExpMacroAssemblerMIPS::Backtrack() { |
| 163 CheckPreemption(); | 163 CheckPreemption(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 __ Branch(&loop, lt, a0, Operand(a1)); | 282 __ Branch(&loop, lt, a0, Operand(a1)); |
| 283 __ jmp(&success); | 283 __ jmp(&success); |
| 284 | 284 |
| 285 __ bind(&fail); | 285 __ bind(&fail); |
| 286 GoTo(on_no_match); | 286 GoTo(on_no_match); |
| 287 | 287 |
| 288 __ bind(&success); | 288 __ bind(&success); |
| 289 // Compute new value of character position after the matched part. | 289 // Compute new value of character position after the matched part. |
| 290 __ Subu(current_input_offset(), a2, end_of_input_address()); | 290 __ Subu(current_input_offset(), a2, end_of_input_address()); |
| 291 } else { | 291 } else { |
| 292 ASSERT(mode_ == UC16); | 292 DCHECK(mode_ == UC16); |
| 293 // Put regexp engine registers on stack. | 293 // Put regexp engine registers on stack. |
| 294 RegList regexp_registers_to_retain = current_input_offset().bit() | | 294 RegList regexp_registers_to_retain = current_input_offset().bit() | |
| 295 current_character().bit() | backtrack_stackpointer().bit(); | 295 current_character().bit() | backtrack_stackpointer().bit(); |
| 296 __ MultiPush(regexp_registers_to_retain); | 296 __ MultiPush(regexp_registers_to_retain); |
| 297 | 297 |
| 298 int argument_count = 4; | 298 int argument_count = 4; |
| 299 __ PrepareCallCFunction(argument_count, a2); | 299 __ PrepareCallCFunction(argument_count, a2); |
| 300 | 300 |
| 301 // a0 - offset of start of capture. | 301 // a0 - offset of start of capture. |
| 302 // a1 - length of capture. | 302 // a1 - length of capture. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 __ Addu(a1, a1, Operand(a0)); | 364 __ Addu(a1, a1, Operand(a0)); |
| 365 | 365 |
| 366 Label loop; | 366 Label loop; |
| 367 __ bind(&loop); | 367 __ bind(&loop); |
| 368 if (mode_ == ASCII) { | 368 if (mode_ == ASCII) { |
| 369 __ lbu(a3, MemOperand(a0, 0)); | 369 __ lbu(a3, MemOperand(a0, 0)); |
| 370 __ addiu(a0, a0, char_size()); | 370 __ addiu(a0, a0, char_size()); |
| 371 __ lbu(t0, MemOperand(a2, 0)); | 371 __ lbu(t0, MemOperand(a2, 0)); |
| 372 __ addiu(a2, a2, char_size()); | 372 __ addiu(a2, a2, char_size()); |
| 373 } else { | 373 } else { |
| 374 ASSERT(mode_ == UC16); | 374 DCHECK(mode_ == UC16); |
| 375 __ lhu(a3, MemOperand(a0, 0)); | 375 __ lhu(a3, MemOperand(a0, 0)); |
| 376 __ addiu(a0, a0, char_size()); | 376 __ addiu(a0, a0, char_size()); |
| 377 __ lhu(t0, MemOperand(a2, 0)); | 377 __ lhu(t0, MemOperand(a2, 0)); |
| 378 __ addiu(a2, a2, char_size()); | 378 __ addiu(a2, a2, char_size()); |
| 379 } | 379 } |
| 380 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0)); | 380 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0)); |
| 381 __ Branch(&loop, lt, a0, Operand(a1)); | 381 __ Branch(&loop, lt, a0, Operand(a1)); |
| 382 | 382 |
| 383 // Move current character position to position after match. | 383 // Move current character position to position after match. |
| 384 __ Subu(current_input_offset(), a2, end_of_input_address()); | 384 __ Subu(current_input_offset(), a2, end_of_input_address()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 408 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); | 408 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); |
| 409 BranchOrBacktrack(on_not_equal, ne, a0, rhs); | 409 BranchOrBacktrack(on_not_equal, ne, a0, rhs); |
| 410 } | 410 } |
| 411 | 411 |
| 412 | 412 |
| 413 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( | 413 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( |
| 414 uc16 c, | 414 uc16 c, |
| 415 uc16 minus, | 415 uc16 minus, |
| 416 uc16 mask, | 416 uc16 mask, |
| 417 Label* on_not_equal) { | 417 Label* on_not_equal) { |
| 418 ASSERT(minus < String::kMaxUtf16CodeUnit); | 418 DCHECK(minus < String::kMaxUtf16CodeUnit); |
| 419 __ Subu(a0, current_character(), Operand(minus)); | 419 __ Subu(a0, current_character(), Operand(minus)); |
| 420 __ And(a0, a0, Operand(mask)); | 420 __ And(a0, a0, Operand(mask)); |
| 421 BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); | 421 BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); |
| 422 } | 422 } |
| 423 | 423 |
| 424 | 424 |
| 425 void RegExpMacroAssemblerMIPS::CheckCharacterInRange( | 425 void RegExpMacroAssemblerMIPS::CheckCharacterInRange( |
| 426 uc16 from, | 426 uc16 from, |
| 427 uc16 to, | 427 uc16 to, |
| 428 Label* on_in_range) { | 428 Label* on_in_range) { |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 __ lw(a2, MemOperand(frame_pointer(), kStartIndex)); | 699 __ lw(a2, MemOperand(frame_pointer(), kStartIndex)); |
| 700 __ Subu(a1, end_of_input_address(), a1); | 700 __ Subu(a1, end_of_input_address(), a1); |
| 701 // a1 is length of input in bytes. | 701 // a1 is length of input in bytes. |
| 702 if (mode_ == UC16) { | 702 if (mode_ == UC16) { |
| 703 __ srl(a1, a1, 1); | 703 __ srl(a1, a1, 1); |
| 704 } | 704 } |
| 705 // a1 is length of input in characters. | 705 // a1 is length of input in characters. |
| 706 __ Addu(a1, a1, Operand(a2)); | 706 __ Addu(a1, a1, Operand(a2)); |
| 707 // a1 is length of string in characters. | 707 // a1 is length of string in characters. |
| 708 | 708 |
| 709 ASSERT_EQ(0, num_saved_registers_ % 2); | 709 DCHECK_EQ(0, num_saved_registers_ % 2); |
| 710 // Always an even number of capture registers. This allows us to | 710 // Always an even number of capture registers. This allows us to |
| 711 // unroll the loop once to add an operation between a load of a register | 711 // unroll the loop once to add an operation between a load of a register |
| 712 // and the following use of that register. | 712 // and the following use of that register. |
| 713 for (int i = 0; i < num_saved_registers_; i += 2) { | 713 for (int i = 0; i < num_saved_registers_; i += 2) { |
| 714 __ lw(a2, register_location(i)); | 714 __ lw(a2, register_location(i)); |
| 715 __ lw(a3, register_location(i + 1)); | 715 __ lw(a3, register_location(i + 1)); |
| 716 if (i == 0 && global_with_zero_length_check()) { | 716 if (i == 0 && global_with_zero_length_check()) { |
| 717 // Keep capture start in a4 for the zero-length check later. | 717 // Keep capture start in a4 for the zero-length check later. |
| 718 __ mov(t7, a2); | 718 __ mov(t7, a2); |
| 719 } | 719 } |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 RegExpMacroAssembler::IrregexpImplementation | 901 RegExpMacroAssembler::IrregexpImplementation |
| 902 RegExpMacroAssemblerMIPS::Implementation() { | 902 RegExpMacroAssemblerMIPS::Implementation() { |
| 903 return kMIPSImplementation; | 903 return kMIPSImplementation; |
| 904 } | 904 } |
| 905 | 905 |
| 906 | 906 |
| 907 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, | 907 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, |
| 908 Label* on_end_of_input, | 908 Label* on_end_of_input, |
| 909 bool check_bounds, | 909 bool check_bounds, |
| 910 int characters) { | 910 int characters) { |
| 911 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. | 911 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. |
| 912 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works). | 912 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works). |
| 913 if (check_bounds) { | 913 if (check_bounds) { |
| 914 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 914 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
| 915 } | 915 } |
| 916 LoadCurrentCharacterUnchecked(cp_offset, characters); | 916 LoadCurrentCharacterUnchecked(cp_offset, characters); |
| 917 } | 917 } |
| 918 | 918 |
| 919 | 919 |
| 920 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { | 920 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { |
| 921 Pop(current_input_offset()); | 921 Pop(current_input_offset()); |
| 922 } | 922 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 __ li(current_input_offset(), -by * char_size()); | 987 __ li(current_input_offset(), -by * char_size()); |
| 988 // On RegExp code entry (where this operation is used), the character before | 988 // On RegExp code entry (where this operation is used), the character before |
| 989 // the current position is expected to be already loaded. | 989 // the current position is expected to be already loaded. |
| 990 // We have advanced the position, so it's safe to read backwards. | 990 // We have advanced the position, so it's safe to read backwards. |
| 991 LoadCurrentCharacterUnchecked(-1, 1); | 991 LoadCurrentCharacterUnchecked(-1, 1); |
| 992 __ bind(&after_position); | 992 __ bind(&after_position); |
| 993 } | 993 } |
| 994 | 994 |
| 995 | 995 |
| 996 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { | 996 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { |
| 997 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! | 997 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! |
| 998 __ li(a0, Operand(to)); | 998 __ li(a0, Operand(to)); |
| 999 __ sw(a0, register_location(register_index)); | 999 __ sw(a0, register_location(register_index)); |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 | 1002 |
| 1003 bool RegExpMacroAssemblerMIPS::Succeed() { | 1003 bool RegExpMacroAssemblerMIPS::Succeed() { |
| 1004 __ jmp(&success_label_); | 1004 __ jmp(&success_label_); |
| 1005 return global(); | 1005 return global(); |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 | 1008 |
| 1009 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, | 1009 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, |
| 1010 int cp_offset) { | 1010 int cp_offset) { |
| 1011 if (cp_offset == 0) { | 1011 if (cp_offset == 0) { |
| 1012 __ sw(current_input_offset(), register_location(reg)); | 1012 __ sw(current_input_offset(), register_location(reg)); |
| 1013 } else { | 1013 } else { |
| 1014 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); | 1014 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); |
| 1015 __ sw(a0, register_location(reg)); | 1015 __ sw(a0, register_location(reg)); |
| 1016 } | 1016 } |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 | 1019 |
| 1020 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { | 1020 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { |
| 1021 ASSERT(reg_from <= reg_to); | 1021 DCHECK(reg_from <= reg_to); |
| 1022 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 1022 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
| 1023 for (int reg = reg_from; reg <= reg_to; reg++) { | 1023 for (int reg = reg_from; reg <= reg_to; reg++) { |
| 1024 __ sw(a0, register_location(reg)); | 1024 __ sw(a0, register_location(reg)); |
| 1025 } | 1025 } |
| 1026 } | 1026 } |
| 1027 | 1027 |
| 1028 | 1028 |
| 1029 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { | 1029 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { |
| 1030 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd)); | 1030 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd)); |
| 1031 __ Subu(a0, backtrack_stackpointer(), a1); | 1031 __ Subu(a0, backtrack_stackpointer(), a1); |
| 1032 __ sw(a0, register_location(reg)); | 1032 __ sw(a0, register_location(reg)); |
| 1033 } | 1033 } |
| 1034 | 1034 |
| 1035 | 1035 |
| 1036 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { | 1036 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { |
| 1037 return false; | 1037 return false; |
| 1038 } | 1038 } |
| 1039 | 1039 |
| 1040 | 1040 |
| 1041 // Private methods: | 1041 // Private methods: |
| 1042 | 1042 |
| 1043 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { | 1043 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { |
| 1044 int stack_alignment = base::OS::ActivationFrameAlignment(); | 1044 int stack_alignment = base::OS::ActivationFrameAlignment(); |
| 1045 | 1045 |
| 1046 // Align the stack pointer and save the original sp value on the stack. | 1046 // Align the stack pointer and save the original sp value on the stack. |
| 1047 __ mov(scratch, sp); | 1047 __ mov(scratch, sp); |
| 1048 __ Subu(sp, sp, Operand(kPointerSize)); | 1048 __ Subu(sp, sp, Operand(kPointerSize)); |
| 1049 ASSERT(IsPowerOf2(stack_alignment)); | 1049 DCHECK(IsPowerOf2(stack_alignment)); |
| 1050 __ And(sp, sp, Operand(-stack_alignment)); | 1050 __ And(sp, sp, Operand(-stack_alignment)); |
| 1051 __ sw(scratch, MemOperand(sp)); | 1051 __ sw(scratch, MemOperand(sp)); |
| 1052 | 1052 |
| 1053 __ mov(a2, frame_pointer()); | 1053 __ mov(a2, frame_pointer()); |
| 1054 // Code* of self. | 1054 // Code* of self. |
| 1055 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); | 1055 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); |
| 1056 | 1056 |
| 1057 // We need to make room for the return address on the stack. | 1057 // We need to make room for the return address on the stack. |
| 1058 ASSERT(IsAligned(stack_alignment, kPointerSize)); | 1058 DCHECK(IsAligned(stack_alignment, kPointerSize)); |
| 1059 __ Subu(sp, sp, Operand(stack_alignment)); | 1059 __ Subu(sp, sp, Operand(stack_alignment)); |
| 1060 | 1060 |
| 1061 // Stack pointer now points to cell where return address is to be written. | 1061 // Stack pointer now points to cell where return address is to be written. |
| 1062 // Arguments are in registers, meaning we teat the return address as | 1062 // Arguments are in registers, meaning we teat the return address as |
| 1063 // argument 5. Since DirectCEntryStub will handleallocating space for the C | 1063 // argument 5. Since DirectCEntryStub will handleallocating space for the C |
| 1064 // argument slots, we don't need to care about that here. This is how the | 1064 // argument slots, we don't need to care about that here. This is how the |
| 1065 // stack will look (sp meaning the value of sp at this moment): | 1065 // stack will look (sp meaning the value of sp at this moment): |
| 1066 // [sp + 3] - empty slot if needed for alignment. | 1066 // [sp + 3] - empty slot if needed for alignment. |
| 1067 // [sp + 2] - saved sp. | 1067 // [sp + 2] - saved sp. |
| 1068 // [sp + 1] - second word reserved for return value. | 1068 // [sp + 1] - second word reserved for return value. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 } | 1121 } |
| 1122 | 1122 |
| 1123 // Prepare for possible GC. | 1123 // Prepare for possible GC. |
| 1124 HandleScope handles(isolate); | 1124 HandleScope handles(isolate); |
| 1125 Handle<Code> code_handle(re_code); | 1125 Handle<Code> code_handle(re_code); |
| 1126 | 1126 |
| 1127 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); | 1127 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); |
| 1128 // Current string. | 1128 // Current string. |
| 1129 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); | 1129 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); |
| 1130 | 1130 |
| 1131 ASSERT(re_code->instruction_start() <= *return_address); | 1131 DCHECK(re_code->instruction_start() <= *return_address); |
| 1132 ASSERT(*return_address <= | 1132 DCHECK(*return_address <= |
| 1133 re_code->instruction_start() + re_code->instruction_size()); | 1133 re_code->instruction_start() + re_code->instruction_size()); |
| 1134 | 1134 |
| 1135 Object* result = isolate->stack_guard()->HandleInterrupts(); | 1135 Object* result = isolate->stack_guard()->HandleInterrupts(); |
| 1136 | 1136 |
| 1137 if (*code_handle != re_code) { // Return address no longer valid. | 1137 if (*code_handle != re_code) { // Return address no longer valid. |
| 1138 int delta = code_handle->address() - re_code->address(); | 1138 int delta = code_handle->address() - re_code->address(); |
| 1139 // Overwrite the return address on the stack. | 1139 // Overwrite the return address on the stack. |
| 1140 *return_address += delta; | 1140 *return_address += delta; |
| 1141 } | 1141 } |
| 1142 | 1142 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1161 // If we changed between an ASCII and an UC16 string, the specialized | 1161 // If we changed between an ASCII and an UC16 string, the specialized |
| 1162 // code cannot be used, and we need to restart regexp matching from | 1162 // code cannot be used, and we need to restart regexp matching from |
| 1163 // scratch (including, potentially, compiling a new version of the code). | 1163 // scratch (including, potentially, compiling a new version of the code). |
| 1164 return RETRY; | 1164 return RETRY; |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 // Otherwise, the content of the string might have moved. It must still | 1167 // Otherwise, the content of the string might have moved. It must still |
| 1168 // be a sequential or external string with the same content. | 1168 // be a sequential or external string with the same content. |
| 1169 // Update the start and end pointers in the stack frame to the current | 1169 // Update the start and end pointers in the stack frame to the current |
| 1170 // location (whether it has actually moved or not). | 1170 // location (whether it has actually moved or not). |
| 1171 ASSERT(StringShape(*subject_tmp).IsSequential() || | 1171 DCHECK(StringShape(*subject_tmp).IsSequential() || |
| 1172 StringShape(*subject_tmp).IsExternal()); | 1172 StringShape(*subject_tmp).IsExternal()); |
| 1173 | 1173 |
| 1174 // The original start address of the characters to match. | 1174 // The original start address of the characters to match. |
| 1175 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); | 1175 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); |
| 1176 | 1176 |
| 1177 // Find the current start address of the same character at the current string | 1177 // Find the current start address of the same character at the current string |
| 1178 // position. | 1178 // position. |
| 1179 int start_index = frame_entry<int>(re_frame, kStartIndex); | 1179 int start_index = frame_entry<int>(re_frame, kStartIndex); |
| 1180 const byte* new_address = StringCharacterPosition(*subject_tmp, | 1180 const byte* new_address = StringCharacterPosition(*subject_tmp, |
| 1181 start_index + slice_offset); | 1181 start_index + slice_offset); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1193 // short-circuiting during GC. That will not change start_address but | 1193 // short-circuiting during GC. That will not change start_address but |
| 1194 // will change pointer inside the subject handle. | 1194 // will change pointer inside the subject handle. |
| 1195 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1195 frame_entry<const String*>(re_frame, kInputString) = *subject; |
| 1196 } | 1196 } |
| 1197 | 1197 |
| 1198 return 0; | 1198 return 0; |
| 1199 } | 1199 } |
| 1200 | 1200 |
| 1201 | 1201 |
| 1202 MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { | 1202 MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { |
| 1203 ASSERT(register_index < (1<<30)); | 1203 DCHECK(register_index < (1<<30)); |
| 1204 if (num_registers_ <= register_index) { | 1204 if (num_registers_ <= register_index) { |
| 1205 num_registers_ = register_index + 1; | 1205 num_registers_ = register_index + 1; |
| 1206 } | 1206 } |
| 1207 return MemOperand(frame_pointer(), | 1207 return MemOperand(frame_pointer(), |
| 1208 kRegisterZero - register_index * kPointerSize); | 1208 kRegisterZero - register_index * kPointerSize); |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 | 1211 |
| 1212 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, | 1212 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, |
| 1213 Label* on_outside_input) { | 1213 Label* on_outside_input) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 | 1254 |
| 1255 | 1255 |
| 1256 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { | 1256 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { |
| 1257 __ bind(name); | 1257 __ bind(name); |
| 1258 __ Subu(ra, ra, Operand(masm_->CodeObject())); | 1258 __ Subu(ra, ra, Operand(masm_->CodeObject())); |
| 1259 __ push(ra); | 1259 __ push(ra); |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 | 1262 |
| 1263 void RegExpMacroAssemblerMIPS::Push(Register source) { | 1263 void RegExpMacroAssemblerMIPS::Push(Register source) { |
| 1264 ASSERT(!source.is(backtrack_stackpointer())); | 1264 DCHECK(!source.is(backtrack_stackpointer())); |
| 1265 __ Addu(backtrack_stackpointer(), | 1265 __ Addu(backtrack_stackpointer(), |
| 1266 backtrack_stackpointer(), | 1266 backtrack_stackpointer(), |
| 1267 Operand(-kPointerSize)); | 1267 Operand(-kPointerSize)); |
| 1268 __ sw(source, MemOperand(backtrack_stackpointer())); | 1268 __ sw(source, MemOperand(backtrack_stackpointer())); |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 | 1271 |
| 1272 void RegExpMacroAssemblerMIPS::Pop(Register target) { | 1272 void RegExpMacroAssemblerMIPS::Pop(Register target) { |
| 1273 ASSERT(!target.is(backtrack_stackpointer())); | 1273 DCHECK(!target.is(backtrack_stackpointer())); |
| 1274 __ lw(target, MemOperand(backtrack_stackpointer())); | 1274 __ lw(target, MemOperand(backtrack_stackpointer())); |
| 1275 __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), kPointerSize); | 1275 __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), kPointerSize); |
| 1276 } | 1276 } |
| 1277 | 1277 |
| 1278 | 1278 |
| 1279 void RegExpMacroAssemblerMIPS::CheckPreemption() { | 1279 void RegExpMacroAssemblerMIPS::CheckPreemption() { |
| 1280 // Check for preemption. | 1280 // Check for preemption. |
| 1281 ExternalReference stack_limit = | 1281 ExternalReference stack_limit = |
| 1282 ExternalReference::address_of_stack_limit(masm_->isolate()); | 1282 ExternalReference::address_of_stack_limit(masm_->isolate()); |
| 1283 __ li(a0, Operand(stack_limit)); | 1283 __ li(a0, Operand(stack_limit)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1299 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, | 1299 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, |
| 1300 int characters) { | 1300 int characters) { |
| 1301 Register offset = current_input_offset(); | 1301 Register offset = current_input_offset(); |
| 1302 if (cp_offset != 0) { | 1302 if (cp_offset != 0) { |
| 1303 // t7 is not being used to store the capture start index at this point. | 1303 // t7 is not being used to store the capture start index at this point. |
| 1304 __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size())); | 1304 __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size())); |
| 1305 offset = t7; | 1305 offset = t7; |
| 1306 } | 1306 } |
| 1307 // We assume that we cannot do unaligned loads on MIPS, so this function | 1307 // We assume that we cannot do unaligned loads on MIPS, so this function |
| 1308 // must only be used to load a single character at a time. | 1308 // must only be used to load a single character at a time. |
| 1309 ASSERT(characters == 1); | 1309 DCHECK(characters == 1); |
| 1310 __ Addu(t5, end_of_input_address(), Operand(offset)); | 1310 __ Addu(t5, end_of_input_address(), Operand(offset)); |
| 1311 if (mode_ == ASCII) { | 1311 if (mode_ == ASCII) { |
| 1312 __ lbu(current_character(), MemOperand(t5, 0)); | 1312 __ lbu(current_character(), MemOperand(t5, 0)); |
| 1313 } else { | 1313 } else { |
| 1314 ASSERT(mode_ == UC16); | 1314 DCHECK(mode_ == UC16); |
| 1315 __ lhu(current_character(), MemOperand(t5, 0)); | 1315 __ lhu(current_character(), MemOperand(t5, 0)); |
| 1316 } | 1316 } |
| 1317 } | 1317 } |
| 1318 | 1318 |
| 1319 | 1319 |
| 1320 #undef __ | 1320 #undef __ |
| 1321 | 1321 |
| 1322 #endif // V8_INTERPRETED_REGEXP | 1322 #endif // V8_INTERPRETED_REGEXP |
| 1323 | 1323 |
| 1324 }} // namespace v8::internal | 1324 }} // namespace v8::internal |
| 1325 | 1325 |
| 1326 #endif // V8_TARGET_ARCH_MIPS | 1326 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |