Rolled back eager hash calculation during flattening. Introduced
authorchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 7 Oct 2008 13:04:56 +0000 (13:04 +0000)
committerchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 7 Oct 2008 13:04:56 +0000 (13:04 +0000)
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

src/heap.cc
src/objects.cc
src/objects.h
src/runtime.cc

index 34201996b03357bd0c318ff29ccf6a6c44ae96c4..9029819fd18c864937c5dd8a6ecd394ce694da97 100644 (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;
 }
 
index 1b3e6d001e2d58ab909debb30624e5bd0a35e086..c5399fa137d7b66ea330afc0c7106517a570da92 100644 (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;
index b1aa550079eb353a4a4646e55b043fe886a63f4b..d21ad65d7588f75e9426d02c78c122131a650a93 100644 (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 {
index 2b0b2cd0c4894e33bc9a08f522986b50ed0935b5..92e23301b786070b788ac3d3a25053b492d26a38 100644 (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;
 }