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

Side by Side Diff: src/x64/code-stubs-x64.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: Implemented some changes suggested by Anton. 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
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 2285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 // Ensure that a RegExp stack is allocated. 2296 // Ensure that a RegExp stack is allocated.
2297 Isolate* isolate = masm->isolate(); 2297 Isolate* isolate = masm->isolate();
2298 ExternalReference address_of_regexp_stack_memory_address = 2298 ExternalReference address_of_regexp_stack_memory_address =
2299 ExternalReference::address_of_regexp_stack_memory_address(isolate); 2299 ExternalReference::address_of_regexp_stack_memory_address(isolate);
2300 ExternalReference address_of_regexp_stack_memory_size = 2300 ExternalReference address_of_regexp_stack_memory_size =
2301 ExternalReference::address_of_regexp_stack_memory_size(isolate); 2301 ExternalReference::address_of_regexp_stack_memory_size(isolate);
2302 __ Load(kScratchRegister, address_of_regexp_stack_memory_size); 2302 __ Load(kScratchRegister, address_of_regexp_stack_memory_size);
2303 __ testq(kScratchRegister, kScratchRegister); 2303 __ testq(kScratchRegister, kScratchRegister);
2304 __ j(zero, &runtime); 2304 __ j(zero, &runtime);
2305 2305
2306
2307 // Check that the first argument is a JSRegExp object. 2306 // Check that the first argument is a JSRegExp object.
2308 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2307 __ movq(rax, Operand(rsp, kJSRegExpOffset));
2309 __ JumpIfSmi(rax, &runtime); 2308 __ JumpIfSmi(rax, &runtime);
2310 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister); 2309 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
2311 __ j(not_equal, &runtime); 2310 __ j(not_equal, &runtime);
2312 // Check that the RegExp has been compiled (data contains a fixed array). 2311 // Check that the RegExp has been compiled (data contains a fixed array).
2313 __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset)); 2312 __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset));
2314 if (FLAG_debug_code) { 2313 if (FLAG_debug_code) {
2315 Condition is_smi = masm->CheckSmi(rax); 2314 Condition is_smi = masm->CheckSmi(rax);
2316 __ Check(NegateCondition(is_smi), 2315 __ Check(NegateCondition(is_smi),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 Label seq_ascii_string, seq_two_byte_string, check_code; 2378 Label seq_ascii_string, seq_two_byte_string, check_code;
2380 __ movq(rdi, Operand(rsp, kSubjectOffset)); 2379 __ movq(rdi, Operand(rsp, kSubjectOffset));
2381 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2380 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2382 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 2381 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
2383 // First check for flat two byte string. 2382 // First check for flat two byte string.
2384 __ andb(rbx, Immediate( 2383 __ andb(rbx, Immediate(
2385 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask)); 2384 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
2386 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 2385 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
2387 __ j(zero, &seq_two_byte_string, Label::kNear); 2386 __ j(zero, &seq_two_byte_string, Label::kNear);
2388 // Any other flat string must be a flat ascii string. 2387 // Any other flat string must be a flat ascii string.
2389 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask)); 2388 __ andb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
2390 __ j(zero, &seq_ascii_string, Label::kNear); 2389 __ j(zero, &seq_ascii_string, Label::kNear);
2391 2390
2392 // Check for flat cons string. 2391 // Check for flat cons string or truncated sliced string.
2393 // A flat cons string is a cons string where the second part is the empty 2392 // A flat cons string is a cons string where the second part is the empty
2394 // string. In that case the subject string is just the first part of the cons 2393 // string. In that case the subject string is just the first part of the cons
2395 // string. Also in this case the first part of the cons string is known to be 2394 // string. Also in this case the first part of the cons string is known to be
2396 // a sequential string or an external string. 2395 // a sequential string or an external string.
2397 STATIC_ASSERT(kExternalStringTag !=0); 2396 // A truncated sliced string has the offset 0 and the same length as the
2398 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 2397 // parent string.
2399 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag)); 2398 Label cons_string, encoding;
2400 __ j(not_zero, &runtime); 2399 __ cmpq(rbx, Immediate(kConsStringTag));
2401 // String is a cons string. 2400 __ j(equal, &cons_string, Label::kNear);
2401 __ cmpq(rbx, Immediate(kSlicedStringTag));
2402 // If subject is not a sliced string, it can only be a non-string or an
2403 // external string.
2404 __ j(not_equal, &runtime);
2405 // String is sliced, check whether it is truncated.
2406 __ movq(rbx, FieldOperand(rdi, SlicedString::kLengthOffset));
2407 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
2408 // rbx: length of sliced string.
2409 // rdi: parent string.
2410 __ cmpq(rbx, FieldOperand(rdi, SlicedString::kLengthOffset));
2411 __ j(not_equal, &runtime);
2412 __ jmp(&encoding, Label::kNear);
2413 // String is a cons string, check whether it is flat.
2414 __ bind(&cons_string);
2402 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), 2415 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset),
2403 Heap::kEmptyStringRootIndex); 2416 Heap::kEmptyStringRootIndex);
2404 __ j(not_equal, &runtime); 2417 __ j(not_equal, &runtime);
2405 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); 2418 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
2419 // rdi: first part of cons string or parent of sliced string.
2420 // rbx: map of first part of cons string or map of parent of sliced string.
2421 // Is first part of cons or parent of slice a flat two byte string?
2422 __ bind(&encoding);
2406 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2423 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2407 // String is a cons string with empty second part.
2408 // rdi: first part of cons string.
2409 // rbx: map of first part of cons string.
2410 // Is first part a flat two byte string?
2411 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2424 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2412 Immediate(kStringRepresentationMask | kStringEncodingMask)); 2425 Immediate(kStringRepresentationMask | kStringEncodingMask));
2413 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 2426 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
2414 __ j(zero, &seq_two_byte_string, Label::kNear); 2427 __ j(zero, &seq_two_byte_string, Label::kNear);
2415 // Any other flat string must be ascii. 2428 // Any other flat string must be ascii.
2416 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2429 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2417 Immediate(kStringRepresentationMask)); 2430 Immediate(kStringRepresentationMask));
2418 __ j(not_zero, &runtime); 2431 __ j(not_zero, &runtime);
2419 2432
2420 __ bind(&seq_ascii_string); 2433 __ bind(&seq_ascii_string);
(...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after
3773 } 3786 }
3774 3787
3775 3788
3776 // ------------------------------------------------------------------------- 3789 // -------------------------------------------------------------------------
3777 // StringCharCodeAtGenerator 3790 // StringCharCodeAtGenerator
3778 3791
3779 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3792 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3780 Label flat_string; 3793 Label flat_string;
3781 Label ascii_string; 3794 Label ascii_string;
3782 Label got_char_code; 3795 Label got_char_code;
3796 Label sliced_string;
3783 3797
3784 // If the receiver is a smi trigger the non-string case. 3798 // If the receiver is a smi trigger the non-string case.
3785 __ JumpIfSmi(object_, receiver_not_string_); 3799 __ JumpIfSmi(object_, receiver_not_string_);
3786 3800
3787 // Fetch the instance type of the receiver into result register. 3801 // Fetch the instance type of the receiver into result register.
3788 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 3802 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3789 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 3803 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3790 // If the receiver is not a string trigger the non-string case. 3804 // If the receiver is not a string trigger the non-string case.
3791 __ testb(result_, Immediate(kIsNotStringMask)); 3805 __ testb(result_, Immediate(kIsNotStringMask));
3792 __ j(not_zero, receiver_not_string_); 3806 __ j(not_zero, receiver_not_string_);
3793 3807
3794 // If the index is non-smi trigger the non-smi case. 3808 // If the index is non-smi trigger the non-smi case.
3795 __ JumpIfNotSmi(index_, &index_not_smi_); 3809 __ JumpIfNotSmi(index_, &index_not_smi_);
3796 3810
3797 // Put smi-tagged index into scratch register. 3811 // Put smi-tagged index into scratch register.
3798 __ movq(scratch_, index_); 3812 __ movq(scratch_, index_);
3799 __ bind(&got_smi_index_); 3813 __ bind(&got_smi_index_);
3800 3814
3801 // Check for index out of range. 3815 // Check for index out of range.
3802 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset)); 3816 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset));
3803 __ j(above_equal, index_out_of_range_); 3817 __ j(above_equal, index_out_of_range_);
3804 3818
3805 // We need special handling for non-flat strings. 3819 // We need special handling for non-flat strings.
3806 STATIC_ASSERT(kSeqStringTag == 0); 3820 STATIC_ASSERT(kSeqStringTag == 0);
3807 __ testb(result_, Immediate(kStringRepresentationMask)); 3821 __ testb(result_, Immediate(kStringRepresentationMask));
3808 __ j(zero, &flat_string); 3822 __ j(zero, &flat_string);
3809 3823
3810 // Handle non-flat strings. 3824 // Handle non-flat strings.
3811 __ testb(result_, Immediate(kIsConsStringMask)); 3825 __ and_(result_, Immediate(kStringRepresentationMask));
3812 __ j(zero, &call_runtime_); 3826 __ cmpb(result_, Immediate(kSlicedStringTag));
3827 __ j(equal, &sliced_string);
3828 __ cmpb(result_, Immediate(kExternalStringTag));
3829 __ j(equal, &call_runtime_);
3813 3830
3814 // ConsString. 3831 // ConsString.
3815 // Check whether the right hand side is the empty string (i.e. if 3832 // Check whether the right hand side is the empty string (i.e. if
3816 // this is really a flat string in a cons string). If that is not 3833 // this is really a flat string in a cons string). If that is not
3817 // the case we would rather go to the runtime system now to flatten 3834 // the case we would rather go to the runtime system now to flatten
3818 // the string. 3835 // the string.
3819 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset), 3836 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset),
3820 Heap::kEmptyStringRootIndex); 3837 Heap::kEmptyStringRootIndex);
3821 __ j(not_equal, &call_runtime_); 3838 __ j(not_equal, &call_runtime_);
3822 // Get the first of the two strings and load its instance type. 3839 // Get the first of the two strings and load its instance type.
3823 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset)); 3840 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset));
3824 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 3841 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3825 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 3842 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3826 // If the first cons component is also non-flat, then go to runtime. 3843 // If the first cons component is also non-flat, then go to runtime.
3827 STATIC_ASSERT(kSeqStringTag == 0); 3844 STATIC_ASSERT(kSeqStringTag == 0);
3828 __ testb(result_, Immediate(kStringRepresentationMask)); 3845 __ testb(result_, Immediate(kStringRepresentationMask));
3829 __ j(not_zero, &call_runtime_); 3846 __ j(not_zero, &call_runtime_);
3847 __ jmp(&flat_string);
3848
3849 // SlicedString, unpack and add offset.
3850 __ bind(&sliced_string);
3851 __ addq(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
3852 __ movq(object_, FieldOperand(object_, SlicedString::kParentOffset));
3853 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3854 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3830 3855
3831 // Check for 1-byte or 2-byte string. 3856 // Check for 1-byte or 2-byte string.
3832 __ bind(&flat_string); 3857 __ bind(&flat_string);
3833 STATIC_ASSERT(kAsciiStringTag != 0); 3858 STATIC_ASSERT(kAsciiStringTag != 0);
3834 __ testb(result_, Immediate(kStringEncodingMask)); 3859 __ testb(result_, Immediate(kStringEncodingMask));
3835 __ j(not_zero, &ascii_string); 3860 __ j(not_zero, &ascii_string);
3836 3861
3837 // 2-byte string. 3862 // 2-byte string.
3838 // Load the 2-byte character code into the result register. 3863 // Load the 2-byte character code into the result register.
3839 __ SmiToInteger32(scratch_, scratch_); 3864 __ SmiToInteger32(scratch_, scratch_);
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4130 __ bind(&string_add_flat_result); 4155 __ bind(&string_add_flat_result);
4131 __ SmiToInteger32(rbx, rbx); 4156 __ SmiToInteger32(rbx, rbx);
4132 __ movl(rcx, r8); 4157 __ movl(rcx, r8);
4133 __ and_(rcx, Immediate(kStringRepresentationMask)); 4158 __ and_(rcx, Immediate(kStringRepresentationMask));
4134 __ cmpl(rcx, Immediate(kExternalStringTag)); 4159 __ cmpl(rcx, Immediate(kExternalStringTag));
4135 __ j(equal, &string_add_runtime); 4160 __ j(equal, &string_add_runtime);
4136 __ movl(rcx, r9); 4161 __ movl(rcx, r9);
4137 __ and_(rcx, Immediate(kStringRepresentationMask)); 4162 __ and_(rcx, Immediate(kStringRepresentationMask));
4138 __ cmpl(rcx, Immediate(kExternalStringTag)); 4163 __ cmpl(rcx, Immediate(kExternalStringTag));
4139 __ j(equal, &string_add_runtime); 4164 __ j(equal, &string_add_runtime);
4165 // We cannot encounter sliced strings here since:
4166 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
4140 // Now check if both strings are ascii strings. 4167 // Now check if both strings are ascii strings.
4141 // rax: first string 4168 // rax: first string
4142 // rbx: length of resulting flat string 4169 // rbx: length of resulting flat string
4143 // rdx: second string 4170 // rdx: second string
4144 // r8: instance type of first string 4171 // r8: instance type of first string
4145 // r9: instance type of second string 4172 // r9: instance type of second string
4146 Label non_ascii_string_add_flat_result; 4173 Label non_ascii_string_add_flat_result;
4147 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 4174 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
4148 __ testl(r8, Immediate(kAsciiStringTag)); 4175 __ testl(r8, Immediate(kAsciiStringTag));
4149 __ j(zero, &non_ascii_string_add_flat_result); 4176 __ j(zero, &non_ascii_string_add_flat_result);
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
4522 // if (hash == 0) hash = 27; 4549 // if (hash == 0) hash = 27;
4523 Label hash_not_zero; 4550 Label hash_not_zero;
4524 __ j(not_zero, &hash_not_zero); 4551 __ j(not_zero, &hash_not_zero);
4525 __ Set(hash, 27); 4552 __ Set(hash, 27);
4526 __ bind(&hash_not_zero); 4553 __ bind(&hash_not_zero);
4527 } 4554 }
4528 4555
4529 void SubStringStub::Generate(MacroAssembler* masm) { 4556 void SubStringStub::Generate(MacroAssembler* masm) {
4530 Label runtime; 4557 Label runtime;
4531 4558
4559 if (FLAG_string_slices) {
4560 __ jmp(&runtime);
4561 }
4532 // Stack frame on entry. 4562 // Stack frame on entry.
4533 // rsp[0]: return address 4563 // rsp[0]: return address
4534 // rsp[8]: to 4564 // rsp[8]: to
4535 // rsp[16]: from 4565 // rsp[16]: from
4536 // rsp[24]: string 4566 // rsp[24]: string
4537 4567
4538 const int kToOffset = 1 * kPointerSize; 4568 const int kToOffset = 1 * kPointerSize;
4539 const int kFromOffset = kToOffset + kPointerSize; 4569 const int kFromOffset = kToOffset + kPointerSize;
4540 const int kStringOffset = kFromOffset + kPointerSize; 4570 const int kStringOffset = kFromOffset + kPointerSize;
4541 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset; 4571 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
5283 __ Drop(1); 5313 __ Drop(1);
5284 __ ret(2 * kPointerSize); 5314 __ ret(2 * kPointerSize);
5285 } 5315 }
5286 5316
5287 5317
5288 #undef __ 5318 #undef __
5289 5319
5290 } } // namespace v8::internal 5320 } } // namespace v8::internal
5291 5321
5292 #endif // V8_TARGET_ARCH_X64 5322 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/objects.h ('K') | « src/runtime.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698