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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 7736010: MIPS: port Tentative implementation of string slices (hidden under the flag --string-slices). (Closed)
Patch Set: Created 9 years, 3 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
« no previous file with comments | « no previous file | src/mips/regexp-macro-assembler-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 4499 matching lines...) Expand 10 before | Expand all | Expand 10 after
4510 __ lw(a0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset)); 4510 __ lw(a0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset));
4511 __ Branch(&runtime, ne, a0, Operand( 4511 __ Branch(&runtime, ne, a0, Operand(
4512 masm->isolate()->factory()->fixed_array_map())); 4512 masm->isolate()->factory()->fixed_array_map()));
4513 // Check that the last match info has space for the capture registers and the 4513 // Check that the last match info has space for the capture registers and the
4514 // additional information. 4514 // additional information.
4515 __ lw(a0, 4515 __ lw(a0,
4516 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset)); 4516 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
4517 __ Addu(a2, a2, Operand(RegExpImpl::kLastMatchOverhead)); 4517 __ Addu(a2, a2, Operand(RegExpImpl::kLastMatchOverhead));
4518 __ sra(at, a0, kSmiTagSize); // Untag length for comparison. 4518 __ sra(at, a0, kSmiTagSize); // Untag length for comparison.
4519 __ Branch(&runtime, gt, a2, Operand(at)); 4519 __ Branch(&runtime, gt, a2, Operand(at));
4520
4521 // Reset offset for possibly sliced string.
4522 __ mov(t0, zero_reg);
4520 // subject: Subject string 4523 // subject: Subject string
4521 // regexp_data: RegExp data (FixedArray) 4524 // regexp_data: RegExp data (FixedArray)
4522 // Check the representation and encoding of the subject string. 4525 // Check the representation and encoding of the subject string.
4523 Label seq_string; 4526 Label seq_string;
4524 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); 4527 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
4525 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); 4528 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
4526 // First check for flat string. 4529 // First check for flat string.
4527 __ And(at, a0, Operand(kIsNotStringMask | kStringRepresentationMask)); 4530 __ And(at, a0, Operand(kIsNotStringMask | kStringRepresentationMask));
4528 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); 4531 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
4529 __ Branch(&seq_string, eq, at, Operand(zero_reg)); 4532 __ Branch(&seq_string, eq, at, Operand(zero_reg));
4530 4533
4531 // subject: Subject string 4534 // subject: Subject string
4532 // a0: instance type if Subject string 4535 // a0: instance type if Subject string
4533 // regexp_data: RegExp data (FixedArray) 4536 // regexp_data: RegExp data (FixedArray)
4534 // Check for flat cons string. 4537 // Check for flat cons string or sliced string.
4535 // A flat cons string is a cons string where the second part is the empty 4538 // A flat cons string is a cons string where the second part is the empty
4536 // string. In that case the subject string is just the first part of the cons 4539 // string. In that case the subject string is just the first part of the cons
4537 // string. Also in this case the first part of the cons string is known to be 4540 // string. Also in this case the first part of the cons string is known to be
4538 // a sequential string or an external string. 4541 // a sequential string or an external string.
4539 STATIC_ASSERT(kExternalStringTag != 0); 4542 // In the case of a sliced string its offset has to be taken into account.
4540 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 4543 Label cons_string, check_encoding;
4541 __ And(at, a0, Operand(kIsNotStringMask | kExternalStringTag)); 4544 STATIC_ASSERT((kConsStringTag < kExternalStringTag));
4542 __ Branch(&runtime, ne, at, Operand(zero_reg)); 4545 STATIC_ASSERT((kSlicedStringTag > kExternalStringTag));
4546 __ Branch(&cons_string, lt, at, Operand(kExternalStringTag));
4547 __ Branch(&runtime, eq, at, Operand(kExternalStringTag));
4548
4549 // String is sliced.
4550 __ lw(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset));
4551 __ sra(t0, t0, kSmiTagSize);
4552 __ lw(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
4553 // t5: offset of sliced string, smi-tagged.
4554 __ jmp(&check_encoding);
4555 // String is a cons string, check whether it is flat.
4556 __ bind(&cons_string);
4543 __ lw(a0, FieldMemOperand(subject, ConsString::kSecondOffset)); 4557 __ lw(a0, FieldMemOperand(subject, ConsString::kSecondOffset));
4544 __ LoadRoot(a1, Heap::kEmptyStringRootIndex); 4558 __ LoadRoot(a1, Heap::kEmptyStringRootIndex);
4545 __ Branch(&runtime, ne, a0, Operand(a1)); 4559 __ Branch(&runtime, ne, a0, Operand(a1));
4546 __ lw(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); 4560 __ lw(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
4561 // Is first part of cons or parent of slice a flat string?
4562 __ bind(&check_encoding);
4547 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); 4563 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
4548 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); 4564 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
4549 // Is first part a flat string?
4550 STATIC_ASSERT(kSeqStringTag == 0); 4565 STATIC_ASSERT(kSeqStringTag == 0);
4551 __ And(at, a0, Operand(kStringRepresentationMask)); 4566 __ And(at, a0, Operand(kStringRepresentationMask));
4552 __ Branch(&runtime, ne, at, Operand(zero_reg)); 4567 __ Branch(&runtime, ne, at, Operand(zero_reg));
4553 4568
4554 __ bind(&seq_string); 4569 __ bind(&seq_string);
4555 // subject: Subject string 4570 // subject: Subject string
4556 // regexp_data: RegExp data (FixedArray) 4571 // regexp_data: RegExp data (FixedArray)
4557 // a0: Instance type of subject string 4572 // a0: Instance type of subject string
4558 STATIC_ASSERT(kStringEncodingMask == 4); 4573 STATIC_ASSERT(kStringEncodingMask == 4);
4559 STATIC_ASSERT(kAsciiStringTag == 4); 4574 STATIC_ASSERT(kAsciiStringTag == 4);
4560 STATIC_ASSERT(kTwoByteStringTag == 0); 4575 STATIC_ASSERT(kTwoByteStringTag == 0);
4561 // Find the code object based on the assumptions above. 4576 // Find the code object based on the assumptions above.
4562 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ascii. 4577 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ascii.
4563 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset)); 4578 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset));
4564 __ sra(a3, a0, 2); // a3 is 1 for ascii, 0 for UC16 (usyed below). 4579 __ sra(a3, a0, 2); // a3 is 1 for ascii, 0 for UC16 (usyed below).
4565 __ lw(t0, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset)); 4580 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
4566 __ movz(t9, t0, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset. 4581 __ movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.
4567 4582
4568 // Check that the irregexp code has been generated for the actual string 4583 // Check that the irregexp code has been generated for the actual string
4569 // encoding. If it has, the field contains a code object otherwise it contains 4584 // encoding. If it has, the field contains a code object otherwise it contains
4570 // a smi (code flushing support). 4585 // a smi (code flushing support).
4571 __ JumpIfSmi(t9, &runtime); 4586 __ JumpIfSmi(t9, &runtime);
4572 4587
4573 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); 4588 // a3: encoding of subject string (1 if ASCII, 0 if two_byte);
4574 // t9: code 4589 // t9: code
4575 // subject: Subject string 4590 // subject: Subject string
4576 // regexp_data: RegExp data (FixedArray) 4591 // regexp_data: RegExp data (FixedArray)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4623 __ addu(a0, a0, a2); 4638 __ addu(a0, a0, a2);
4624 __ sw(a0, MemOperand(sp, 2 * kPointerSize)); 4639 __ sw(a0, MemOperand(sp, 2 * kPointerSize));
4625 4640
4626 // Argument 5: static offsets vector buffer. 4641 // Argument 5: static offsets vector buffer.
4627 __ li(a0, Operand( 4642 __ li(a0, Operand(
4628 ExternalReference::address_of_static_offsets_vector(masm->isolate()))); 4643 ExternalReference::address_of_static_offsets_vector(masm->isolate())));
4629 __ sw(a0, MemOperand(sp, 1 * kPointerSize)); 4644 __ sw(a0, MemOperand(sp, 1 * kPointerSize));
4630 4645
4631 // For arguments 4 and 3 get string length, calculate start of string data 4646 // For arguments 4 and 3 get string length, calculate start of string data
4632 // and calculate the shift of the index (0 for ASCII and 1 for two byte). 4647 // and calculate the shift of the index (0 for ASCII and 1 for two byte).
4633 __ lw(a0, FieldMemOperand(subject, String::kLengthOffset));
4634 __ sra(a0, a0, kSmiTagSize);
4635 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); 4648 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
4636 __ Addu(t0, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4649 __ Addu(t2, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4637 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte. 4650 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte.
4638 // Argument 4 (a3): End of string data 4651 // Load the length from the original subject string from the previous stack
4639 // Argument 3 (a2): Start of string data 4652 // frame. Therefore we have to use fp, which points exactly to two pointer
4653 // sizes below the previous sp. (Because creating a new stack frame pushes
4654 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
4655 __ lw(a0, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
4656 // If slice offset is not 0, load the length from the original sliced string.
4657 // Argument 4, a3: End of string data
4658 // Argument 3, a2: Start of string data
4659 // Prepare start and end index of the input.
4660 __ sllv(t1, t0, a3);
4661 __ addu(t0, t2, t1);
4640 __ sllv(t1, a1, a3); 4662 __ sllv(t1, a1, a3);
4641 __ addu(a2, t0, t1); 4663 __ addu(a2, t0, t1);
4642 __ sllv(t1, a0, a3); 4664
4665 __ lw(t2, FieldMemOperand(a0, String::kLengthOffset));
4666 __ sra(t2, t2, kSmiTagSize);
4667 __ sllv(t1, t2, a3);
4643 __ addu(a3, t0, t1); 4668 __ addu(a3, t0, t1);
4644
4645 // Argument 2 (a1): Previous index. 4669 // Argument 2 (a1): Previous index.
4646 // Already there 4670 // Already there
4647 4671
4648 // Argument 1 (a0): Subject string. 4672 // Argument 1 (a0): Subject string.
4649 __ mov(a0, subject); 4673 // Already there
4650 4674
4651 // Locate the code entry and call it. 4675 // Locate the code entry and call it.
4652 __ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag)); 4676 __ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag));
4653 DirectCEntryStub stub; 4677 DirectCEntryStub stub;
4654 stub.GenerateCall(masm, t9); 4678 stub.GenerateCall(masm, t9);
4655 4679
4656 __ LeaveExitFrame(false, no_reg); 4680 __ LeaveExitFrame(false, no_reg);
4657 4681
4658 // v0: result 4682 // v0: result
4659 // subject: subject string (callee saved) 4683 // subject: subject string (callee saved)
4660 // regexp_data: RegExp data (callee saved) 4684 // regexp_data: RegExp data (callee saved)
4661 // last_match_info_elements: Last match info elements (callee saved) 4685 // last_match_info_elements: Last match info elements (callee saved)
4662 4686
4663 // Check the result. 4687 // Check the result.
4664 4688
4665 Label success; 4689 Label success;
4666 __ Branch(&success, eq, v0, Operand(NativeRegExpMacroAssembler::SUCCESS)); 4690 __ Branch(&success, eq,
4691 subject, Operand(NativeRegExpMacroAssembler::SUCCESS));
4667 Label failure; 4692 Label failure;
4668 __ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE)); 4693 __ Branch(&failure, eq,
4694 subject, Operand(NativeRegExpMacroAssembler::FAILURE));
4669 // If not exception it can only be retry. Handle that in the runtime system. 4695 // If not exception it can only be retry. Handle that in the runtime system.
4670 __ Branch(&runtime, ne, v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); 4696 __ Branch(&runtime, ne,
4697 subject, Operand(NativeRegExpMacroAssembler::EXCEPTION));
4671 // Result must now be exception. If there is no pending exception already a 4698 // Result must now be exception. If there is no pending exception already a
4672 // stack overflow (on the backtrack stack) was detected in RegExp code but 4699 // stack overflow (on the backtrack stack) was detected in RegExp code but
4673 // haven't created the exception yet. Handle that in the runtime system. 4700 // haven't created the exception yet. Handle that in the runtime system.
4674 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 4701 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
4675 __ li(a1, Operand( 4702 __ li(a1, Operand(
4676 ExternalReference::the_hole_value_location(masm->isolate()))); 4703 ExternalReference::the_hole_value_location(masm->isolate())));
4677 __ lw(a1, MemOperand(a1, 0)); 4704 __ lw(a1, MemOperand(a1, 0));
4678 __ li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address, 4705 __ li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address,
4679 masm->isolate()))); 4706 masm->isolate())));
4680 __ lw(v0, MemOperand(a2, 0)); 4707 __ lw(v0, MemOperand(a2, 0));
4681 __ Branch(&runtime, eq, v0, Operand(a1)); 4708 __ Branch(&runtime, eq, subject, Operand(a1));
4682 4709
4683 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception. 4710 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception.
4684 4711
4685 // Check if the exception is a termination. If so, throw as uncatchable. 4712 // Check if the exception is a termination. If so, throw as uncatchable.
4686 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex); 4713 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex);
4687 Label termination_exception; 4714 Label termination_exception;
4688 __ Branch(&termination_exception, eq, v0, Operand(a0)); 4715 __ Branch(&termination_exception, eq, subject, Operand(a0));
4689 4716
4690 __ Throw(a0); // Expects thrown value in v0. 4717 __ Throw(subject); // Expects thrown value in v0.
4691 4718
4692 __ bind(&termination_exception); 4719 __ bind(&termination_exception);
4693 __ ThrowUncatchable(TERMINATION, v0); // Expects thrown value in v0. 4720 __ ThrowUncatchable(TERMINATION, v0); // Expects thrown value in v0.
4694 4721
4695 __ bind(&failure); 4722 __ bind(&failure);
4696 // For failure and exception return null. 4723 // For failure and exception return null.
4697 __ li(v0, Operand(masm->isolate()->factory()->null_value())); 4724 __ li(v0, Operand(masm->isolate()->factory()->null_value()));
4698 __ Addu(sp, sp, Operand(4 * kPointerSize)); 4725 __ Addu(sp, sp, Operand(4 * kPointerSize));
4699 __ Ret(); 4726 __ Ret();
4700 4727
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4956 | NeverNanNanField::encode(cc_ == eq ? never_nan_nan_ : false) 4983 | NeverNanNanField::encode(cc_ == eq ? never_nan_nan_ : false)
4957 | IncludeSmiCompareField::encode(include_smi_compare_); 4984 | IncludeSmiCompareField::encode(include_smi_compare_);
4958 } 4985 }
4959 4986
4960 4987
4961 // StringCharCodeAtGenerator. 4988 // StringCharCodeAtGenerator.
4962 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4989 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4963 Label flat_string; 4990 Label flat_string;
4964 Label ascii_string; 4991 Label ascii_string;
4965 Label got_char_code; 4992 Label got_char_code;
4993 Label sliced_string;
4966 4994
4967 ASSERT(!t0.is(scratch_)); 4995 ASSERT(!t0.is(scratch_));
4968 ASSERT(!t0.is(index_)); 4996 ASSERT(!t0.is(index_));
4969 ASSERT(!t0.is(result_)); 4997 ASSERT(!t0.is(result_));
4970 ASSERT(!t0.is(object_)); 4998 ASSERT(!t0.is(object_));
4971 4999
4972 // If the receiver is a smi trigger the non-string case. 5000 // If the receiver is a smi trigger the non-string case.
4973 __ JumpIfSmi(object_, receiver_not_string_); 5001 __ JumpIfSmi(object_, receiver_not_string_);
4974 5002
4975 // Fetch the instance type of the receiver into result register. 5003 // Fetch the instance type of the receiver into result register.
(...skipping 13 matching lines...) Expand all
4989 // Check for index out of range. 5017 // Check for index out of range.
4990 __ lw(t0, FieldMemOperand(object_, String::kLengthOffset)); 5018 __ lw(t0, FieldMemOperand(object_, String::kLengthOffset));
4991 __ Branch(index_out_of_range_, ls, t0, Operand(scratch_)); 5019 __ Branch(index_out_of_range_, ls, t0, Operand(scratch_));
4992 5020
4993 // We need special handling for non-flat strings. 5021 // We need special handling for non-flat strings.
4994 STATIC_ASSERT(kSeqStringTag == 0); 5022 STATIC_ASSERT(kSeqStringTag == 0);
4995 __ And(t0, result_, Operand(kStringRepresentationMask)); 5023 __ And(t0, result_, Operand(kStringRepresentationMask));
4996 __ Branch(&flat_string, eq, t0, Operand(zero_reg)); 5024 __ Branch(&flat_string, eq, t0, Operand(zero_reg));
4997 5025
4998 // Handle non-flat strings. 5026 // Handle non-flat strings.
4999 __ And(t0, result_, Operand(kIsConsStringMask)); 5027 __ And(result_, result_, Operand(kStringRepresentationMask));
5000 __ Branch(&call_runtime_, eq, t0, Operand(zero_reg)); 5028 STATIC_ASSERT((kConsStringTag < kExternalStringTag));
5029 STATIC_ASSERT((kSlicedStringTag > kExternalStringTag));
5030 __ Branch(&sliced_string, gt, result_, Operand(kExternalStringTag));
5031 __ Branch(&call_runtime_, eq, result_, Operand(kExternalStringTag));
5001 5032
5002 // ConsString. 5033 // ConsString.
5003 // Check whether the right hand side is the empty string (i.e. if 5034 // Check whether the right hand side is the empty string (i.e. if
5004 // this is really a flat string in a cons string). If that is not 5035 // this is really a flat string in a cons string). If that is not
5005 // the case we would rather go to the runtime system now to flatten 5036 // the case we would rather go to the runtime system now to flatten
5006 // the string. 5037 // the string.
5038 Label assure_seq_string;
5007 __ lw(result_, FieldMemOperand(object_, ConsString::kSecondOffset)); 5039 __ lw(result_, FieldMemOperand(object_, ConsString::kSecondOffset));
5008 __ LoadRoot(t0, Heap::kEmptyStringRootIndex); 5040 __ LoadRoot(t0, Heap::kEmptyStringRootIndex);
5009 __ Branch(&call_runtime_, ne, result_, Operand(t0)); 5041 __ Branch(&call_runtime_, ne, result_, Operand(t0));
5010 5042
5011 // Get the first of the two strings and load its instance type. 5043 // Get the first of the two strings and load its instance type.
5012 __ lw(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); 5044 __ lw(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
5045 __ jmp(&assure_seq_string);
5046
5047 // SlicedString, unpack and add offset.
5048 __ bind(&sliced_string);
5049 __ lw(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset));
5050 __ addu(scratch_, scratch_, result_);
5051 __ lw(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
5052
5053 // Assure that we are dealing with a sequential string. Go to runtime if not.
5054 __ bind(&assure_seq_string);
5013 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 5055 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
5014 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 5056 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
5015 // If the first cons component is also non-flat, then go to runtime. 5057 // Check that parent is not an external string. Go to runtime otherwise.
5016 STATIC_ASSERT(kSeqStringTag == 0); 5058 STATIC_ASSERT(kSeqStringTag == 0);
5017 5059
5018 __ And(t0, result_, Operand(kStringRepresentationMask)); 5060 __ And(t0, result_, Operand(kStringRepresentationMask));
5019 __ Branch(&call_runtime_, ne, t0, Operand(zero_reg)); 5061 __ Branch(&call_runtime_, ne, t0, Operand(zero_reg));
5020 5062
5021 // Check for 1-byte or 2-byte string. 5063 // Check for 1-byte or 2-byte string.
5022 __ bind(&flat_string); 5064 __ bind(&flat_string);
5023 STATIC_ASSERT(kAsciiStringTag != 0); 5065 STATIC_ASSERT(kAsciiStringTag != 0);
5024 __ And(t0, result_, Operand(kStringEncodingMask)); 5066 __ And(t0, result_, Operand(kStringEncodingMask));
5025 __ Branch(&ascii_string, ne, t0, Operand(zero_reg)); 5067 __ Branch(&ascii_string, ne, t0, Operand(zero_reg));
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
5576 // 0 <= from <= to <= string.length. 5618 // 0 <= from <= to <= string.length.
5577 // If any of these assumptions fail, we call the runtime system. 5619 // If any of these assumptions fail, we call the runtime system.
5578 5620
5579 static const int kToOffset = 0 * kPointerSize; 5621 static const int kToOffset = 0 * kPointerSize;
5580 static const int kFromOffset = 1 * kPointerSize; 5622 static const int kFromOffset = 1 * kPointerSize;
5581 static const int kStringOffset = 2 * kPointerSize; 5623 static const int kStringOffset = 2 * kPointerSize;
5582 5624
5583 Register to = t2; 5625 Register to = t2;
5584 Register from = t3; 5626 Register from = t3;
5585 5627
5628 if (FLAG_string_slices) {
5629 __ nop(); // Jumping as first instruction would crash the code generation.
5630 __ jmp(&sub_string_runtime);
5631 }
5632
5586 // Check bounds and smi-ness. 5633 // Check bounds and smi-ness.
5587 __ lw(to, MemOperand(sp, kToOffset)); 5634 __ lw(to, MemOperand(sp, kToOffset));
5588 __ lw(from, MemOperand(sp, kFromOffset)); 5635 __ lw(from, MemOperand(sp, kFromOffset));
5589 STATIC_ASSERT(kFromOffset == kToOffset + 4); 5636 STATIC_ASSERT(kFromOffset == kToOffset + 4);
5590 STATIC_ASSERT(kSmiTag == 0); 5637 STATIC_ASSERT(kSmiTag == 0);
5591 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 5638 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
5592 5639
5593 __ JumpIfNotSmi(from, &sub_string_runtime); 5640 __ JumpIfNotSmi(from, &sub_string_runtime);
5594 __ JumpIfNotSmi(to, &sub_string_runtime); 5641 __ JumpIfNotSmi(to, &sub_string_runtime);
5595 5642
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after
6821 __ mov(result, zero_reg); 6868 __ mov(result, zero_reg);
6822 __ Ret(); 6869 __ Ret();
6823 } 6870 }
6824 6871
6825 6872
6826 #undef __ 6873 #undef __
6827 6874
6828 } } // namespace v8::internal 6875 } } // namespace v8::internal
6829 6876
6830 #endif // V8_TARGET_ARCH_MIPS 6877 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips/regexp-macro-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698