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();
// 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;
}
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;
String* sink,
int f,
int t,
- int so,
- StringHasher* hasher) {
+ int so) {
String* source = src;
int from = f;
int to = t;
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;
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 {
// 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;
String* sink,
int from,
int to,
- int sink_offset,
- StringHasher* hasher);
+ int sink_offset);
protected:
class ReadBlockBuffer {
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;
}