Commit 304d49cd authored by yangguo@chromium.org's avatar yangguo@chromium.org

Porting r10023 and r10054 to arm (pointer cache for external strings).

Review URL: http://codereview.chromium.org/8682010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10059 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 198e3356
...@@ -5107,74 +5107,14 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { ...@@ -5107,74 +5107,14 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
__ cmp(ip, Operand(index_)); __ cmp(ip, Operand(index_));
__ b(ls, index_out_of_range_); __ b(ls, index_out_of_range_);
// We need special handling for non-flat strings. __ mov(index_, Operand(index_, ASR, kSmiTagSize));
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result_, Operand(kStringRepresentationMask)); StringCharLoadGenerator::Generate(masm,
__ b(eq, &flat_string); object_,
index_,
result_,
&call_runtime_);
// Handle non-flat strings.
__ and_(result_, result_, Operand(kStringRepresentationMask));
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
__ cmp(result_, Operand(kExternalStringTag));
__ b(gt, &sliced_string);
__ b(eq, &call_runtime_);
// ConsString.
// 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;
__ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset));
__ LoadRoot(ip, Heap::kEmptyStringRootIndex);
__ cmp(result_, Operand(ip));
__ b(ne, &call_runtime_);
// 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(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(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 adjusted index to the runtime function.
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result_, Operand(kStringRepresentationMask));
__ b(ne, &call_runtime_);
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);
STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
__ tst(result_, Operand(kStringEncodingMask));
__ b(ne, &ascii_string);
// 2-byte string.
// Load the 2-byte character code into the result register. We can
// 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(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(index_, object_, Operand(index_, LSR, kSmiTagSize));
__ ldrb(result_, FieldMemOperand(index_, SeqAsciiString::kHeaderSize));
__ bind(&got_char_code);
__ mov(result_, Operand(result_, LSL, kSmiTagSize)); __ mov(result_, Operand(result_, LSL, kSmiTagSize));
__ bind(&exit_); __ bind(&exit_);
} }
...@@ -5221,6 +5161,7 @@ void StringCharCodeAtGenerator::GenerateSlow( ...@@ -5221,6 +5161,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
// is too complex (e.g., when the string needs to be flattened). // is too complex (e.g., when the string needs to be flattened).
__ bind(&call_runtime_); __ bind(&call_runtime_);
call_helper.BeforeCall(masm); call_helper.BeforeCall(masm);
__ mov(index_, Operand(index_, LSL, kSmiTagSize));
__ Push(object_, index_); __ Push(object_, index_);
__ CallRuntime(Runtime::kStringCharCodeAt, 2); __ CallRuntime(Runtime::kStringCharCodeAt, 2);
__ Move(result_, r0); __ Move(result_, r0);
......
...@@ -302,6 +302,94 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( ...@@ -302,6 +302,94 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ pop(lr); __ pop(lr);
} }
void StringCharLoadGenerator::Generate(MacroAssembler* masm,
Register string,
Register index,
Register result,
Label* call_runtime) {
// 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 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;
__ 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 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);
__ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset));
__ LoadRoot(ip, Heap::kEmptyStringRootIndex);
__ cmp(result, ip);
__ b(ne, call_runtime);
// 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));
// 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);
__ tst(result, Operand(kStringRepresentationMask));
__ b(ne, &external_string);
// Prepare sequential strings
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
__ add(string,
string,
Operand(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.
__ tst(result, Operand(kIsIndirectStringMask));
__ Assert(eq, "external string expected, but not found");
}
// Rule out short external strings.
STATIC_CHECK(kShortExternalStringTag != 0);
__ tst(result, Operand(kShortExternalStringMask));
__ b(ne, call_runtime);
__ ldr(string, FieldMemOperand(string, ExternalString::kResourceDataOffset));
Label ascii, done;
__ bind(&check_encoding);
STATIC_ASSERT(kTwoByteStringTag == 0);
__ tst(result, Operand(kStringEncodingMask));
__ b(ne, &ascii);
// Two-byte string.
__ ldrh(result, MemOperand(string, index, LSL, 1));
__ jmp(&done);
__ bind(&ascii);
// Ascii string.
__ ldrb(result, MemOperand(string, index));
__ bind(&done);
}
#undef __ #undef __
} } // namespace v8::internal } } // namespace v8::internal
......
...@@ -73,6 +73,21 @@ class CodeGenerator: public AstVisitor { ...@@ -73,6 +73,21 @@ class CodeGenerator: public AstVisitor {
}; };
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
// indexed character into |result|. We expect |index| as untagged input and
// |result| as untagged output.
static void Generate(MacroAssembler* masm,
Register string,
Register index,
Register result,
Label* call_runtime);
private:
DISALLOW_COPY_AND_ASSIGN(StringCharLoadGenerator);
};
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_ARM_CODEGEN_ARM_H_ #endif // V8_ARM_CODEGEN_ARM_H_
...@@ -3592,86 +3592,14 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { ...@@ -3592,86 +3592,14 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
LStringCharCodeAt* instr_; LStringCharCodeAt* instr_;
}; };
Register string = ToRegister(instr->string());
Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
DeferredStringCharCodeAt* deferred = DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr); new DeferredStringCharCodeAt(this, instr);
// Fetch the instance type of the receiver into result register. StringCharLoadGenerator::Generate(masm(),
__ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); ToRegister(instr->string()),
__ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); ToRegister(instr->index()),
ToRegister(instr->result()),
// We need special handling for indirect strings. deferred->entry());
Label check_sequential;
__ tst(result, Operand(kIsIndirectStringMask));
__ b(eq, &check_sequential);
// Dispatch on the indirect string shape: slice or cons.
Label cons_string;
__ 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.
__ bind(&cons_string);
__ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset));
__ LoadRoot(ip, Heap::kEmptyStringRootIndex);
__ 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));
// 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(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result, Operand(kStringRepresentationMask));
__ b(ne, deferred->entry());
// Dispatch on the encoding: ASCII or two-byte.
Label ascii_string;
STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
__ tst(result, Operand(kStringEncodingMask));
__ b(ne, &ascii_string);
// 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);
__ add(result,
string,
Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
__ ldrb(result, MemOperand(result, index));
__ bind(&done);
__ bind(deferred->exit()); __ bind(deferred->exit());
} }
......
...@@ -538,12 +538,12 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -538,12 +538,12 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// We need special handling for indirect strings. // We need special handling for indirect strings.
Label check_sequential; Label check_sequential;
__ test(result, Immediate(kIsIndirectStringMask)); __ test(result, Immediate(kIsIndirectStringMask));
__ j(zero, &check_sequential); __ j(zero, &check_sequential, Label::kNear);
// Dispatch on the indirect string shape: slice or cons. // Dispatch on the indirect string shape: slice or cons.
Label cons_string; Label cons_string;
__ test(result, Immediate(kSlicedNotConsMask)); __ test(result, Immediate(kSlicedNotConsMask));
__ j(zero, &cons_string); __ j(zero, &cons_string, Label::kNear);
// Handle slices. // Handle slices.
Label indirect_string_loaded; Label indirect_string_loaded;
...@@ -551,33 +551,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -551,33 +551,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
__ SmiUntag(result); __ SmiUntag(result);
__ add(index, result); __ add(index, result);
__ mov(string, FieldOperand(string, SlicedString::kParentOffset)); __ mov(string, FieldOperand(string, SlicedString::kParentOffset));
__ jmp(&indirect_string_loaded); __ jmp(&indirect_string_loaded, Label::kNear);
// 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.
// Sequential strings have already been ruled out.
__ test(result, Immediate(kIsIndirectStringMask));
__ Assert(zero, "external string expected, but not found");
}
// Rule out short external strings.
STATIC_CHECK(kShortExternalStringTag != 0);
__ test_b(result, kShortExternalStringMask);
__ j(not_zero, call_runtime);
// Check encoding.
STATIC_ASSERT(kTwoByteStringTag == 0);
__ test_b(result, kStringEncodingMask);
__ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset));
__ j(not_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 cons strings. // Handle cons strings.
// Check whether the right hand side is the empty string (i.e. if // Check whether the right hand side is the empty string (i.e. if
...@@ -597,21 +571,47 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -597,21 +571,47 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// Distinguish sequential and external strings. Only these two string // Distinguish sequential and external strings. Only these two string
// representations can reach here (slices and flat cons strings have been // representations can reach here (slices and flat cons strings have been
// reduced to the underlying sequential or external string). // reduced to the underlying sequential or external string).
Label seq_string;
__ bind(&check_sequential); __ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0); STATIC_ASSERT(kSeqStringTag == 0);
__ test(result, Immediate(kStringRepresentationMask)); __ test(result, Immediate(kStringRepresentationMask));
__ j(not_zero, &external_string); __ j(zero, &seq_string, Label::kNear);
// Handle external strings.
Label ascii_external, done;
if (FLAG_debug_code) {
// Assert that we do not have a cons or slice (indirect strings) here.
// Sequential strings have already been ruled out.
__ test(result, Immediate(kIsIndirectStringMask));
__ Assert(zero, "external string expected, but not found");
}
// Rule out short external strings.
STATIC_CHECK(kShortExternalStringTag != 0);
__ test_b(result, kShortExternalStringMask);
__ j(not_zero, call_runtime);
// Check encoding.
STATIC_ASSERT(kTwoByteStringTag == 0);
__ test_b(result, kStringEncodingMask);
__ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset));
__ j(not_equal, &ascii_external, Label::kNear);
// Two-byte string.
__ movzx_w(result, Operand(result, index, times_2, 0));
__ jmp(&done, Label::kNear);
__ bind(&ascii_external);
// Ascii string.
__ movzx_b(result, Operand(result, index, times_1, 0));
__ jmp(&done, Label::kNear);
// Dispatch on the encoding: ASCII or two-byte. // Dispatch on the encoding: ASCII or two-byte.
Label ascii_string; Label ascii;
__ bind(&seq_string);
STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
__ test(result, Immediate(kStringEncodingMask)); __ test(result, Immediate(kStringEncodingMask));
__ j(not_zero, &ascii_string, Label::kNear); __ j(not_zero, &ascii, Label::kNear);
// Two-byte string. // Two-byte string.
// Load the two-byte character code into the result register. // Load the two-byte character code into the result register.
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
__ movzx_w(result, FieldOperand(string, __ movzx_w(result, FieldOperand(string,
index, index,
times_2, times_2,
...@@ -620,7 +620,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -620,7 +620,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// Ascii string. // Ascii string.
// Load the byte into the result register. // Load the byte into the result register.
__ bind(&ascii_string); __ bind(&ascii);
__ movzx_b(result, FieldOperand(string, __ movzx_b(result, FieldOperand(string,
index, index,
times_1, times_1,
......
...@@ -380,7 +380,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -380,7 +380,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// We need special handling for indirect strings. // We need special handling for indirect strings.
Label check_sequential; Label check_sequential;
__ testb(result, Immediate(kIsIndirectStringMask)); __ testb(result, Immediate(kIsIndirectStringMask));
__ j(zero, &check_sequential); __ j(zero, &check_sequential, Label::kNear);
// Dispatch on the indirect string shape: slice or cons. // Dispatch on the indirect string shape: slice or cons.
Label cons_string; Label cons_string;
...@@ -394,32 +394,6 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -394,32 +394,6 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
__ movq(string, FieldOperand(string, SlicedString::kParentOffset)); __ movq(string, FieldOperand(string, SlicedString::kParentOffset));
__ jmp(&indirect_string_loaded, Label::kNear); __ jmp(&indirect_string_loaded, Label::kNear);
// 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.
// Sequential strings have already been ruled out.
__ testb(result, Immediate(kIsIndirectStringMask));
__ Assert(zero, "external string expected, but not found");
}
// Rule out short external strings.
STATIC_CHECK(kShortExternalStringTag != 0);
__ testb(result, Immediate(kShortExternalStringTag));
__ j(not_zero, call_runtime);
// Check encoding.
STATIC_ASSERT(kTwoByteStringTag == 0);
__ testb(result, Immediate(kStringEncodingMask));
__ movq(result, FieldOperand(string, ExternalString::kResourceDataOffset));
__ j(not_equal, &ascii_external, Label::kNear);
// Two-byte string.
__ movzxwl(result, Operand(result, index, times_2, 0));
__ jmp(&done);
__ bind(&ascii_external);
// Ascii string.
__ movzxbl(result, Operand(result, index, times_1, 0));
__ jmp(&done);
// Handle cons strings. // Handle cons strings.
// Check whether the right hand side is the empty string (i.e. if // 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 // this is really a flat string in a cons string). If that is not
...@@ -438,17 +412,44 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -438,17 +412,44 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// Distinguish sequential and external strings. Only these two string // Distinguish sequential and external strings. Only these two string
// representations can reach here (slices and flat cons strings have been // representations can reach here (slices and flat cons strings have been
// reduced to the underlying sequential or external string). // reduced to the underlying sequential or external string).
Label seq_string;
__ bind(&check_sequential); __ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0); STATIC_ASSERT(kSeqStringTag == 0);
__ testb(result, Immediate(kStringRepresentationMask)); __ testb(result, Immediate(kStringRepresentationMask));
__ j(not_zero, &external_string); __ j(zero, &seq_string, Label::kNear);
// Handle external strings.
Label ascii_external, done;
if (FLAG_debug_code) {
// Assert that we do not have a cons or slice (indirect strings) here.
// Sequential strings have already been ruled out.
__ testb(result, Immediate(kIsIndirectStringMask));
__ Assert(zero, "external string expected, but not found");
}
// Rule out short external strings.
STATIC_CHECK(kShortExternalStringTag != 0);
__ testb(result, Immediate(kShortExternalStringTag));
__ j(not_zero, call_runtime);
// Check encoding.
STATIC_ASSERT(kTwoByteStringTag == 0);
__ testb(result, Immediate(kStringEncodingMask));
__ movq(result, FieldOperand(string, ExternalString::kResourceDataOffset));
__ j(not_equal, &ascii_external, Label::kNear);
// Two-byte string.
__ movzxwl(result, Operand(result, index, times_2, 0));
__ jmp(&done, Label::kNear);
__ bind(&ascii_external);
// Ascii string.
__ movzxbl(result, Operand(result, index, times_1, 0));
__ jmp(&done, Label::kNear);
// Dispatch on the encoding: ASCII or two-byte. // Dispatch on the encoding: ASCII or two-byte.
Label ascii_string; Label ascii;
__ bind(&seq_string);
STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
__ testb(result, Immediate(kStringEncodingMask)); __ testb(result, Immediate(kStringEncodingMask));
__ j(not_zero, &ascii_string, Label::kNear); __ j(not_zero, &ascii, Label::kNear);
// Two-byte string. // Two-byte string.
// Load the two-byte character code into the result register. // Load the two-byte character code into the result register.
...@@ -461,7 +462,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, ...@@ -461,7 +462,7 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
// ASCII string. // ASCII string.
// Load the byte into the result register. // Load the byte into the result register.
__ bind(&ascii_string); __ bind(&ascii);
__ movzxbl(result, FieldOperand(string, __ movzxbl(result, FieldOperand(string,
index, index,
times_1, times_1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment