Push version 1.2.9 to trunk.

Improved math performance on ARM.

Fixed profiler name-inference bug.

Fixed handling of shared libraries in the profiler tick processor scripts.

Fixed handling of tests that time out in the test scripts.

Fixed compilation on MacOS X version 10.4.

Fixed two bugs in the regular expression engine.

Fixed a bug in the string type inference.

Fixed a bug in the handling of 'constant function' properties.
        
Improved overall performance.


git-svn-id: http://v8.googlecode.com/svn/trunk@2249 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 6fce1f5..eea7051 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -405,7 +405,6 @@
   // Prepare space for the return values.
   int number_of_capture_registers =
       (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
-  OffsetsVector offsets(number_of_capture_registers);
 
 #ifdef DEBUG
   if (FLAG_trace_regexp_bytecodes) {
@@ -421,15 +420,16 @@
 
   last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead);
 
-  int* offsets_vector = offsets.vector();
   bool rc;
+  FixedArray* array;
 
   // Dispatch to the correct RegExp implementation.
-
   Handle<String> original_subject = subject;
   Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data()));
   if (UseNativeRegexp()) {
 #if V8_TARGET_ARCH_IA32
+    OffsetsVector captures(number_of_capture_registers);
+    int* captures_vector = captures.vector();
     RegExpMacroAssemblerIA32::Result res;
     do {
       bool is_ascii = subject->IsAsciiRepresentation();
@@ -439,8 +439,8 @@
       Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii));
       res = RegExpMacroAssemblerIA32::Match(code,
                                             subject,
-                                            offsets_vector,
-                                            offsets.length(),
+                                            captures_vector,
+                                            captures.length(),
                                             previous_index);
       // If result is RETRY, the string have changed representation, and we
       // must restart from scratch.
@@ -453,7 +453,16 @@
         || res == RegExpMacroAssemblerIA32::FAILURE);
 
     rc = (res == RegExpMacroAssemblerIA32::SUCCESS);
-#else
+    if (!rc) return Factory::null_value();
+
+    array = last_match_info->elements();
+    ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
+    // The captures come in (start, end+1) pairs.
+    for (int i = 0; i < number_of_capture_registers; i += 2) {
+      SetCapture(array, i, captures_vector[i]);
+      SetCapture(array, i + 1, captures_vector[i + 1]);
+    }
+#else  // !V8_TARGET_ARCH_IA32
     UNREACHABLE();
 #endif
   } else {
@@ -461,33 +470,36 @@
     if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
       return Handle<Object>::null();
     }
+    // Now that we have done EnsureCompiledIrregexp we can get the number of
+    // registers.
+    int number_of_registers =
+        IrregexpNumberOfRegisters(FixedArray::cast(jsregexp->data()));
+    OffsetsVector registers(number_of_registers);
+    int* register_vector = registers.vector();
     for (int i = number_of_capture_registers - 1; i >= 0; i--) {
-      offsets_vector[i] = -1;
+      register_vector[i] = -1;
     }
     Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii));
 
     rc = IrregexpInterpreter::Match(byte_codes,
                                     subject,
-                                    offsets_vector,
+                                    register_vector,
                                     previous_index);
+    if (!rc) return Factory::null_value();
+
+    array = last_match_info->elements();
+    ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
+    // The captures come in (start, end+1) pairs.
+    for (int i = 0; i < number_of_capture_registers; i += 2) {
+      SetCapture(array, i, register_vector[i]);
+      SetCapture(array, i + 1, register_vector[i + 1]);
+    }
   }
 
-  // Handle results from RegExp implementation.
-
-  if (!rc) {
-    return Factory::null_value();
-  }
-
-  FixedArray* array = last_match_info->elements();
-  ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
-  // The captures come in (start, end+1) pairs.
   SetLastCaptureCount(array, number_of_capture_registers);
   SetLastSubject(array, *original_subject);
   SetLastInput(array, *original_subject);
-  for (int i = 0; i < number_of_capture_registers; i+=2) {
-    SetCapture(array, i, offsets_vector[i]);
-    SetCapture(array, i + 1, offsets_vector[i + 1]);
-  }
+
   return last_match_info;
 }
 
@@ -896,12 +908,13 @@
   // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1.
   const int push_limit = (assembler->stack_limit_slack() + 1) / 2;
 
+  // Count pushes performed to force a stack limit check occasionally.
+  int pushes = 0;
+
   for (int reg = 0; reg <= max_register; reg++) {
     if (!affected_registers.Get(reg)) {
       continue;
     }
-    // Count pushes performed to force a stack limit check occasionally.
-    int pushes = 0;
 
     // The chronologically first deferred action in the trace
     // is used to infer the action needed to restore a register
@@ -1885,7 +1898,8 @@
         uint32_t differing_bits = (from ^ to);
         // A mask and compare is only perfect if the differing bits form a
         // number like 00011111 with one single block of trailing 1s.
-        if ((differing_bits & (differing_bits + 1)) == 0) {
+        if ((differing_bits & (differing_bits + 1)) == 0 &&
+             from + differing_bits == to) {
           pos->determines_perfectly = true;
         }
         uint32_t common_bits = ~SmearBitsRight(differing_bits);