Revision: 3153
Author: [email protected]
Date: Wed Oct 28 02:11:45 2009
Log: Don't use string slices when processing RexExp replace.

String slices from RegExp replace results is now encoded in either one or  
two smis. Substrings are not used any more.

If the existing one smi encoding cannot hold the start/length information  
two smis are used the first having the negative length and the second  
having the start.

This is in preparation for removing string slices.
Review URL: http://codereview.chromium.org/342015
http://code.google.com/p/v8/source/detail?r=3153

Modified:
  /branches/bleeding_edge/src/runtime.cc
  /branches/bleeding_edge/src/string.js

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Oct 27 08:38:49 2009
+++ /branches/bleeding_edge/src/runtime.cc      Wed Oct 28 02:11:45 2009
@@ -1357,8 +1357,9 @@
            StringBuilderSubstringPosition::encode(from);
        AddElement(Smi::FromInt(encoded_slice));
      } else {
-      Handle<String> slice = Factory::NewStringSlice(subject_, from, to);
-      AddElement(*slice);
+      // Otherwise encode as two smis.
+      AddElement(Smi::FromInt(-length));
+      AddElement(Smi::FromInt(from));
      }
      IncrementCharacterCount(length);
    }
@@ -3766,9 +3767,21 @@
    for (int i = 0; i < array_length; i++) {
      Object* element = fixed_array->get(i);
      if (element->IsSmi()) {
+      // Smi encoding of position and length.
        int encoded_slice = Smi::cast(element)->value();
-      int pos = StringBuilderSubstringPosition::decode(encoded_slice);
-      int len = StringBuilderSubstringLength::decode(encoded_slice);
+      int pos;
+      int len;
+      if (encoded_slice > 0) {
+        // Position and length encoded in one smi.
+        pos = StringBuilderSubstringPosition::decode(encoded_slice);
+        len = StringBuilderSubstringLength::decode(encoded_slice);
+      } else {
+        // Position and length encoded in two smis.
+        Object* obj = fixed_array->get(++i);
+        ASSERT(obj->IsSmi());
+        pos = Smi::cast(obj)->value();
+        len = -encoded_slice;
+      }
        String::WriteToFlat(special,
                            sink + position,
                            pos,
@@ -3789,6 +3802,10 @@
    ASSERT(args.length() == 2);
    CONVERT_CHECKED(JSArray, array, args[0]);
    CONVERT_CHECKED(String, special, args[1]);
+
+  // This assumption is used by the slice encoding in one or two smis.
+  ASSERT(Smi::kMaxValue >= String::kMaxLength);
+
    int special_length = special->length();
    Object* smi_array_length = array->length();
    if (!smi_array_length->IsSmi()) {
@@ -3816,13 +3833,29 @@
    for (int i = 0; i < array_length; i++) {
      Object* elt = fixed_array->get(i);
      if (elt->IsSmi()) {
+      // Smi encoding of position and length.
        int len = Smi::cast(elt)->value();
-      int pos = len >> 11;
-      len &= 0x7ff;
-      if (pos + len > special_length) {
-        return Top::Throw(Heap::illegal_argument_symbol());
-      }
-      position += len;
+      if (len > 0) {
+        // Position and length encoded in one smi.
+        int pos = len >> 11;
+        len &= 0x7ff;
+        if (pos + len > special_length) {
+          return Top::Throw(Heap::illegal_argument_symbol());
+        }
+        position += len;
+      } else {
+        // Position and length encoded in two smis.
+        position += (-len);
+        // Get the position and check that it is also a smi.
+        i++;
+        if (i >= array_length) {
+          return Top::Throw(Heap::illegal_argument_symbol());
+        }
+        Object* pos = fixed_array->get(i);
+        if (!pos->IsSmi()) {
+          return Top::Throw(Heap::illegal_argument_symbol());
+        }
+      }
      } else if (elt->IsString()) {
        String* element = String::cast(elt);
        int element_length = element->length();
=======================================
--- /branches/bleeding_edge/src/string.js       Tue Oct 13 01:13:45 2009
+++ /branches/bleeding_edge/src/string.js       Wed Oct 28 02:11:45 2009
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
@@ -810,10 +810,13 @@
    var len = end - start;
    if (len == 0) return;
    var elements = this.elements;
-  if (start >= 0 && len >= 0 && start < 0x80000 && len < 0x800) {
+  if (start < 0x80000 && len < 0x800) {
      elements[elements.length] = (start << 11) + len;
    } else {
-    elements[elements.length] = SubString(this.special_string, start, end);
+    // 0 < len <= String::kMaxLength and Smi::kMaxValue >=  
String::kMaxLength,
+    // so -len is a smi.
+    elements[elements.length] = -len;
+    elements[elements.length] = start;
    }
  }


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

Reply via email to