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

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: Included Vitaly's suggestions. 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 Heap::kFixedArrayMapRootIndex); 2366 Heap::kFixedArrayMapRootIndex);
2368 __ j(not_equal, &runtime); 2367 __ j(not_equal, &runtime);
2369 // Check that the last match info has space for the capture registers and the 2368 // Check that the last match info has space for the capture registers and the
2370 // additional information. Ensure no overflow in add. 2369 // additional information. Ensure no overflow in add.
2371 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); 2370 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
2372 __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset)); 2371 __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset));
2373 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead)); 2372 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
2374 __ cmpl(rdx, rdi); 2373 __ cmpl(rdx, rdi);
2375 __ j(greater, &runtime); 2374 __ j(greater, &runtime);
2376 2375
2376 // Reset offset for possibly sliced string. This also serves as indicator
2377 // whether the subject string is a sliced string. 0 is not suitable for this
2378 // purpose because a slice can start at offset 0 but have a shorter length.
2379 const int64_t kNotAStringSlice = -1;
2380 __ Set(r14, kNotAStringSlice);
2377 // rax: RegExp data (FixedArray) 2381 // rax: RegExp data (FixedArray)
2378 // Check the representation and encoding of the subject string. 2382 // Check the representation and encoding of the subject string.
2379 Label seq_ascii_string, seq_two_byte_string, check_code; 2383 Label seq_ascii_string, seq_two_byte_string, check_code;
2380 __ movq(rdi, Operand(rsp, kSubjectOffset)); 2384 __ movq(rdi, Operand(rsp, kSubjectOffset));
2381 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2385 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2382 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 2386 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
2383 // First check for flat two byte string. 2387 // First check for flat two byte string.
2384 __ andb(rbx, Immediate( 2388 __ andb(rbx, Immediate(
2385 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask)); 2389 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
2386 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 2390 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
2387 __ j(zero, &seq_two_byte_string, Label::kNear); 2391 __ j(zero, &seq_two_byte_string, Label::kNear);
2388 // Any other flat string must be a flat ascii string. 2392 // Any other flat string must be a flat ascii string.
2389 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask)); 2393 __ andb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
2390 __ j(zero, &seq_ascii_string, Label::kNear); 2394 __ j(zero, &seq_ascii_string, Label::kNear);
2391 2395
2392 // Check for flat cons string. 2396 // Check for flat cons string or sliced string.
2393 // A flat cons string is a cons string where the second part is the empty 2397 // 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 2398 // 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 2399 // string. Also in this case the first part of the cons string is known to be
2396 // a sequential string or an external string. 2400 // a sequential string or an external string.
2397 STATIC_ASSERT(kExternalStringTag !=0); 2401 // In the case of a sliced string its offset has to be taken into account.
2398 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 2402 Label cons_string, check_encoding;
2399 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag)); 2403 __ cmpq(rbx, Immediate(kConsStringTag));
2400 __ j(not_zero, &runtime); 2404 __ j(equal, &cons_string, Label::kNear);
2401 // String is a cons string. 2405 __ cmpq(rbx, Immediate(kSlicedStringTag));
2406 // If subject is not a sliced string, it can only be a non-string or an
2407 // external string.
2408 __ j(not_equal, &runtime);
2409 // String is sliced.
2410 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
2411 __ SmiToInteger32(r15, FieldOperand(rdi, SlicedString::kLengthOffset));
2412 __ addq(r15, r14); // Add offset to length to get input end.
2413 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
2414 // r14: offset of sliced string
2415 // r15: length of sliced string + slice offset
2416 // rdi: parent string.
2417 __ jmp(&check_encoding, Label::kNear);
2418 // String is a cons string, check whether it is flat.
2419 __ bind(&cons_string);
2402 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), 2420 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset),
2403 Heap::kEmptyStringRootIndex); 2421 Heap::kEmptyStringRootIndex);
2404 __ j(not_equal, &runtime); 2422 __ j(not_equal, &runtime);
2405 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); 2423 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
2424 // rdi: first part of cons string or parent of sliced string.
2425 // rbx: map of first part of cons string or map of parent of sliced string.
2426 // Is first part of cons or parent of slice a flat two byte string?
2427 __ bind(&check_encoding);
2406 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2428 __ 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), 2429 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2412 Immediate(kStringRepresentationMask | kStringEncodingMask)); 2430 Immediate(kStringRepresentationMask | kStringEncodingMask));
2413 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 2431 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
2414 __ j(zero, &seq_two_byte_string, Label::kNear); 2432 __ j(zero, &seq_two_byte_string, Label::kNear);
2415 // Any other flat string must be ascii. 2433 // Any other flat string must be ascii.
2416 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2434 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2417 Immediate(kStringRepresentationMask)); 2435 Immediate(kStringRepresentationMask));
2418 __ j(not_zero, &runtime); 2436 __ j(not_zero, &runtime);
2419 2437
2420 __ bind(&seq_ascii_string); 2438 __ bind(&seq_ascii_string);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 Register arg3 = rdx; 2515 Register arg3 = rdx;
2498 Register arg2 = rsi; 2516 Register arg2 = rsi;
2499 Register arg1 = rdi; 2517 Register arg1 = rdi;
2500 #endif 2518 #endif
2501 2519
2502 // Keep track on aliasing between argX defined above and the registers used. 2520 // Keep track on aliasing between argX defined above and the registers used.
2503 // rdi: subject string 2521 // rdi: subject string
2504 // rbx: previous index 2522 // rbx: previous index
2505 // rcx: encoding of subject string (1 if ascii 0 if two_byte); 2523 // rcx: encoding of subject string (1 if ascii 0 if two_byte);
2506 // r11: code 2524 // r11: code
2525 // r14: slice offset or NOT_SLICE
2526 // r15: slice length + slice offset if r14 == NOTS_SLICE
2527
2528 // Argument 2: Previous index.
2529 __ movq(arg2, rbx);
2507 2530
2508 // Argument 4: End of string data 2531 // Argument 4: End of string data
2509 // Argument 3: Start of string data 2532 // Argument 3: Start of string data
2510 Label setup_two_byte, setup_rest; 2533 Label setup_two_byte, setup_rest, got_length, length_not_from_slice;
2534 // Prepare start and end index of the input.
2535 // Load the length from the original sliced string if that is the case.
2536 __ cmpq(r14, Immediate(kNotAStringSlice));
2537 __ j(equal, &length_not_from_slice, Label::kNear);
2538 __ addq(rbx, r14);
2539 __ jmp(&got_length);
2540 __ bind(&length_not_from_slice);
2541 __ SmiToInteger32(r15, FieldOperand(rdi, String::kLengthOffset));
2542 __ bind(&got_length);
2543
2544 // rbx: start index of the input
2545 // r15: end index of the input
2511 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string. 2546 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
2512 __ j(zero, &setup_two_byte, Label::kNear); 2547 __ j(zero, &setup_two_byte, Label::kNear);
2513 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset)); 2548 __ lea(arg4, FieldOperand(rdi, r15, times_1, SeqAsciiString::kHeaderSize));
2514 __ lea(arg4, FieldOperand(rdi, rcx, times_1, SeqAsciiString::kHeaderSize));
2515 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize)); 2549 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize));
2516 __ jmp(&setup_rest, Label::kNear); 2550 __ jmp(&setup_rest, Label::kNear);
2517 __ bind(&setup_two_byte); 2551 __ bind(&setup_two_byte);
2518 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset)); 2552 __ lea(arg4, FieldOperand(rdi, r15, times_2, SeqTwoByteString::kHeaderSize));
2519 __ lea(arg4, FieldOperand(rdi, rcx, times_2, SeqTwoByteString::kHeaderSize));
2520 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize)); 2553 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
2554 __ bind(&setup_rest);
2521 2555
2522 __ bind(&setup_rest); 2556 // Argument 1: Original subject string.
2523 // Argument 2: Previous index. 2557 // The original subject is in the previous stack frame. Therefore we have to
2524 __ movq(arg2, rbx); 2558 // use rbp, which points exactly to one pointer size below the previous rsp.
2525 2559 // (Because creating a new stack frame pushes the previous rbp onto the stack
2526 // Argument 1: Subject string. 2560 // and thereby moves up rsp by one kPointerSize.)
2527 #ifdef _WIN64 2561 __ movq(arg1, Operand(rbp, kSubjectOffset + kPointerSize));
2528 __ movq(arg1, rdi);
2529 #else
2530 // Already there in AMD64 calling convention.
2531 ASSERT(arg1.is(rdi));
2532 USE(arg1);
2533 #endif
2534 2562
2535 // Locate the code entry and call it. 2563 // Locate the code entry and call it.
2536 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); 2564 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
2537 __ call(r11); 2565 __ call(r11);
2538 2566
2539 __ LeaveApiExitFrame(); 2567 __ LeaveApiExitFrame();
2540 2568
2541 // Check the result. 2569 // Check the result.
2542 Label success; 2570 Label success;
2543 Label exception; 2571 Label exception;
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after
3773 } 3801 }
3774 3802
3775 3803
3776 // ------------------------------------------------------------------------- 3804 // -------------------------------------------------------------------------
3777 // StringCharCodeAtGenerator 3805 // StringCharCodeAtGenerator
3778 3806
3779 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3807 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3780 Label flat_string; 3808 Label flat_string;
3781 Label ascii_string; 3809 Label ascii_string;
3782 Label got_char_code; 3810 Label got_char_code;
3811 Label sliced_string;
3783 3812
3784 // If the receiver is a smi trigger the non-string case. 3813 // If the receiver is a smi trigger the non-string case.
3785 __ JumpIfSmi(object_, receiver_not_string_); 3814 __ JumpIfSmi(object_, receiver_not_string_);
3786 3815
3787 // Fetch the instance type of the receiver into result register. 3816 // Fetch the instance type of the receiver into result register.
3788 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 3817 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3789 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 3818 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3790 // If the receiver is not a string trigger the non-string case. 3819 // If the receiver is not a string trigger the non-string case.
3791 __ testb(result_, Immediate(kIsNotStringMask)); 3820 __ testb(result_, Immediate(kIsNotStringMask));
3792 __ j(not_zero, receiver_not_string_); 3821 __ j(not_zero, receiver_not_string_);
3793 3822
3794 // If the index is non-smi trigger the non-smi case. 3823 // If the index is non-smi trigger the non-smi case.
3795 __ JumpIfNotSmi(index_, &index_not_smi_); 3824 __ JumpIfNotSmi(index_, &index_not_smi_);
3796 3825
3797 // Put smi-tagged index into scratch register. 3826 // Put smi-tagged index into scratch register.
3798 __ movq(scratch_, index_); 3827 __ movq(scratch_, index_);
3799 __ bind(&got_smi_index_); 3828 __ bind(&got_smi_index_);
3800 3829
3801 // Check for index out of range. 3830 // Check for index out of range.
3802 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset)); 3831 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset));
3803 __ j(above_equal, index_out_of_range_); 3832 __ j(above_equal, index_out_of_range_);
3804 3833
3805 // We need special handling for non-flat strings. 3834 // We need special handling for non-flat strings.
3806 STATIC_ASSERT(kSeqStringTag == 0); 3835 STATIC_ASSERT(kSeqStringTag == 0);
3807 __ testb(result_, Immediate(kStringRepresentationMask)); 3836 __ testb(result_, Immediate(kStringRepresentationMask));
3808 __ j(zero, &flat_string); 3837 __ j(zero, &flat_string);
3809 3838
3810 // Handle non-flat strings. 3839 // Handle non-flat strings.
3811 __ testb(result_, Immediate(kIsConsStringMask)); 3840 __ and_(result_, Immediate(kStringRepresentationMask));
3812 __ j(zero, &call_runtime_); 3841 __ cmpb(result_, Immediate(kSlicedStringTag));
3842 __ j(equal, &sliced_string);
3843 __ cmpb(result_, Immediate(kExternalStringTag));
3844 __ j(equal, &call_runtime_);
3813 3845
3814 // ConsString. 3846 // ConsString.
3815 // Check whether the right hand side is the empty string (i.e. if 3847 // 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 3848 // 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 3849 // the case we would rather go to the runtime system now to flatten
3818 // the string. 3850 // the string.
3819 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset), 3851 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset),
3820 Heap::kEmptyStringRootIndex); 3852 Heap::kEmptyStringRootIndex);
3821 __ j(not_equal, &call_runtime_); 3853 __ j(not_equal, &call_runtime_);
3822 // Get the first of the two strings and load its instance type. 3854 // Get the first of the two strings and load its instance type.
3823 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset)); 3855 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset));
3824 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 3856 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3825 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 3857 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3826 // If the first cons component is also non-flat, then go to runtime. 3858 // If the first cons component is also non-flat, then go to runtime.
3827 STATIC_ASSERT(kSeqStringTag == 0); 3859 STATIC_ASSERT(kSeqStringTag == 0);
3828 __ testb(result_, Immediate(kStringRepresentationMask)); 3860 __ testb(result_, Immediate(kStringRepresentationMask));
3829 __ j(not_zero, &call_runtime_); 3861 __ j(not_zero, &call_runtime_);
3862 __ jmp(&flat_string);
3863
3864 // SlicedString, unpack and add offset.
3865 __ bind(&sliced_string);
3866 __ addq(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
3867 __ movq(object_, FieldOperand(object_, SlicedString::kParentOffset));
3868 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3869 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3830 3870
3831 // Check for 1-byte or 2-byte string. 3871 // Check for 1-byte or 2-byte string.
3832 __ bind(&flat_string); 3872 __ bind(&flat_string);
3833 STATIC_ASSERT(kAsciiStringTag != 0); 3873 STATIC_ASSERT(kAsciiStringTag != 0);
3834 __ testb(result_, Immediate(kStringEncodingMask)); 3874 __ testb(result_, Immediate(kStringEncodingMask));
3835 __ j(not_zero, &ascii_string); 3875 __ j(not_zero, &ascii_string);
3836 3876
3837 // 2-byte string. 3877 // 2-byte string.
3838 // Load the 2-byte character code into the result register. 3878 // Load the 2-byte character code into the result register.
3839 __ SmiToInteger32(scratch_, scratch_); 3879 __ SmiToInteger32(scratch_, scratch_);
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4130 __ bind(&string_add_flat_result); 4170 __ bind(&string_add_flat_result);
4131 __ SmiToInteger32(rbx, rbx); 4171 __ SmiToInteger32(rbx, rbx);
4132 __ movl(rcx, r8); 4172 __ movl(rcx, r8);
4133 __ and_(rcx, Immediate(kStringRepresentationMask)); 4173 __ and_(rcx, Immediate(kStringRepresentationMask));
4134 __ cmpl(rcx, Immediate(kExternalStringTag)); 4174 __ cmpl(rcx, Immediate(kExternalStringTag));
4135 __ j(equal, &string_add_runtime); 4175 __ j(equal, &string_add_runtime);
4136 __ movl(rcx, r9); 4176 __ movl(rcx, r9);
4137 __ and_(rcx, Immediate(kStringRepresentationMask)); 4177 __ and_(rcx, Immediate(kStringRepresentationMask));
4138 __ cmpl(rcx, Immediate(kExternalStringTag)); 4178 __ cmpl(rcx, Immediate(kExternalStringTag));
4139 __ j(equal, &string_add_runtime); 4179 __ j(equal, &string_add_runtime);
4180 // We cannot encounter sliced strings here since:
4181 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
4140 // Now check if both strings are ascii strings. 4182 // Now check if both strings are ascii strings.
4141 // rax: first string 4183 // rax: first string
4142 // rbx: length of resulting flat string 4184 // rbx: length of resulting flat string
4143 // rdx: second string 4185 // rdx: second string
4144 // r8: instance type of first string 4186 // r8: instance type of first string
4145 // r9: instance type of second string 4187 // r9: instance type of second string
4146 Label non_ascii_string_add_flat_result; 4188 Label non_ascii_string_add_flat_result;
4147 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 4189 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
4148 __ testl(r8, Immediate(kAsciiStringTag)); 4190 __ testl(r8, Immediate(kAsciiStringTag));
4149 __ j(zero, &non_ascii_string_add_flat_result); 4191 __ 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; 4564 // if (hash == 0) hash = 27;
4523 Label hash_not_zero; 4565 Label hash_not_zero;
4524 __ j(not_zero, &hash_not_zero); 4566 __ j(not_zero, &hash_not_zero);
4525 __ Set(hash, 27); 4567 __ Set(hash, 27);
4526 __ bind(&hash_not_zero); 4568 __ bind(&hash_not_zero);
4527 } 4569 }
4528 4570
4529 void SubStringStub::Generate(MacroAssembler* masm) { 4571 void SubStringStub::Generate(MacroAssembler* masm) {
4530 Label runtime; 4572 Label runtime;
4531 4573
4574 if (FLAG_string_slices) {
4575 __ jmp(&runtime);
4576 }
4532 // Stack frame on entry. 4577 // Stack frame on entry.
4533 // rsp[0]: return address 4578 // rsp[0]: return address
4534 // rsp[8]: to 4579 // rsp[8]: to
4535 // rsp[16]: from 4580 // rsp[16]: from
4536 // rsp[24]: string 4581 // rsp[24]: string
4537 4582
4538 const int kToOffset = 1 * kPointerSize; 4583 const int kToOffset = 1 * kPointerSize;
4539 const int kFromOffset = kToOffset + kPointerSize; 4584 const int kFromOffset = kToOffset + kPointerSize;
4540 const int kStringOffset = kFromOffset + kPointerSize; 4585 const int kStringOffset = kFromOffset + kPointerSize;
4541 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset; 4586 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
5283 __ Drop(1); 5328 __ Drop(1);
5284 __ ret(2 * kPointerSize); 5329 __ ret(2 * kPointerSize);
5285 } 5330 }
5286 5331
5287 5332
5288 #undef __ 5333 #undef __
5289 5334
5290 } } // namespace v8::internal 5335 } } // namespace v8::internal
5291 5336
5292 #endif // V8_TARGET_ARCH_X64 5337 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/objects-inl.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