Improved string hash-code distribution by excluding bit-field bits from the hash-code.

Changed string search algorithm used in indexOf from KMP to Boyer-Moore.

Improved the generated code for the instanceof operator.

Improved performance of slow-case string equality checks by specializing the code based on the string representation.

Improve the handling of out-of-memory situations (issue 70).

Improved performance of strict equality checks.

Improved profiler output to make it easier to see anonymous functions.

Improved performance of slow-case keyed loads.

Improved property access performance by allocating a number of properties in the front object.

Changed the toString behavior on the built-in object constructors to print [native code] instead of the actual source.  Some web applications do not like constructors with complex toString results.


git-svn-id: http://v8.googlecode.com/svn/trunk@511 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 0e4dee1..768c719 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -128,7 +128,7 @@
   ASSERT(!flat_string->IsConsString());
   ASSERT(flat_string->IsSeqString() || flat_string->IsSlicedString() ||
          flat_string->IsExternalString());
-  if (!flat_string->IsAscii()) {
+  if (!flat_string->IsAsciiRepresentation()) {
     return flat_string;
   }
 
@@ -218,12 +218,13 @@
   }
 
   LOG(RegExpExecEvent(re, start_index, subject));
-  int value = Runtime::StringMatchKmp(*subject, *needle, start_index);
+  int value = Runtime::StringMatch(subject, needle, start_index);
   if (value == -1) return Factory::null_value();
-  Handle<JSArray> result = Factory::NewJSArray(2);
-  SetElement(result, 0, Handle<Smi>(Smi::FromInt(value)));
-  SetElement(result, 1, Handle<Smi>(Smi::FromInt(value + needle->length())));
-  return result;
+
+  Handle<FixedArray> array = Factory::NewFixedArray(2);
+  array->set(0, Smi::FromInt(value));
+  array->set(1, Smi::FromInt(value + needle->length()));
+  return Factory::NewJSArrayWithElements(array);
 }
 
 
@@ -231,24 +232,28 @@
                                           Handle<String> subject) {
   Handle<String> needle(String::cast(re->data()));
   Handle<JSArray> result = Factory::NewJSArray(1);
-  bool keep_going = true;
   int index = 0;
   int match_count = 0;
+  int subject_length = subject->length();
   int needle_length = needle->length();
-  while (keep_going) {
+  while (true) {
     LOG(RegExpExecEvent(re, index, subject));
-    int value = Runtime::StringMatchKmp(*subject, *needle, index);
+    int value = -1;
+    if (index + needle_length <= subject_length) {
+      value = Runtime::StringMatch(subject, needle, index);
+    }
     if (value == -1) break;
     HandleScope scope;
     int end = value + needle_length;
-    Handle<JSArray> pair = Factory::NewJSArray(2);
-    SetElement(pair, 0, Handle<Smi>(Smi::FromInt(value)));
-    SetElement(pair, 1, Handle<Smi>(Smi::FromInt(end)));
+
+    Handle<FixedArray> array = Factory::NewFixedArray(2);
+    array->set(0, Smi::FromInt(value));
+    array->set(1, Smi::FromInt(end));
+    Handle<JSArray> pair = Factory::NewJSArrayWithElements(array);
     SetElement(result, match_count, pair);
     match_count++;
     index = end;
-    if (needle_length == 0)
-      index++;
+    if (needle_length == 0) index++;
   }
   return result;
 }
@@ -270,55 +275,56 @@
   unsigned number_of_captures;
   const char* error_message = NULL;
 
-  malloc_failure = Failure::Exception();
-  JscreRegExp* code = jsRegExpCompile(two_byte_pattern->GetTwoByteData(),
-                                      pattern->length(), case_option,
-                                      multiline_option, &number_of_captures,
-                                      &error_message, &JSREMalloc, &JSREFree);
+  JscreRegExp* code = NULL;
+  FlattenString(pattern);
 
-  if (code == NULL && malloc_failure->IsRetryAfterGC()) {
-    // Performs a GC, then retries.
-    if (!Heap::CollectGarbage(malloc_failure->requested(),
-                              malloc_failure->allocation_space())) {
-      // TODO(1181417): Fix this.
-      V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile");
-    }
+  bool first_time = true;
+
+  while (true) {
     malloc_failure = Failure::Exception();
     code = jsRegExpCompile(two_byte_pattern->GetTwoByteData(),
                            pattern->length(), case_option,
                            multiline_option, &number_of_captures,
                            &error_message, &JSREMalloc, &JSREFree);
-    if (code == NULL && malloc_failure->IsRetryAfterGC()) {
-      // TODO(1181417): Fix this.
-      V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile");
+    if (code == NULL) {
+      if (first_time && malloc_failure->IsRetryAfterGC()) {
+        first_time = false;
+        if (!Heap::CollectGarbage(malloc_failure->requested(),
+                                  malloc_failure->allocation_space())) {
+          // TODO(1181417): Fix this.
+          V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile");
+        }
+        continue;
+      }
+      if (malloc_failure->IsRetryAfterGC() ||
+          malloc_failure->IsOutOfMemoryFailure()) {
+        // TODO(1181417): Fix this.
+        V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile");
+      } else {
+        // Throw an exception.
+        Handle<JSArray> array = Factory::NewJSArray(2);
+        SetElement(array, 0, pattern);
+        SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector(
+            (error_message == NULL) ? "Unknown regexp error" : error_message)));
+        Handle<Object> regexp_err =
+            Factory::NewSyntaxError("malformed_regexp", array);
+        return Handle<Object>(Top::Throw(*regexp_err));
+      }
     }
+
+    ASSERT(code != NULL);
+    // Convert the return address to a ByteArray pointer.
+    Handle<ByteArray> internal(
+        ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code)));
+
+    Handle<FixedArray> value = Factory::NewFixedArray(2);
+    value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures));
+    value->set(INTERNAL_INDEX, *internal);
+    re->set_type_tag(JSRegExp::JSCRE);
+    re->set_data(*value);
+
+    return re;
   }
-
-  if (error_message != NULL) {
-    // Throw an exception.
-    SmartPointer<char> char_pattern =
-        two_byte_pattern->ToCString(DISALLOW_NULLS);
-    Handle<JSArray> array = Factory::NewJSArray(2);
-    SetElement(array, 0, Factory::NewStringFromUtf8(CStrVector(*char_pattern)));
-    SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector(error_message)));
-    Handle<Object> regexp_err =
-        Factory::NewSyntaxError("malformed_regexp", array);
-    return Handle<Object>(Top::Throw(*regexp_err));
-  }
-
-  ASSERT(code != NULL);
-
-  // Convert the return address to a ByteArray pointer.
-  Handle<ByteArray> internal(
-      ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code)));
-
-  Handle<FixedArray> value = Factory::NewFixedArray(2);
-  value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures));
-  value->set(INTERNAL_INDEX, *internal);
-  re->set_type_tag(JSRegExp::JSCRE);
-  re->set_data(*value);
-
-  return re;
 }
 
 
@@ -363,14 +369,13 @@
     return Handle<Object>(Top::Throw(*regexp_err));
   }
 
-  Handle<JSArray> result = Factory::NewJSArray(2 * (num_captures+1));
-
+  Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1));
   // The captures come in (start, end+1) pairs.
   for (int i = 0; i < 2 * (num_captures+1); i += 2) {
-    SetElement(result, i, Handle<Object>(Smi::FromInt(offsets_vector[i])));
-    SetElement(result, i+1, Handle<Object>(Smi::FromInt(offsets_vector[i+1])));
+    array->set(i, Smi::FromInt(offsets_vector[i]));
+    array->set(i+1, Smi::FromInt(offsets_vector[i+1]));
   }
-  return result;
+  return Factory::NewJSArrayWithElements(array);
 }
 
 
@@ -445,7 +450,7 @@
 
   int previous_index = 0;
 
-  Handle<JSArray> result =  Factory::NewJSArray(0);
+  Handle<JSArray> result = Factory::NewJSArray(0);
   int i = 0;
   Handle<Object> matches;