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

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: 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 3381 matching lines...) Expand 10 before | Expand all | Expand 10 after
3392 Label seq_ascii_string, seq_two_byte_string, check_code; 3392 Label seq_ascii_string, seq_two_byte_string, check_code;
3393 __ mov(eax, Operand(esp, kSubjectOffset)); 3393 __ mov(eax, Operand(esp, kSubjectOffset));
3394 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3394 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
3395 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 3395 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
3396 // First check for flat two byte string. 3396 // First check for flat two byte string.
3397 __ and_(ebx, 3397 __ and_(ebx,
3398 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 3398 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
3399 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 3399 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
3400 __ j(zero, &seq_two_byte_string); 3400 __ j(zero, &seq_two_byte_string);
3401 // Any other flat string must be a flat ascii string. 3401 // Any other flat string must be a flat ascii string.
3402 __ test(Operand(ebx), 3402 __ and_(Operand(ebx),
3403 Immediate(kIsNotStringMask | kStringRepresentationMask)); 3403 Immediate(kIsNotStringMask | kStringRepresentationMask));
3404 __ j(zero, &seq_ascii_string); 3404 __ j(zero, &seq_ascii_string);
3405 3405
3406 // Check for flat cons string. 3406 // Check for flat cons string or truncated sliced string.
3407 // A flat cons string is a cons string where the second part is the empty 3407 // 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 3408 // 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 3409 // string. Also in this case the first part of the cons string is known to be
3410 // a sequential string or an external string. 3410 // a sequential string or an external string.
3411 STATIC_ASSERT(kExternalStringTag != 0); 3411 // A truncated sliced string has the offset 0 and the same length as the
3412 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 3412 // parent string.
3413 __ test(Operand(ebx), 3413 Label cons_string, encoding;
Vitaly Repeshko 2011/08/05 12:14:14 encoding -> check_encoding
3414 Immediate(kIsNotStringMask | kExternalStringTag)); 3414 __ cmp(Operand(ebx), Immediate(kConsStringTag));
3415 __ j(not_zero, &runtime); 3415 __ j(equal, &cons_string);
3416 // String is a cons string. 3416 __ cmp(Operand(ebx), Immediate(kSlicedStringTag));
3417 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); 3417 // If subject is not a sliced string, it can only be a non-string or an
3418 __ cmp(Operand(edx), factory->empty_string()); 3418 // external string.
3419 __ j(not_equal, &runtime);
3420 // String is sliced, check whether it is truncated.
3421 __ mov(ebx, FieldOperand(eax, SlicedString::kLengthOffset));
3422 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset));
3423 // ebx: length of sliced string.
3424 // eax: parent string.
3425 __ cmp(ebx, FieldOperand(eax, String::kLengthOffset));
3426 __ j(not_equal, &runtime);
3427 __ jmp(&encoding);
3428 // String is a cons string, check whether it is flat.
3429 __ bind(&cons_string);
3430 __ mov(ebx, FieldOperand(eax, ConsString::kSecondOffset));
3431 __ cmp(Operand(ebx), factory->empty_string());
3419 __ j(not_equal, &runtime); 3432 __ j(not_equal, &runtime);
3420 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 3433 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
3434 // eax: first part of cons string or parent of sliced string.
3435 // edx: map of first part of cons string or map of parent of sliced string.
3436 // Is first part of cons or parent of slice a flat two byte string?
3437 __ bind(&encoding);
3421 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3438 __ 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), 3439 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
3427 kStringRepresentationMask | kStringEncodingMask); 3440 kStringRepresentationMask | kStringEncodingMask);
3428 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 3441 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
3429 __ j(zero, &seq_two_byte_string); 3442 __ j(zero, &seq_two_byte_string);
3430 // Any other flat string must be ascii. 3443 // Any other flat string must be ascii.
3431 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), 3444 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
3432 kStringRepresentationMask); 3445 kStringRepresentationMask);
3433 __ j(not_zero, &runtime); 3446 __ j(not_zero, &runtime);
3434 3447
3435 __ bind(&seq_ascii_string); 3448 __ bind(&seq_ascii_string);
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
4820 } 4833 }
4821 4834
4822 4835
4823 // ------------------------------------------------------------------------- 4836 // -------------------------------------------------------------------------
4824 // StringCharCodeAtGenerator 4837 // StringCharCodeAtGenerator
4825 4838
4826 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4839 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4827 Label flat_string; 4840 Label flat_string;
4828 Label ascii_string; 4841 Label ascii_string;
4829 Label got_char_code; 4842 Label got_char_code;
4843 Label sliced_string;
4830 4844
4831 // If the receiver is a smi trigger the non-string case. 4845 // If the receiver is a smi trigger the non-string case.
4832 STATIC_ASSERT(kSmiTag == 0); 4846 STATIC_ASSERT(kSmiTag == 0);
4833 __ JumpIfSmi(object_, receiver_not_string_); 4847 __ JumpIfSmi(object_, receiver_not_string_);
4834 4848
4835 // Fetch the instance type of the receiver into result register. 4849 // Fetch the instance type of the receiver into result register.
4836 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4850 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4837 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4851 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4838 // If the receiver is not a string trigger the non-string case. 4852 // If the receiver is not a string trigger the non-string case.
4839 __ test(result_, Immediate(kIsNotStringMask)); 4853 __ test(result_, Immediate(kIsNotStringMask));
(...skipping 10 matching lines...) Expand all
4850 // Check for index out of range. 4864 // Check for index out of range.
4851 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); 4865 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset));
4852 __ j(above_equal, index_out_of_range_); 4866 __ j(above_equal, index_out_of_range_);
4853 4867
4854 // We need special handling for non-flat strings. 4868 // We need special handling for non-flat strings.
4855 STATIC_ASSERT(kSeqStringTag == 0); 4869 STATIC_ASSERT(kSeqStringTag == 0);
4856 __ test(result_, Immediate(kStringRepresentationMask)); 4870 __ test(result_, Immediate(kStringRepresentationMask));
4857 __ j(zero, &flat_string); 4871 __ j(zero, &flat_string);
4858 4872
4859 // Handle non-flat strings. 4873 // Handle non-flat strings.
4860 __ test(result_, Immediate(kIsConsStringMask)); 4874 __ and_(result_, kStringRepresentationMask);
4861 __ j(zero, &call_runtime_); 4875 __ cmp(result_, kSlicedStringTag);
4876 __ j(equal, &sliced_string);
4877 __ cmp(result_, kExternalStringTag);
4878 __ j(equal, &call_runtime_);
4862 4879
4863 // ConsString. 4880 // ConsString.
4864 // Check whether the right hand side is the empty string (i.e. if 4881 // 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 4882 // 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 4883 // the case we would rather go to the runtime system now to flatten
4867 // the string. 4884 // the string.
4868 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), 4885 __ cmp(FieldOperand(object_, ConsString::kSecondOffset),
4869 Immediate(masm->isolate()->factory()->empty_string())); 4886 Immediate(masm->isolate()->factory()->empty_string()));
4870 __ j(not_equal, &call_runtime_); 4887 __ j(not_equal, &call_runtime_);
4871 // Get the first of the two strings and load its instance type. 4888 // Get the first of the two strings and load its instance type.
4872 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset)); 4889 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
4873 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4890 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4874 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4891 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4875 // If the first cons component is also non-flat, then go to runtime. 4892 // If the first cons component is also non-flat, then go to runtime.
4876 STATIC_ASSERT(kSeqStringTag == 0); 4893 STATIC_ASSERT(kSeqStringTag == 0);
4877 __ test(result_, Immediate(kStringRepresentationMask)); 4894 __ test(result_, Immediate(kStringRepresentationMask));
4878 __ j(not_zero, &call_runtime_); 4895 __ j(not_zero, &call_runtime_);
4896 __ jmp(&flat_string);
4897
4898 // SlicedString, unpack and add offset.
4899 __ bind(&sliced_string);
4900 __ add(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
4901 __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
4902 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4903 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4879 4904
4880 // Check for 1-byte or 2-byte string. 4905 // Check for 1-byte or 2-byte string.
4881 __ bind(&flat_string); 4906 __ bind(&flat_string);
4882 STATIC_ASSERT(kAsciiStringTag != 0); 4907 STATIC_ASSERT(kAsciiStringTag != 0);
4883 __ test(result_, Immediate(kStringEncodingMask)); 4908 __ test(result_, Immediate(kStringEncodingMask));
4884 __ j(not_zero, &ascii_string); 4909 __ j(not_zero, &ascii_string);
4885 4910
4886 // 2-byte string. 4911 // 2-byte string.
4887 // Load the 2-byte character code into the result register. 4912 // Load the 2-byte character code into the result register.
4888 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 4913 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)); 5219 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5195 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5220 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5196 __ and_(ecx, kStringRepresentationMask); 5221 __ and_(ecx, kStringRepresentationMask);
5197 __ cmp(ecx, kExternalStringTag); 5222 __ cmp(ecx, kExternalStringTag);
5198 __ j(equal, &string_add_runtime); 5223 __ j(equal, &string_add_runtime);
5199 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5224 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
5200 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5225 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5201 __ and_(ecx, kStringRepresentationMask); 5226 __ and_(ecx, kStringRepresentationMask);
5202 __ cmp(ecx, kExternalStringTag); 5227 __ cmp(ecx, kExternalStringTag);
5203 __ j(equal, &string_add_runtime); 5228 __ j(equal, &string_add_runtime);
5229 // We cannot encounter sliced strings here since:
5230 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
5204 // Now check if both strings are ascii strings. 5231 // Now check if both strings are ascii strings.
5205 // eax: first string 5232 // eax: first string
5206 // ebx: length of resulting flat string as a smi 5233 // ebx: length of resulting flat string as a smi
5207 // edx: second string 5234 // edx: second string
5208 Label non_ascii_string_add_flat_result; 5235 Label non_ascii_string_add_flat_result;
5209 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 5236 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
5210 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 5237 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5211 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 5238 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
5212 __ j(zero, &non_ascii_string_add_flat_result); 5239 __ j(zero, &non_ascii_string_add_flat_result);
5213 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5240 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
5605 __ test(hash, Operand(hash)); 5632 __ test(hash, Operand(hash));
5606 __ j(not_zero, &hash_not_zero, Label::kNear); 5633 __ j(not_zero, &hash_not_zero, Label::kNear);
5607 __ mov(hash, Immediate(27)); 5634 __ mov(hash, Immediate(27));
5608 __ bind(&hash_not_zero); 5635 __ bind(&hash_not_zero);
5609 } 5636 }
5610 5637
5611 5638
5612 void SubStringStub::Generate(MacroAssembler* masm) { 5639 void SubStringStub::Generate(MacroAssembler* masm) {
5613 Label runtime; 5640 Label runtime;
5614 5641
5642 if (FLAG_string_slices) {
5643 __ jmp(&runtime);
5644 }
5615 // Stack frame on entry. 5645 // Stack frame on entry.
5616 // esp[0]: return address 5646 // esp[0]: return address
5617 // esp[4]: to 5647 // esp[4]: to
5618 // esp[8]: from 5648 // esp[8]: from
5619 // esp[12]: string 5649 // esp[12]: string
5620 5650
5621 // Make sure first argument is a string. 5651 // Make sure first argument is a string.
5622 __ mov(eax, Operand(esp, 3 * kPointerSize)); 5652 __ mov(eax, Operand(esp, 3 * kPointerSize));
5623 STATIC_ASSERT(kSmiTag == 0); 5653 STATIC_ASSERT(kSmiTag == 0);
5624 __ JumpIfSmi(eax, &runtime); 5654 __ JumpIfSmi(eax, &runtime);
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
6381 __ Drop(1); 6411 __ Drop(1);
6382 __ ret(2 * kPointerSize); 6412 __ ret(2 * kPointerSize);
6383 } 6413 }
6384 6414
6385 6415
6386 #undef __ 6416 #undef __
6387 6417
6388 } } // namespace v8::internal 6418 } } // namespace v8::internal
6389 6419
6390 #endif // V8_TARGET_ARCH_IA32 6420 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698