| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "cpu-profiler.h" | 9 #include "cpu-profiler.h" |
| 10 #include "unicode.h" | 10 #include "unicode.h" |
| 11 #include "log.h" | 11 #include "log.h" |
| 12 #include "regexp-stack.h" | 12 #include "regexp-stack.h" |
| 13 #include "macro-assembler.h" | 13 #include "macro-assembler.h" |
| 14 #include "regexp-macro-assembler.h" | 14 #include "regexp-macro-assembler.h" |
| 15 #include "ia32/regexp-macro-assembler-ia32.h" | 15 #include "x87/regexp-macro-assembler-x87.h" |
| 16 | 16 |
| 17 namespace v8 { | 17 namespace v8 { |
| 18 namespace internal { | 18 namespace internal { |
| 19 | 19 |
| 20 #ifndef V8_INTERPRETED_REGEXP | 20 #ifndef V8_INTERPRETED_REGEXP |
| 21 /* | 21 /* |
| 22 * This assembler uses the following register assignment convention | 22 * This assembler uses the following register assignment convention |
| 23 * - edx : Current character. Must be loaded using LoadCurrentCharacter | 23 * - edx : Current character. Must be loaded using LoadCurrentCharacter |
| 24 * before using any of the dispatch methods. Temporarily stores the | 24 * before using any of the dispatch methods. Temporarily stores the |
| 25 * index of capture start after a matching pass for a global regexp. | 25 * index of capture start after a matching pass for a global regexp. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 * Address start, | 70 * Address start, |
| 71 * Address end, | 71 * Address end, |
| 72 * int* capture_output_array, | 72 * int* capture_output_array, |
| 73 * bool at_start, | 73 * bool at_start, |
| 74 * byte* stack_area_base, | 74 * byte* stack_area_base, |
| 75 * bool direct_call) | 75 * bool direct_call) |
| 76 */ | 76 */ |
| 77 | 77 |
| 78 #define __ ACCESS_MASM(masm_) | 78 #define __ ACCESS_MASM(masm_) |
| 79 | 79 |
| 80 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32( | 80 RegExpMacroAssemblerX87::RegExpMacroAssemblerX87( |
| 81 Mode mode, | 81 Mode mode, |
| 82 int registers_to_save, | 82 int registers_to_save, |
| 83 Zone* zone) | 83 Zone* zone) |
| 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 ASSERT_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 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { | 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(); |
| 105 success_label_.Unuse(); | 105 success_label_.Unuse(); |
| 106 backtrack_label_.Unuse(); | 106 backtrack_label_.Unuse(); |
| 107 exit_label_.Unuse(); | 107 exit_label_.Unuse(); |
| 108 check_preempt_label_.Unuse(); | 108 check_preempt_label_.Unuse(); |
| 109 stack_overflow_label_.Unuse(); | 109 stack_overflow_label_.Unuse(); |
| 110 } | 110 } |
| 111 | 111 |
| 112 | 112 |
| 113 int RegExpMacroAssemblerIA32::stack_limit_slack() { | 113 int RegExpMacroAssemblerX87::stack_limit_slack() { |
| 114 return RegExpStack::kStackLimitSlack; | 114 return RegExpStack::kStackLimitSlack; |
| 115 } | 115 } |
| 116 | 116 |
| 117 | 117 |
| 118 void RegExpMacroAssemblerIA32::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 RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { | 125 void RegExpMacroAssemblerX87::AdvanceRegister(int reg, int by) { |
| 126 ASSERT(reg >= 0); | 126 ASSERT(reg >= 0); |
| 127 ASSERT(reg < num_registers_); | 127 ASSERT(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 RegExpMacroAssemblerIA32::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); |
| 138 __ add(ebx, Immediate(masm_->CodeObject())); | 138 __ add(ebx, Immediate(masm_->CodeObject())); |
| 139 __ jmp(ebx); | 139 __ jmp(ebx); |
| 140 } | 140 } |
| 141 | 141 |
| 142 | 142 |
| 143 void RegExpMacroAssemblerIA32::Bind(Label* label) { | 143 void RegExpMacroAssemblerX87::Bind(Label* label) { |
| 144 __ bind(label); | 144 __ bind(label); |
| 145 } | 145 } |
| 146 | 146 |
| 147 | 147 |
| 148 void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) { | 148 void RegExpMacroAssemblerX87::CheckCharacter(uint32_t c, Label* on_equal) { |
| 149 __ cmp(current_character(), c); | 149 __ cmp(current_character(), c); |
| 150 BranchOrBacktrack(equal, on_equal); | 150 BranchOrBacktrack(equal, on_equal); |
| 151 } | 151 } |
| 152 | 152 |
| 153 | 153 |
| 154 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { | 154 void RegExpMacroAssemblerX87::CheckCharacterGT(uc16 limit, Label* on_greater) { |
| 155 __ cmp(current_character(), limit); | 155 __ cmp(current_character(), limit); |
| 156 BranchOrBacktrack(greater, on_greater); | 156 BranchOrBacktrack(greater, on_greater); |
| 157 } | 157 } |
| 158 | 158 |
| 159 | 159 |
| 160 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { | 160 void RegExpMacroAssemblerX87::CheckAtStart(Label* on_at_start) { |
| 161 Label not_at_start; | 161 Label not_at_start; |
| 162 // Did we start the match at the start of the string at all? | 162 // Did we start the match at the start of the string at all? |
| 163 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 163 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); |
| 164 BranchOrBacktrack(not_equal, ¬_at_start); | 164 BranchOrBacktrack(not_equal, ¬_at_start); |
| 165 // If we did, are we still at the start of the input? | 165 // If we did, are we still at the start of the input? |
| 166 __ lea(eax, Operand(esi, edi, times_1, 0)); | 166 __ lea(eax, Operand(esi, edi, times_1, 0)); |
| 167 __ cmp(eax, Operand(ebp, kInputStart)); | 167 __ cmp(eax, Operand(ebp, kInputStart)); |
| 168 BranchOrBacktrack(equal, on_at_start); | 168 BranchOrBacktrack(equal, on_at_start); |
| 169 __ bind(¬_at_start); | 169 __ bind(¬_at_start); |
| 170 } | 170 } |
| 171 | 171 |
| 172 | 172 |
| 173 void RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) { | 173 void RegExpMacroAssemblerX87::CheckNotAtStart(Label* on_not_at_start) { |
| 174 // Did we start the match at the start of the string at all? | 174 // Did we start the match at the start of the string at all? |
| 175 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 175 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); |
| 176 BranchOrBacktrack(not_equal, on_not_at_start); | 176 BranchOrBacktrack(not_equal, on_not_at_start); |
| 177 // If we did, are we still at the start of the input? | 177 // If we did, are we still at the start of the input? |
| 178 __ lea(eax, Operand(esi, edi, times_1, 0)); | 178 __ lea(eax, Operand(esi, edi, times_1, 0)); |
| 179 __ cmp(eax, Operand(ebp, kInputStart)); | 179 __ cmp(eax, Operand(ebp, kInputStart)); |
| 180 BranchOrBacktrack(not_equal, on_not_at_start); | 180 BranchOrBacktrack(not_equal, on_not_at_start); |
| 181 } | 181 } |
| 182 | 182 |
| 183 | 183 |
| 184 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { | 184 void RegExpMacroAssemblerX87::CheckCharacterLT(uc16 limit, Label* on_less) { |
| 185 __ cmp(current_character(), limit); | 185 __ cmp(current_character(), limit); |
| 186 BranchOrBacktrack(less, on_less); | 186 BranchOrBacktrack(less, on_less); |
| 187 } | 187 } |
| 188 | 188 |
| 189 | 189 |
| 190 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { | 190 void RegExpMacroAssemblerX87::CheckGreedyLoop(Label* on_equal) { |
| 191 Label fallthrough; | 191 Label fallthrough; |
| 192 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); | 192 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); |
| 193 __ j(not_equal, &fallthrough); | 193 __ j(not_equal, &fallthrough); |
| 194 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. | 194 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. |
| 195 BranchOrBacktrack(no_condition, on_equal); | 195 BranchOrBacktrack(no_condition, on_equal); |
| 196 __ bind(&fallthrough); | 196 __ bind(&fallthrough); |
| 197 } | 197 } |
| 198 | 198 |
| 199 | 199 |
| 200 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( | 200 void RegExpMacroAssemblerX87::CheckNotBackReferenceIgnoreCase( |
| 201 int start_reg, | 201 int start_reg, |
| 202 Label* on_no_match) { | 202 Label* on_no_match) { |
| 203 Label fallthrough; | 203 Label fallthrough; |
| 204 __ mov(edx, register_location(start_reg)); // Index of start of capture | 204 __ mov(edx, register_location(start_reg)); // Index of start of capture |
| 205 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture | 205 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture |
| 206 __ sub(ebx, edx); // Length of capture. | 206 __ sub(ebx, edx); // Length of capture. |
| 207 | 207 |
| 208 // The length of a capture should not be negative. This can only happen | 208 // The length of a capture should not be negative. This can only happen |
| 209 // if the end of the capture is unrecorded, or at a point earlier than | 209 // if the end of the capture is unrecorded, or at a point earlier than |
| 210 // the start of the capture. | 210 // the start of the capture. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 // Check if function returned non-zero for success or zero for failure. | 327 // Check if function returned non-zero for success or zero for failure. |
| 328 __ or_(eax, eax); | 328 __ or_(eax, eax); |
| 329 BranchOrBacktrack(zero, on_no_match); | 329 BranchOrBacktrack(zero, on_no_match); |
| 330 // On success, increment position by length of capture. | 330 // On success, increment position by length of capture. |
| 331 __ add(edi, ebx); | 331 __ add(edi, ebx); |
| 332 } | 332 } |
| 333 __ bind(&fallthrough); | 333 __ bind(&fallthrough); |
| 334 } | 334 } |
| 335 | 335 |
| 336 | 336 |
| 337 void RegExpMacroAssemblerIA32::CheckNotBackReference( | 337 void RegExpMacroAssemblerX87::CheckNotBackReference( |
| 338 int start_reg, | 338 int start_reg, |
| 339 Label* on_no_match) { | 339 Label* on_no_match) { |
| 340 Label fallthrough; | 340 Label fallthrough; |
| 341 Label success; | 341 Label success; |
| 342 Label fail; | 342 Label fail; |
| 343 | 343 |
| 344 // Find length of back-referenced capture. | 344 // Find length of back-referenced capture. |
| 345 __ mov(edx, register_location(start_reg)); | 345 __ mov(edx, register_location(start_reg)); |
| 346 __ mov(eax, register_location(start_reg + 1)); | 346 __ mov(eax, register_location(start_reg + 1)); |
| 347 __ sub(eax, edx); // Length to check. | 347 __ sub(eax, edx); // Length to check. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 // Move current character position to position after match. | 391 // Move current character position to position after match. |
| 392 __ mov(edi, ecx); | 392 __ mov(edi, ecx); |
| 393 __ sub(edi, esi); | 393 __ sub(edi, esi); |
| 394 // Restore backtrack stackpointer. | 394 // Restore backtrack stackpointer. |
| 395 __ pop(backtrack_stackpointer()); | 395 __ pop(backtrack_stackpointer()); |
| 396 | 396 |
| 397 __ bind(&fallthrough); | 397 __ bind(&fallthrough); |
| 398 } | 398 } |
| 399 | 399 |
| 400 | 400 |
| 401 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, | 401 void RegExpMacroAssemblerX87::CheckNotCharacter(uint32_t c, |
| 402 Label* on_not_equal) { | 402 Label* on_not_equal) { |
| 403 __ cmp(current_character(), c); | 403 __ cmp(current_character(), c); |
| 404 BranchOrBacktrack(not_equal, on_not_equal); | 404 BranchOrBacktrack(not_equal, on_not_equal); |
| 405 } | 405 } |
| 406 | 406 |
| 407 | 407 |
| 408 void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c, | 408 void RegExpMacroAssemblerX87::CheckCharacterAfterAnd(uint32_t c, |
| 409 uint32_t mask, | 409 uint32_t mask, |
| 410 Label* on_equal) { | 410 Label* on_equal) { |
| 411 if (c == 0) { | 411 if (c == 0) { |
| 412 __ test(current_character(), Immediate(mask)); | 412 __ test(current_character(), Immediate(mask)); |
| 413 } else { | 413 } else { |
| 414 __ mov(eax, mask); | 414 __ mov(eax, mask); |
| 415 __ and_(eax, current_character()); | 415 __ and_(eax, current_character()); |
| 416 __ cmp(eax, c); | 416 __ cmp(eax, c); |
| 417 } | 417 } |
| 418 BranchOrBacktrack(equal, on_equal); | 418 BranchOrBacktrack(equal, on_equal); |
| 419 } | 419 } |
| 420 | 420 |
| 421 | 421 |
| 422 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(uint32_t c, | 422 void RegExpMacroAssemblerX87::CheckNotCharacterAfterAnd(uint32_t c, |
| 423 uint32_t mask, | 423 uint32_t mask, |
| 424 Label* on_not_equal) { | 424 Label* on_not_equal) { |
| 425 if (c == 0) { | 425 if (c == 0) { |
| 426 __ test(current_character(), Immediate(mask)); | 426 __ test(current_character(), Immediate(mask)); |
| 427 } else { | 427 } else { |
| 428 __ mov(eax, mask); | 428 __ mov(eax, mask); |
| 429 __ and_(eax, current_character()); | 429 __ and_(eax, current_character()); |
| 430 __ cmp(eax, c); | 430 __ cmp(eax, c); |
| 431 } | 431 } |
| 432 BranchOrBacktrack(not_equal, on_not_equal); | 432 BranchOrBacktrack(not_equal, on_not_equal); |
| 433 } | 433 } |
| 434 | 434 |
| 435 | 435 |
| 436 void RegExpMacroAssemblerIA32::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 ASSERT(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 |
| 452 | 452 |
| 453 void RegExpMacroAssemblerIA32::CheckCharacterInRange( | 453 void RegExpMacroAssemblerX87::CheckCharacterInRange( |
| 454 uc16 from, | 454 uc16 from, |
| 455 uc16 to, | 455 uc16 to, |
| 456 Label* on_in_range) { | 456 Label* on_in_range) { |
| 457 __ lea(eax, Operand(current_character(), -from)); | 457 __ lea(eax, Operand(current_character(), -from)); |
| 458 __ cmp(eax, to - from); | 458 __ cmp(eax, to - from); |
| 459 BranchOrBacktrack(below_equal, on_in_range); | 459 BranchOrBacktrack(below_equal, on_in_range); |
| 460 } | 460 } |
| 461 | 461 |
| 462 | 462 |
| 463 void RegExpMacroAssemblerIA32::CheckCharacterNotInRange( | 463 void RegExpMacroAssemblerX87::CheckCharacterNotInRange( |
| 464 uc16 from, | 464 uc16 from, |
| 465 uc16 to, | 465 uc16 to, |
| 466 Label* on_not_in_range) { | 466 Label* on_not_in_range) { |
| 467 __ lea(eax, Operand(current_character(), -from)); | 467 __ lea(eax, Operand(current_character(), -from)); |
| 468 __ cmp(eax, to - from); | 468 __ cmp(eax, to - from); |
| 469 BranchOrBacktrack(above, on_not_in_range); | 469 BranchOrBacktrack(above, on_not_in_range); |
| 470 } | 470 } |
| 471 | 471 |
| 472 | 472 |
| 473 void RegExpMacroAssemblerIA32::CheckBitInTable( | 473 void RegExpMacroAssemblerX87::CheckBitInTable( |
| 474 Handle<ByteArray> table, | 474 Handle<ByteArray> table, |
| 475 Label* on_bit_set) { | 475 Label* on_bit_set) { |
| 476 __ mov(eax, Immediate(table)); | 476 __ mov(eax, Immediate(table)); |
| 477 Register index = current_character(); | 477 Register index = current_character(); |
| 478 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { | 478 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { |
| 479 __ mov(ebx, kTableSize - 1); | 479 __ mov(ebx, kTableSize - 1); |
| 480 __ and_(ebx, current_character()); | 480 __ and_(ebx, current_character()); |
| 481 index = ebx; | 481 index = ebx; |
| 482 } | 482 } |
| 483 __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0); | 483 __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0); |
| 484 BranchOrBacktrack(not_equal, on_bit_set); | 484 BranchOrBacktrack(not_equal, on_bit_set); |
| 485 } | 485 } |
| 486 | 486 |
| 487 | 487 |
| 488 bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, | 488 bool RegExpMacroAssemblerX87::CheckSpecialCharacterClass(uc16 type, |
| 489 Label* on_no_match) { | 489 Label* on_no_match) { |
| 490 // Range checks (c in min..max) are generally implemented by an unsigned | 490 // Range checks (c in min..max) are generally implemented by an unsigned |
| 491 // (c - min) <= (max - min) check | 491 // (c - min) <= (max - min) check |
| 492 switch (type) { | 492 switch (type) { |
| 493 case 's': | 493 case 's': |
| 494 // Match space-characters | 494 // Match space-characters |
| 495 if (mode_ == ASCII) { | 495 if (mode_ == ASCII) { |
| 496 // One byte space characters are '\t'..'\r', ' ' and \u00a0. | 496 // One byte space characters are '\t'..'\r', ' ' and \u00a0. |
| 497 Label success; | 497 Label success; |
| 498 __ cmp(current_character(), ' '); | 498 __ cmp(current_character(), ' '); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 } | 599 } |
| 600 return true; | 600 return true; |
| 601 } | 601 } |
| 602 // No custom implementation (yet): s(UC16), S(UC16). | 602 // No custom implementation (yet): s(UC16), S(UC16). |
| 603 default: | 603 default: |
| 604 return false; | 604 return false; |
| 605 } | 605 } |
| 606 } | 606 } |
| 607 | 607 |
| 608 | 608 |
| 609 void RegExpMacroAssemblerIA32::Fail() { | 609 void RegExpMacroAssemblerX87::Fail() { |
| 610 STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. | 610 STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. |
| 611 if (!global()) { | 611 if (!global()) { |
| 612 __ Move(eax, Immediate(FAILURE)); | 612 __ Move(eax, Immediate(FAILURE)); |
| 613 } | 613 } |
| 614 __ jmp(&exit_label_); | 614 __ jmp(&exit_label_); |
| 615 } | 615 } |
| 616 | 616 |
| 617 | 617 |
| 618 Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { | 618 Handle<HeapObject> RegExpMacroAssemblerX87::GetCode(Handle<String> source) { |
| 619 Label return_eax; | 619 Label return_eax; |
| 620 // Finalize code - write the entry point code now we know how many | 620 // Finalize code - write the entry point code now we know how many |
| 621 // registers we need. | 621 // registers we need. |
| 622 | 622 |
| 623 // Entry code: | 623 // Entry code: |
| 624 __ bind(&entry_label_); | 624 __ bind(&entry_label_); |
| 625 | 625 |
| 626 // Tell the system that we have a stack frame. Because the type is MANUAL, no | 626 // Tell the system that we have a stack frame. Because the type is MANUAL, no |
| 627 // code is generated. | 627 // code is generated. |
| 628 FrameScope scope(masm_, StackFrame::MANUAL); | 628 FrameScope scope(masm_, StackFrame::MANUAL); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 masm_->GetCode(&code_desc); | 901 masm_->GetCode(&code_desc); |
| 902 Handle<Code> code = | 902 Handle<Code> code = |
| 903 isolate()->factory()->NewCode(code_desc, | 903 isolate()->factory()->NewCode(code_desc, |
| 904 Code::ComputeFlags(Code::REGEXP), | 904 Code::ComputeFlags(Code::REGEXP), |
| 905 masm_->CodeObject()); | 905 masm_->CodeObject()); |
| 906 PROFILE(isolate(), RegExpCodeCreateEvent(*code, *source)); | 906 PROFILE(isolate(), RegExpCodeCreateEvent(*code, *source)); |
| 907 return Handle<HeapObject>::cast(code); | 907 return Handle<HeapObject>::cast(code); |
| 908 } | 908 } |
| 909 | 909 |
| 910 | 910 |
| 911 void RegExpMacroAssemblerIA32::GoTo(Label* to) { | 911 void RegExpMacroAssemblerX87::GoTo(Label* to) { |
| 912 BranchOrBacktrack(no_condition, to); | 912 BranchOrBacktrack(no_condition, to); |
| 913 } | 913 } |
| 914 | 914 |
| 915 | 915 |
| 916 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg, | 916 void RegExpMacroAssemblerX87::IfRegisterGE(int reg, |
| 917 int comparand, | 917 int comparand, |
| 918 Label* if_ge) { | 918 Label* if_ge) { |
| 919 __ cmp(register_location(reg), Immediate(comparand)); | 919 __ cmp(register_location(reg), Immediate(comparand)); |
| 920 BranchOrBacktrack(greater_equal, if_ge); | 920 BranchOrBacktrack(greater_equal, if_ge); |
| 921 } | 921 } |
| 922 | 922 |
| 923 | 923 |
| 924 void RegExpMacroAssemblerIA32::IfRegisterLT(int reg, | 924 void RegExpMacroAssemblerX87::IfRegisterLT(int reg, |
| 925 int comparand, | 925 int comparand, |
| 926 Label* if_lt) { | 926 Label* if_lt) { |
| 927 __ cmp(register_location(reg), Immediate(comparand)); | 927 __ cmp(register_location(reg), Immediate(comparand)); |
| 928 BranchOrBacktrack(less, if_lt); | 928 BranchOrBacktrack(less, if_lt); |
| 929 } | 929 } |
| 930 | 930 |
| 931 | 931 |
| 932 void RegExpMacroAssemblerIA32::IfRegisterEqPos(int reg, | 932 void RegExpMacroAssemblerX87::IfRegisterEqPos(int reg, |
| 933 Label* if_eq) { | 933 Label* if_eq) { |
| 934 __ cmp(edi, register_location(reg)); | 934 __ cmp(edi, register_location(reg)); |
| 935 BranchOrBacktrack(equal, if_eq); | 935 BranchOrBacktrack(equal, if_eq); |
| 936 } | 936 } |
| 937 | 937 |
| 938 | 938 |
| 939 RegExpMacroAssembler::IrregexpImplementation | 939 RegExpMacroAssembler::IrregexpImplementation |
| 940 RegExpMacroAssemblerIA32::Implementation() { | 940 RegExpMacroAssemblerX87::Implementation() { |
| 941 return kIA32Implementation; | 941 return kX87Implementation; |
| 942 } | 942 } |
| 943 | 943 |
| 944 | 944 |
| 945 void RegExpMacroAssemblerIA32::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 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. |
| 950 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 950 ASSERT(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 RegExpMacroAssemblerIA32::PopCurrentPosition() { | 958 void RegExpMacroAssemblerX87::PopCurrentPosition() { |
| 959 Pop(edi); | 959 Pop(edi); |
| 960 } | 960 } |
| 961 | 961 |
| 962 | 962 |
| 963 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { | 963 void RegExpMacroAssemblerX87::PopRegister(int register_index) { |
| 964 Pop(eax); | 964 Pop(eax); |
| 965 __ mov(register_location(register_index), eax); | 965 __ mov(register_location(register_index), eax); |
| 966 } | 966 } |
| 967 | 967 |
| 968 | 968 |
| 969 void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) { | 969 void RegExpMacroAssemblerX87::PushBacktrack(Label* label) { |
| 970 Push(Immediate::CodeRelativeOffset(label)); | 970 Push(Immediate::CodeRelativeOffset(label)); |
| 971 CheckStackLimit(); | 971 CheckStackLimit(); |
| 972 } | 972 } |
| 973 | 973 |
| 974 | 974 |
| 975 void RegExpMacroAssemblerIA32::PushCurrentPosition() { | 975 void RegExpMacroAssemblerX87::PushCurrentPosition() { |
| 976 Push(edi); | 976 Push(edi); |
| 977 } | 977 } |
| 978 | 978 |
| 979 | 979 |
| 980 void RegExpMacroAssemblerIA32::PushRegister(int register_index, | 980 void RegExpMacroAssemblerX87::PushRegister(int register_index, |
| 981 StackCheckFlag check_stack_limit) { | 981 StackCheckFlag check_stack_limit) { |
| 982 __ mov(eax, register_location(register_index)); | 982 __ mov(eax, register_location(register_index)); |
| 983 Push(eax); | 983 Push(eax); |
| 984 if (check_stack_limit) CheckStackLimit(); | 984 if (check_stack_limit) CheckStackLimit(); |
| 985 } | 985 } |
| 986 | 986 |
| 987 | 987 |
| 988 void RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(int reg) { | 988 void RegExpMacroAssemblerX87::ReadCurrentPositionFromRegister(int reg) { |
| 989 __ mov(edi, register_location(reg)); | 989 __ mov(edi, register_location(reg)); |
| 990 } | 990 } |
| 991 | 991 |
| 992 | 992 |
| 993 void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) { | 993 void RegExpMacroAssemblerX87::ReadStackPointerFromRegister(int reg) { |
| 994 __ mov(backtrack_stackpointer(), register_location(reg)); | 994 __ mov(backtrack_stackpointer(), register_location(reg)); |
| 995 __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); | 995 __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); |
| 996 } | 996 } |
| 997 | 997 |
| 998 void RegExpMacroAssemblerIA32::SetCurrentPositionFromEnd(int by) { | 998 void RegExpMacroAssemblerX87::SetCurrentPositionFromEnd(int by) { |
| 999 Label after_position; | 999 Label after_position; |
| 1000 __ cmp(edi, -by * char_size()); | 1000 __ cmp(edi, -by * char_size()); |
| 1001 __ j(greater_equal, &after_position, Label::kNear); | 1001 __ j(greater_equal, &after_position, Label::kNear); |
| 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 RegExpMacroAssemblerIA32::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 ASSERT(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 RegExpMacroAssemblerIA32::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 RegExpMacroAssemblerIA32::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 RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) { | 1034 void RegExpMacroAssemblerX87::ClearRegisters(int reg_from, int reg_to) { |
| 1035 ASSERT(reg_from <= reg_to); | 1035 ASSERT(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 RegExpMacroAssemblerIA32::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)); |
| 1046 __ mov(register_location(reg), eax); | 1046 __ mov(register_location(reg), eax); |
| 1047 } | 1047 } |
| 1048 | 1048 |
| 1049 | 1049 |
| 1050 // Private methods: | 1050 // Private methods: |
| 1051 | 1051 |
| 1052 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { | 1052 void RegExpMacroAssemblerX87::CallCheckStackGuardState(Register scratch) { |
| 1053 static const int num_arguments = 3; | 1053 static const int num_arguments = 3; |
| 1054 __ PrepareCallCFunction(num_arguments, scratch); | 1054 __ PrepareCallCFunction(num_arguments, scratch); |
| 1055 // RegExp code frame pointer. | 1055 // RegExp code frame pointer. |
| 1056 __ mov(Operand(esp, 2 * kPointerSize), ebp); | 1056 __ mov(Operand(esp, 2 * kPointerSize), ebp); |
| 1057 // Code* of self. | 1057 // Code* of self. |
| 1058 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); | 1058 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); |
| 1059 // Next address on the stack (will be address of return address). | 1059 // Next address on the stack (will be address of return address). |
| 1060 __ lea(eax, Operand(esp, -kPointerSize)); | 1060 __ lea(eax, Operand(esp, -kPointerSize)); |
| 1061 __ mov(Operand(esp, 0 * kPointerSize), eax); | 1061 __ mov(Operand(esp, 0 * kPointerSize), eax); |
| 1062 ExternalReference check_stack_guard = | 1062 ExternalReference check_stack_guard = |
| 1063 ExternalReference::re_check_stack_guard_state(isolate()); | 1063 ExternalReference::re_check_stack_guard_state(isolate()); |
| 1064 __ CallCFunction(check_stack_guard, num_arguments); | 1064 __ CallCFunction(check_stack_guard, num_arguments); |
| 1065 } | 1065 } |
| 1066 | 1066 |
| 1067 | 1067 |
| 1068 // Helper function for reading a value out of a stack frame. | 1068 // Helper function for reading a value out of a stack frame. |
| 1069 template <typename T> | 1069 template <typename T> |
| 1070 static T& frame_entry(Address re_frame, int frame_offset) { | 1070 static T& frame_entry(Address re_frame, int frame_offset) { |
| 1071 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); | 1071 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); |
| 1072 } | 1072 } |
| 1073 | 1073 |
| 1074 | 1074 |
| 1075 int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, | 1075 int RegExpMacroAssemblerX87::CheckStackGuardState(Address* return_address, |
| 1076 Code* re_code, | 1076 Code* re_code, |
| 1077 Address re_frame) { | 1077 Address re_frame) { |
| 1078 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); | 1078 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); |
| 1079 if (isolate->stack_guard()->IsStackOverflow()) { | 1079 if (isolate->stack_guard()->IsStackOverflow()) { |
| 1080 isolate->StackOverflow(); | 1080 isolate->StackOverflow(); |
| 1081 return EXCEPTION; | 1081 return EXCEPTION; |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 // If not real stack overflow the stack guard was used to interrupt | 1084 // If not real stack overflow the stack guard was used to interrupt |
| 1085 // execution for another purpose. | 1085 // execution for another purpose. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 // Subject string might have been a ConsString that underwent | 1163 // Subject string might have been a ConsString that underwent |
| 1164 // short-circuiting during GC. That will not change start_address but | 1164 // short-circuiting during GC. That will not change start_address but |
| 1165 // will change pointer inside the subject handle. | 1165 // will change pointer inside the subject handle. |
| 1166 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1166 frame_entry<const String*>(re_frame, kInputString) = *subject; |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 return 0; | 1169 return 0; |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 | 1172 |
| 1173 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { | 1173 Operand RegExpMacroAssemblerX87::register_location(int register_index) { |
| 1174 ASSERT(register_index < (1<<30)); | 1174 ASSERT(register_index < (1<<30)); |
| 1175 if (num_registers_ <= register_index) { | 1175 if (num_registers_ <= register_index) { |
| 1176 num_registers_ = register_index + 1; | 1176 num_registers_ = register_index + 1; |
| 1177 } | 1177 } |
| 1178 return Operand(ebp, kRegisterZero - register_index * kPointerSize); | 1178 return Operand(ebp, kRegisterZero - register_index * kPointerSize); |
| 1179 } | 1179 } |
| 1180 | 1180 |
| 1181 | 1181 |
| 1182 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, | 1182 void RegExpMacroAssemblerX87::CheckPosition(int cp_offset, |
| 1183 Label* on_outside_input) { | 1183 Label* on_outside_input) { |
| 1184 __ cmp(edi, -cp_offset * char_size()); | 1184 __ cmp(edi, -cp_offset * char_size()); |
| 1185 BranchOrBacktrack(greater_equal, on_outside_input); | 1185 BranchOrBacktrack(greater_equal, on_outside_input); |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 | 1188 |
| 1189 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, | 1189 void RegExpMacroAssemblerX87::BranchOrBacktrack(Condition condition, |
| 1190 Label* to) { | 1190 Label* to) { |
| 1191 if (condition < 0) { // No condition | 1191 if (condition < 0) { // No condition |
| 1192 if (to == NULL) { | 1192 if (to == NULL) { |
| 1193 Backtrack(); | 1193 Backtrack(); |
| 1194 return; | 1194 return; |
| 1195 } | 1195 } |
| 1196 __ jmp(to); | 1196 __ jmp(to); |
| 1197 return; | 1197 return; |
| 1198 } | 1198 } |
| 1199 if (to == NULL) { | 1199 if (to == NULL) { |
| 1200 __ j(condition, &backtrack_label_); | 1200 __ j(condition, &backtrack_label_); |
| 1201 return; | 1201 return; |
| 1202 } | 1202 } |
| 1203 __ j(condition, to); | 1203 __ j(condition, to); |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 | 1206 |
| 1207 void RegExpMacroAssemblerIA32::SafeCall(Label* to) { | 1207 void RegExpMacroAssemblerX87::SafeCall(Label* to) { |
| 1208 Label return_to; | 1208 Label return_to; |
| 1209 __ push(Immediate::CodeRelativeOffset(&return_to)); | 1209 __ push(Immediate::CodeRelativeOffset(&return_to)); |
| 1210 __ jmp(to); | 1210 __ jmp(to); |
| 1211 __ bind(&return_to); | 1211 __ bind(&return_to); |
| 1212 } | 1212 } |
| 1213 | 1213 |
| 1214 | 1214 |
| 1215 void RegExpMacroAssemblerIA32::SafeReturn() { | 1215 void RegExpMacroAssemblerX87::SafeReturn() { |
| 1216 __ pop(ebx); | 1216 __ pop(ebx); |
| 1217 __ add(ebx, Immediate(masm_->CodeObject())); | 1217 __ add(ebx, Immediate(masm_->CodeObject())); |
| 1218 __ jmp(ebx); | 1218 __ jmp(ebx); |
| 1219 } | 1219 } |
| 1220 | 1220 |
| 1221 | 1221 |
| 1222 void RegExpMacroAssemblerIA32::SafeCallTarget(Label* name) { | 1222 void RegExpMacroAssemblerX87::SafeCallTarget(Label* name) { |
| 1223 __ bind(name); | 1223 __ bind(name); |
| 1224 } | 1224 } |
| 1225 | 1225 |
| 1226 | 1226 |
| 1227 void RegExpMacroAssemblerIA32::Push(Register source) { | 1227 void RegExpMacroAssemblerX87::Push(Register source) { |
| 1228 ASSERT(!source.is(backtrack_stackpointer())); | 1228 ASSERT(!source.is(backtrack_stackpointer())); |
| 1229 // Notice: This updates flags, unlike normal Push. | 1229 // Notice: This updates flags, unlike normal Push. |
| 1230 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); | 1230 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); |
| 1231 __ mov(Operand(backtrack_stackpointer(), 0), source); | 1231 __ mov(Operand(backtrack_stackpointer(), 0), source); |
| 1232 } | 1232 } |
| 1233 | 1233 |
| 1234 | 1234 |
| 1235 void RegExpMacroAssemblerIA32::Push(Immediate value) { | 1235 void RegExpMacroAssemblerX87::Push(Immediate value) { |
| 1236 // Notice: This updates flags, unlike normal Push. | 1236 // Notice: This updates flags, unlike normal Push. |
| 1237 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); | 1237 __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); |
| 1238 __ mov(Operand(backtrack_stackpointer(), 0), value); | 1238 __ mov(Operand(backtrack_stackpointer(), 0), value); |
| 1239 } | 1239 } |
| 1240 | 1240 |
| 1241 | 1241 |
| 1242 void RegExpMacroAssemblerIA32::Pop(Register target) { | 1242 void RegExpMacroAssemblerX87::Pop(Register target) { |
| 1243 ASSERT(!target.is(backtrack_stackpointer())); | 1243 ASSERT(!target.is(backtrack_stackpointer())); |
| 1244 __ mov(target, Operand(backtrack_stackpointer(), 0)); | 1244 __ mov(target, Operand(backtrack_stackpointer(), 0)); |
| 1245 // Notice: This updates flags, unlike normal Pop. | 1245 // Notice: This updates flags, unlike normal Pop. |
| 1246 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); | 1246 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); |
| 1247 } | 1247 } |
| 1248 | 1248 |
| 1249 | 1249 |
| 1250 void RegExpMacroAssemblerIA32::CheckPreemption() { | 1250 void RegExpMacroAssemblerX87::CheckPreemption() { |
| 1251 // Check for preemption. | 1251 // Check for preemption. |
| 1252 Label no_preempt; | 1252 Label no_preempt; |
| 1253 ExternalReference stack_limit = | 1253 ExternalReference stack_limit = |
| 1254 ExternalReference::address_of_stack_limit(isolate()); | 1254 ExternalReference::address_of_stack_limit(isolate()); |
| 1255 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 1255 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
| 1256 __ j(above, &no_preempt); | 1256 __ j(above, &no_preempt); |
| 1257 | 1257 |
| 1258 SafeCall(&check_preempt_label_); | 1258 SafeCall(&check_preempt_label_); |
| 1259 | 1259 |
| 1260 __ bind(&no_preempt); | 1260 __ bind(&no_preempt); |
| 1261 } | 1261 } |
| 1262 | 1262 |
| 1263 | 1263 |
| 1264 void RegExpMacroAssemblerIA32::CheckStackLimit() { | 1264 void RegExpMacroAssemblerX87::CheckStackLimit() { |
| 1265 Label no_stack_overflow; | 1265 Label no_stack_overflow; |
| 1266 ExternalReference stack_limit = | 1266 ExternalReference stack_limit = |
| 1267 ExternalReference::address_of_regexp_stack_limit(isolate()); | 1267 ExternalReference::address_of_regexp_stack_limit(isolate()); |
| 1268 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); | 1268 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); |
| 1269 __ j(above, &no_stack_overflow); | 1269 __ j(above, &no_stack_overflow); |
| 1270 | 1270 |
| 1271 SafeCall(&stack_overflow_label_); | 1271 SafeCall(&stack_overflow_label_); |
| 1272 | 1272 |
| 1273 __ bind(&no_stack_overflow); | 1273 __ bind(&no_stack_overflow); |
| 1274 } | 1274 } |
| 1275 | 1275 |
| 1276 | 1276 |
| 1277 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, | 1277 void RegExpMacroAssemblerX87::LoadCurrentCharacterUnchecked(int cp_offset, |
| 1278 int characters) { | 1278 int characters) { |
| 1279 if (mode_ == ASCII) { | 1279 if (mode_ == ASCII) { |
| 1280 if (characters == 4) { | 1280 if (characters == 4) { |
| 1281 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1281 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); |
| 1282 } else if (characters == 2) { | 1282 } else if (characters == 2) { |
| 1283 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1283 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); |
| 1284 } else { | 1284 } else { |
| 1285 ASSERT(characters == 1); | 1285 ASSERT(characters == 1); |
| 1286 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1286 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); |
| 1287 } | 1287 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1298 } | 1298 } |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 | 1301 |
| 1302 #undef __ | 1302 #undef __ |
| 1303 | 1303 |
| 1304 #endif // V8_INTERPRETED_REGEXP | 1304 #endif // V8_INTERPRETED_REGEXP |
| 1305 | 1305 |
| 1306 }} // namespace v8::internal | 1306 }} // namespace v8::internal |
| 1307 | 1307 |
| 1308 #endif // V8_TARGET_ARCH_IA32 | 1308 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |