Revision: 5755
Author: [email protected]
Date: Tue Nov  2 06:37:59 2010
Log: Remove regexp caching.

Review URL: http://codereview.chromium.org/4308001
http://code.google.com/p/v8/source/detail?r=5755

Modified:
 /branches/bleeding_edge/src/arm/codegen-arm.cc
 /branches/bleeding_edge/src/arm/codegen-arm.h
 /branches/bleeding_edge/src/full-codegen.cc
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/codegen-ia32.h
 /branches/bleeding_edge/src/regexp.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/string.js
 /branches/bleeding_edge/src/x64/codegen-x64.cc
 /branches/bleeding_edge/src/x64/codegen-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc      Wed Oct 27 04:37:59 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc      Tue Nov  2 06:37:59 2010
@@ -5494,73 +5494,6 @@
   frame_->Forget(3);
   frame_->EmitPush(r0);
 }
-
-
-void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT_EQ(1, args->length());
-
-  Load(args->at(0));
-  frame_->PopToR0();
-  {
-    VirtualFrame::SpilledScope spilled_scope(frame_);
-
-    Label done;
-    Label call_runtime;
-    __ BranchOnSmi(r0, &done);
-
-    // Load JSRegExp map into r1. Check that argument object has this map.
-    // Arguments to this function should be results of calling RegExp exec,
- // which is either an unmodified JSRegExpResult or null. Anything not having
-    // the unmodified JSRegExpResult map is returned unmodified.
-    // This also ensures that elements are fast.
-
-    __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX));
-    __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset));
-    __ ldr(r1, ContextOperand(r1, Context::REGEXP_RESULT_MAP_INDEX));
-    __ ldr(ip, FieldMemOperand(r0, HeapObject::kMapOffset));
-    __ cmp(r1, Operand(ip));
-    __ b(ne, &done);
-
-    if (FLAG_debug_code) {
-      __ LoadRoot(r2, Heap::kEmptyFixedArrayRootIndex);
-      __ ldr(ip, FieldMemOperand(r0, JSObject::kPropertiesOffset));
-      __ cmp(ip, r2);
- __ Check(eq, "JSRegExpResult: default map but non-empty properties.");
-    }
-
-    // All set, copy the contents to a new object.
-    __ AllocateInNewSpace(JSRegExpResult::kSize,
-                          r2,
-                          r3,
-                          r4,
-                          &call_runtime,
-                          NO_ALLOCATION_FLAGS);
-    // Store RegExpResult map as map of allocated object.
-    ASSERT(JSRegExpResult::kSize == 6 * kPointerSize);
-    // Copy all fields (map is already in r1) from (untagged) r0 to r2.
-    // Change map of elements array (ends up in r4) to be a FixedCOWArray.
-    __ bic(r0, r0, Operand(kHeapObjectTagMask));
-    __ ldm(ib, r0, r3.bit() | r4.bit() | r5.bit() | r6.bit() | r7.bit());
-    __ stm(ia, r2,
- r1.bit() | r3.bit() | r4.bit() | r5.bit() | r6.bit() | r7.bit());
-    ASSERT(JSRegExp::kElementsOffset == 2 * kPointerSize);
- // Check whether elements array is empty fixed array, and otherwise make
-    // it copy-on-write (it never should be empty unless someone is messing
-    // with the arguments to the runtime function).
-    __ LoadRoot(ip, Heap::kEmptyFixedArrayRootIndex);
- __ add(r0, r2, Operand(kHeapObjectTag)); // Tag result and move it to r0.
-    __ cmp(r4, ip);
-    __ b(eq, &done);
-    __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
-    __ str(ip, FieldMemOperand(r4, HeapObject::kMapOffset));
-    __ b(&done);
-    __ bind(&call_runtime);
-    __ push(r0);
-    __ CallRuntime(Runtime::kRegExpCloneResult, 1);
-    __ bind(&done);
-  }
-  frame_->EmitPush(r0);
-}


 class DeferredSearchCache: public DeferredCode {
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.h       Mon Oct 18 03:23:45 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.h       Tue Nov  2 06:37:59 2010
@@ -518,8 +518,6 @@

   void GenerateRegExpConstructResult(ZoneList<Expression*>* args);

-  void GenerateRegExpCloneResult(ZoneList<Expression*>* args);
-
   // Support for fast native caches.
   void GenerateGetFromCache(ZoneList<Expression*>* args);

=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Fri Oct  8 06:07:55 2010
+++ /branches/bleeding_edge/src/full-codegen.cc Tue Nov  2 06:37:59 2010
@@ -1225,13 +1225,6 @@
 }


-void FullCodeGenerator::EmitRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 1);
-  VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kRegExpCloneResult, 1);
-  context()->Plug(result_register());
-}
-
 #undef __


=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Thu Oct 28 23:15:34 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Nov 2 06:37:59 2010
@@ -7290,88 +7290,6 @@
   frame_->Forget(3);
   frame_->Push(eax);
 }
-
-
-void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT_EQ(1, args->length());
-
-  Load(args->at(0));
-  Result object_result = frame_->Pop();
-  object_result.ToRegister(eax);
-  object_result.Unuse();
-  {
-    VirtualFrame::SpilledScope spilled_scope;
-
-    Label done;
-
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, &done);
-
-    // Load JSRegExpResult map into edx.
-    // Arguments to this function should be results of calling RegExp exec,
- // which is either an unmodified JSRegExpResult or null. Anything not having
-    // the unmodified JSRegExpResult map is returned unmodified.
-    // This also ensures that elements are fast.
-    __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
-    __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
-    __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX));
-    __ cmp(edx, FieldOperand(eax, HeapObject::kMapOffset));
-    __ j(not_equal, &done);
-
-    if (FLAG_debug_code) {
-      // Check that object really has empty properties array, as the map
-      // should guarantee.
-      __ cmp(FieldOperand(eax, JSObject::kPropertiesOffset),
-             Immediate(Factory::empty_fixed_array()));
- __ Check(equal, "JSRegExpResult: default map but non-empty properties.");
-    }
-
-    DeferredAllocateInNewSpace* allocate_fallback =
-        new DeferredAllocateInNewSpace(JSRegExpResult::kSize,
-                                       ebx,
-                                       edx.bit() | eax.bit());
-
-    // All set, copy the contents to a new object.
-    __ AllocateInNewSpace(JSRegExpResult::kSize,
-                          ebx,
-                          ecx,
-                          no_reg,
-                          allocate_fallback->entry_label(),
-                          TAG_OBJECT);
-    __ bind(allocate_fallback->exit_label());
-
-    // Copy all fields from eax to ebx.
-    STATIC_ASSERT(JSRegExpResult::kSize % (2 * kPointerSize) == 0);
-    // There is an even number of fields, so unroll the loop once
-    // for efficiency.
-    for (int i = 0; i < JSRegExpResult::kSize; i += 2 * kPointerSize) {
-      STATIC_ASSERT(JSObject::kMapOffset % (2 * kPointerSize) == 0);
-      if (i != JSObject::kMapOffset) {
-        // The map was already loaded into edx.
-        __ mov(edx, FieldOperand(eax, i));
-      }
-      __ mov(ecx, FieldOperand(eax, i + kPointerSize));
-
-      STATIC_ASSERT(JSObject::kElementsOffset % (2 * kPointerSize) == 0);
-      if (i == JSObject::kElementsOffset) {
-        // If the elements array isn't empty, make it copy-on-write
-        // before copying it.
-        Label empty;
-        __ cmp(Operand(edx), Immediate(Factory::empty_fixed_array()));
-        __ j(equal, &empty);
-        __ mov(FieldOperand(edx, HeapObject::kMapOffset),
-               Immediate(Factory::fixed_cow_array_map()));
-        __ bind(&empty);
-      }
-      __ mov(FieldOperand(ebx, i), edx);
-      __ mov(FieldOperand(ebx, i + kPointerSize), ecx);
-    }
-    __ mov(eax, ebx);
-
-    __ bind(&done);
-  }
-  frame_->Push(eax);
-}


 class DeferredSearchCache: public DeferredCode {
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Thu Oct 28 23:15:34 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Tue Nov  2 06:37:59 2010
@@ -697,11 +697,6 @@
   // Construct a RegExp exec result with two in-object properties.
   void GenerateRegExpConstructResult(ZoneList<Expression*>* args);

-  // Clone the result of a regexp function.
-  // Must be an object created by GenerateRegExpConstructResult with
-  // no extra properties.
-  void GenerateRegExpCloneResult(ZoneList<Expression*>* args);
-
   // Support for fast native caches.
   void GenerateGetFromCache(ZoneList<Expression*>* args);

=======================================
--- /branches/bleeding_edge/src/regexp.js       Fri Oct 15 06:03:59 2010
+++ /branches/bleeding_edge/src/regexp.js       Tue Nov  2 06:37:59 2010
@@ -71,9 +71,6 @@
     }
   }

-  if (!isConstructorCall) {
-    regExpCache.type = 'none';
-  }
   %RegExpInitializeObject(object, pattern, global, ignoreCase, multiline);

   // Call internal function to compile the pattern.
@@ -121,22 +118,6 @@
 }


-function RegExpCache() {
-  this.type = 'none';
-  this.regExp = 0;
-  this.subject = 0;
-  this.replaceString = 0;
-  this.answer = 0;
-  // answerSaved marks whether the contents of answer is valid for a cache
-  // hit in RegExpExec, StringMatch and StringSplit.
-  this.answerSaved = false;
-  this.splitLimit = 0;  // Used only when type is "split".
-}
-
-
-var regExpCache = new RegExpCache();
-
-
 function BuildResultFromMatchInfo(lastMatchInfo, s) {
   var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
var result = %_RegExpConstructResult(numResults, lastMatchInfo[CAPTURE0], s);
@@ -177,32 +158,6 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['RegExp.prototype.exec', this]);
   }
-
-  var cache = regExpCache;
-  var saveAnswer = false;
-
-  var lastIndex = this.lastIndex;
-
-  // Since cache.subject is always a string, a matching input can not
-  // cause visible side-effects when converted to a string, so we can omit
-  // the conversion required by the specification.
-  // Likewise, the regexp.lastIndex and regexp.global properties are value
- // properties that are not configurable, so reading them can also not cause
-  // any side effects (converting lastIndex to a number can, though).
-  if (%_ObjectEquals(cache.type, 'exec') &&
-      %_ObjectEquals(0, lastIndex) &&
-      %_IsRegExpEquivalent(cache.regExp, this) &&
-      %_ObjectEquals(cache.subject, string)) {
-    if (cache.answerSaved) {
- // The regexp.lastIndex value must be 0 for non-global RegExps, and for - // global RegExps we only cache negative results, which gives a lastIndex
-      // of zero as well.
-      this.lastIndex = 0;
-      return %_RegExpCloneResult(cache.answer);
-    } else {
-      saveAnswer = true;
-    }
-  }

   if (%_ArgumentsLength() === 0) {
     var regExpInput = LAST_INPUT(lastMatchInfo);
@@ -217,11 +172,13 @@
   } else {
     s = ToString(string);
   }
-  var global = this.global;
+  var lastIndex = this.lastIndex;

   // Conversion is required by the ES5 specification (RegExp.prototype.exec
// algorithm, step 5) even if the value is discarded for non-global RegExps.
   var i = TO_INTEGER(lastIndex);
+
+  var global = this.global;
   if (global) {
     if (i < 0 || i > s.length) {
       this.lastIndex = 0;
@@ -237,16 +194,9 @@

   if (matchIndices === null) {
     if (global) {
-      // Cache negative result only if initial lastIndex was zero.
       this.lastIndex = 0;
-      if (lastIndex !== 0) return matchIndices;
-    }
-    cache.regExp = this;
-    cache.subject = s;            // Always a string.
-    cache.answer = null;
-    cache.answerSaved = true;     // Safe since no cloning is needed.
-    cache.type = 'exec';
-    return matchIndices;        // No match.
+    }
+    return null;
   }

   // Successful match.
@@ -254,17 +204,9 @@
   var result = BuildResultFromMatchInfo(matchIndices, s);

   if (global) {
-    // Don't cache positive results for global regexps.
     this.lastIndex = lastMatchInfo[CAPTURE1];
-  } else {
-    cache.regExp = this;
-    cache.subject = s;
-    if (saveAnswer) cache.answer = %_RegExpCloneResult(result);
-    cache.answerSaved = saveAnswer;
-    cache.type = 'exec';
   }
   return result;
-
 }


@@ -288,20 +230,6 @@
     }
     string = regExpInput;
   }
-
-  var lastIndex = this.lastIndex;
-
-  var cache = regExpCache;
-  if (%_ObjectEquals(cache.type, 'test') &&
-      %_IsRegExpEquivalent(cache.regExp, this) &&
-      %_ObjectEquals(cache.subject, string) &&
-      %_ObjectEquals(0, lastIndex)) {
-    // The regexp.lastIndex value must be 0 for non-global RegExps, and for
- // global RegExps we only cache negative results, which gives a resulting
-    // lastIndex of zero as well.
-    if (global) this.lastIndex = 0;
-    return cache.answer;
-  }

   var s;
   if (IS_STRING(string)) {
@@ -311,9 +239,13 @@
   }
   var length = s.length;

+  var lastIndex = this.lastIndex;
+
   // Conversion is required by the ES5 specification (RegExp.prototype.exec
// algorithm, step 5) even if the value is discarded for non-global RegExps.
   var i = TO_INTEGER(lastIndex);
+
+  var global = this.global;
   if (global) {
     if (i < 0 || i > length) {
       this.lastIndex = 0;
@@ -322,8 +254,6 @@
   } else {
     i = 0;
   }
-
-  var global = this.global;

   // Remove irrelevant preceeding '.*' in a test regexp. The expression
   // checks whether this.source starts with '.*' and that the third
@@ -334,35 +264,31 @@
     if (!%_ObjectEquals(regexp_key, this)) {
       regexp_key = this;
regexp_val = new $RegExp(this.source.substring(2, this.source.length),
-                               (this.global ? 'g' : '')
+                               (global ? 'g' : '')
                                + (this.ignoreCase ? 'i' : '')
                                + (this.multiline ? 'm' : ''));
     }
     if (!regexp_val.test(s)) return false;
   }
+
+  var length = s.length;
+
+  if (i < 0 || i > length) {
+    this.lastIndex = 0;
+    return false;
+  }

   %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
   // matchIndices is either null or the lastMatchInfo array.
   var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);

-  var result = (matchIndices !== null);
-  if (result) {
-    lastMatchInfoOverride = null;
-  }
-  if (global) {
-    if (result) {
-      this.lastIndex = lastMatchInfo[CAPTURE1];
-      return true;
-    } else {
-      this.lastIndex = 0;
-      if (lastIndex !== 0) return false;
-    }
-  }
-  cache.type = 'test';
-  cache.regExp = this;
-  cache.subject = s;
-  cache.answer = result;
-  return result;
+  if (matchIndices === null) {
+    if (global) this.lastIndex = 0;
+    return false;
+  }
+  lastMatchInfoOverride = null;
+  if (global) this.lastIndex = lastMatchInfo[CAPTURE1];
+  return true;
 }


@@ -510,7 +436,6 @@
     return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
   }
   function RegExpSetInput(string) {
-    regExpCache.type = 'none';
     LAST_INPUT(lastMatchInfo) = ToString(string);
   };

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Nov  2 05:08:58 2010
+++ /branches/bleeding_edge/src/runtime.cc      Tue Nov  2 06:37:59 2010
@@ -1422,66 +1422,6 @@
   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
   return array;
 }
-
-
-static MaybeObject* Runtime_RegExpCloneResult(Arguments args) {
-  ASSERT(args.length() == 1);
-  Map* regexp_result_map;
-  {
-    AssertNoAllocation no_gc;
-    HandleScope handles;
-    regexp_result_map = Top::global_context()->regexp_result_map();
-  }
-  if (!args[0]->IsJSArray()) return args[0];
-
-  JSArray* result = JSArray::cast(args[0]);
-  // Arguments to RegExpCloneResult should always be fresh RegExp exec call
-  // results (either a fresh JSRegExpResult or null).
- // If the argument is not a JSRegExpResult, or isn't unmodified, just return
-  // the argument uncloned.
-  if (result->map() != regexp_result_map) return result;
-
-  // Having the original JSRegExpResult map guarantees that we have
-  // fast elements and no properties except the two in-object properties.
-  ASSERT(result->HasFastElements());
-  ASSERT(result->properties() == Heap::empty_fixed_array());
-  ASSERT_EQ(2, regexp_result_map->inobject_properties());
-
-  Object* new_array_alloc;
-  { MaybeObject* maybe_new_array_alloc =
- Heap::AllocateRaw(JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
-    if (!maybe_new_array_alloc->ToObject(&new_array_alloc)) {
-      return maybe_new_array_alloc;
-    }
-  }
-
-  // Set HeapObject map to JSRegExpResult map.
- reinterpret_cast<HeapObject*>(new_array_alloc)->set_map(regexp_result_map);
-
-  JSArray* new_array = JSArray::cast(new_array_alloc);
-
-  // Copy JSObject properties.
-  new_array->set_properties(result->properties());  // Empty FixedArray.
-
-  // Copy JSObject elements as copy-on-write.
-  FixedArray* elements = FixedArray::cast(result->elements());
-  if (elements != Heap::empty_fixed_array()) {
-    elements->set_map(Heap::fixed_cow_array_map());
-  }
-  new_array->set_elements(elements);
-
-  // Copy JSArray length.
-  new_array->set_length(result->length());
-
-  // Copy JSRegExpResult in-object property fields input and index.
-  new_array->FastPropertyAtPut(JSRegExpResult::kIndexIndex,
-                               result->FastPropertyAt(
-                                   JSRegExpResult::kIndexIndex));
-  new_array->FastPropertyAtPut(JSRegExpResult::kInputIndex,
-                               result->FastPropertyAt(
-                                   JSRegExpResult::kInputIndex));
-  return new_array;
-}


 static MaybeObject* Runtime_RegExpInitializeObject(Arguments args) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Tue Nov  2 05:08:58 2010
+++ /branches/bleeding_edge/src/runtime.h       Tue Nov  2 06:37:59 2010
@@ -162,7 +162,6 @@
   F(RegExpExecMultiple, 4, 1) \
   F(RegExpInitializeObject, 5, 1) \
   F(RegExpConstructResult, 3, 1) \
-  F(RegExpCloneResult, 1, 1) \
   \
   /* JSON */ \
   F(ParseJson, 1, 1) \
@@ -425,7 +424,7 @@
// ----------------------------------------------------------------------------
 // INLINE_AND_RUNTIME_FUNCTION_LIST defines all inlined functions accessed
 // with a native call of the form %_name from within JS code that also have
-  // a corresponding runtime function, that is called for slow cases.
+// a corresponding runtime function, that is called for slow cases.
// Entries have the form F(name, number of arguments, number of return values).
 #define INLINE_RUNTIME_FUNCTION_LIST(F) \
F(IsConstructCall, 0, 1) \
@@ -437,7 +436,6 @@
F(StringCompare, 2, 1) \ F(RegExpExec, 4, 1) \ F(RegExpConstructResult, 3, 1) \ - F(RegExpCloneResult, 1, 1) \ F(GetFromCache, 2, 1) \ F(NumberToString, 1, 1) \
   F(SwapElements, 3, 1)
=======================================
--- /branches/bleeding_edge/src/string.js       Thu Oct 14 05:54:00 2010
+++ /branches/bleeding_edge/src/string.js       Tue Nov  2 06:37:59 2010
@@ -142,16 +142,6 @@
   }
   return %StringLastIndexOf(sub, pat, index);
 }
-
-
-function CloneDenseArray(array) {
-  if (array === null) return null;
-  var clone = new $Array(array.length);
-  for (var i = 0; i < array.length; i++) {
-    clone[i] = array[i];
-  }
-  return clone;
-}


 // ECMA-262 section 15.5.4.9
@@ -173,32 +163,14 @@
   if (IS_REGEXP(regexp)) {
     if (!regexp.global) return regexp.exec(subject);

-    var cache = regExpCache;
     var saveAnswer = false;

-    if (%_ObjectEquals(cache.type, 'match') &&
-        %_IsRegExpEquivalent(cache.regExp, regexp) &&
-        %_ObjectEquals(cache.subject, subject)) {
-      if (cache.answerSaved) {
-        return CloneDenseArray(cache.answer);
-      } else {
-        saveAnswer = true;
-      }
-    }
     %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
     // lastMatchInfo is defined in regexp.js.
-    var result = %StringMatch(subject, regexp, lastMatchInfo);
-    cache.type = 'match';
-    cache.regExp = regexp;
-    cache.subject = subject;
-    if (saveAnswer) cache.answer = CloneDenseArray(result);
-    cache.answerSaved = saveAnswer;
-    return result;
+    return %StringMatch(subject, regexp, lastMatchInfo);
   }
   // Non-regexp argument.
   regexp = new $RegExp(regexp);
-  // Don't check regexp exec cache, since the regexp is new.
-  // TODO(lrn): Change this if we start caching regexps here.
   return RegExpExecNoTests(regexp, subject, 0);
 }

@@ -231,7 +203,6 @@
   if (IS_REGEXP(search)) {
     %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
     if (IS_FUNCTION(replace)) {
-      regExpCache.type = 'none';
       if (search.global) {
return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
       } else {
@@ -273,24 +244,10 @@

 // Helper function for regular expressions in String.prototype.replace.
 function StringReplaceRegExp(subject, regexp, replace) {
-  var cache = regExpCache;
-  if (%_ObjectEquals(cache.type, 'replace') &&
-      %_IsRegExpEquivalent(cache.regExp, regexp) &&
-      %_ObjectEquals(cache.replaceString, replace) &&
-      %_ObjectEquals(cache.subject, subject)) {
-    return cache.answer;
-  }
-  replace = TO_STRING_INLINE(replace);
-  var answer = %StringReplaceRegExpWithString(subject,
-                                              regexp,
-                                              replace,
-                                              lastMatchInfo);
-  cache.subject = subject;
-  cache.regExp = regexp;
-  cache.replaceString = replace;
-  cache.answer = answer;
-  cache.type = 'replace';
-  return answer;
+  return %StringReplaceRegExpWithString(subject,
+                                        regexp,
+                                        TO_STRING_INLINE(replace),
+                                        lastMatchInfo);
 }


@@ -605,34 +562,14 @@
     return result;
   }

-  var cache = regExpCache;
   var saveAnswer = false;

-  if (%_ObjectEquals(cache.type, 'split') &&
-      %_IsRegExpEquivalent(cache.regExp, separator) &&
-      %_ObjectEquals(cache.subject, subject) &&
-      %_ObjectEquals(cache.splitLimit, limit)) {
-    if (cache.answerSaved) {
-      return CloneDenseArray(cache.answer);
-    } else {
-      saveAnswer = true;
-    }
-  }
-
-  cache.type = 'split';
-  cache.regExp = separator;
-  cache.subject = subject;
-  cache.splitLimit = limit;
-
   %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);

   if (length === 0) {
-    cache.answerSaved = true;
     if (splitMatch(separator, subject, 0, 0) != null) {
-      cache.answer = [];
       return [];
     }
-    cache.answer = [subject];
     return [subject];
   }

@@ -680,8 +617,6 @@

     startIndex = currentIndex = endIndex;
   }
-  if (saveAnswer) cache.answer = CloneDenseArray(result);
-  cache.answerSaved = saveAnswer;
   return result;
 }

=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Oct 27 04:37:59 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue Nov  2 06:37:59 2010
@@ -6562,86 +6562,6 @@
   frame_->Forget(3);
   frame_->Push(rax);
 }
-
-
-void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT_EQ(1, args->length());
-
-  Load(args->at(0));
-  Result object_result = frame_->Pop();
-  object_result.ToRegister(rax);
-  object_result.Unuse();
-  {
-    VirtualFrame::SpilledScope spilled_scope;
-
-    Label done;
-    __ JumpIfSmi(rax, &done);
-
-    // Load JSRegExpResult map into rdx.
-    // Arguments to this function should be results of calling RegExp exec,
- // which is either an unmodified JSRegExpResult or null. Anything not having
-    // the unmodified JSRegExpResult map is returned unmodified.
-    // This also ensures that elements are fast.
-
-    __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX));
-    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
-    __ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX));
-    __ cmpq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
-    __ j(not_equal, &done);
-
-    if (FLAG_debug_code) {
-      // Check that object really has empty properties array, as the map
-      // should guarantee.
-      __ CompareRoot(FieldOperand(rax, JSObject::kPropertiesOffset),
-                     Heap::kEmptyFixedArrayRootIndex);
- __ Check(equal, "JSRegExpResult: default map but non-empty properties.");
-    }
-
-    DeferredAllocateInNewSpace* allocate_fallback =
-        new DeferredAllocateInNewSpace(JSRegExpResult::kSize,
-                                       rbx,
-                                       rdx.bit() | rax.bit());
-
-    // All set, copy the contents to a new object.
-    __ AllocateInNewSpace(JSRegExpResult::kSize,
-                          rbx,
-                          no_reg,
-                          no_reg,
-                          allocate_fallback->entry_label(),
-                          TAG_OBJECT);
-    __ bind(allocate_fallback->exit_label());
-
-    STATIC_ASSERT(JSRegExpResult::kSize % (2 * kPointerSize) == 0);
-    // There is an even number of fields, so unroll the loop once
-    // for efficiency.
-    for (int i = 0; i < JSRegExpResult::kSize; i += 2 * kPointerSize) {
-      STATIC_ASSERT(JSObject::kMapOffset % (2 * kPointerSize) == 0);
-      if (i != JSObject::kMapOffset) {
-        // The map was already loaded into edx.
-        __ movq(rdx, FieldOperand(rax, i));
-      }
-      __ movq(rcx, FieldOperand(rax, i + kPointerSize));
-
-      STATIC_ASSERT(JSObject::kElementsOffset % (2 * kPointerSize) == 0);
-      if (i == JSObject::kElementsOffset) {
-        // If the elements array isn't empty, make it copy-on-write
-        // before copying it.
-        Label empty;
-        __ CompareRoot(rdx, Heap::kEmptyFixedArrayRootIndex);
-        __ j(equal, &empty);
-        __ LoadRoot(kScratchRegister, Heap::kFixedCOWArrayMapRootIndex);
- __ movq(FieldOperand(rdx, HeapObject::kMapOffset), kScratchRegister);
-        __ bind(&empty);
-      }
-      __ movq(FieldOperand(rbx, i), rdx);
-      __ movq(FieldOperand(rbx, i + kPointerSize), rcx);
-    }
-    __ movq(rax, rbx);
-
-    __ bind(&done);
-  }
-  frame_->Push(rax);
-}


 class DeferredSearchCache: public DeferredCode {
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h       Mon Oct 18 03:23:45 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h       Tue Nov  2 06:37:59 2010
@@ -656,8 +656,6 @@

   void GenerateRegExpConstructResult(ZoneList<Expression*>* args);

-  void GenerateRegExpCloneResult(ZoneList<Expression*>* args);
-
   // Support for fast native caches.
   void GenerateGetFromCache(ZoneList<Expression*>* args);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to