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

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

Issue 7795018: Generated code for substring slices in x64 and arm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Applied Bill's suggestions. Created 9 years, 3 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 | « src/arm/macro-assembler-arm.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »
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 4889 matching lines...) Expand 10 before | Expand all | Expand 10 after
4900 __ bind(&assure_seq_string); 4900 __ bind(&assure_seq_string);
4901 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4901 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
4902 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4902 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4903 STATIC_ASSERT(kSeqStringTag == 0); 4903 STATIC_ASSERT(kSeqStringTag == 0);
4904 __ test(result_, Immediate(kStringRepresentationMask)); 4904 __ test(result_, Immediate(kStringRepresentationMask));
4905 __ j(not_zero, &call_runtime_); 4905 __ j(not_zero, &call_runtime_);
4906 __ jmp(&flat_string, Label::kNear); 4906 __ jmp(&flat_string, Label::kNear);
4907 4907
4908 // Check for 1-byte or 2-byte string. 4908 // Check for 1-byte or 2-byte string.
4909 __ bind(&flat_string); 4909 __ bind(&flat_string);
4910 STATIC_ASSERT(kAsciiStringTag != 0); 4910 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
4911 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
4911 __ test(result_, Immediate(kStringEncodingMask)); 4912 __ test(result_, Immediate(kStringEncodingMask));
4912 __ j(not_zero, &ascii_string, Label::kNear); 4913 __ j(not_zero, &ascii_string, Label::kNear);
4913 4914
4914 // 2-byte string. 4915 // 2-byte string.
4915 // Load the 2-byte character code into the result register. 4916 // Load the 2-byte character code into the result register.
4916 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 4917 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
4917 __ movzx_w(result_, FieldOperand(object_, 4918 __ movzx_w(result_, FieldOperand(object_,
4918 scratch_, times_1, // Scratch is smi-tagged. 4919 scratch_, times_1, // Scratch is smi-tagged.
4919 SeqTwoByteString::kHeaderSize)); 4920 SeqTwoByteString::kHeaderSize));
4920 __ jmp(&got_char_code, Label::kNear); 4921 __ jmp(&got_char_code, Label::kNear);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
5171 __ j(below, &string_add_flat_result); 5172 __ j(below, &string_add_flat_result);
5172 5173
5173 // If result is not supposed to be flat allocate a cons string object. If both 5174 // If result is not supposed to be flat allocate a cons string object. If both
5174 // strings are ascii the result is an ascii cons string. 5175 // strings are ascii the result is an ascii cons string.
5175 Label non_ascii, allocated, ascii_data; 5176 Label non_ascii, allocated, ascii_data;
5176 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset)); 5177 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset));
5177 __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset)); 5178 __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset));
5178 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 5179 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
5179 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset)); 5180 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset));
5180 __ and_(ecx, Operand(edi)); 5181 __ and_(ecx, Operand(edi));
5181 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 5182 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
5182 __ test(ecx, Immediate(kAsciiStringTag)); 5183 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
5184 __ test(ecx, Immediate(kStringEncodingMask));
5183 __ j(zero, &non_ascii); 5185 __ j(zero, &non_ascii);
5184 __ bind(&ascii_data); 5186 __ bind(&ascii_data);
5185 // Allocate an acsii cons string. 5187 // Allocate an acsii cons string.
5186 __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime); 5188 __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime);
5187 __ bind(&allocated); 5189 __ bind(&allocated);
5188 // Fill the fields of the cons string. 5190 // Fill the fields of the cons string.
5189 if (FLAG_debug_code) __ AbortIfNotSmi(ebx); 5191 if (FLAG_debug_code) __ AbortIfNotSmi(ebx);
5190 __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx); 5192 __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx);
5191 __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset), 5193 __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset),
5192 Immediate(String::kEmptyHashField)); 5194 Immediate(String::kEmptyHashField));
(...skipping 10 matching lines...) Expand all
5203 __ test(ecx, Immediate(kAsciiDataHintMask)); 5205 __ test(ecx, Immediate(kAsciiDataHintMask));
5204 __ j(not_zero, &ascii_data); 5206 __ j(not_zero, &ascii_data);
5205 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 5207 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5206 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5208 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5207 __ xor_(edi, Operand(ecx)); 5209 __ xor_(edi, Operand(ecx));
5208 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); 5210 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0);
5209 __ and_(edi, kAsciiStringTag | kAsciiDataHintTag); 5211 __ and_(edi, kAsciiStringTag | kAsciiDataHintTag);
5210 __ cmp(edi, kAsciiStringTag | kAsciiDataHintTag); 5212 __ cmp(edi, kAsciiStringTag | kAsciiDataHintTag);
5211 __ j(equal, &ascii_data); 5213 __ j(equal, &ascii_data);
5212 // Allocate a two byte cons string. 5214 // Allocate a two byte cons string.
5213 __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime); 5215 __ AllocateTwoByteConsString(ecx, edi, no_reg, &string_add_runtime);
5214 __ jmp(&allocated); 5216 __ jmp(&allocated);
5215 5217
5216 // Handle creating a flat result. First check that both strings are not 5218 // Handle creating a flat result. First check that both strings are not
5217 // external strings. 5219 // external strings.
5218 // eax: first string 5220 // eax: first string
5219 // ebx: length of resulting flat string as a smi 5221 // ebx: length of resulting flat string as a smi
5220 // edx: second string 5222 // edx: second string
5221 __ bind(&string_add_flat_result); 5223 __ bind(&string_add_flat_result);
5222 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 5224 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5223 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5225 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5224 __ and_(ecx, kStringRepresentationMask); 5226 __ and_(ecx, kStringRepresentationMask);
5225 __ cmp(ecx, kExternalStringTag); 5227 __ cmp(ecx, kExternalStringTag);
5226 __ j(equal, &string_add_runtime); 5228 __ j(equal, &string_add_runtime);
5227 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5229 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
5228 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 5230 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
5229 __ and_(ecx, kStringRepresentationMask); 5231 __ and_(ecx, kStringRepresentationMask);
5230 __ cmp(ecx, kExternalStringTag); 5232 __ cmp(ecx, kExternalStringTag);
5231 __ j(equal, &string_add_runtime); 5233 __ j(equal, &string_add_runtime);
5232 // We cannot encounter sliced strings here since: 5234 // We cannot encounter sliced strings here since:
5233 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength); 5235 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
5234 // Now check if both strings are ascii strings. 5236 // Now check if both strings are ascii strings.
5235 // eax: first string 5237 // eax: first string
5236 // ebx: length of resulting flat string as a smi 5238 // ebx: length of resulting flat string as a smi
5237 // edx: second string 5239 // edx: second string
5238 Label non_ascii_string_add_flat_result; 5240 Label non_ascii_string_add_flat_result;
5239 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 5241 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
5242 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
5240 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 5243 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
5241 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 5244 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
5242 __ j(zero, &non_ascii_string_add_flat_result); 5245 __ j(zero, &non_ascii_string_add_flat_result);
5243 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5246 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
5244 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 5247 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
5245 __ j(zero, &string_add_runtime); 5248 __ j(zero, &string_add_runtime);
5246 5249
5247 // Both strings are ascii strings. As they are short they are both flat. 5250 // Both strings are ascii strings. As they are short they are both flat.
5248 // ebx: length of resulting flat string as a smi 5251 // ebx: length of resulting flat string as a smi
5249 __ SmiUntag(ebx); 5252 __ SmiUntag(ebx);
5250 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); 5253 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
5251 // eax: result string 5254 // eax: result string
5252 __ mov(ecx, eax); 5255 __ mov(ecx, eax);
5253 // Locate first character of result. 5256 // Locate first character of result.
5254 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 5257 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
(...skipping 19 matching lines...) Expand all
5274 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true); 5277 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
5275 __ IncrementCounter(counters->string_add_native(), 1); 5278 __ IncrementCounter(counters->string_add_native(), 1);
5276 __ ret(2 * kPointerSize); 5279 __ ret(2 * kPointerSize);
5277 5280
5278 // Handle creating a flat two byte result. 5281 // Handle creating a flat two byte result.
5279 // eax: first string - known to be two byte 5282 // eax: first string - known to be two byte
5280 // ebx: length of resulting flat string as a smi 5283 // ebx: length of resulting flat string as a smi
5281 // edx: second string 5284 // edx: second string
5282 __ bind(&non_ascii_string_add_flat_result); 5285 __ bind(&non_ascii_string_add_flat_result);
5283 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 5286 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
5284 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 5287 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
5285 __ j(not_zero, &string_add_runtime); 5288 __ j(not_zero, &string_add_runtime);
5286 // Both strings are two byte strings. As they are short they are both 5289 // Both strings are two byte strings. As they are short they are both
5287 // flat. 5290 // flat.
5288 __ SmiUntag(ebx); 5291 __ SmiUntag(ebx);
5289 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime); 5292 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime);
5290 // eax: result string 5293 // eax: result string
5291 __ mov(ecx, eax); 5294 __ mov(ecx, eax);
5292 // Locate first character of result. 5295 // Locate first character of result.
5293 __ add(Operand(ecx), 5296 __ add(Operand(ecx),
5294 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 5297 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
5752 // edi: underlying subject string 5755 // edi: underlying subject string
5753 // ebx: instance type of original subject string 5756 // ebx: instance type of original subject string
5754 // edx: offset 5757 // edx: offset
5755 // ecx: length 5758 // ecx: length
5756 // Allocate new sliced string. At this point we do not reload the instance 5759 // Allocate new sliced string. At this point we do not reload the instance
5757 // type including the string encoding because we simply rely on the info 5760 // type including the string encoding because we simply rely on the info
5758 // provided by the original string. It does not matter if the original 5761 // provided by the original string. It does not matter if the original
5759 // string's encoding is wrong because we always have to recheck encoding of 5762 // string's encoding is wrong because we always have to recheck encoding of
5760 // the newly created string's parent anyways due to externalized strings. 5763 // the newly created string's parent anyways due to externalized strings.
5761 Label two_byte_slice, set_slice_header; 5764 Label two_byte_slice, set_slice_header;
5762 STATIC_ASSERT(kAsciiStringTag != 0); 5765 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
5763 __ test(ebx, Immediate(kAsciiStringTag)); 5766 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
5767 __ test(ebx, Immediate(kStringEncodingMask));
5764 __ j(zero, &two_byte_slice, Label::kNear); 5768 __ j(zero, &two_byte_slice, Label::kNear);
5765 __ AllocateAsciiSlicedString(eax, ebx, no_reg, &runtime); 5769 __ AllocateAsciiSlicedString(eax, ebx, no_reg, &runtime);
5766 __ jmp(&set_slice_header, Label::kNear); 5770 __ jmp(&set_slice_header, Label::kNear);
5767 __ bind(&two_byte_slice); 5771 __ bind(&two_byte_slice);
5768 __ AllocateSlicedString(eax, ebx, no_reg, &runtime); 5772 __ AllocateTwoByteSlicedString(eax, ebx, no_reg, &runtime);
5769 __ bind(&set_slice_header); 5773 __ bind(&set_slice_header);
5770 __ mov(FieldOperand(eax, SlicedString::kOffsetOffset), edx); 5774 __ mov(FieldOperand(eax, SlicedString::kOffsetOffset), edx);
5771 __ SmiTag(ecx); 5775 __ SmiTag(ecx);
5772 __ mov(FieldOperand(eax, SlicedString::kLengthOffset), ecx); 5776 __ mov(FieldOperand(eax, SlicedString::kLengthOffset), ecx);
5773 __ mov(FieldOperand(eax, SlicedString::kParentOffset), edi); 5777 __ mov(FieldOperand(eax, SlicedString::kParentOffset), edi);
5774 __ mov(FieldOperand(eax, SlicedString::kHashFieldOffset), 5778 __ mov(FieldOperand(eax, SlicedString::kHashFieldOffset),
5775 Immediate(String::kEmptyHashField)); 5779 Immediate(String::kEmptyHashField));
5776 __ jmp(&return_eax); 5780 __ jmp(&return_eax);
5777 5781
5778 __ bind(&copy_routine); 5782 __ bind(&copy_routine);
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after
6487 __ Drop(1); 6491 __ Drop(1);
6488 __ ret(2 * kPointerSize); 6492 __ ret(2 * kPointerSize);
6489 } 6493 }
6490 6494
6491 6495
6492 #undef __ 6496 #undef __
6493 6497
6494 } } // namespace v8::internal 6498 } } // namespace v8::internal
6495 6499
6496 #endif // V8_TARGET_ARCH_IA32 6500 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698