Index: src/x64/code-stubs-x64.cc |
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
index b8f820d7f5581e9727731f61fa8481a751258aa0..19326f2775ea2e7205015243eb96291c006d3107 100644 |
--- a/src/x64/code-stubs-x64.cc |
+++ b/src/x64/code-stubs-x64.cc |
@@ -4157,70 +4157,11 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
__ SmiCompare(index_, FieldOperand(object_, String::kLengthOffset)); |
__ j(above_equal, index_out_of_range_); |
- // We need special handling for non-flat strings. |
- STATIC_ASSERT(kSeqStringTag == 0); |
- __ testb(result_, Immediate(kStringRepresentationMask)); |
- __ j(zero, &flat_string); |
+ __ SmiToInteger32(index_, index_); |
- // Handle non-flat strings. |
- __ and_(result_, Immediate(kStringRepresentationMask)); |
- STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
- STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
- __ cmpb(result_, Immediate(kExternalStringTag)); |
- __ j(greater, &sliced_string); |
- __ j(equal, &call_runtime_); |
- |
- // ConsString. |
- // Check whether the right hand side is the empty string (i.e. if |
- // this is really a flat string in a cons string). If that is not |
- // the case we would rather go to the runtime system now to flatten |
- // the string. |
- Label assure_seq_string; |
- __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset), |
- Heap::kEmptyStringRootIndex); |
- __ j(not_equal, &call_runtime_); |
- // Get the first of the two parts. |
- __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset)); |
- __ jmp(&assure_seq_string, Label::kNear); |
- |
- // SlicedString, unpack and add offset. |
- __ bind(&sliced_string); |
- __ addq(index_, FieldOperand(object_, SlicedString::kOffsetOffset)); |
- __ movq(object_, FieldOperand(object_, SlicedString::kParentOffset)); |
- |
- // Assure that we are dealing with a sequential string. Go to runtime if not. |
- // Note that if the original string is a cons or slice with an external |
- // string as underlying string, we pass that unpacked underlying string with |
- // the adjusted index to the runtime function. |
- __ bind(&assure_seq_string); |
- __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
- __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
- STATIC_ASSERT(kSeqStringTag == 0); |
- __ testb(result_, Immediate(kStringRepresentationMask)); |
- __ j(not_zero, &call_runtime_); |
+ StringCharLoadGenerator::Generate( |
+ masm, object_, index_, result_, &call_runtime_); |
- // Check for 1-byte or 2-byte string. |
- __ bind(&flat_string); |
- STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
- STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
- __ SmiToInteger32(index_, index_); |
- __ testb(result_, Immediate(kStringEncodingMask)); |
- __ j(not_zero, &ascii_string); |
- |
- // 2-byte string. |
- // Load the 2-byte character code into the result register. |
- __ movzxwl(result_, FieldOperand(object_, |
- index_, times_2, |
- SeqTwoByteString::kHeaderSize)); |
- __ jmp(&got_char_code); |
- |
- // ASCII string. |
- // Load the byte into the result register. |
- __ bind(&ascii_string); |
- __ movzxbl(result_, FieldOperand(object_, |
- index_, times_1, |
- SeqAsciiString::kHeaderSize)); |
- __ bind(&got_char_code); |
__ Integer32ToSmi(result_, result_); |
__ bind(&exit_); |
} |
@@ -4270,6 +4211,7 @@ void StringCharCodeAtGenerator::GenerateSlow( |
__ bind(&call_runtime_); |
call_helper.BeforeCall(masm); |
__ push(object_); |
+ __ Integer32ToSmi(index_, index_); |
__ push(index_); |
__ CallRuntime(Runtime::kStringCharCodeAt, 2); |
if (!result_.is(rax)) { |