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

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

Issue 8510005: Simplify StringCharCodeAt in non-crankshaft codegen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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 5089 matching lines...) Expand 10 before | Expand all | Expand 10 after
5100 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 5100 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
5101 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 5101 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
5102 // If the receiver is not a string trigger the non-string case. 5102 // If the receiver is not a string trigger the non-string case.
5103 __ test(result_, Immediate(kIsNotStringMask)); 5103 __ test(result_, Immediate(kIsNotStringMask));
5104 __ j(not_zero, receiver_not_string_); 5104 __ j(not_zero, receiver_not_string_);
5105 5105
5106 // If the index is non-smi trigger the non-smi case. 5106 // If the index is non-smi trigger the non-smi case.
5107 STATIC_ASSERT(kSmiTag == 0); 5107 STATIC_ASSERT(kSmiTag == 0);
5108 __ JumpIfNotSmi(index_, &index_not_smi_); 5108 __ JumpIfNotSmi(index_, &index_not_smi_);
5109 5109
5110 // Put smi-tagged index into scratch register. 5110 // Put smi-tagged index into scratch register.
Lasse Reichstein 2011/11/09 12:48:11 Remove the comment too.
5111 __ mov(scratch_, index_);
5112 __ bind(&got_smi_index_); 5111 __ bind(&got_smi_index_);
5113 5112
5114 // Check for index out of range. 5113 // Check for index out of range.
5115 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); 5114 __ cmp(index_, FieldOperand(object_, String::kLengthOffset));
5116 __ j(above_equal, index_out_of_range_); 5115 __ j(above_equal, index_out_of_range_);
5117 5116
5118 // We need special handling for non-flat strings. 5117 // We need special handling for non-flat strings.
5119 STATIC_ASSERT(kSeqStringTag == 0); 5118 STATIC_ASSERT(kSeqStringTag == 0);
5120 __ test(result_, Immediate(kStringRepresentationMask)); 5119 __ test(result_, Immediate(kStringRepresentationMask));
5121 __ j(zero, &flat_string); 5120 __ j(zero, &flat_string);
5122 5121
5123 // Handle non-flat strings. 5122 // Handle non-flat strings.
5124 __ and_(result_, kStringRepresentationMask); 5123 __ and_(result_, kStringRepresentationMask);
5125 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 5124 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
5126 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); 5125 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
5127 __ cmp(result_, kExternalStringTag); 5126 __ cmp(result_, kExternalStringTag);
5128 __ j(greater, &sliced_string, Label::kNear); 5127 __ j(greater, &sliced_string, Label::kNear);
5129 __ j(equal, &call_runtime_); 5128 __ j(equal, &call_runtime_);
5130 5129
5131 // ConsString. 5130 // ConsString.
5132 // Check whether the right hand side is the empty string (i.e. if 5131 // Check whether the right hand side is the empty string (i.e. if
5133 // this is really a flat string in a cons string). If that is not 5132 // this is really a flat string in a cons string). If that is not
5134 // the case we would rather go to the runtime system now to flatten 5133 // the case we would rather go to the runtime system now to flatten
5135 // the string. 5134 // the string.
5136 Label assure_seq_string; 5135 Label assure_seq_string;
5137 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), 5136 __ cmp(FieldOperand(object_, ConsString::kSecondOffset),
5138 Immediate(masm->isolate()->factory()->empty_string())); 5137 Immediate(masm->isolate()->factory()->empty_string()));
5139 __ j(not_equal, &call_runtime_); 5138 __ j(not_equal, &call_runtime_);
5140 // Get the first of the two strings and load its instance type. 5139 // Get the first of the two parts.
5141 __ mov(result_, FieldOperand(object_, ConsString::kFirstOffset)); 5140 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
5142 __ jmp(&assure_seq_string, Label::kNear); 5141 __ jmp(&assure_seq_string, Label::kNear);
5143 5142
5144 // SlicedString, unpack and add offset. 5143 // SlicedString, unpack and add offset.
5145 __ bind(&sliced_string); 5144 __ bind(&sliced_string);
5146 __ add(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset)); 5145 __ add(index_, FieldOperand(object_, SlicedString::kOffsetOffset));
5147 __ mov(result_, FieldOperand(object_, SlicedString::kParentOffset)); 5146 __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
5148 5147
5149 // Assure that we are dealing with a sequential string. Go to runtime if not. 5148 // Assure that we are dealing with a sequential string. Go to runtime if not.
5149 // Note that if the original string is a cons or slice with an external
5150 // string as underlying string, we pass that unpacked underlying string with
5151 // the updated index to the runtime function.
5150 __ bind(&assure_seq_string); 5152 __ bind(&assure_seq_string);
5151 __ mov(result_, FieldOperand(result_, HeapObject::kMapOffset)); 5153 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
5152 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 5154 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
5153 STATIC_ASSERT(kSeqStringTag == 0); 5155 STATIC_ASSERT(kSeqStringTag == 0);
5154 __ test(result_, Immediate(kStringRepresentationMask)); 5156 __ test(result_, Immediate(kStringRepresentationMask));
5155 __ j(not_zero, &call_runtime_); 5157 __ j(not_zero, &call_runtime_);
5156 // Actually fetch the parent string if it is confirmed to be sequential.
5157 STATIC_ASSERT(SlicedString::kParentOffset == ConsString::kFirstOffset);
5158 __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
5159 5158
5160 // Check for 1-byte or 2-byte string. 5159 // Check for 1-byte or 2-byte string.
5161 __ bind(&flat_string); 5160 __ bind(&flat_string);
5162 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); 5161 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
5163 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 5162 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
5164 __ test(result_, Immediate(kStringEncodingMask)); 5163 __ test(result_, Immediate(kStringEncodingMask));
5165 __ j(not_zero, &ascii_string, Label::kNear); 5164 __ j(not_zero, &ascii_string, Label::kNear);
5166 5165
5167 // 2-byte string. 5166 // 2-byte string.
5168 // Load the 2-byte character code into the result register. 5167 // Load the 2-byte character code into the result register.
5169 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 5168 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
5170 __ movzx_w(result_, FieldOperand(object_, 5169 __ movzx_w(result_, FieldOperand(object_,
5171 scratch_, times_1, // Scratch is smi-tagged. 5170 index_, times_1, // Scratch is smi-tagged.
5172 SeqTwoByteString::kHeaderSize)); 5171 SeqTwoByteString::kHeaderSize));
5173 __ jmp(&got_char_code, Label::kNear); 5172 __ jmp(&got_char_code, Label::kNear);
5174 5173
5175 // ASCII string. 5174 // ASCII string.
5176 // Load the byte into the result register. 5175 // Load the byte into the result register.
5177 __ bind(&ascii_string); 5176 __ bind(&ascii_string);
5178 __ SmiUntag(scratch_); 5177 __ SmiUntag(index_);
5179 __ movzx_b(result_, FieldOperand(object_, 5178 __ movzx_b(result_, FieldOperand(object_,
5180 scratch_, times_1, 5179 index_, times_1,
5181 SeqAsciiString::kHeaderSize)); 5180 SeqAsciiString::kHeaderSize));
5182 __ bind(&got_char_code); 5181 __ bind(&got_char_code);
5183 __ SmiTag(result_); 5182 __ SmiTag(result_);
5184 __ bind(&exit_); 5183 __ bind(&exit_);
5185 } 5184 }
5186 5185
5187 5186
5188 void StringCharCodeAtGenerator::GenerateSlow( 5187 void StringCharCodeAtGenerator::GenerateSlow(
5189 MacroAssembler* masm, 5188 MacroAssembler* masm,
5190 const RuntimeCallHelper& call_helper) { 5189 const RuntimeCallHelper& call_helper) {
5191 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); 5190 __ Abort("Unexpected fallthrough to CharCodeAt slow case");
5192 5191
5193 // Index is not a smi. 5192 // Index is not a smi.
5194 __ bind(&index_not_smi_); 5193 __ bind(&index_not_smi_);
5195 // If index is a heap number, try converting it to an integer. 5194 // If index is a heap number, try converting it to an integer.
5196 __ CheckMap(index_, 5195 __ CheckMap(index_,
5197 masm->isolate()->factory()->heap_number_map(), 5196 masm->isolate()->factory()->heap_number_map(),
5198 index_not_number_, 5197 index_not_number_,
5199 DONT_DO_SMI_CHECK); 5198 DONT_DO_SMI_CHECK);
5200 call_helper.BeforeCall(masm); 5199 call_helper.BeforeCall(masm);
5201 __ push(object_); 5200 __ push(object_);
5202 __ push(index_);
5203 __ push(index_); // Consumed by runtime conversion function. 5201 __ push(index_); // Consumed by runtime conversion function.
5204 if (index_flags_ == STRING_INDEX_IS_NUMBER) { 5202 if (index_flags_ == STRING_INDEX_IS_NUMBER) {
5205 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); 5203 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
5206 } else { 5204 } else {
5207 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); 5205 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
5208 // NumberToSmi discards numbers that are not exact integers. 5206 // NumberToSmi discards numbers that are not exact integers.
5209 __ CallRuntime(Runtime::kNumberToSmi, 1); 5207 __ CallRuntime(Runtime::kNumberToSmi, 1);
5210 } 5208 }
5211 if (!scratch_.is(eax)) { 5209 if (!index_.is(eax)) {
5212 // Save the conversion result before the pop instructions below 5210 // Save the conversion result before the pop instructions below
5213 // have a chance to overwrite it. 5211 // have a chance to overwrite it.
5214 __ mov(scratch_, eax); 5212 __ mov(index_, eax);
5215 } 5213 }
5216 __ pop(index_);
5217 __ pop(object_); 5214 __ pop(object_);
5218 // Reload the instance type. 5215 // Reload the instance type.
5219 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 5216 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
5220 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 5217 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
5221 call_helper.AfterCall(masm); 5218 call_helper.AfterCall(masm);
5222 // If index is still not a smi, it must be out of range. 5219 // If index is still not a smi, it must be out of range.
5223 STATIC_ASSERT(kSmiTag == 0); 5220 STATIC_ASSERT(kSmiTag == 0);
5224 __ JumpIfNotSmi(scratch_, index_out_of_range_); 5221 __ JumpIfNotSmi(index_, index_out_of_range_);
5225 // Otherwise, return to the fast path. 5222 // Otherwise, return to the fast path.
5226 __ jmp(&got_smi_index_); 5223 __ jmp(&got_smi_index_);
5227 5224
5228 // Call runtime. We get here when the receiver is a string and the 5225 // Call runtime. We get here when the receiver is a string and the
5229 // index is a number, but the code of getting the actual character 5226 // index is a number, but the code of getting the actual character
5230 // is too complex (e.g., when the string needs to be flattened). 5227 // is too complex (e.g., when the string needs to be flattened).
5231 __ bind(&call_runtime_); 5228 __ bind(&call_runtime_);
5232 call_helper.BeforeCall(masm); 5229 call_helper.BeforeCall(masm);
5233 __ push(object_); 5230 __ push(object_);
5234 __ push(index_); 5231 __ push(index_);
(...skipping 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after
7113 __ bind(&element_done); 7110 __ bind(&element_done);
7114 __ ret(0); 7111 __ ret(0);
7115 } 7112 }
7116 } 7113 }
7117 7114
7118 #undef __ 7115 #undef __
7119 7116
7120 } } // namespace v8::internal 7117 } } // namespace v8::internal
7121 7118
7122 #endif // V8_TARGET_ARCH_IA32 7119 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | src/x64/code-stubs-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698