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

Unified Diff: src/arm/lithium-codegen-arm.cc

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more suggested changes. Created 9 years, 4 months 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 side-by-side diff with in-line comments
Download patch
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 54ad4581c5ce632e7c74d7f193e5a627fcdff88f..351e9d982a196e2df7038012ab8be053da3c738d 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3421,97 +3421,83 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
LStringCharCodeAt* instr_;
};
- Register scratch = scratch0();
Register string = ToRegister(instr->string());
- Register index = no_reg;
- int const_index = -1;
- if (instr->index()->IsConstantOperand()) {
- const_index = ToInteger32(LConstantOperand::cast(instr->index()));
- STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
- if (!Smi::IsValid(const_index)) {
- // Guaranteed to be out of bounds because of the assert above.
- // So the bounds check that must dominate this instruction must
- // have deoptimized already.
- if (FLAG_debug_code) {
- __ Abort("StringCharCodeAt: out of bounds index.");
- }
- // No code needs to be generated.
- return;
- }
- } else {
- index = ToRegister(instr->index());
- }
+ Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr);
- Label flat_string, ascii_string, done;
-
// Fetch the instance type of the receiver into result register.
__ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset));
__ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
- // We need special handling for non-flat strings.
- STATIC_ASSERT(kSeqStringTag == 0);
- __ tst(result, Operand(kStringRepresentationMask));
- __ b(eq, &flat_string);
-
- // Handle non-flat strings.
- __ tst(result, Operand(kIsConsStringMask));
- __ b(eq, deferred->entry());
-
- // ConsString.
+ // We need special handling for indirect strings.
+ Label check_sequential;
+ __ tst(result, Operand(kIsIndirectStringMask));
+ __ b(eq, &check_sequential);
+
+ // Dispatch on the indirect string shape: slice or cons.
+ Label cons_string;
+ const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
+ ASSERT(IsPowerOf2(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
+ __ tst(result, Operand(kSlicedNotConsMask));
+ __ b(eq, &cons_string);
+
+ // Handle slices.
+ Label indirect_string_loaded;
+ __ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
+ __ add(index, index, Operand(result, ASR, kSmiTagSize));
+ __ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset));
+ __ jmp(&indirect_string_loaded);
+
+ // Handle conses.
// 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.
- __ ldr(scratch, FieldMemOperand(string, ConsString::kSecondOffset));
+ __ bind(&cons_string);
+ __ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset));
__ LoadRoot(ip, Heap::kEmptyStringRootIndex);
- __ cmp(scratch, ip);
+ __ cmp(result, ip);
__ b(ne, deferred->entry());
// Get the first of the two strings and load its instance type.
__ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset));
+
+ __ bind(&indirect_string_loaded);
__ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset));
__ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
- // If the first cons component is also non-flat, then go to runtime.
+
+ // Check whether the string is sequential. The only non-sequential
+ // shapes we support have just been unwrapped above.
+ __ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result, Operand(kStringRepresentationMask));
__ b(ne, deferred->entry());
- // Check for 1-byte or 2-byte string.
- __ bind(&flat_string);
+ // Dispatch on the encoding: ASCII or two-byte.
+ Label ascii_string;
STATIC_ASSERT(kAsciiStringTag != 0);
__ tst(result, Operand(kStringEncodingMask));
__ b(ne, &ascii_string);
- // 2-byte string.
- // Load the 2-byte character code into the result register.
- STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
- if (instr->index()->IsConstantOperand()) {
- __ ldrh(result,
- FieldMemOperand(string,
- SeqTwoByteString::kHeaderSize + 2 * const_index));
- } else {
- __ add(scratch,
- string,
- Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- __ ldrh(result, MemOperand(scratch, index, LSL, 1));
- }
+ // Two-byte string.
+ // Load the two-byte character code into the result register.
+ Label done;
+ __ add(result,
+ string,
+ Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+ __ ldrh(result, MemOperand(result, index, LSL, 1));
__ jmp(&done);
// ASCII string.
// Load the byte into the result register.
__ bind(&ascii_string);
- if (instr->index()->IsConstantOperand()) {
- __ ldrb(result, FieldMemOperand(string,
- SeqAsciiString::kHeaderSize + const_index));
- } else {
- __ add(scratch,
- string,
- Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
- __ ldrb(result, MemOperand(scratch, index));
- }
+ __ add(result,
+ string,
+ Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
+ __ ldrb(result, MemOperand(result, index));
+
__ bind(&done);
__ bind(deferred->exit());
}

Powered by Google App Engine
This is Rietveld 408576698