| 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_);
|
|
|
|
|