Ignore:
Timestamp:
Jun 11, 2015, 9:09:11 PM (10 years ago)
Author:
[email protected]
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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r185368 r185486  
    187187
    188188    bool isRope() const { return m_value.isNull(); }
     189    bool isSubstring() const;
    189190    bool is8Bit() const { return m_flags & Is8Bit; }
    190191    void setIs8Bit(bool flag) const
     
    292293    }
    293294
    294     void finishCreation(VM& vm, JSString* base, unsigned offset, unsigned length)
    295     {
     295    void finishCreation(ExecState& exec, JSString& base, unsigned offset, unsigned length)
     296    {
     297        VM& vm = exec.vm();
    296298        Base::finishCreation(vm);
    297         ASSERT(!base->isRope());
    298299        ASSERT(!sumOverflows<int32_t>(offset, length));
    299         ASSERT(offset + length <= base->length());
     300        ASSERT(offset + length <= base.length());
    300301        m_length = length;
    301         setIs8Bit(base->is8Bit());
     302        setIs8Bit(base.is8Bit());
    302303        setIsSubstring(true);
    303         substringBase().set(vm, this, base);
    304         substringOffset() = offset;
     304        if (base.isSubstring()) {
     305            JSRopeString& baseRope = static_cast<JSRopeString&>(base);
     306            substringBase().set(vm, this, baseRope.substringBase().get());
     307            substringOffset() = baseRope.substringOffset() + offset;
     308        } else {
     309            substringBase().set(vm, this, &base);
     310            substringOffset() = offset;
     311
     312            // For now, let's not allow substrings with a rope base.
     313            // Resolve non-substring rope bases so we don't have to deal with it.
     314            // FIXME: Evaluate if this would be worth adding more branches.
     315            if (base.isRope())
     316                static_cast<JSRopeString&>(base).resolveRope(&exec);
     317        }
    305318    }
    306319
     
    343356    }
    344357
    345     static JSString* create(VM& vm, JSString* base, unsigned offset, unsigned length)
    346     {
    347         JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
    348         newString->finishCreation(vm, base, offset, length);
     358    static JSString* create(ExecState& exec, JSString& base, unsigned offset, unsigned length)
     359    {
     360        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(exec.vm().heap)) JSRopeString(exec.vm());
     361        newString->finishCreation(exec, base, offset, length);
    349362        return newString;
    350363    }
     
    516529    if (!length)
    517530        return vm.smallStrings.emptyString();
    518     s->value(exec); // For effect. We need to ensure that any string that is used as a substring base is not a rope.
    519     return JSRopeString::create(vm, s, offset, length);
     531    return JSRopeString::create(*exec, *s, offset, length);
    520532}
    521533
     
    704716}
    705717
     718inline bool JSString::isSubstring() const
     719{
     720    return isRope() && static_cast<const JSRopeString*>(this)->isSubstring();
     721}
     722
    706723} // namespace JSC
    707724
Note: See TracChangeset for help on using the changeset viewer.