Rolled back eager hash calculation during flattening. Introduced

eager flattening of really short strings and lookup of one-character
strings in the one-character symbol cache.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@462 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
christian.plesner.hansen@gmail.com 2008-10-07 13:04:56 +00:00
parent 6a76d3c448
commit 097d35065a
4 changed files with 23 additions and 28 deletions

View File

@ -1400,6 +1400,10 @@ Object* Heap::AllocateSlicedString(String* buffer, int start, int end) {
Object* Heap::AllocateSubString(String* buffer, int start, int end) {
int length = end - start;
if (length == 1) {
return Heap::LookupSingleCharacterStringFromCode(buffer->Get(start));
}
// Make an attempt to flatten the buffer to reduce access time.
buffer->TryFlatten();
@ -1410,9 +1414,19 @@ Object* Heap::AllocateSubString(String* buffer, int start, int end) {
// Copy the characters into the new object.
String* string_result = String::cast(result);
for (int i = 0; i < length; i++) {
string_result->Set(i, buffer->Get(start + i));
StringHasher hasher(length);
int i = 0;
for (; i < length && hasher.is_array_index(); i++) {
uc32 c = buffer->Get(start + i);
hasher.AddCharacter(c);
string_result->Set(i, c);
}
for (; i < length; i++) {
uc32 c = buffer->Get(start + i);
hasher.AddCharacterNoIndex(c);
string_result->Set(i, c);
}
string_result->set_length_field(hasher.GetHashField());
return result;
}

View File

@ -527,17 +527,7 @@ Object* String::Flatten() {
Heap::AllocateRawTwoByteString(len, tenure);
if (object->IsFailure()) return object;
String* result = String::cast(object);
StringHasher hasher(len);
Flatten(this, result, 0, len, 0, &hasher);
if (hasher.is_valid()) {
#ifdef DEBUG
result->ComputeAndSetHash();
ASSERT(result->length_field() == hasher.GetHashField());
#else
result->set_length_field(hasher.GetHashField());
#endif
Heap::LookupSymbolIfExists(result, &result);
}
Flatten(this, result, 0, len, 0);
cs->set_first(result);
cs->set_second(Heap::empty_string());
return this;
@ -3621,8 +3611,7 @@ void String::Flatten(String* src,
String* sink,
int f,
int t,
int so,
StringHasher* hasher) {
int so) {
String* source = src;
int from = f;
int to = t;
@ -3638,8 +3627,6 @@ void String::Flatten(String* src,
int j = sink_offset;
for (int i = from; i < to; i++) {
uc32 c = buffer->GetNext();
if (hasher->is_valid())
hasher->AddCharacter(c);
sink->Set(j++, c);
}
return;
@ -3659,7 +3646,7 @@ void String::Flatten(String* src,
if (to - boundary >= boundary - from) {
// Right hand side is longer. Recurse over left.
if (from < boundary) {
Flatten(first, sink, from, boundary, sink_offset, hasher);
Flatten(first, sink, from, boundary, sink_offset);
sink_offset += boundary - from;
from = 0;
} else {
@ -3671,15 +3658,13 @@ void String::Flatten(String* src,
// Left hand side is longer. Recurse over right. The hasher
// needs us to visit the string from left to right so doing
// this invalidates that hash.
hasher->invalidate();
if (to > boundary) {
String* second = String::cast(cons_string->second());
Flatten(second,
sink,
0,
to - boundary,
sink_offset + boundary - from,
hasher);
sink_offset + boundary - from);
to = boundary;
}
source = first;

View File

@ -3077,8 +3077,7 @@ class String: public HeapObject {
String* sink,
int from,
int to,
int sink_offset,
StringHasher* hasher);
int sink_offset);
protected:
class ReadBlockBuffer {

View File

@ -2404,24 +2404,21 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
if (object->IsFailure()) return object;
String* answer = String::cast(object);
StringHasher hasher(length);
for (int i = 0; i < array_length; i++) {
Object* element = fixed_array->get(i);
if (element->IsSmi()) {
int len = Smi::cast(element)->value();
int pos = len >> 11;
len &= 0x7ff;
String::Flatten(special, answer, pos, pos + len, position, &hasher);
String::Flatten(special, answer, pos, pos + len, position);
position += len;
} else {
String* string = String::cast(element);
int element_length = string->length();
String::Flatten(string, answer, 0, element_length, position, &hasher);
String::Flatten(string, answer, 0, element_length, position);
position += element_length;
}
}
if (hasher.is_valid())
answer->set_length_field(hasher.GetHashField());
return answer;
}