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

Side by Side Diff: src/ia32/code-stubs-ia32.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: Support for RegExp. Removed methods related to truncate. 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 3369 matching lines...) Expand 10 before | Expand all | Expand 10 after
3380 __ cmp(eax, factory->fixed_array_map()); 3380 __ cmp(eax, factory->fixed_array_map());
3381 __ j(not_equal, &runtime); 3381 __ j(not_equal, &runtime);
3382 // Check that the last match info has space for the capture registers and the 3382 // Check that the last match info has space for the capture registers and the
3383 // additional information. 3383 // additional information.
3384 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset)); 3384 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset));
3385 __ SmiUntag(eax); 3385 __ SmiUntag(eax);
3386 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead)); 3386 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead));
3387 __ cmp(edx, Operand(eax)); 3387 __ cmp(edx, Operand(eax));
3388 __ j(greater, &runtime); 3388 __ j(greater, &runtime);
3389 3389
3390 // Reset offset for possibly sliced string. This also serves as indicator
3391 // whether the subject string is a sliced string. 0 is not suitable for this
3392 // purpose because a slice can start at offset 0 but have a shorter length.
3393 #define NOT_SLICED -1
Vitaly Repeshko 2011/08/12 19:01:00 Ugh, use a constant instead.
3394 __ Set(edi, Immediate(NOT_SLICED));
3390 // ecx: RegExp data (FixedArray) 3395 // ecx: RegExp data (FixedArray)
3391 // Check the representation and encoding of the subject string. 3396 // Check the representation and encoding of the subject string.
3392 Label seq_ascii_string, seq_two_byte_string, check_code; 3397 Label seq_ascii_string, seq_two_byte_string, check_code;
3393 __ mov(eax, Operand(esp, kSubjectOffset)); 3398 __ mov(eax, Operand(esp, kSubjectOffset));
3394 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3399 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
3395 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 3400 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
3396 // First check for flat two byte string. 3401 // First check for flat two byte string.
3397 __ and_(ebx, 3402 __ and_(ebx,
3398 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 3403 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
3399 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 3404 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
3400 __ j(zero, &seq_two_byte_string); 3405 __ j(zero, &seq_two_byte_string);
3401 // Any other flat string must be a flat ascii string. 3406 // Any other flat string must be a flat ascii string.
3402 __ test(Operand(ebx), 3407 __ and_(Operand(ebx),
3403 Immediate(kIsNotStringMask | kStringRepresentationMask)); 3408 Immediate(kIsNotStringMask | kStringRepresentationMask));
3404 __ j(zero, &seq_ascii_string); 3409 __ j(zero, &seq_ascii_string);
3405 3410
3406 // Check for flat cons string. 3411 // Check for flat cons string or truncated sliced string.
Vitaly Repeshko 2011/08/12 19:01:00 Update the comment.
3407 // A flat cons string is a cons string where the second part is the empty 3412 // A flat cons string is a cons string where the second part is the empty
3408 // string. In that case the subject string is just the first part of the cons 3413 // string. In that case the subject string is just the first part of the cons
3409 // string. Also in this case the first part of the cons string is known to be 3414 // string. Also in this case the first part of the cons string is known to be
3410 // a sequential string or an external string. 3415 // a sequential string or an external string.
3411 STATIC_ASSERT(kExternalStringTag != 0); 3416 // A truncated sliced string has the offset 0 and the same length as the
3412 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 3417 // parent string.
3413 __ test(Operand(ebx), 3418 Label cons_string, check_encoding;
3414 Immediate(kIsNotStringMask | kExternalStringTag)); 3419 __ cmp(Operand(ebx), Immediate(kConsStringTag));
3415 __ j(not_zero, &runtime); 3420 __ j(equal, &cons_string);
3416 // String is a cons string. 3421 __ cmp(Operand(ebx), Immediate(kSlicedStringTag));
3417 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); 3422 // If subject is not a sliced string, it can only be a non-string or an
3418 __ cmp(Operand(edx), factory->empty_string()); 3423 // external string.
3424 __ j(not_equal, &runtime);
3425 // String is sliced.
3426 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset));
3427 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset));
3428 // edi: offset of sliced string, smi-tagged.
3429 // eax: parent string.
3430 __ jmp(&check_encoding);
3431 // String is a cons string, check whether it is flat.
3432 __ bind(&cons_string);
3433 __ mov(ebx, FieldOperand(eax, ConsString::kSecondOffset));
3434 __ cmp(Operand(ebx), factory->empty_string());
3419 __ j(not_equal, &runtime); 3435 __ j(not_equal, &runtime);
3420 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 3436 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
3437 // eax: first part of cons string or parent of sliced string.
3438 // edx: map of first part of cons string or map of parent of sliced string.
3439 // Is first part of cons or parent of slice a flat two byte string?
3440 __ bind(&check_encoding);
3421 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3441 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
3422 // String is a cons string with empty second part.
3423 // eax: first part of cons string.
3424 // ebx: map of first part of cons string.
3425 // Is first part a flat two byte string?
3426 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), 3442 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
3427 kStringRepresentationMask | kStringEncodingMask); 3443 kStringRepresentationMask | kStringEncodingMask);
3428 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 3444 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
3429 __ j(zero, &seq_two_byte_string); 3445 __ j(zero, &seq_two_byte_string);
3430 // Any other flat string must be ascii. 3446 // Any other flat string must be ascii.
3431 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), 3447 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
3432 kStringRepresentationMask); 3448 kStringRepresentationMask);
3433 __ j(not_zero, &runtime); 3449 __ j(not_zero, &runtime);
3434 3450
3435 __ bind(&seq_ascii_string); 3451 __ bind(&seq_ascii_string);
3436 // eax: subject string (flat ascii) 3452 // eax: subject string (flat ascii)
3437 // ecx: RegExp data (FixedArray) 3453 // ecx: RegExp data (FixedArray)
3438 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); 3454 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
3439 __ Set(edi, Immediate(1)); // Type is ascii. 3455 __ Set(ecx, Immediate(1)); // Type is ascii.
3440 __ jmp(&check_code); 3456 __ jmp(&check_code);
3441 3457
3442 __ bind(&seq_two_byte_string); 3458 __ bind(&seq_two_byte_string);
3443 // eax: subject string (flat two byte) 3459 // eax: subject string (flat two byte)
3444 // ecx: RegExp data (FixedArray) 3460 // ecx: RegExp data (FixedArray)
3445 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); 3461 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
3446 __ Set(edi, Immediate(0)); // Type is two byte. 3462 __ Set(ecx, Immediate(0)); // Type is two byte.
3447 3463
3448 __ bind(&check_code); 3464 __ bind(&check_code);
3449 // Check that the irregexp code has been generated for the actual string 3465 // Check that the irregexp code has been generated for the actual string
3450 // encoding. If it has, the field contains a code object otherwise it contains 3466 // encoding. If it has, the field contains a code object otherwise it contains
3451 // a smi (code flushing support). 3467 // a smi (code flushing support).
3452 __ JumpIfSmi(edx, &runtime); 3468 __ JumpIfSmi(edx, &runtime);
3453 3469
3454 // eax: subject string 3470 // eax: subject string
3455 // edx: code 3471 // edx: code
3456 // edi: encoding of subject string (1 if ascii, 0 if two_byte); 3472 // edi: encoding of subject string (1 if ascii, 0 if two_byte);
Vitaly Repeshko 2011/08/12 19:01:00 Update the comment.
3457 // Load used arguments before starting to push arguments for call to native 3473 // Load used arguments before starting to push arguments for call to native
3458 // RegExp code to avoid handling changing stack height. 3474 // RegExp code to avoid handling changing stack height.
3459 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 3475 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
3460 __ SmiUntag(ebx); // Previous index from smi. 3476 __ SmiUntag(ebx); // Previous index from smi.
3461 3477
3462 // eax: subject string 3478 // eax: subject string
3463 // ebx: previous index 3479 // ebx: previous index
3464 // edx: code 3480 // edx: code
3465 // edi: encoding of subject string (1 if ascii 0 if two_byte); 3481 // edi: encoding of subject string (1 if ascii 0 if two_byte);
3466 // All checks done. Now push arguments for native regexp code. 3482 // All checks done. Now push arguments for native regexp code.
3467 Counters* counters = masm->isolate()->counters(); 3483 Counters* counters = masm->isolate()->counters();
3468 __ IncrementCounter(counters->regexp_entry_native(), 1); 3484 __ IncrementCounter(counters->regexp_entry_native(), 1);
3469 3485
3470 // Isolates: note we add an additional parameter here (isolate pointer). 3486 // Isolates: note we add an additional parameter here (isolate pointer).
3471 static const int kRegExpExecuteArguments = 8; 3487 static const int kRegExpExecuteArguments = 8;
3472 __ EnterApiExitFrame(kRegExpExecuteArguments); 3488 __ EnterApiExitFrame(kRegExpExecuteArguments);
3473 3489
3474 // Argument 8: Pass current isolate address. 3490 // Argument 8: Pass current isolate address.
3475 __ mov(Operand(esp, 7 * kPointerSize), 3491 __ mov(Operand(esp, 7 * kPointerSize),
3476 Immediate(ExternalReference::isolate_address())); 3492 Immediate(ExternalReference::isolate_address()));
3477 3493
3478 // Argument 7: Indicate that this is a direct call from JavaScript. 3494 // Argument 7: Indicate that this is a direct call from JavaScript.
3479 __ mov(Operand(esp, 6 * kPointerSize), Immediate(1)); 3495 __ mov(Operand(esp, 6 * kPointerSize), Immediate(1));
3480 3496
3481 // Argument 6: Start (high end) of backtracking stack memory area. 3497 // Argument 6: Start (high end) of backtracking stack memory area.
3482 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); 3498 __ mov(esi, Operand::StaticVariable(address_of_regexp_stack_memory_address));
3483 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); 3499 __ add(esi, Operand::StaticVariable(address_of_regexp_stack_memory_size));
3484 __ mov(Operand(esp, 5 * kPointerSize), ecx); 3500 __ mov(Operand(esp, 5 * kPointerSize), esi);
3485 3501
3486 // Argument 5: static offsets vector buffer. 3502 // Argument 5: static offsets vector buffer.
3487 __ mov(Operand(esp, 4 * kPointerSize), 3503 __ mov(Operand(esp, 4 * kPointerSize),
3488 Immediate(ExternalReference::address_of_static_offsets_vector( 3504 Immediate(ExternalReference::address_of_static_offsets_vector(
3489 masm->isolate()))); 3505 masm->isolate())));
3490 3506
3507 // Argument 2: Previous index.
3508 __ mov(Operand(esp, 1 * kPointerSize), ebx);
3509
3510 // Argument 1: Original subject string.
3511 // The original subject is in the previous stack frame. Therefore we have to
3512 // use ebp, which points exactly to one pointer size below the previous esp.
3513 // (Because creating a new stack frame pushes the previous ebp onto the stack
3514 // and thereby moves up esp by one kPointerSize.)
3515 __ mov(esi, Operand(ebp, kSubjectOffset + kPointerSize));
3516 __ mov(Operand(esp, 0 * kPointerSize), esi);
3517 // esi: original subject string
3518 // eax: underlying subject string
3519
3491 // Argument 4: End of string data 3520 // Argument 4: End of string data
3492 // Argument 3: Start of string data 3521 // Argument 3: Start of string data
3493 Label setup_two_byte, setup_rest; 3522 Label setup_two_byte, setup_rest, length_not_from_slice, got_length;
3494 __ test(edi, Operand(edi)); 3523 // Prepare start and end index of the input.
3495 __ mov(edi, FieldOperand(eax, String::kLengthOffset)); 3524 // Load the length from the original sliced string if that is the case.
3525 __ cmp(edi, NOT_SLICED);
3526 __ j(equal, &length_not_from_slice);
3527 __ mov(esi, FieldOperand(esi, String::kLengthOffset));
3528 __ add(esi, Operand(edi)); // Calculate input end wrt offset.
3529 __ SmiUntag(edi);
3530 __ add(ebx, Operand(edi)); // Calculate input start wrt offset.
3531 __ jmp(&got_length);
3532 __ bind(&length_not_from_slice);
3533 __ mov(esi, FieldOperand(eax, String::kLengthOffset));
3534 __ bind(&got_length);
3535
3536 // ebx: start index of the input string
3537 // esi: end index of the input string
3538 __ test(ecx, Operand(ecx));
3496 __ j(zero, &setup_two_byte, Label::kNear); 3539 __ j(zero, &setup_two_byte, Label::kNear);
3497 __ SmiUntag(edi); 3540 __ SmiUntag(esi);
3498 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize)); 3541 __ lea(ecx, FieldOperand(eax, esi, times_1, SeqAsciiString::kHeaderSize));
3499 __ mov(Operand(esp, 3 * kPointerSize), ecx); // Argument 4. 3542 __ mov(Operand(esp, 3 * kPointerSize), ecx); // Argument 4.
3500 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); 3543 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize));
3501 __ mov(Operand(esp, 2 * kPointerSize), ecx); // Argument 3. 3544 __ mov(Operand(esp, 2 * kPointerSize), ecx); // Argument 3.
3502 __ jmp(&setup_rest, Label::kNear); 3545 __ jmp(&setup_rest, Label::kNear);
3503 3546
3504 __ bind(&setup_two_byte); 3547 __ bind(&setup_two_byte);
3505 STATIC_ASSERT(kSmiTag == 0); 3548 STATIC_ASSERT(kSmiTag == 0);
3506 STATIC_ASSERT(kSmiTagSize == 1); // edi is smi (powered by 2). 3549 STATIC_ASSERT(kSmiTagSize == 1); // esi is smi (powered by 2).
3507 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqTwoByteString::kHeaderSize)); 3550 __ lea(ecx, FieldOperand(eax, esi, times_1, SeqTwoByteString::kHeaderSize));
3508 __ mov(Operand(esp, 3 * kPointerSize), ecx); // Argument 4. 3551 __ mov(Operand(esp, 3 * kPointerSize), ecx); // Argument 4.
3509 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); 3552 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize));
3510 __ mov(Operand(esp, 2 * kPointerSize), ecx); // Argument 3. 3553 __ mov(Operand(esp, 2 * kPointerSize), ecx); // Argument 3.
3511 3554
3512 __ bind(&setup_rest); 3555 __ bind(&setup_rest);
3513 3556
3514 // Argument 2: Previous index.
3515 __ mov(Operand(esp, 1 * kPointerSize), ebx);
3516
3517 // Argument 1: Subject string.
3518 __ mov(Operand(esp, 0 * kPointerSize), eax);
3519
3520 // Locate the code entry and call it. 3557 // Locate the code entry and call it.
3521 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); 3558 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
3522 __ call(Operand(edx)); 3559 __ call(Operand(edx));
3523 3560
3524 // Drop arguments and come back to JS mode. 3561 // Drop arguments and come back to JS mode.
3525 __ LeaveApiExitFrame(); 3562 __ LeaveApiExitFrame();
3526 3563
3527 // Check the result. 3564 // Check the result.
3528 Label success; 3565 Label success;
3529 __ cmp(eax, NativeRegExpMacroAssembler::SUCCESS); 3566 __ cmp(eax, NativeRegExpMacroAssembler::SUCCESS);
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4820 } 4857 }
4821 4858
4822 4859
4823 // ------------------------------------------------------------------------- 4860 // -------------------------------------------------------------------------
4824 // StringCharCodeAtGenerator 4861 // StringCharCodeAtGenerator
4825 4862
4826 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4863 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4827 Label flat_string; 4864 Label flat_string;
4828 Label ascii_string; 4865 Label ascii_string;
4829 Label got_char_code; 4866 Label got_char_code;
4867 Label sliced_string;
4830 4868
4831 // If the receiver is a smi trigger the non-string case. 4869 // If the receiver is a smi trigger the non-string case.
4832 STATIC_ASSERT(kSmiTag == 0); 4870 STATIC_ASSERT(kSmiTag == 0);
4833 __ JumpIfSmi(object_, receiver_not_string_); 4871 __ JumpIfSmi(object_, receiver_not_string_);
4834 4872
4835 // Fetch the instance type of the receiver into result register. 4873 // Fetch the instance type of the receiver into result register.
4836 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4874 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4837 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4875 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4838 // If the receiver is not a string trigger the non-string case. 4876 // If the receiver is not a string trigger the non-string case.
4839 __ test(result_, Immediate(kIsNotStringMask)); 4877 __ test(result_, Immediate(kIsNotStringMask));
(...skipping 10 matching lines...) Expand all
4850 // Check for index out of range. 4888 // Check for index out of range.
4851 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); 4889 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset));
4852 __ j(above_equal, index_out_of_range_); 4890 __ j(above_equal, index_out_of_range_);
4853 4891
4854 // We need special handling for non-flat strings. 4892 // We need special handling for non-flat strings.
4855 STATIC_ASSERT(kSeqStringTag == 0); 4893 STATIC_ASSERT(kSeqStringTag == 0);
4856 __ test(result_, Immediate(kStringRepresentationMask)); 4894 __ test(result_, Immediate(kStringRepresentationMask));
4857 __ j(zero, &flat_string); 4895 __ j(zero, &flat_string);
4858 4896
4859 // Handle non-flat strings. 4897 // Handle non-flat strings.
4860 __ test(result_, Immediate(kIsConsStringMask)); 4898 __ and_(result_, kStringRepresentationMask);
4861 __ j(zero, &call_runtime_); 4899 __ cmp(result_, kSlicedStringTag);
4900 __ j(equal, &sliced_string);
4901 __ cmp(result_, kExternalStringTag);
4902 __ j(equal, &call_runtime_);
4862 4903
4863 // ConsString. 4904 // ConsString.
4864 // Check whether the right hand side is the empty string (i.e. if 4905 // Check whether the right hand side is the empty string (i.e. if
4865 // this is really a flat string in a cons string). If that is not 4906 // this is really a flat string in a cons string). If that is not
4866 // the case we would rather go to the runtime system now to flatten 4907 // the case we would rather go to the runtime system now to flatten
4867 // the string. 4908 // the string.
4868 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), 4909 __ cmp(FieldOperand(object_, ConsString::kSecondOffset),
4869 Immediate(masm->isolate()->factory()->empty_string())); 4910 Immediate(masm->isolate()->factory()->empty_string()));
4870 __ j(not_equal, &call_runtime_); 4911 __ j(not_equal, &call_runtime_);
4871 // Get the first of the two strings and load its instance type. 4912 // Get the first of the two strings and load its instance type.
4872 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset)); 4913 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
4873 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4914 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4874 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4915 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4875 // If the first cons component is also non-flat, then go to runtime. 4916 // If the first cons component is also non-flat, then go to runtime.
4876 STATIC_ASSERT(kSeqStringTag == 0); 4917 STATIC_ASSERT(kSeqStringTag == 0);
4877 __ test(result_, Immediate(kStringRepresentationMask)); 4918 __ test(result_, Immediate(kStringRepresentationMask));
4878 __ j(not_zero, &call_runtime_); 4919 __ j(not_zero, &call_runtime_);
4920 __ jmp(&flat_string);
4921
4922 // SlicedString, unpack and add offset.
4923 __ bind(&sliced_string);
4924 __ add(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
4925 __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
4926 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4927 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4879 4928
4880 // Check for 1-byte or 2-byte string. 4929 // Check for 1-byte or 2-byte string.
4881 __ bind(&flat_string); 4930 __ bind(&flat_string);
4882 STATIC_ASSERT(kAsciiStringTag != 0); 4931 STATIC_ASSERT(kAsciiStringTag != 0);
4883 __ test(result_, Immediate(kStringEncodingMask)); 4932 __ test(result_, Immediate(kStringEncodingMask));
4884 __ j(not_zero, &ascii_string); 4933 __ j(not_zero, &ascii_string);
4885 4934
4886 // 2-byte string. 4935 // 2-byte string.
4887 // Load the 2-byte character code into the result register. 4936 // Load the 2-byte character code into the result register.
4888 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 4937 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
5194 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 5243 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5195 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5244 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5196 __ and_(ecx, kStringRepresentationMask); 5245 __ and_(ecx, kStringRepresentationMask);
5197 __ cmp(ecx, kExternalStringTag); 5246 __ cmp(ecx, kExternalStringTag);
5198 __ j(equal, &string_add_runtime); 5247 __ j(equal, &string_add_runtime);
5199 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5248 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
5200 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5249 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5201 __ and_(ecx, kStringRepresentationMask); 5250 __ and_(ecx, kStringRepresentationMask);
5202 __ cmp(ecx, kExternalStringTag); 5251 __ cmp(ecx, kExternalStringTag);
5203 __ j(equal, &string_add_runtime); 5252 __ j(equal, &string_add_runtime);
5253 // We cannot encounter sliced strings here since:
5254 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
5204 // Now check if both strings are ascii strings. 5255 // Now check if both strings are ascii strings.
5205 // eax: first string 5256 // eax: first string
5206 // ebx: length of resulting flat string as a smi 5257 // ebx: length of resulting flat string as a smi
5207 // edx: second string 5258 // edx: second string
5208 Label non_ascii_string_add_flat_result; 5259 Label non_ascii_string_add_flat_result;
5209 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 5260 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
5210 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 5261 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5211 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 5262 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
5212 __ j(zero, &non_ascii_string_add_flat_result); 5263 __ j(zero, &non_ascii_string_add_flat_result);
5213 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5264 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
5605 __ test(hash, Operand(hash)); 5656 __ test(hash, Operand(hash));
5606 __ j(not_zero, &hash_not_zero, Label::kNear); 5657 __ j(not_zero, &hash_not_zero, Label::kNear);
5607 __ mov(hash, Immediate(27)); 5658 __ mov(hash, Immediate(27));
5608 __ bind(&hash_not_zero); 5659 __ bind(&hash_not_zero);
5609 } 5660 }
5610 5661
5611 5662
5612 void SubStringStub::Generate(MacroAssembler* masm) { 5663 void SubStringStub::Generate(MacroAssembler* masm) {
5613 Label runtime; 5664 Label runtime;
5614 5665
5666 if (FLAG_string_slices) {
5667 __ jmp(&runtime);
5668 }
5615 // Stack frame on entry. 5669 // Stack frame on entry.
5616 // esp[0]: return address 5670 // esp[0]: return address
5617 // esp[4]: to 5671 // esp[4]: to
5618 // esp[8]: from 5672 // esp[8]: from
5619 // esp[12]: string 5673 // esp[12]: string
5620 5674
5621 // Make sure first argument is a string. 5675 // Make sure first argument is a string.
5622 __ mov(eax, Operand(esp, 3 * kPointerSize)); 5676 __ mov(eax, Operand(esp, 3 * kPointerSize));
5623 STATIC_ASSERT(kSmiTag == 0); 5677 STATIC_ASSERT(kSmiTag == 0);
5624 __ JumpIfSmi(eax, &runtime); 5678 __ JumpIfSmi(eax, &runtime);
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
6381 __ Drop(1); 6435 __ Drop(1);
6382 __ ret(2 * kPointerSize); 6436 __ ret(2 * kPointerSize);
6383 } 6437 }
6384 6438
6385 6439
6386 #undef __ 6440 #undef __
6387 6441
6388 } } // namespace v8::internal 6442 } } // namespace v8::internal
6389 6443
6390 #endif // V8_TARGET_ARCH_IA32 6444 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698