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

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

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 4 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
« no previous file with comments | « no previous file | src/arm/lithium-arm.h » ('j') | src/heap.cc » ('J')
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 4757 matching lines...) Expand 10 before | Expand all | Expand 10 after
4768 | IncludeNumberCompareField::encode(include_number_compare_) 4768 | IncludeNumberCompareField::encode(include_number_compare_)
4769 | IncludeSmiCompareField::encode(include_smi_compare_); 4769 | IncludeSmiCompareField::encode(include_smi_compare_);
4770 } 4770 }
4771 4771
4772 4772
4773 // StringCharCodeAtGenerator 4773 // StringCharCodeAtGenerator
4774 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4774 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4775 Label flat_string; 4775 Label flat_string;
4776 Label ascii_string; 4776 Label ascii_string;
4777 Label got_char_code; 4777 Label got_char_code;
4778 Label sliced_string;
4778 4779
4779 // If the receiver is a smi trigger the non-string case. 4780 // If the receiver is a smi trigger the non-string case.
4780 __ JumpIfSmi(object_, receiver_not_string_); 4781 __ JumpIfSmi(object_, receiver_not_string_);
4781 4782
4782 // Fetch the instance type of the receiver into result register. 4783 // Fetch the instance type of the receiver into result register.
4783 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4784 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4784 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4785 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4785 // If the receiver is not a string trigger the non-string case. 4786 // If the receiver is not a string trigger the non-string case.
4786 __ tst(result_, Operand(kIsNotStringMask)); 4787 __ tst(result_, Operand(kIsNotStringMask));
4787 __ b(ne, receiver_not_string_); 4788 __ b(ne, receiver_not_string_);
4788 4789
4789 // If the index is non-smi trigger the non-smi case. 4790 // If the index is non-smi trigger the non-smi case.
4790 __ JumpIfNotSmi(index_, &index_not_smi_); 4791 __ JumpIfNotSmi(index_, &index_not_smi_);
4791 4792
4792 // Put smi-tagged index into scratch register. 4793 // Put smi-tagged index into scratch register.
4793 __ mov(scratch_, index_); 4794 __ mov(scratch_, index_);
4794 __ bind(&got_smi_index_); 4795 __ bind(&got_smi_index_);
4795 4796
4796 // Check for index out of range. 4797 // Check for index out of range.
4797 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); 4798 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset));
4798 __ cmp(ip, Operand(scratch_)); 4799 __ cmp(ip, Operand(scratch_));
4799 __ b(ls, index_out_of_range_); 4800 __ b(ls, index_out_of_range_);
4800 4801
4801 // We need special handling for non-flat strings. 4802 // We need special handling for non-flat strings.
4802 STATIC_ASSERT(kSeqStringTag == 0); 4803 STATIC_ASSERT(kSeqStringTag == 0);
4803 __ tst(result_, Operand(kStringRepresentationMask)); 4804 __ tst(result_, Operand(kStringRepresentationMask));
4804 __ b(eq, &flat_string); 4805 __ b(eq, &flat_string);
4805 4806
4806 // Handle non-flat strings. 4807 // Handle non-flat strings.
4807 __ tst(result_, Operand(kIsConsStringMask)); 4808 __ and_(result_, result_, Operand(kStringRepresentationMask));
4809 __ cmp(result_, Operand(kSlicedStringTag));
4810 __ b(eq, &sliced_string);
4811 __ cmp(result_, Operand(kExternalStringTag));
4808 __ b(eq, &call_runtime_); 4812 __ b(eq, &call_runtime_);
4809 4813
4810 // ConsString. 4814 // ConsString.
4811 // Check whether the right hand side is the empty string (i.e. if 4815 // Check whether the right hand side is the empty string (i.e. if
4812 // this is really a flat string in a cons string). If that is not 4816 // this is really a flat string in a cons string). If that is not
4813 // the case we would rather go to the runtime system now to flatten 4817 // the case we would rather go to the runtime system now to flatten
4814 // the string. 4818 // the string.
4815 __ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset)); 4819 __ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset));
4816 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); 4820 __ LoadRoot(ip, Heap::kEmptyStringRootIndex);
4817 __ cmp(result_, Operand(ip)); 4821 __ cmp(result_, Operand(ip));
4818 __ b(ne, &call_runtime_); 4822 __ b(ne, &call_runtime_);
4819 // Get the first of the two strings and load its instance type. 4823 // Get the first of the two strings and load its instance type.
4820 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); 4824 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
4821 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4825 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4822 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4826 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4823 // If the first cons component is also non-flat, then go to runtime. 4827 // If the first cons component is also non-flat, then go to runtime.
4824 STATIC_ASSERT(kSeqStringTag == 0); 4828 STATIC_ASSERT(kSeqStringTag == 0);
4825 __ tst(result_, Operand(kStringRepresentationMask)); 4829 __ tst(result_, Operand(kStringRepresentationMask));
4826 __ b(ne, &call_runtime_); 4830 __ b(ne, &call_runtime_);
4831 __ jmp(&flat_string);
4832
4833 // SlicedString, unpack and add offset.
4834 __ bind(&sliced_string);
4835 __ ldr(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset));
4836 __ add(scratch_, scratch_, result_);
4837 __ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
4838 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4839 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4827 4840
4828 // Check for 1-byte or 2-byte string. 4841 // Check for 1-byte or 2-byte string.
4829 __ bind(&flat_string); 4842 __ bind(&flat_string);
4830 STATIC_ASSERT(kAsciiStringTag != 0); 4843 STATIC_ASSERT(kAsciiStringTag != 0);
4831 __ tst(result_, Operand(kStringEncodingMask)); 4844 __ tst(result_, Operand(kStringEncodingMask));
4832 __ b(ne, &ascii_string); 4845 __ b(ne, &ascii_string);
4833 4846
4834 // 2-byte string. 4847 // 2-byte string.
4835 // Load the 2-byte character code into the result register. We can 4848 // Load the 2-byte character code into the result register. We can
4836 // add without shifting since the smi tag size is the log2 of the 4849 // add without shifting since the smi tag size is the log2 of the
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
5372 // hash += hash << 15; 5385 // hash += hash << 15;
5373 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); 5386 __ add(hash, hash, Operand(hash, LSL, 15), SetCC);
5374 5387
5375 // if (hash == 0) hash = 27; 5388 // if (hash == 0) hash = 27;
5376 __ mov(hash, Operand(27), LeaveCC, ne); 5389 __ mov(hash, Operand(27), LeaveCC, ne);
5377 } 5390 }
5378 5391
5379 5392
5380 void SubStringStub::Generate(MacroAssembler* masm) { 5393 void SubStringStub::Generate(MacroAssembler* masm) {
5381 Label runtime; 5394 Label runtime;
5382 5395
Yang 2011/07/27 11:51:58 Do not create string slice unless experimental fla
5396 if (FLAG_string_slices) {
5397 __ jmp(&runtime);
5398 }
5383 // Stack frame on entry. 5399 // Stack frame on entry.
5384 // lr: return address 5400 // lr: return address
5385 // sp[0]: to 5401 // sp[0]: to
5386 // sp[4]: from 5402 // sp[4]: from
5387 // sp[8]: string 5403 // sp[8]: string
5388 5404
5389 // This stub is called from the native-call %_SubString(...), so 5405 // This stub is called from the native-call %_SubString(...), so
5390 // nothing can be assumed about the arguments. It is tested that: 5406 // nothing can be assumed about the arguments. It is tested that:
5391 // "string" is a sequential string, 5407 // "string" is a sequential string,
5392 // both "from" and "to" are smis, and 5408 // both "from" and "to" are smis, and
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
5911 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 5927 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
5912 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 5928 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
5913 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 5929 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
5914 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 5930 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
5915 } 5931 }
5916 // Check that both strings are sequential. 5932 // Check that both strings are sequential.
5917 STATIC_ASSERT(kSeqStringTag == 0); 5933 STATIC_ASSERT(kSeqStringTag == 0);
5918 __ tst(r4, Operand(kStringRepresentationMask)); 5934 __ tst(r4, Operand(kStringRepresentationMask));
5919 __ tst(r5, Operand(kStringRepresentationMask), eq); 5935 __ tst(r5, Operand(kStringRepresentationMask), eq);
5920 __ b(ne, &string_add_runtime); 5936 __ b(ne, &string_add_runtime);
5937 // We cannot encounter sliced strings here since:
5938 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
5921 // Now check if both strings have the same encoding (ASCII/Two-byte). 5939 // Now check if both strings have the same encoding (ASCII/Two-byte).
5922 // r0: first string. 5940 // r0: first string.
5923 // r1: second string. 5941 // r1: second string.
5924 // r2: length of first string. 5942 // r2: length of first string.
5925 // r3: length of second string. 5943 // r3: length of second string.
5926 // r6: sum of lengths.. 5944 // r6: sum of lengths..
5927 Label non_ascii_string_add_flat_result; 5945 Label non_ascii_string_add_flat_result;
5928 ASSERT(IsPowerOf2(kStringEncodingMask)); // Just one bit to test. 5946 ASSERT(IsPowerOf2(kStringEncodingMask)); // Just one bit to test.
5929 __ eor(r7, r4, Operand(r5)); 5947 __ eor(r7, r4, Operand(r5));
5930 __ tst(r7, Operand(kStringEncodingMask)); 5948 __ tst(r7, Operand(kStringEncodingMask));
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
6535 __ mov(result, Operand(0)); 6553 __ mov(result, Operand(0));
6536 __ Ret(); 6554 __ Ret();
6537 } 6555 }
6538 6556
6539 6557
6540 #undef __ 6558 #undef __
6541 6559
6542 } } // namespace v8::internal 6560 } } // namespace v8::internal
6543 6561
6544 #endif // V8_TARGET_ARCH_ARM 6562 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/lithium-arm.h » ('j') | src/heap.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698