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:
parent
6a76d3c448
commit
097d35065a
18
src/heap.cc
18
src/heap.cc
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user