| Index: src/mips/codegen-mips.cc
|
| diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
|
| index c94e0fa52939947439062bd13e7dd57a325de1dd..0b6838497353c7a1d8fb0c7a069e679da2bb8d2a 100644
|
| --- a/src/mips/codegen-mips.cc
|
| +++ b/src/mips/codegen-mips.cc
|
| @@ -310,6 +310,98 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
|
| __ pop(ra);
|
| }
|
|
|
| +
|
| +void StringCharLoadGenerator::Generate(MacroAssembler* masm,
|
| + Register string,
|
| + Register index,
|
| + Register result,
|
| + Label* call_runtime) {
|
| + // Fetch the instance type of the receiver into result register.
|
| + __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset));
|
| + __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
|
| +
|
| + // We need special handling for indirect strings.
|
| + Label check_sequential;
|
| + __ And(at, result, Operand(kIsIndirectStringMask));
|
| + __ Branch(&check_sequential, eq, at, Operand(zero_reg));
|
| +
|
| + // Dispatch on the indirect string shape: slice or cons.
|
| + Label cons_string;
|
| + __ And(at, result, Operand(kSlicedNotConsMask));
|
| + __ Branch(&cons_string, eq, at, Operand(zero_reg));
|
| +
|
| + // Handle slices.
|
| + Label indirect_string_loaded;
|
| + __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
|
| + __ sra(at, result, kSmiTagSize);
|
| + __ Addu(index, index, at);
|
| + __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset));
|
| + __ jmp(&indirect_string_loaded);
|
| +
|
| + // Handle cons strings.
|
| + // 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.
|
| + __ bind(&cons_string);
|
| + __ lw(result, FieldMemOperand(string, ConsString::kSecondOffset));
|
| + __ LoadRoot(at, Heap::kEmptyStringRootIndex);
|
| + __ Branch(call_runtime, ne, result, Operand(at));
|
| + // Get the first of the two strings and load its instance type.
|
| + __ lw(string, FieldMemOperand(string, ConsString::kFirstOffset));
|
| +
|
| + __ bind(&indirect_string_loaded);
|
| + __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset));
|
| + __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
|
| +
|
| + // Distinguish sequential and external strings. Only these two string
|
| + // representations can reach here (slices and flat cons strings have been
|
| + // reduced to the underlying sequential or external string).
|
| + Label external_string, check_encoding;
|
| + __ bind(&check_sequential);
|
| + STATIC_ASSERT(kSeqStringTag == 0);
|
| + __ And(at, result, Operand(kStringRepresentationMask));
|
| + __ Branch(&external_string, ne, at, Operand(zero_reg));
|
| +
|
| + // Prepare sequential strings
|
| + STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
|
| + __ Addu(string,
|
| + string,
|
| + SeqTwoByteString::kHeaderSize - kHeapObjectTag);
|
| + __ jmp(&check_encoding);
|
| +
|
| + // Handle external strings.
|
| + __ bind(&external_string);
|
| + if (FLAG_debug_code) {
|
| + // Assert that we do not have a cons or slice (indirect strings) here.
|
| + // Sequential strings have already been ruled out.
|
| + __ And(at, result, Operand(kIsIndirectStringMask));
|
| + __ Assert(eq, "external string expected, but not found",
|
| + at, Operand(zero_reg));
|
| + }
|
| + // Rule out short external strings.
|
| + STATIC_CHECK(kShortExternalStringTag != 0);
|
| + __ And(at, result, Operand(kShortExternalStringMask));
|
| + __ Branch(call_runtime, ne, at, Operand(zero_reg));
|
| + __ lw(string, FieldMemOperand(string, ExternalString::kResourceDataOffset));
|
| +
|
| + Label ascii, done;
|
| + __ bind(&check_encoding);
|
| + STATIC_ASSERT(kTwoByteStringTag == 0);
|
| + __ And(at, result, Operand(kStringEncodingMask));
|
| + __ Branch(&ascii, ne, at, Operand(zero_reg));
|
| + // Two-byte string.
|
| + __ sll(at, index, 1);
|
| + __ Addu(at, string, at);
|
| + __ lhu(result, MemOperand(at));
|
| + __ jmp(&done);
|
| + __ bind(&ascii);
|
| + // Ascii string.
|
| + __ Addu(at, string, index);
|
| + __ lbu(result, MemOperand(at));
|
| + __ bind(&done);
|
| +}
|
| +
|
| #undef __
|
|
|
| } } // namespace v8::internal
|
|
|