Title: [185486] trunk/Source/_javascript_Core
Revision
185486
Author
[email protected]
Date
2015-06-11 21:09:11 -0700 (Thu, 11 Jun 2015)

Log Message

jsSubstring() should support creating substrings from substrings.
<https://webkit.org/b/145427>

Reviewed by Geoffrey Garen

Tweak jsSubstring() to support base strings that are themselves substrings.
They will now share the same grandparent base. This avoids creating a new StringImpl.

* runtime/JSString.h:
(JSC::jsSubstring): Don't force rope resolution here. Instead do that in finishCreation()
if the base string is a non-substring rope. Note that resolveRope() is the very last thing
called, since it may allocate and the JSRopeString needs to be ready for marking.

(JSC::JSString::isSubstring): Added a helper to find out if a JSString is
a substring. This is just for internal use, so you don't have to cast to
JSRopeString for the real substringness flag.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (185485 => 185486)


--- trunk/Source/_javascript_Core/ChangeLog	2015-06-12 02:59:59 UTC (rev 185485)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-06-12 04:09:11 UTC (rev 185486)
@@ -1,3 +1,22 @@
+2015-06-11  Andreas Kling  <[email protected]>
+
+        jsSubstring() should support creating substrings from substrings.
+        <https://webkit.org/b/145427>
+
+        Reviewed by Geoffrey Garen
+
+        Tweak jsSubstring() to support base strings that are themselves substrings.
+        They will now share the same grandparent base. This avoids creating a new StringImpl.
+
+        * runtime/JSString.h:
+        (JSC::jsSubstring): Don't force rope resolution here. Instead do that in finishCreation()
+        if the base string is a non-substring rope. Note that resolveRope() is the very last thing
+        called, since it may allocate and the JSRopeString needs to be ready for marking.
+
+        (JSC::JSString::isSubstring): Added a helper to find out if a JSString is
+        a substring. This is just for internal use, so you don't have to cast to
+        JSRopeString for the real substringness flag.
+
 2015-06-11  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r185465.

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (185485 => 185486)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2015-06-12 02:59:59 UTC (rev 185485)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2015-06-12 04:09:11 UTC (rev 185486)
@@ -186,6 +186,7 @@
     friend class JSValue;
 
     bool isRope() const { return m_value.isNull(); }
+    bool isSubstring() const;
     bool is8Bit() const { return m_flags & Is8Bit; }
     void setIs8Bit(bool flag) const
     {
@@ -291,17 +292,29 @@
         fiber(2).set(vm, this, s3);
     }
 
-    void finishCreation(VM& vm, JSString* base, unsigned offset, unsigned length)
+    void finishCreation(ExecState& exec, JSString& base, unsigned offset, unsigned length)
     {
+        VM& vm = exec.vm();
         Base::finishCreation(vm);
-        ASSERT(!base->isRope());
         ASSERT(!sumOverflows<int32_t>(offset, length));
-        ASSERT(offset + length <= base->length());
+        ASSERT(offset + length <= base.length());
         m_length = length;
-        setIs8Bit(base->is8Bit());
+        setIs8Bit(base.is8Bit());
         setIsSubstring(true);
-        substringBase().set(vm, this, base);
-        substringOffset() = offset;
+        if (base.isSubstring()) {
+            JSRopeString& baseRope = static_cast<JSRopeString&>(base);
+            substringBase().set(vm, this, baseRope.substringBase().get());
+            substringOffset() = baseRope.substringOffset() + offset;
+        } else {
+            substringBase().set(vm, this, &base);
+            substringOffset() = offset;
+
+            // For now, let's not allow substrings with a rope base.
+            // Resolve non-substring rope bases so we don't have to deal with it.
+            // FIXME: Evaluate if this would be worth adding more branches.
+            if (base.isRope())
+                static_cast<JSRopeString&>(base).resolveRope(&exec);
+        }
     }
 
     void finishCreation(VM& vm)
@@ -342,10 +355,10 @@
         return newString;
     }
 
-    static JSString* create(VM& vm, JSString* base, unsigned offset, unsigned length)
+    static JSString* create(ExecState& exec, JSString& base, unsigned offset, unsigned length)
     {
-        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
-        newString->finishCreation(vm, base, offset, length);
+        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(exec.vm().heap)) JSRopeString(exec.vm());
+        newString->finishCreation(exec, base, offset, length);
         return newString;
     }
 
@@ -515,8 +528,7 @@
     VM& vm = exec->vm();
     if (!length)
         return vm.smallStrings.emptyString();
-    s->value(exec); // For effect. We need to ensure that any string that is used as a substring base is not a rope.
-    return JSRopeString::create(vm, s, offset, length);
+    return JSRopeString::create(*exec, *s, offset, length);
 }
 
 inline JSString* jsSubstring8(VM* vm, const String& s, unsigned offset, unsigned length)
@@ -703,6 +715,11 @@
     return StringView(m_value);
 }
 
+inline bool JSString::isSubstring() const
+{
+    return isRope() && static_cast<const JSRopeString*>(this)->isSubstring();
+}
+
 } // namespace JSC
 
 #endif // JSString_h
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to