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 |