Index: src/arm/code-stubs-arm.cc |
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
index 023312f4435f911606b3114578b064fc03f438ca..564fda7220983a0a250ef6fa0c1f10105c2b2cf1 100644 |
--- a/src/arm/code-stubs-arm.cc |
+++ b/src/arm/code-stubs-arm.cc |
@@ -5058,12 +5058,11 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
__ JumpIfNotSmi(index_, &index_not_smi_); |
// Put smi-tagged index into scratch register. |
- __ mov(scratch_, index_); |
__ bind(&got_smi_index_); |
// Check for index out of range. |
__ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); |
- __ cmp(ip, Operand(scratch_)); |
+ __ cmp(ip, Operand(index_)); |
__ b(ls, index_out_of_range_); |
// We need special handling for non-flat strings. |
@@ -5089,27 +5088,27 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
__ LoadRoot(ip, Heap::kEmptyStringRootIndex); |
__ cmp(result_, Operand(ip)); |
__ b(ne, &call_runtime_); |
- // Get the first of the two strings and load its instance type. |
- __ ldr(result_, FieldMemOperand(object_, ConsString::kFirstOffset)); |
+ // Get the first of the two parts. |
+ __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); |
__ jmp(&assure_seq_string); |
// SlicedString, unpack and add offset. |
__ bind(&sliced_string); |
__ ldr(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset)); |
- __ add(scratch_, scratch_, result_); |
- __ ldr(result_, FieldMemOperand(object_, SlicedString::kParentOffset)); |
+ __ add(index_, index_, result_); |
+ __ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset)); |
// Assure that we are dealing with a sequential string. Go to runtime if not. |
__ bind(&assure_seq_string); |
- __ ldr(result_, FieldMemOperand(result_, HeapObject::kMapOffset)); |
+ __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
__ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
// Check that parent is not an external string. Go to runtime otherwise. |
+ // 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 updated index to the runtime function. |
STATIC_ASSERT(kSeqStringTag == 0); |
__ tst(result_, Operand(kStringRepresentationMask)); |
__ b(ne, &call_runtime_); |
- // Actually fetch the parent string if it is confirmed to be sequential. |
- STATIC_ASSERT(SlicedString::kParentOffset == ConsString::kFirstOffset); |
- __ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset)); |
// Check for 1-byte or 2-byte string. |
__ bind(&flat_string); |
@@ -5123,15 +5122,15 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
// add without shifting since the smi tag size is the log2 of the |
// number of bytes in a two-byte character. |
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0); |
- __ add(scratch_, object_, Operand(scratch_)); |
- __ ldrh(result_, FieldMemOperand(scratch_, SeqTwoByteString::kHeaderSize)); |
+ __ add(index_, object_, Operand(index_)); |
+ __ ldrh(result_, FieldMemOperand(index_, SeqTwoByteString::kHeaderSize)); |
__ jmp(&got_char_code); |
// ASCII string. |
// Load the byte into the result register. |
__ bind(&ascii_string); |
- __ add(scratch_, object_, Operand(scratch_, LSR, kSmiTagSize)); |
- __ ldrb(result_, FieldMemOperand(scratch_, SeqAsciiString::kHeaderSize)); |
+ __ add(index_, object_, Operand(index_, LSR, kSmiTagSize)); |
+ __ ldrb(result_, FieldMemOperand(index_, SeqAsciiString::kHeaderSize)); |
__ bind(&got_char_code); |
__ mov(result_, Operand(result_, LSL, kSmiTagSize)); |
@@ -5148,12 +5147,12 @@ void StringCharCodeAtGenerator::GenerateSlow( |
__ bind(&index_not_smi_); |
// If index is a heap number, try converting it to an integer. |
__ CheckMap(index_, |
- scratch_, |
+ result_, |
Heap::kHeapNumberMapRootIndex, |
index_not_number_, |
DONT_DO_SMI_CHECK); |
call_helper.BeforeCall(masm); |
- __ Push(object_, index_); |
+ __ push(object_); |
__ push(index_); // Consumed by runtime conversion function. |
if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
__ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
@@ -5164,15 +5163,14 @@ void StringCharCodeAtGenerator::GenerateSlow( |
} |
// Save the conversion result before the pop instructions below |
// have a chance to overwrite it. |
- __ Move(scratch_, r0); |
- __ pop(index_); |
+ __ Move(index_, r0); |
__ pop(object_); |
// Reload the instance type. |
__ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
__ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
call_helper.AfterCall(masm); |
// If index is still not a smi, it must be out of range. |
- __ JumpIfNotSmi(scratch_, index_out_of_range_); |
+ __ JumpIfNotSmi(index_, index_out_of_range_); |
// Otherwise, return to the fast path. |
__ jmp(&got_smi_index_); |