Don't use string slices when processing RexExp replace.

String slices from RegExp replace results is now encoded in either one or two smis. Substrings are not used any more.

If the existing one smi encoding cannot hold the start/length information two smis are used the first having the negative length and the second having the start.

This is in preparation for removing string slices.
Review URL: http://codereview.chromium.org/342015

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3153 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2009-10-28 09:11:45 +00:00
parent 64e1d3205f
commit abbc6b9147
2 changed files with 48 additions and 12 deletions

View File

@ -1357,8 +1357,9 @@ class ReplacementStringBuilder {
StringBuilderSubstringPosition::encode(from);
AddElement(Smi::FromInt(encoded_slice));
} else {
Handle<String> slice = Factory::NewStringSlice(subject_, from, to);
AddElement(*slice);
// Otherwise encode as two smis.
AddElement(Smi::FromInt(-length));
AddElement(Smi::FromInt(from));
}
IncrementCharacterCount(length);
}
@ -3766,9 +3767,21 @@ static inline void StringBuilderConcatHelper(String* special,
for (int i = 0; i < array_length; i++) {
Object* element = fixed_array->get(i);
if (element->IsSmi()) {
// Smi encoding of position and length.
int encoded_slice = Smi::cast(element)->value();
int pos = StringBuilderSubstringPosition::decode(encoded_slice);
int len = StringBuilderSubstringLength::decode(encoded_slice);
int pos;
int len;
if (encoded_slice > 0) {
// Position and length encoded in one smi.
pos = StringBuilderSubstringPosition::decode(encoded_slice);
len = StringBuilderSubstringLength::decode(encoded_slice);
} else {
// Position and length encoded in two smis.
Object* obj = fixed_array->get(++i);
ASSERT(obj->IsSmi());
pos = Smi::cast(obj)->value();
len = -encoded_slice;
}
String::WriteToFlat(special,
sink + position,
pos,
@ -3789,6 +3802,10 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
ASSERT(args.length() == 2);
CONVERT_CHECKED(JSArray, array, args[0]);
CONVERT_CHECKED(String, special, args[1]);
// This assumption is used by the slice encoding in one or two smis.
ASSERT(Smi::kMaxValue >= String::kMaxLength);
int special_length = special->length();
Object* smi_array_length = array->length();
if (!smi_array_length->IsSmi()) {
@ -3816,13 +3833,29 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
for (int i = 0; i < array_length; i++) {
Object* elt = fixed_array->get(i);
if (elt->IsSmi()) {
// Smi encoding of position and length.
int len = Smi::cast(elt)->value();
int pos = len >> 11;
len &= 0x7ff;
if (pos + len > special_length) {
return Top::Throw(Heap::illegal_argument_symbol());
if (len > 0) {
// Position and length encoded in one smi.
int pos = len >> 11;
len &= 0x7ff;
if (pos + len > special_length) {
return Top::Throw(Heap::illegal_argument_symbol());
}
position += len;
} else {
// Position and length encoded in two smis.
position += (-len);
// Get the position and check that it is also a smi.
i++;
if (i >= array_length) {
return Top::Throw(Heap::illegal_argument_symbol());
}
Object* pos = fixed_array->get(i);
if (!pos->IsSmi()) {
return Top::Throw(Heap::illegal_argument_symbol());
}
}
position += len;
} else if (elt->IsString()) {
String* element = String::cast(elt);
int element_length = element->length();

View File

@ -1,4 +1,4 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Copyright 2006-2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -810,10 +810,13 @@ ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) {
var len = end - start;
if (len == 0) return;
var elements = this.elements;
if (start >= 0 && len >= 0 && start < 0x80000 && len < 0x800) {
if (start < 0x80000 && len < 0x800) {
elements[elements.length] = (start << 11) + len;
} else {
elements[elements.length] = SubString(this.special_string, start, end);
// 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength,
// so -len is a smi.
elements[elements.length] = -len;
elements[elements.length] = start;
}
}