| 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_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 : NativeRegExpMacroAssembler(zone), | 103 : NativeRegExpMacroAssembler(zone), |
| 104 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), | 104 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), |
| 105 mode_(mode), | 105 mode_(mode), |
| 106 num_registers_(registers_to_save), | 106 num_registers_(registers_to_save), |
| 107 num_saved_registers_(registers_to_save), | 107 num_saved_registers_(registers_to_save), |
| 108 entry_label_(), | 108 entry_label_(), |
| 109 start_label_(), | 109 start_label_(), |
| 110 success_label_(), | 110 success_label_(), |
| 111 backtrack_label_(), | 111 backtrack_label_(), |
| 112 exit_label_() { | 112 exit_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 __ bind(&start_label_); // And then continue from here. | 115 __ bind(&start_label_); // And then continue from here. |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 RegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() { | 119 RegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() { |
| 120 delete masm_; | 120 delete masm_; |
| 121 // Unuse labels in case we throw away the assembler without calling GetCode. | 121 // Unuse labels in case we throw away the assembler without calling GetCode. |
| 122 entry_label_.Unuse(); | 122 entry_label_.Unuse(); |
| 123 start_label_.Unuse(); | 123 start_label_.Unuse(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 136 | 136 |
| 137 void RegExpMacroAssemblerARM::AdvanceCurrentPosition(int by) { | 137 void RegExpMacroAssemblerARM::AdvanceCurrentPosition(int by) { |
| 138 if (by != 0) { | 138 if (by != 0) { |
| 139 __ add(current_input_offset(), | 139 __ add(current_input_offset(), |
| 140 current_input_offset(), Operand(by * char_size())); | 140 current_input_offset(), Operand(by * char_size())); |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 | 144 |
| 145 void RegExpMacroAssemblerARM::AdvanceRegister(int reg, int by) { | 145 void RegExpMacroAssemblerARM::AdvanceRegister(int reg, int by) { |
| 146 ASSERT(reg >= 0); | 146 DCHECK(reg >= 0); |
| 147 ASSERT(reg < num_registers_); | 147 DCHECK(reg < num_registers_); |
| 148 if (by != 0) { | 148 if (by != 0) { |
| 149 __ ldr(r0, register_location(reg)); | 149 __ ldr(r0, register_location(reg)); |
| 150 __ add(r0, r0, Operand(by)); | 150 __ add(r0, r0, Operand(by)); |
| 151 __ str(r0, register_location(reg)); | 151 __ str(r0, register_location(reg)); |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 | 155 |
| 156 void RegExpMacroAssemblerARM::Backtrack() { | 156 void RegExpMacroAssemblerARM::Backtrack() { |
| 157 CheckPreemption(); | 157 CheckPreemption(); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 __ b(lt, &loop); | 280 __ b(lt, &loop); |
| 281 __ jmp(&success); | 281 __ jmp(&success); |
| 282 | 282 |
| 283 __ bind(&fail); | 283 __ bind(&fail); |
| 284 BranchOrBacktrack(al, on_no_match); | 284 BranchOrBacktrack(al, on_no_match); |
| 285 | 285 |
| 286 __ bind(&success); | 286 __ bind(&success); |
| 287 // Compute new value of character position after the matched part. | 287 // Compute new value of character position after the matched part. |
| 288 __ sub(current_input_offset(), r2, end_of_input_address()); | 288 __ sub(current_input_offset(), r2, end_of_input_address()); |
| 289 } else { | 289 } else { |
| 290 ASSERT(mode_ == UC16); | 290 DCHECK(mode_ == UC16); |
| 291 int argument_count = 4; | 291 int argument_count = 4; |
| 292 __ PrepareCallCFunction(argument_count, r2); | 292 __ PrepareCallCFunction(argument_count, r2); |
| 293 | 293 |
| 294 // r0 - offset of start of capture | 294 // r0 - offset of start of capture |
| 295 // r1 - length of capture | 295 // r1 - length of capture |
| 296 | 296 |
| 297 // Put arguments into arguments registers. | 297 // Put arguments into arguments registers. |
| 298 // Parameters are | 298 // Parameters are |
| 299 // r0: Address byte_offset1 - Address captured substring's start. | 299 // r0: Address byte_offset1 - Address captured substring's start. |
| 300 // r1: Address byte_offset2 - Address of current character position. | 300 // r1: Address byte_offset2 - Address of current character position. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 __ add(r0, r0, Operand(end_of_input_address())); | 351 __ add(r0, r0, Operand(end_of_input_address())); |
| 352 __ add(r2, end_of_input_address(), Operand(current_input_offset())); | 352 __ add(r2, end_of_input_address(), Operand(current_input_offset())); |
| 353 __ add(r1, r1, Operand(r0)); | 353 __ add(r1, r1, Operand(r0)); |
| 354 | 354 |
| 355 Label loop; | 355 Label loop; |
| 356 __ bind(&loop); | 356 __ bind(&loop); |
| 357 if (mode_ == ASCII) { | 357 if (mode_ == ASCII) { |
| 358 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); | 358 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); |
| 359 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); | 359 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); |
| 360 } else { | 360 } else { |
| 361 ASSERT(mode_ == UC16); | 361 DCHECK(mode_ == UC16); |
| 362 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); | 362 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); |
| 363 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); | 363 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); |
| 364 } | 364 } |
| 365 __ cmp(r3, r4); | 365 __ cmp(r3, r4); |
| 366 BranchOrBacktrack(ne, on_no_match); | 366 BranchOrBacktrack(ne, on_no_match); |
| 367 __ cmp(r0, r1); | 367 __ cmp(r0, r1); |
| 368 __ b(lt, &loop); | 368 __ b(lt, &loop); |
| 369 | 369 |
| 370 // Move current character position to position after match. | 370 // Move current character position to position after match. |
| 371 __ sub(current_input_offset(), r2, end_of_input_address()); | 371 __ sub(current_input_offset(), r2, end_of_input_address()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 } | 404 } |
| 405 BranchOrBacktrack(ne, on_not_equal); | 405 BranchOrBacktrack(ne, on_not_equal); |
| 406 } | 406 } |
| 407 | 407 |
| 408 | 408 |
| 409 void RegExpMacroAssemblerARM::CheckNotCharacterAfterMinusAnd( | 409 void RegExpMacroAssemblerARM::CheckNotCharacterAfterMinusAnd( |
| 410 uc16 c, | 410 uc16 c, |
| 411 uc16 minus, | 411 uc16 minus, |
| 412 uc16 mask, | 412 uc16 mask, |
| 413 Label* on_not_equal) { | 413 Label* on_not_equal) { |
| 414 ASSERT(minus < String::kMaxUtf16CodeUnit); | 414 DCHECK(minus < String::kMaxUtf16CodeUnit); |
| 415 __ sub(r0, current_character(), Operand(minus)); | 415 __ sub(r0, current_character(), Operand(minus)); |
| 416 __ and_(r0, r0, Operand(mask)); | 416 __ and_(r0, r0, Operand(mask)); |
| 417 __ cmp(r0, Operand(c)); | 417 __ cmp(r0, Operand(c)); |
| 418 BranchOrBacktrack(ne, on_not_equal); | 418 BranchOrBacktrack(ne, on_not_equal); |
| 419 } | 419 } |
| 420 | 420 |
| 421 | 421 |
| 422 void RegExpMacroAssemblerARM::CheckCharacterInRange( | 422 void RegExpMacroAssemblerARM::CheckCharacterInRange( |
| 423 uc16 from, | 423 uc16 from, |
| 424 uc16 to, | 424 uc16 to, |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 __ ldr(r2, MemOperand(frame_pointer(), kStartIndex)); | 703 __ ldr(r2, MemOperand(frame_pointer(), kStartIndex)); |
| 704 __ sub(r1, end_of_input_address(), r1); | 704 __ sub(r1, end_of_input_address(), r1); |
| 705 // r1 is length of input in bytes. | 705 // r1 is length of input in bytes. |
| 706 if (mode_ == UC16) { | 706 if (mode_ == UC16) { |
| 707 __ mov(r1, Operand(r1, LSR, 1)); | 707 __ mov(r1, Operand(r1, LSR, 1)); |
| 708 } | 708 } |
| 709 // r1 is length of input in characters. | 709 // r1 is length of input in characters. |
| 710 __ add(r1, r1, Operand(r2)); | 710 __ add(r1, r1, Operand(r2)); |
| 711 // r1 is length of string in characters. | 711 // r1 is length of string in characters. |
| 712 | 712 |
| 713 ASSERT_EQ(0, num_saved_registers_ % 2); | 713 DCHECK_EQ(0, num_saved_registers_ % 2); |
| 714 // Always an even number of capture registers. This allows us to | 714 // Always an even number of capture registers. This allows us to |
| 715 // unroll the loop once to add an operation between a load of a register | 715 // unroll the loop once to add an operation between a load of a register |
| 716 // and the following use of that register. | 716 // and the following use of that register. |
| 717 for (int i = 0; i < num_saved_registers_; i += 2) { | 717 for (int i = 0; i < num_saved_registers_; i += 2) { |
| 718 __ ldr(r2, register_location(i)); | 718 __ ldr(r2, register_location(i)); |
| 719 __ ldr(r3, register_location(i + 1)); | 719 __ ldr(r3, register_location(i + 1)); |
| 720 if (i == 0 && global_with_zero_length_check()) { | 720 if (i == 0 && global_with_zero_length_check()) { |
| 721 // Keep capture start in r4 for the zero-length check later. | 721 // Keep capture start in r4 for the zero-length check later. |
| 722 __ mov(r4, r2); | 722 __ mov(r4, r2); |
| 723 } | 723 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 RegExpMacroAssembler::IrregexpImplementation | 888 RegExpMacroAssembler::IrregexpImplementation |
| 889 RegExpMacroAssemblerARM::Implementation() { | 889 RegExpMacroAssemblerARM::Implementation() { |
| 890 return kARMImplementation; | 890 return kARMImplementation; |
| 891 } | 891 } |
| 892 | 892 |
| 893 | 893 |
| 894 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, | 894 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, |
| 895 Label* on_end_of_input, | 895 Label* on_end_of_input, |
| 896 bool check_bounds, | 896 bool check_bounds, |
| 897 int characters) { | 897 int characters) { |
| 898 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. | 898 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. |
| 899 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 899 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
| 900 if (check_bounds) { | 900 if (check_bounds) { |
| 901 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 901 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
| 902 } | 902 } |
| 903 LoadCurrentCharacterUnchecked(cp_offset, characters); | 903 LoadCurrentCharacterUnchecked(cp_offset, characters); |
| 904 } | 904 } |
| 905 | 905 |
| 906 | 906 |
| 907 void RegExpMacroAssemblerARM::PopCurrentPosition() { | 907 void RegExpMacroAssemblerARM::PopCurrentPosition() { |
| 908 Pop(current_input_offset()); | 908 Pop(current_input_offset()); |
| 909 } | 909 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 __ mov(current_input_offset(), Operand(-by * char_size())); | 954 __ mov(current_input_offset(), Operand(-by * char_size())); |
| 955 // On RegExp code entry (where this operation is used), the character before | 955 // On RegExp code entry (where this operation is used), the character before |
| 956 // the current position is expected to be already loaded. | 956 // the current position is expected to be already loaded. |
| 957 // We have advanced the position, so it's safe to read backwards. | 957 // We have advanced the position, so it's safe to read backwards. |
| 958 LoadCurrentCharacterUnchecked(-1, 1); | 958 LoadCurrentCharacterUnchecked(-1, 1); |
| 959 __ bind(&after_position); | 959 __ bind(&after_position); |
| 960 } | 960 } |
| 961 | 961 |
| 962 | 962 |
| 963 void RegExpMacroAssemblerARM::SetRegister(int register_index, int to) { | 963 void RegExpMacroAssemblerARM::SetRegister(int register_index, int to) { |
| 964 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! | 964 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! |
| 965 __ mov(r0, Operand(to)); | 965 __ mov(r0, Operand(to)); |
| 966 __ str(r0, register_location(register_index)); | 966 __ str(r0, register_location(register_index)); |
| 967 } | 967 } |
| 968 | 968 |
| 969 | 969 |
| 970 bool RegExpMacroAssemblerARM::Succeed() { | 970 bool RegExpMacroAssemblerARM::Succeed() { |
| 971 __ jmp(&success_label_); | 971 __ jmp(&success_label_); |
| 972 return global(); | 972 return global(); |
| 973 } | 973 } |
| 974 | 974 |
| 975 | 975 |
| 976 void RegExpMacroAssemblerARM::WriteCurrentPositionToRegister(int reg, | 976 void RegExpMacroAssemblerARM::WriteCurrentPositionToRegister(int reg, |
| 977 int cp_offset) { | 977 int cp_offset) { |
| 978 if (cp_offset == 0) { | 978 if (cp_offset == 0) { |
| 979 __ str(current_input_offset(), register_location(reg)); | 979 __ str(current_input_offset(), register_location(reg)); |
| 980 } else { | 980 } else { |
| 981 __ add(r0, current_input_offset(), Operand(cp_offset * char_size())); | 981 __ add(r0, current_input_offset(), Operand(cp_offset * char_size())); |
| 982 __ str(r0, register_location(reg)); | 982 __ str(r0, register_location(reg)); |
| 983 } | 983 } |
| 984 } | 984 } |
| 985 | 985 |
| 986 | 986 |
| 987 void RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) { | 987 void RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) { |
| 988 ASSERT(reg_from <= reg_to); | 988 DCHECK(reg_from <= reg_to); |
| 989 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 989 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
| 990 for (int reg = reg_from; reg <= reg_to; reg++) { | 990 for (int reg = reg_from; reg <= reg_to; reg++) { |
| 991 __ str(r0, register_location(reg)); | 991 __ str(r0, register_location(reg)); |
| 992 } | 992 } |
| 993 } | 993 } |
| 994 | 994 |
| 995 | 995 |
| 996 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) { | 996 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) { |
| 997 __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd)); | 997 __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd)); |
| 998 __ sub(r0, backtrack_stackpointer(), r1); | 998 __ sub(r0, backtrack_stackpointer(), r1); |
| 999 __ str(r0, register_location(reg)); | 999 __ str(r0, register_location(reg)); |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 | 1002 |
| 1003 // Private methods: | 1003 // Private methods: |
| 1004 | 1004 |
| 1005 void RegExpMacroAssemblerARM::CallCheckStackGuardState(Register scratch) { | 1005 void RegExpMacroAssemblerARM::CallCheckStackGuardState(Register scratch) { |
| 1006 __ PrepareCallCFunction(3, scratch); | 1006 __ PrepareCallCFunction(3, scratch); |
| 1007 | 1007 |
| 1008 // RegExp code frame pointer. | 1008 // RegExp code frame pointer. |
| 1009 __ mov(r2, frame_pointer()); | 1009 __ mov(r2, frame_pointer()); |
| 1010 // Code* of self. | 1010 // Code* of self. |
| 1011 __ mov(r1, Operand(masm_->CodeObject())); | 1011 __ mov(r1, Operand(masm_->CodeObject())); |
| 1012 | 1012 |
| 1013 // We need to make room for the return address on the stack. | 1013 // We need to make room for the return address on the stack. |
| 1014 int stack_alignment = base::OS::ActivationFrameAlignment(); | 1014 int stack_alignment = base::OS::ActivationFrameAlignment(); |
| 1015 ASSERT(IsAligned(stack_alignment, kPointerSize)); | 1015 DCHECK(IsAligned(stack_alignment, kPointerSize)); |
| 1016 __ sub(sp, sp, Operand(stack_alignment)); | 1016 __ sub(sp, sp, Operand(stack_alignment)); |
| 1017 | 1017 |
| 1018 // r0 will point to the return address, placed by DirectCEntry. | 1018 // r0 will point to the return address, placed by DirectCEntry. |
| 1019 __ mov(r0, sp); | 1019 __ mov(r0, sp); |
| 1020 | 1020 |
| 1021 ExternalReference stack_guard_check = | 1021 ExternalReference stack_guard_check = |
| 1022 ExternalReference::re_check_stack_guard_state(isolate()); | 1022 ExternalReference::re_check_stack_guard_state(isolate()); |
| 1023 __ mov(ip, Operand(stack_guard_check)); | 1023 __ mov(ip, Operand(stack_guard_check)); |
| 1024 DirectCEntryStub stub(isolate()); | 1024 DirectCEntryStub stub(isolate()); |
| 1025 stub.GenerateCall(masm_, ip); | 1025 stub.GenerateCall(masm_, ip); |
| 1026 | 1026 |
| 1027 // Drop the return address from the stack. | 1027 // Drop the return address from the stack. |
| 1028 __ add(sp, sp, Operand(stack_alignment)); | 1028 __ add(sp, sp, Operand(stack_alignment)); |
| 1029 | 1029 |
| 1030 ASSERT(stack_alignment != 0); | 1030 DCHECK(stack_alignment != 0); |
| 1031 __ ldr(sp, MemOperand(sp, 0)); | 1031 __ ldr(sp, MemOperand(sp, 0)); |
| 1032 | 1032 |
| 1033 __ mov(code_pointer(), Operand(masm_->CodeObject())); | 1033 __ mov(code_pointer(), Operand(masm_->CodeObject())); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 | 1036 |
| 1037 // Helper function for reading a value out of a stack frame. | 1037 // Helper function for reading a value out of a stack frame. |
| 1038 template <typename T> | 1038 template <typename T> |
| 1039 static T& frame_entry(Address re_frame, int frame_offset) { | 1039 static T& frame_entry(Address re_frame, int frame_offset) { |
| 1040 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); | 1040 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1062 | 1062 |
| 1063 // Prepare for possible GC. | 1063 // Prepare for possible GC. |
| 1064 HandleScope handles(isolate); | 1064 HandleScope handles(isolate); |
| 1065 Handle<Code> code_handle(re_code); | 1065 Handle<Code> code_handle(re_code); |
| 1066 | 1066 |
| 1067 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); | 1067 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); |
| 1068 | 1068 |
| 1069 // Current string. | 1069 // Current string. |
| 1070 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); | 1070 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); |
| 1071 | 1071 |
| 1072 ASSERT(re_code->instruction_start() <= *return_address); | 1072 DCHECK(re_code->instruction_start() <= *return_address); |
| 1073 ASSERT(*return_address <= | 1073 DCHECK(*return_address <= |
| 1074 re_code->instruction_start() + re_code->instruction_size()); | 1074 re_code->instruction_start() + re_code->instruction_size()); |
| 1075 | 1075 |
| 1076 Object* result = isolate->stack_guard()->HandleInterrupts(); | 1076 Object* result = isolate->stack_guard()->HandleInterrupts(); |
| 1077 | 1077 |
| 1078 if (*code_handle != re_code) { // Return address no longer valid | 1078 if (*code_handle != re_code) { // Return address no longer valid |
| 1079 int delta = code_handle->address() - re_code->address(); | 1079 int delta = code_handle->address() - re_code->address(); |
| 1080 // Overwrite the return address on the stack. | 1080 // Overwrite the return address on the stack. |
| 1081 *return_address += delta; | 1081 *return_address += delta; |
| 1082 } | 1082 } |
| 1083 | 1083 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1102 // If we changed between an ASCII and an UC16 string, the specialized | 1102 // If we changed between an ASCII and an UC16 string, the specialized |
| 1103 // code cannot be used, and we need to restart regexp matching from | 1103 // code cannot be used, and we need to restart regexp matching from |
| 1104 // scratch (including, potentially, compiling a new version of the code). | 1104 // scratch (including, potentially, compiling a new version of the code). |
| 1105 return RETRY; | 1105 return RETRY; |
| 1106 } | 1106 } |
| 1107 | 1107 |
| 1108 // Otherwise, the content of the string might have moved. It must still | 1108 // Otherwise, the content of the string might have moved. It must still |
| 1109 // be a sequential or external string with the same content. | 1109 // be a sequential or external string with the same content. |
| 1110 // Update the start and end pointers in the stack frame to the current | 1110 // Update the start and end pointers in the stack frame to the current |
| 1111 // location (whether it has actually moved or not). | 1111 // location (whether it has actually moved or not). |
| 1112 ASSERT(StringShape(*subject_tmp).IsSequential() || | 1112 DCHECK(StringShape(*subject_tmp).IsSequential() || |
| 1113 StringShape(*subject_tmp).IsExternal()); | 1113 StringShape(*subject_tmp).IsExternal()); |
| 1114 | 1114 |
| 1115 // The original start address of the characters to match. | 1115 // The original start address of the characters to match. |
| 1116 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); | 1116 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); |
| 1117 | 1117 |
| 1118 // Find the current start address of the same character at the current string | 1118 // Find the current start address of the same character at the current string |
| 1119 // position. | 1119 // position. |
| 1120 int start_index = frame_entry<int>(re_frame, kStartIndex); | 1120 int start_index = frame_entry<int>(re_frame, kStartIndex); |
| 1121 const byte* new_address = StringCharacterPosition(*subject_tmp, | 1121 const byte* new_address = StringCharacterPosition(*subject_tmp, |
| 1122 start_index + slice_offset); | 1122 start_index + slice_offset); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1134 // short-circuiting during GC. That will not change start_address but | 1134 // short-circuiting during GC. That will not change start_address but |
| 1135 // will change pointer inside the subject handle. | 1135 // will change pointer inside the subject handle. |
| 1136 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1136 frame_entry<const String*>(re_frame, kInputString) = *subject; |
| 1137 } | 1137 } |
| 1138 | 1138 |
| 1139 return 0; | 1139 return 0; |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 | 1142 |
| 1143 MemOperand RegExpMacroAssemblerARM::register_location(int register_index) { | 1143 MemOperand RegExpMacroAssemblerARM::register_location(int register_index) { |
| 1144 ASSERT(register_index < (1<<30)); | 1144 DCHECK(register_index < (1<<30)); |
| 1145 if (num_registers_ <= register_index) { | 1145 if (num_registers_ <= register_index) { |
| 1146 num_registers_ = register_index + 1; | 1146 num_registers_ = register_index + 1; |
| 1147 } | 1147 } |
| 1148 return MemOperand(frame_pointer(), | 1148 return MemOperand(frame_pointer(), |
| 1149 kRegisterZero - register_index * kPointerSize); | 1149 kRegisterZero - register_index * kPointerSize); |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 | 1152 |
| 1153 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, | 1153 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, |
| 1154 Label* on_outside_input) { | 1154 Label* on_outside_input) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 | 1187 |
| 1188 | 1188 |
| 1189 void RegExpMacroAssemblerARM::SafeCallTarget(Label* name) { | 1189 void RegExpMacroAssemblerARM::SafeCallTarget(Label* name) { |
| 1190 __ bind(name); | 1190 __ bind(name); |
| 1191 __ sub(lr, lr, Operand(masm_->CodeObject())); | 1191 __ sub(lr, lr, Operand(masm_->CodeObject())); |
| 1192 __ push(lr); | 1192 __ push(lr); |
| 1193 } | 1193 } |
| 1194 | 1194 |
| 1195 | 1195 |
| 1196 void RegExpMacroAssemblerARM::Push(Register source) { | 1196 void RegExpMacroAssemblerARM::Push(Register source) { |
| 1197 ASSERT(!source.is(backtrack_stackpointer())); | 1197 DCHECK(!source.is(backtrack_stackpointer())); |
| 1198 __ str(source, | 1198 __ str(source, |
| 1199 MemOperand(backtrack_stackpointer(), kPointerSize, NegPreIndex)); | 1199 MemOperand(backtrack_stackpointer(), kPointerSize, NegPreIndex)); |
| 1200 } | 1200 } |
| 1201 | 1201 |
| 1202 | 1202 |
| 1203 void RegExpMacroAssemblerARM::Pop(Register target) { | 1203 void RegExpMacroAssemblerARM::Pop(Register target) { |
| 1204 ASSERT(!target.is(backtrack_stackpointer())); | 1204 DCHECK(!target.is(backtrack_stackpointer())); |
| 1205 __ ldr(target, | 1205 __ ldr(target, |
| 1206 MemOperand(backtrack_stackpointer(), kPointerSize, PostIndex)); | 1206 MemOperand(backtrack_stackpointer(), kPointerSize, PostIndex)); |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 | 1209 |
| 1210 void RegExpMacroAssemblerARM::CheckPreemption() { | 1210 void RegExpMacroAssemblerARM::CheckPreemption() { |
| 1211 // Check for preemption. | 1211 // Check for preemption. |
| 1212 ExternalReference stack_limit = | 1212 ExternalReference stack_limit = |
| 1213 ExternalReference::address_of_stack_limit(isolate()); | 1213 ExternalReference::address_of_stack_limit(isolate()); |
| 1214 __ mov(r0, Operand(stack_limit)); | 1214 __ mov(r0, Operand(stack_limit)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1239 if (cp_offset != 0) { | 1239 if (cp_offset != 0) { |
| 1240 // r4 is not being used to store the capture start index at this point. | 1240 // r4 is not being used to store the capture start index at this point. |
| 1241 __ add(r4, current_input_offset(), Operand(cp_offset * char_size())); | 1241 __ add(r4, current_input_offset(), Operand(cp_offset * char_size())); |
| 1242 offset = r4; | 1242 offset = r4; |
| 1243 } | 1243 } |
| 1244 // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU | 1244 // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU |
| 1245 // and the operating system running on the target allow it. | 1245 // and the operating system running on the target allow it. |
| 1246 // If unaligned load/stores are not supported then this function must only | 1246 // If unaligned load/stores are not supported then this function must only |
| 1247 // be used to load a single character at a time. | 1247 // be used to load a single character at a time. |
| 1248 if (!CanReadUnaligned()) { | 1248 if (!CanReadUnaligned()) { |
| 1249 ASSERT(characters == 1); | 1249 DCHECK(characters == 1); |
| 1250 } | 1250 } |
| 1251 | 1251 |
| 1252 if (mode_ == ASCII) { | 1252 if (mode_ == ASCII) { |
| 1253 if (characters == 4) { | 1253 if (characters == 4) { |
| 1254 __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); | 1254 __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); |
| 1255 } else if (characters == 2) { | 1255 } else if (characters == 2) { |
| 1256 __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); | 1256 __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); |
| 1257 } else { | 1257 } else { |
| 1258 ASSERT(characters == 1); | 1258 DCHECK(characters == 1); |
| 1259 __ ldrb(current_character(), MemOperand(end_of_input_address(), offset)); | 1259 __ ldrb(current_character(), MemOperand(end_of_input_address(), offset)); |
| 1260 } | 1260 } |
| 1261 } else { | 1261 } else { |
| 1262 ASSERT(mode_ == UC16); | 1262 DCHECK(mode_ == UC16); |
| 1263 if (characters == 2) { | 1263 if (characters == 2) { |
| 1264 __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); | 1264 __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); |
| 1265 } else { | 1265 } else { |
| 1266 ASSERT(characters == 1); | 1266 DCHECK(characters == 1); |
| 1267 __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); | 1267 __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); |
| 1268 } | 1268 } |
| 1269 } | 1269 } |
| 1270 } | 1270 } |
| 1271 | 1271 |
| 1272 | 1272 |
| 1273 #undef __ | 1273 #undef __ |
| 1274 | 1274 |
| 1275 #endif // V8_INTERPRETED_REGEXP | 1275 #endif // V8_INTERPRETED_REGEXP |
| 1276 | 1276 |
| 1277 }} // namespace v8::internal | 1277 }} // namespace v8::internal |
| 1278 | 1278 |
| 1279 #endif // V8_TARGET_ARCH_ARM | 1279 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |