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

Unified Diff: src/ia32/code-stubs-ia32.cc

Issue 8513010: Add pointer cache field to external string for access in generated code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 9 years, 1 month 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/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 23bea4f8568ce2cebeccf8212be82343e75e4d29..a37c9d731e2b5218d24e7b3a725c57fd1f5e0a71 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -5089,11 +5089,6 @@ void CompareStub::PrintName(StringStream* stream) {
// StringCharCodeAtGenerator
void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
- Label flat_string;
- Label ascii_string;
- Label got_char_code;
- Label sliced_string;
-
// If the receiver is a smi trigger the non-string case.
STATIC_ASSERT(kSmiTag == 0);
__ JumpIfSmi(object_, receiver_not_string_);
@@ -5114,73 +5109,118 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
__ cmp(index_, FieldOperand(object_, String::kLengthOffset));
__ j(above_equal, index_out_of_range_);
- // We need special handling for non-flat strings.
- STATIC_ASSERT(kSeqStringTag == 0);
- __ test(result_, Immediate(kStringRepresentationMask));
- __ j(zero, &flat_string);
+ __ SmiUntag(index_);
- // Handle non-flat strings.
- __ and_(result_, kStringRepresentationMask);
- STATIC_ASSERT(kConsStringTag < kExternalStringTag);
- STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
- __ cmp(result_, kExternalStringTag);
- __ j(greater, &sliced_string, Label::kNear);
- __ j(equal, &call_runtime_);
+ Factory* factory = masm->isolate()->factory();
+ GenerateCharLoad(masm, factory, object_, index_, result_, &call_runtime_);
- // ConsString.
+ __ SmiTag(result_);
+ __ bind(&exit_);
+}
+
+
+void StringCharCodeAtGenerator::GenerateCharLoad(MacroAssembler* masm,
+ Factory* factory,
+ Register string,
+ Register index,
+ Register result,
+ Label* call_runtime) {
+ // Fetch the instance type of the receiver into result register.
+ __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
+
+ // We need special handling for indirect strings.
+ Label check_sequential;
+ __ test(result, Immediate(kIsIndirectStringMask));
+ __ j(zero, &check_sequential);
+
+ // Dispatch on the indirect string shape: slice or cons.
+ Label cons_string;
+ __ test(result, Immediate(kSlicedNotConsMask));
+ __ j(zero, &cons_string);
+
+ // Handle slices.
+ Label indirect_string_loaded;
+ __ mov(result, FieldOperand(string, SlicedString::kOffsetOffset));
+ __ SmiUntag(result);
+ __ add(index, result);
+ __ mov(string, FieldOperand(string, SlicedString::kParentOffset));
+ __ jmp(&indirect_string_loaded);
+
+ // Handle external strings.
+ Label external_string, ascii_external, done;
+ __ bind(&external_string);
+ if (FLAG_debug_code) {
+ // Assert that we do not have a cons or slice (indirect strings) here.
+ __ test(result, Immediate(kIsIndirectStringMask));
+ __ Assert(zero, "external string expected, but not found");
Lasse Reichstein 2011/11/17 13:40:18 This test checks for "indirect string" but reports
+ }
+ __ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset));
+ __ test(result, result);
+ __ j(zero, call_runtime);
+ __ cmp(FieldOperand(string, HeapObject::kMapOffset),
+ Immediate(factory->external_ascii_string_map()));
+ __ j(equal, &ascii_external, Label::kNear);
+ __ cmp(FieldOperand(string, HeapObject::kMapOffset),
Lasse Reichstein 2011/11/17 13:40:18 Comparing against the same memory location twice i
Yang 2011/11/17 17:06:23 |string| is used as a temp register, so I can use
+ Immediate(factory->external_ascii_symbol_map()));
+ __ j(equal, &ascii_external, Label::kNear);
+ // Two-byte string.
+ __ movzx_w(result, Operand(result, index, times_2, 0));
+ __ jmp(&done);
+ __ bind(&ascii_external);
+ // Ascii string.
+ __ movzx_b(result, Operand(result, index, times_1, 0));
+ __ jmp(&done);
+
+ // 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.
- Label assure_seq_string;
- __ cmp(FieldOperand(object_, ConsString::kSecondOffset),
- Immediate(masm->isolate()->factory()->empty_string()));
- __ j(not_equal, &call_runtime_);
- // Get the first of the two parts.
- __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
- __ jmp(&assure_seq_string, Label::kNear);
-
- // SlicedString, unpack and add offset.
- __ bind(&sliced_string);
- __ add(index_, FieldOperand(object_, SlicedString::kOffsetOffset));
- __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
-
- // Assure that we are dealing with a sequential string. Go to runtime if not.
+ __ bind(&cons_string);
+ __ cmp(FieldOperand(string, ConsString::kSecondOffset),
+ Immediate(factory->empty_string()));
+ __ j(not_equal, call_runtime);
+ __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
+
+ __ bind(&indirect_string_loaded);
+ __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
+
+ // Check whether the string is sequential. The only non-sequential
+ // shapes we support have just been unwrapped above.
// 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);
- __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
- __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
+ __ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0);
- __ test(result_, Immediate(kStringRepresentationMask));
- __ j(not_zero, &call_runtime_);
+ __ test(result, Immediate(kStringRepresentationMask));
+ __ j(not_zero, &external_string);
- // Check for 1-byte or 2-byte string.
- __ bind(&flat_string);
+ // Dispatch on the encoding: ASCII or two-byte.
+ Label ascii_string;
STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
- __ test(result_, Immediate(kStringEncodingMask));
+ __ test(result, Immediate(kStringEncodingMask));
__ j(not_zero, &ascii_string, Label::kNear);
- // 2-byte string.
- // Load the 2-byte character code into the result register.
+ // Two-byte string.
+ // Load the two-byte character code into the result register.
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
- __ movzx_w(result_, FieldOperand(object_,
- index_, times_1, // Scratch is smi-tagged.
- SeqTwoByteString::kHeaderSize));
- __ jmp(&got_char_code, Label::kNear);
+ __ movzx_w(result, FieldOperand(string,
+ index,
+ times_2,
+ SeqTwoByteString::kHeaderSize));
+ __ jmp(&done, Label::kNear);
- // ASCII string.
+ // Ascii string.
// Load the byte into the result register.
__ bind(&ascii_string);
- __ SmiUntag(index_);
- __ movzx_b(result_, FieldOperand(object_,
- index_, times_1,
- SeqAsciiString::kHeaderSize));
- __ bind(&got_char_code);
- __ SmiTag(result_);
- __ bind(&exit_);
+ __ movzx_b(result, FieldOperand(string,
+ index,
+ times_1,
+ SeqAsciiString::kHeaderSize));
+ __ bind(&done);
}
@@ -5228,6 +5268,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
__ bind(&call_runtime_);
call_helper.BeforeCall(masm);
__ push(object_);
+ __ SmiTag(index_);
__ push(index_);
__ CallRuntime(Runtime::kStringCharCodeAt, 2);
if (!result_.is(eax)) {

Powered by Google App Engine
This is Rietveld 408576698