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

Side by Side Diff: src/x64/code-stubs-x64.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 4052 matching lines...) Expand 10 before | Expand all | Expand 10 after
4063 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4063 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
4064 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4064 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4065 // If the receiver is not a string trigger the non-string case. 4065 // If the receiver is not a string trigger the non-string case.
4066 __ testb(result_, Immediate(kIsNotStringMask)); 4066 __ testb(result_, Immediate(kIsNotStringMask));
4067 __ j(not_zero, receiver_not_string_); 4067 __ j(not_zero, receiver_not_string_);
4068 4068
4069 // If the index is non-smi trigger the non-smi case. 4069 // If the index is non-smi trigger the non-smi case.
4070 __ JumpIfNotSmi(index_, &index_not_smi_); 4070 __ JumpIfNotSmi(index_, &index_not_smi_);
4071 4071
4072 // Put smi-tagged index into scratch register. 4072 // Put smi-tagged index into scratch register.
4073 __ movq(scratch_, index_);
4074 __ bind(&got_smi_index_); 4073 __ bind(&got_smi_index_);
4075 4074
4076 // Check for index out of range. 4075 // Check for index out of range.
4077 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset)); 4076 __ SmiCompare(index_, FieldOperand(object_, String::kLengthOffset));
4078 __ j(above_equal, index_out_of_range_); 4077 __ j(above_equal, index_out_of_range_);
4079 4078
4080 // We need special handling for non-flat strings. 4079 // We need special handling for non-flat strings.
4081 STATIC_ASSERT(kSeqStringTag == 0); 4080 STATIC_ASSERT(kSeqStringTag == 0);
4082 __ testb(result_, Immediate(kStringRepresentationMask)); 4081 __ testb(result_, Immediate(kStringRepresentationMask));
4083 __ j(zero, &flat_string); 4082 __ j(zero, &flat_string);
4084 4083
4085 // Handle non-flat strings. 4084 // Handle non-flat strings.
4086 __ and_(result_, Immediate(kStringRepresentationMask)); 4085 __ and_(result_, Immediate(kStringRepresentationMask));
4087 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 4086 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
4088 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); 4087 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
4089 __ cmpb(result_, Immediate(kExternalStringTag)); 4088 __ cmpb(result_, Immediate(kExternalStringTag));
4090 __ j(greater, &sliced_string); 4089 __ j(greater, &sliced_string);
4091 __ j(equal, &call_runtime_); 4090 __ j(equal, &call_runtime_);
4092 4091
4093 // ConsString. 4092 // ConsString.
4094 // Check whether the right hand side is the empty string (i.e. if 4093 // Check whether the right hand side is the empty string (i.e. if
4095 // this is really a flat string in a cons string). If that is not 4094 // this is really a flat string in a cons string). If that is not
4096 // the case we would rather go to the runtime system now to flatten 4095 // the case we would rather go to the runtime system now to flatten
4097 // the string. 4096 // the string.
4098 Label assure_seq_string; 4097 Label assure_seq_string;
4099 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset), 4098 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset),
4100 Heap::kEmptyStringRootIndex); 4099 Heap::kEmptyStringRootIndex);
4101 __ j(not_equal, &call_runtime_); 4100 __ j(not_equal, &call_runtime_);
4102 // Get the first of the two strings and load its instance type. 4101 // Get the first of the two parts.
4103 ASSERT(!kScratchRegister.is(scratch_)); 4102 ASSERT(!kScratchRegister.is(scratch_));
4104 __ movq(kScratchRegister, FieldOperand(object_, ConsString::kFirstOffset)); 4103 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset));
4105 __ jmp(&assure_seq_string, Label::kNear); 4104 __ jmp(&assure_seq_string, Label::kNear);
4106 4105
4107 // SlicedString, unpack and add offset. 4106 // SlicedString, unpack and add offset.
4108 __ bind(&sliced_string); 4107 __ bind(&sliced_string);
4109 __ addq(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset)); 4108 __ addq(index_, FieldOperand(object_, SlicedString::kOffsetOffset));
4110 __ movq(kScratchRegister, FieldOperand(object_, SlicedString::kParentOffset)); 4109 __ movq(object_, FieldOperand(object_, SlicedString::kParentOffset));
4111 4110
4111 // Assure that we are dealing with a sequential string. Go to runtime if not.
4112 // Note that if the original string is a cons or slice with an external
4113 // string as underlying string, we pass that unpacked underlying string with
4114 // the updated index to the runtime function.
4112 __ bind(&assure_seq_string); 4115 __ bind(&assure_seq_string);
4113 __ movq(result_, FieldOperand(kScratchRegister, HeapObject::kMapOffset)); 4116 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
4114 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4117 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4115 // If the first cons component is also non-flat, then go to runtime.
4116 STATIC_ASSERT(kSeqStringTag == 0); 4118 STATIC_ASSERT(kSeqStringTag == 0);
4117 __ testb(result_, Immediate(kStringRepresentationMask)); 4119 __ testb(result_, Immediate(kStringRepresentationMask));
4118 __ j(not_zero, &call_runtime_); 4120 __ j(not_zero, &call_runtime_);
4119 __ movq(object_, kScratchRegister);
4120 4121
4121 // Check for 1-byte or 2-byte string. 4122 // Check for 1-byte or 2-byte string.
4122 __ bind(&flat_string); 4123 __ bind(&flat_string);
4123 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); 4124 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
4124 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 4125 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
Lasse Reichstein 2011/11/09 12:48:11 Could we convert index from smi to int32 here, ins
4125 __ testb(result_, Immediate(kStringEncodingMask)); 4126 __ testb(result_, Immediate(kStringEncodingMask));
4126 __ j(not_zero, &ascii_string); 4127 __ j(not_zero, &ascii_string);
4127 4128
4128 // 2-byte string. 4129 // 2-byte string.
4129 // Load the 2-byte character code into the result register. 4130 // Load the 2-byte character code into the result register.
4130 __ SmiToInteger32(scratch_, scratch_); 4131 __ SmiToInteger32(index_, index_);
4131 __ movzxwl(result_, FieldOperand(object_, 4132 __ movzxwl(result_, FieldOperand(object_,
4132 scratch_, times_2, 4133 index_, times_2,
4133 SeqTwoByteString::kHeaderSize)); 4134 SeqTwoByteString::kHeaderSize));
4134 __ jmp(&got_char_code); 4135 __ jmp(&got_char_code);
4135 4136
4136 // ASCII string. 4137 // ASCII string.
4137 // Load the byte into the result register. 4138 // Load the byte into the result register.
4138 __ bind(&ascii_string); 4139 __ bind(&ascii_string);
4139 __ SmiToInteger32(scratch_, scratch_); 4140 __ SmiToInteger32(index_, index_);
4140 __ movzxbl(result_, FieldOperand(object_, 4141 __ movzxbl(result_, FieldOperand(object_,
4141 scratch_, times_1, 4142 index_, times_1,
4142 SeqAsciiString::kHeaderSize)); 4143 SeqAsciiString::kHeaderSize));
4143 __ bind(&got_char_code); 4144 __ bind(&got_char_code);
4144 __ Integer32ToSmi(result_, result_); 4145 __ Integer32ToSmi(result_, result_);
4145 __ bind(&exit_); 4146 __ bind(&exit_);
4146 } 4147 }
4147 4148
4148 4149
4149 void StringCharCodeAtGenerator::GenerateSlow( 4150 void StringCharCodeAtGenerator::GenerateSlow(
4150 MacroAssembler* masm, 4151 MacroAssembler* masm,
4151 const RuntimeCallHelper& call_helper) { 4152 const RuntimeCallHelper& call_helper) {
4152 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); 4153 __ Abort("Unexpected fallthrough to CharCodeAt slow case");
4153 4154
4154 Factory* factory = masm->isolate()->factory(); 4155 Factory* factory = masm->isolate()->factory();
4155 // Index is not a smi. 4156 // Index is not a smi.
4156 __ bind(&index_not_smi_); 4157 __ bind(&index_not_smi_);
4157 // If index is a heap number, try converting it to an integer. 4158 // If index is a heap number, try converting it to an integer.
4158 __ CheckMap(index_, 4159 __ CheckMap(index_,
4159 factory->heap_number_map(), 4160 factory->heap_number_map(),
4160 index_not_number_, 4161 index_not_number_,
4161 DONT_DO_SMI_CHECK); 4162 DONT_DO_SMI_CHECK);
4162 call_helper.BeforeCall(masm); 4163 call_helper.BeforeCall(masm);
4163 __ push(object_); 4164 __ push(object_);
4164 __ push(index_);
4165 __ push(index_); // Consumed by runtime conversion function. 4165 __ push(index_); // Consumed by runtime conversion function.
4166 if (index_flags_ == STRING_INDEX_IS_NUMBER) { 4166 if (index_flags_ == STRING_INDEX_IS_NUMBER) {
4167 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); 4167 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
4168 } else { 4168 } else {
4169 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); 4169 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
4170 // NumberToSmi discards numbers that are not exact integers. 4170 // NumberToSmi discards numbers that are not exact integers.
4171 __ CallRuntime(Runtime::kNumberToSmi, 1); 4171 __ CallRuntime(Runtime::kNumberToSmi, 1);
4172 } 4172 }
4173 if (!scratch_.is(rax)) { 4173 if (!index_.is(rax)) {
4174 // Save the conversion result before the pop instructions below 4174 // Save the conversion result before the pop instructions below
4175 // have a chance to overwrite it. 4175 // have a chance to overwrite it.
4176 __ movq(scratch_, rax); 4176 __ movq(index_, rax);
4177 } 4177 }
4178 __ pop(index_);
4179 __ pop(object_); 4178 __ pop(object_);
4180 // Reload the instance type. 4179 // Reload the instance type.
4181 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 4180 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
4182 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 4181 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
4183 call_helper.AfterCall(masm); 4182 call_helper.AfterCall(masm);
4184 // If index is still not a smi, it must be out of range. 4183 // If index is still not a smi, it must be out of range.
4185 __ JumpIfNotSmi(scratch_, index_out_of_range_); 4184 __ JumpIfNotSmi(index_, index_out_of_range_);
4186 // Otherwise, return to the fast path. 4185 // Otherwise, return to the fast path.
4187 __ jmp(&got_smi_index_); 4186 __ jmp(&got_smi_index_);
4188 4187
4189 // Call runtime. We get here when the receiver is a string and the 4188 // Call runtime. We get here when the receiver is a string and the
4190 // index is a number, but the code of getting the actual character 4189 // index is a number, but the code of getting the actual character
4191 // is too complex (e.g., when the string needs to be flattened). 4190 // is too complex (e.g., when the string needs to be flattened).
4192 __ bind(&call_runtime_); 4191 __ bind(&call_runtime_);
4193 call_helper.BeforeCall(masm); 4192 call_helper.BeforeCall(masm);
4194 __ push(object_); 4193 __ push(object_);
4195 __ push(index_); 4194 __ push(index_);
(...skipping 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after
6027 __ bind(&element_done); 6026 __ bind(&element_done);
6028 __ ret(0); 6027 __ ret(0);
6029 } 6028 }
6030 } 6029 }
6031 6030
6032 #undef __ 6031 #undef __
6033 6032
6034 } } // namespace v8::internal 6033 } } // namespace v8::internal
6035 6034
6036 #endif // V8_TARGET_ARCH_X64 6035 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698