Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 548179: Port direct call from JavaScript to native RegExp to x64... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5116 matching lines...) Expand 10 before | Expand all | Expand 10 after
5127 __ bind(&not_a_flat_string); 5127 __ bind(&not_a_flat_string);
5128 __ and_(temp.reg(), kStringRepresentationMask); 5128 __ and_(temp.reg(), kStringRepresentationMask);
5129 __ cmp(temp.reg(), kConsStringTag); 5129 __ cmp(temp.reg(), kConsStringTag);
5130 __ j(not_equal, &slow_case); 5130 __ j(not_equal, &slow_case);
5131 5131
5132 // ConsString. 5132 // ConsString.
5133 // Check that the right hand side is the empty string (ie if this is really a 5133 // Check that the right hand side is the empty string (ie if this is really a
5134 // flat string in a cons string). If that is not the case we would rather go 5134 // flat string in a cons string). If that is not the case we would rather go
5135 // to the runtime system now, to flatten the string. 5135 // to the runtime system now, to flatten the string.
5136 __ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset)); 5136 __ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset));
5137 __ cmp(Operand(temp.reg()), Immediate(Handle<String>(Heap::empty_string()))); 5137 __ cmp(Operand(temp.reg()), Factory::empty_string());
5138 __ j(not_equal, &slow_case); 5138 __ j(not_equal, &slow_case);
5139 // Get the first of the two strings. 5139 // Get the first of the two strings.
5140 __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset)); 5140 __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
5141 __ jmp(&try_again_with_new_string); 5141 __ jmp(&try_again_with_new_string);
5142 5142
5143 __ bind(&slow_case); 5143 __ bind(&slow_case);
5144 // Move the undefined value into the result register, which will 5144 // Move the undefined value into the result register, which will
5145 // trigger the slow case. 5145 // trigger the slow case.
5146 __ Set(temp.reg(), Immediate(Factory::undefined_value())); 5146 __ Set(temp.reg(), Immediate(Factory::undefined_value()));
5147 5147
(...skipping 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after
8390 __ bind(&done); 8390 __ bind(&done);
8391 __ ret(3 * kPointerSize); 8391 __ ret(3 * kPointerSize);
8392 8392
8393 // Do the runtime call to allocate the arguments object. 8393 // Do the runtime call to allocate the arguments object.
8394 __ bind(&runtime); 8394 __ bind(&runtime);
8395 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); 8395 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
8396 } 8396 }
8397 8397
8398 8398
8399 void RegExpExecStub::Generate(MacroAssembler* masm) { 8399 void RegExpExecStub::Generate(MacroAssembler* masm) {
8400 // Just jump directly to runtime if regexp entry in generated code is turned 8400 // Just jump directly to runtime if native RegExp is not selected at compile
8401 // off. 8401 // time or if regexp entry in generated code is turned off runtime switch or
8402 // at compilation.
8403 #ifndef V8_NATIVE_REGEXP
8404 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
8405 #endif
Lasse Reichstein 2010/01/29 08:09:08 Perhaps use #else to make all the following code g
Søren Thygesen Gjesse 2010/01/29 13:06:53 Done.
8402 if (!FLAG_regexp_entry_native) { 8406 if (!FLAG_regexp_entry_native) {
8403 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); 8407 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
8404 return; 8408 return;
8405 } 8409 }
8406 8410
8407 // Stack frame on entry. 8411 // Stack frame on entry.
8408 // esp[0]: return address 8412 // esp[0]: return address
8409 // esp[4]: last_match_info (expected JSArray) 8413 // esp[4]: last_match_info (expected JSArray)
8410 // esp[8]: previous index 8414 // esp[8]: previous index
8411 // esp[12]: subject string 8415 // esp[12]: subject string
(...skipping 17 matching lines...) Expand all
8429 8433
8430 // Check that the first argument is a JSRegExp object. 8434 // Check that the first argument is a JSRegExp object.
8431 __ mov(eax, Operand(esp, kJSRegExpOffset)); 8435 __ mov(eax, Operand(esp, kJSRegExpOffset));
8432 ASSERT_EQ(0, kSmiTag); 8436 ASSERT_EQ(0, kSmiTag);
8433 __ test(eax, Immediate(kSmiTagMask)); 8437 __ test(eax, Immediate(kSmiTagMask));
8434 __ j(zero, &runtime); 8438 __ j(zero, &runtime);
8435 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); 8439 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
8436 __ j(not_equal, &runtime); 8440 __ j(not_equal, &runtime);
8437 // Check that the RegExp has been compiled (data contains a fixed array). 8441 // Check that the RegExp has been compiled (data contains a fixed array).
8438 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 8442 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
8439 #ifdef DEBUG 8443 if (FLAG_debug_code) {
8440 __ test(ecx, Immediate(kSmiTagMask)); 8444 __ test(ecx, Immediate(kSmiTagMask));
8441 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); 8445 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected");
8442 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx); 8446 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx);
8443 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected"); 8447 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
8444 #endif 8448 }
8445 8449
8446 // ecx: RegExp data (FixedArray) 8450 // ecx: RegExp data (FixedArray)
8447 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. 8451 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
8448 __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset)); 8452 __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset));
8449 __ cmp(Operand(ebx), Immediate(Smi::FromInt(JSRegExp::IRREGEXP))); 8453 __ cmp(Operand(ebx), Immediate(Smi::FromInt(JSRegExp::IRREGEXP)));
8450 __ j(not_equal, &runtime); 8454 __ j(not_equal, &runtime);
8451 8455
8452 // ecx: RegExp data (FixedArray) 8456 // ecx: RegExp data (FixedArray)
8453 // Check that the number of captures fit in the static offsets vector buffer. 8457 // Check that the number of captures fit in the static offsets vector buffer.
8454 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); 8458 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset));
(...skipping 14 matching lines...) Expand all
8469 __ j(zero, &runtime); 8473 __ j(zero, &runtime);
8470 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); 8474 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
8471 __ j(NegateCondition(is_string), &runtime); 8475 __ j(NegateCondition(is_string), &runtime);
8472 // Get the length of the string to ebx. 8476 // Get the length of the string to ebx.
8473 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); 8477 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
8474 8478
8475 // ebx: Length of subject string 8479 // ebx: Length of subject string
8476 // ecx: RegExp data (FixedArray) 8480 // ecx: RegExp data (FixedArray)
8477 // edx: Number of capture registers 8481 // edx: Number of capture registers
8478 // Check that the third argument is a positive smi. 8482 // Check that the third argument is a positive smi.
8483 // Check that the third argument is a positive smi less than the subject
8484 // string length. A negative value will be greater (usigned comparison).
8479 __ mov(eax, Operand(esp, kPreviousIndexOffset)); 8485 __ mov(eax, Operand(esp, kPreviousIndexOffset));
8480 __ test(eax, Immediate(kSmiTagMask | 0x80000000));
8481 __ j(not_zero, &runtime);
8482 // Check that it is not greater than the subject string length.
8483 __ SmiUntag(eax); 8486 __ SmiUntag(eax);
8484 __ cmp(eax, Operand(ebx)); 8487 __ cmp(eax, Operand(ebx));
8485 __ j(greater, &runtime); 8488 __ j(greater, &runtime);
8486 8489
8487 // ecx: RegExp data (FixedArray) 8490 // ecx: RegExp data (FixedArray)
8488 // edx: Number of capture registers 8491 // edx: Number of capture registers
8489 // Check that the fourth object is a JSArray object. 8492 // Check that the fourth object is a JSArray object.
8490 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); 8493 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
8491 __ test(eax, Immediate(kSmiTagMask)); 8494 __ test(eax, Immediate(kSmiTagMask));
8492 __ j(zero, &runtime); 8495 __ j(zero, &runtime);
(...skipping 24 matching lines...) Expand all
8517 ASSERT_EQ(0, kStringTag); 8520 ASSERT_EQ(0, kStringTag);
8518 ASSERT_EQ(0, kSeqStringTag); 8521 ASSERT_EQ(0, kSeqStringTag);
8519 __ test(Operand(ebx), 8522 __ test(Operand(ebx),
8520 Immediate(kIsNotStringMask | kStringRepresentationMask)); 8523 Immediate(kIsNotStringMask | kStringRepresentationMask));
8521 __ j(zero, &seq_string); 8524 __ j(zero, &seq_string);
8522 8525
8523 // Check for flat cons string. 8526 // Check for flat cons string.
8524 // A flat cons string is a cons string where the second part is the empty 8527 // A flat cons string is a cons string where the second part is the empty
8525 // string. In that case the subject string is just the first part of the cons 8528 // string. In that case the subject string is just the first part of the cons
8526 // string. Also in this case the first part of the cons string is known to be 8529 // string. Also in this case the first part of the cons string is known to be
8527 // a sequential string. 8530 // a sequential string or an external string.
8528 __ mov(edx, ebx); 8531 __ mov(edx, ebx);
8529 __ and_(edx, kStringRepresentationMask); 8532 __ and_(edx, kStringRepresentationMask);
8530 __ cmp(edx, kConsStringTag); 8533 __ cmp(edx, kConsStringTag);
8531 __ j(not_equal, &runtime); 8534 __ j(not_equal, &runtime);
8532 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); 8535 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
8533 __ cmp(Operand(edx), Immediate(Handle<String>(Heap::empty_string()))); 8536 __ cmp(Operand(edx), Factory::empty_string());
8534 __ j(not_equal, &runtime); 8537 __ j(not_equal, &runtime);
8535 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 8538 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
8536 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 8539 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
8537 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 8540 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
8541 ASSERT_EQ(0, kSequentialStringTag);
8542 __ test(ebx, Immediate(kStringRepresentationMask));
8543 __ j(not_zero, &runtime);
8538 __ and_(ebx, kStringRepresentationEncodingMask); 8544 __ and_(ebx, kStringRepresentationEncodingMask);
8539 8545
8540 __ bind(&seq_string); 8546 __ bind(&seq_string);
8541 // eax: subject string (sequential either ascii to two byte) 8547 // eax: subject string (sequential either ascii to two byte)
8542 // ebx: suject string type & kStringRepresentationEncodingMask 8548 // ebx: suject string type & kStringRepresentationEncodingMask
8543 // ecx: RegExp data (FixedArray) 8549 // ecx: RegExp data (FixedArray)
8544 // Check that the irregexp code has been generated for an ascii string. If 8550 // Check that the irregexp code has been generated for an ascii string. If
8545 // it has, the field contains a code object otherwise it contains the hole. 8551 // it has, the field contains a code object otherwise it contains the hole.
8546 __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag); 8552 __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag);
8547 __ j(equal, &seq_two_byte_string); 8553 __ j(equal, &seq_two_byte_string);
8548 #ifdef DEBUG 8554 if (FLAG_debug_code) {
8549 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag); 8555 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
8550 __ Check(equal, "Expected sequential ascii string"); 8556 __ Check(equal, "Expected sequential ascii string");
8551 #endif 8557 }
8552 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); 8558 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
8553 __ Set(edi, Immediate(1)); // Type is ascii. 8559 __ Set(edi, Immediate(1)); // Type is ascii.
8554 __ jmp(&check_code); 8560 __ jmp(&check_code);
8555 8561
8556 __ bind(&seq_two_byte_string); 8562 __ bind(&seq_two_byte_string);
8557 // eax: subject string 8563 // eax: subject string
8558 // ecx: RegExp data (FixedArray) 8564 // ecx: RegExp data (FixedArray)
8559 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); 8565 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
8560 __ Set(edi, Immediate(0)); // Type is two byte. 8566 __ Set(edi, Immediate(0)); // Type is two byte.
8561 8567
8562 __ bind(&check_code); 8568 __ bind(&check_code);
8563 // Check that the irregexp code has been generated for If it has, the field 8569 // Check that the irregexp code has been generated for the actual string
8564 // contains a code object otherwise it contains the hole. 8570 // encoding. If it has, the field contains a code object otherwise it contains
8571 // the hole.
8565 __ CmpObjectType(edx, CODE_TYPE, ebx); 8572 __ CmpObjectType(edx, CODE_TYPE, ebx);
8566 __ j(not_equal, &runtime); 8573 __ j(not_equal, &runtime);
8567 8574
8568 // eax: subject string 8575 // eax: subject string
8569 // edx: code 8576 // edx: code
8570 // edi: encoding of subject string (1 if ascii 0 if two_byte); 8577 // edi: encoding of subject string (1 if ascii, 0 if two_byte);
8571 // Load used arguments before starting to push arguments for call to native 8578 // Load used arguments before starting to push arguments for call to native
8572 // RegExp code to avoid handling changing stack height. 8579 // RegExp code to avoid handling changing stack height.
8573 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 8580 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
8574 __ mov(ecx, Operand(esp, kJSRegExpOffset));
8575 __ SmiUntag(ebx); // Previous index from smi. 8581 __ SmiUntag(ebx); // Previous index from smi.
8576 8582
8577 // eax: subject string 8583 // eax: subject string
8578 // ebx: previous index 8584 // ebx: previous index
8579 // edx: code 8585 // edx: code
8586 // edi: encoding of subject string (1 if ascii 0 if two_byte);
8580 // All checks done. Now push arguments for native regexp code. 8587 // All checks done. Now push arguments for native regexp code.
8581 __ IncrementCounter(&Counters::regexp_entry_native, 1); 8588 __ IncrementCounter(&Counters::regexp_entry_native, 1);
8582 8589
8583 // Argument 7: Indicate that this is a direct call from JavaScript. 8590 // Argument 7: Indicate that this is a direct call from JavaScript.
8584 __ push(Immediate(1)); 8591 __ push(Immediate(1));
8585 8592
8586 // Argument 6: Start (high end) of backtracking stack memory area. 8593 // Argument 6: Start (high end) of backtracking stack memory area.
8587 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); 8594 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address));
8588 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); 8595 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
8589 __ push(ecx); 8596 __ push(ecx);
8590 8597
8591 // Argument 5: static offsets vector buffer. 8598 // Argument 5: static offsets vector buffer.
8592 __ push(Immediate(ExternalReference::address_of_static_offsets_vector())); 8599 __ push(Immediate(ExternalReference::address_of_static_offsets_vector()));
8593 8600
8594 // Argument 4: End of string data 8601 // Argument 4: End of string data
8595 // Argument 3: Start of string data 8602 // Argument 3: Start of string data
8596 Label push_two_byte, push_rest; 8603 Label push_two_byte, push_rest;
8597 __ test(edi, Operand(edi)); 8604 __ test(edi, Operand(edi));
8598 __ mov(edi, FieldOperand(eax, String::kLengthOffset)); 8605 __ mov(edi, FieldOperand(eax, String::kLengthOffset));
8599 __ j(zero, &push_two_byte); 8606 __ j(zero, &push_two_byte);
8600 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize)); 8607 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize));
8601 __ push(ecx); // Argument 4. 8608 __ push(ecx); // Argument 4.
8602 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); 8609 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize));
8603 __ push(ecx); // Argument 3. 8610 __ push(ecx); // Argument 3.
8604 __ jmp(&push_rest); 8611 __ jmp(&push_rest);
8605 8612
8606 __ bind(&push_two_byte); 8613 __ bind(&push_two_byte);
8607 ASSERT(kShortSize == 2);
8608 __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize)); 8614 __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize));
8609 __ push(ecx); // Argument 4. 8615 __ push(ecx); // Argument 4.
8610 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); 8616 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize));
8611 __ push(ecx); // Argument 3. 8617 __ push(ecx); // Argument 3.
8612 8618
8613 __ bind(&push_rest); 8619 __ bind(&push_rest);
8614 8620
8615 // Argument 2: Previous index. 8621 // Argument 2: Previous index.
8616 __ push(ebx); 8622 __ push(ebx);
8617 8623
(...skipping 12 matching lines...) Expand all
8630 __ j(equal, &success, taken); 8636 __ j(equal, &success, taken);
8631 Label failure; 8637 Label failure;
8632 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); 8638 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE);
8633 __ j(equal, &failure, taken); 8639 __ j(equal, &failure, taken);
8634 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); 8640 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION);
8635 // If not exception it can only be retry. Handle that in the runtime system. 8641 // If not exception it can only be retry. Handle that in the runtime system.
8636 __ j(not_equal, &runtime); 8642 __ j(not_equal, &runtime);
8637 // Result must now be exception. If there is no pending exception already a 8643 // Result must now be exception. If there is no pending exception already a
8638 // stack overflow (on the backtrack stack) was detected in RegExp code but 8644 // stack overflow (on the backtrack stack) was detected in RegExp code but
8639 // haven't created the exception yet. Handle that in the runtime system. 8645 // haven't created the exception yet. Handle that in the runtime system.
8646 // TODO(592) Rerunning the RegExp to get the stack overflow exception.
8640 ExternalReference pending_exception(Top::k_pending_exception_address); 8647 ExternalReference pending_exception(Top::k_pending_exception_address);
8641 __ mov(eax, 8648 __ mov(eax,
8642 Operand::StaticVariable(ExternalReference::the_hole_value_location())); 8649 Operand::StaticVariable(ExternalReference::the_hole_value_location()));
8643 __ cmp(eax, Operand::StaticVariable(pending_exception)); 8650 __ cmp(eax, Operand::StaticVariable(pending_exception));
8644 __ j(equal, &runtime); 8651 __ j(equal, &runtime);
8645 __ bind(&failure); 8652 __ bind(&failure);
8646 // For failure and exception return null. 8653 // For failure and exception return null.
8647 __ mov(Operand(eax), Factory::null_value()); 8654 __ mov(Operand(eax), Factory::null_value());
8648 __ ret(4 * kPointerSize); 8655 __ ret(4 * kPointerSize);
8649 8656
8650 // Load RegExp data. 8657 // Load RegExp data.
8651 __ bind(&success); 8658 __ bind(&success);
8652 __ mov(eax, Operand(esp, kJSRegExpOffset)); 8659 __ mov(eax, Operand(esp, kJSRegExpOffset));
8653 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 8660 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
8654 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); 8661 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset));
8655 // Calculate number of capture registers (number_of_captures + 1) * 2. 8662 // Calculate number of capture registers (number_of_captures + 1) * 2.
8663 ASSERT_EQ(0, kSmiTag);
8664 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
8656 __ add(Operand(edx), Immediate(2)); // edx was a smi. 8665 __ add(Operand(edx), Immediate(2)); // edx was a smi.
8657 8666
8658 // edx: Number of capture registers 8667 // edx: Number of capture registers
8659 // Load last_match_info which is still known to be a fast case JSArray. 8668 // Load last_match_info which is still known to be a fast case JSArray.
8660 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); 8669 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
8661 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); 8670 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
8662 8671
8663 // ebx: last_match_info backing store (FixedArray) 8672 // ebx: last_match_info backing store (FixedArray)
8664 // edx: number of capture registers 8673 // edx: number of capture registers
8665 // Store the capture count. 8674 // Store the capture count.
(...skipping 19 matching lines...) Expand all
8685 // ecx: offsets vector 8694 // ecx: offsets vector
8686 // edx: number of capture registers 8695 // edx: number of capture registers
8687 Label next_capture, done; 8696 Label next_capture, done;
8688 __ mov(eax, Operand(esp, kPreviousIndexOffset)); 8697 __ mov(eax, Operand(esp, kPreviousIndexOffset));
8689 // Capture register counter starts from number of capture registers and 8698 // Capture register counter starts from number of capture registers and
8690 // counts down until wraping after zero. 8699 // counts down until wraping after zero.
8691 __ bind(&next_capture); 8700 __ bind(&next_capture);
8692 __ sub(Operand(edx), Immediate(1)); 8701 __ sub(Operand(edx), Immediate(1));
8693 __ j(negative, &done); 8702 __ j(negative, &done);
8694 // Read the value from the static offsets vector buffer. 8703 // Read the value from the static offsets vector buffer.
8695 __ mov(edi, Operand(ecx, edx, times_pointer_size, 0)); 8704 __ mov(edi, Operand(ecx, edx, times_int_size, 0));
8696 // Perform explicit shift 8705 // Perform explicit shift
8697 ASSERT_EQ(0, kSmiTag); 8706 ASSERT_EQ(0, kSmiTag);
8698 __ shl(edi, kSmiTagSize); 8707 __ shl(edi, kSmiTagSize);
8699 // Add previous index (from its stack slot) if value is not negative. 8708 // Add previous index (from its stack slot) if value is not negative.
8700 Label capture_negative; 8709 Label capture_negative;
8701 // Carry flag set by shift above. 8710 // Carry flag set by shift above.
8702 __ j(negative, &capture_negative, not_taken); 8711 __ j(negative, &capture_negative, not_taken);
8703 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi). 8712 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi).
8704 __ bind(&capture_negative); 8713 __ bind(&capture_negative);
8705 // Store the smi value in the last match info. 8714 // Store the smi value in the last match info.
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
10091 10100
10092 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 10101 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
10093 // tagged as a small integer. 10102 // tagged as a small integer.
10094 __ bind(&runtime); 10103 __ bind(&runtime);
10095 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 10104 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
10096 } 10105 }
10097 10106
10098 #undef __ 10107 #undef __
10099 10108
10100 } } // namespace v8::internal 10109 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/x64/codegen-x64.cc » ('j') | src/x64/codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698