Speed up charCodeAt on very large cons strings, by insisting on

flattening the strings and not trying too hard to traverse a big
cons tree from generated code.
Review URL: http://codereview.chromium.org/402008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3317 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2009-11-17 10:28:04 +00:00
parent 63925e5013
commit 41749529dd
3 changed files with 15 additions and 1 deletions

View File

@ -4831,6 +4831,12 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
__ j(not_equal, &slow_case);
// ConsString.
// Check that the right hand side is the empty string (ie 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.
__ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset));
__ cmp(Operand(temp.reg()), Immediate(Handle<String>(Heap::empty_string())));
__ j(not_equal, &slow_case);
// Get the first of the two strings.
__ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
__ jmp(&try_again_with_new_string);

View File

@ -1274,7 +1274,9 @@ static Object* CharCodeAt(String* subject, Object* index) {
// Flatten the string. If someone wants to get a char at an index
// in a cons string, it is likely that more indices will be
// accessed.
subject->TryFlattenIfNotFlat();
Object* flat = subject->TryFlatten();
if (flat->IsFailure()) return flat;
subject = String::cast(flat);
if (i >= static_cast<uint32_t>(subject->length())) {
return Heap::nan_value();
}

View File

@ -3778,6 +3778,12 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
__ j(not_equal, &slow_case);
// ConsString.
// Check that the right hand side is the empty string (ie 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.
__ movq(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset));
__ CompareRoot(temp.reg(), Heap::kEmptyStringRootIndex);
__ j(not_equal, &slow_case);
// Get the first of the two strings.
__ movq(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
__ jmp(&try_again_with_new_string);