Exemple #1
0
RefPtr<AtomicStringImpl> JSRopeString::resolveRopeToExistingAtomicString(ExecState* exec) const
{
    if (length() > maxLengthForOnStackResolve) {
        resolveRope(exec);
        if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(m_value.impl())) {
            m_value = *existingAtomicString;
            setIs8Bit(m_value.impl()->is8Bit());
            clearFibers();
            return existingAtomicString;
        }
        return nullptr;
    }
    
    if (is8Bit()) {
        LChar buffer[maxLengthForOnStackResolve];
        resolveRopeInternal8(buffer);
        if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, length())) {
            m_value = *existingAtomicString;
            setIs8Bit(m_value.impl()->is8Bit());
            clearFibers();
            return existingAtomicString;
        }
    } else {
        UChar buffer[maxLengthForOnStackResolve];
        resolveRopeInternal16(buffer);
        if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, length())) {
            m_value = *existingAtomicString;
            setIs8Bit(m_value.impl()->is8Bit());
            clearFibers();
            return existingAtomicString;
        }
    }

    return nullptr;
}
Exemple #2
0
void JSRopeString::resolveRopeToAtomicString(ExecState* exec) const
{
    if (length() > maxLengthForOnStackResolve) {
        resolveRope(exec);
        m_value = AtomicString(m_value);
        setIs8Bit(m_value.impl()->is8Bit());
        return;
    }

    if (is8Bit()) {
        LChar buffer[maxLengthForOnStackResolve];
        resolveRopeInternal8(buffer);
        m_value = AtomicString(buffer, length());
        setIs8Bit(m_value.impl()->is8Bit());
    } else {
        UChar buffer[maxLengthForOnStackResolve];
        resolveRopeInternal16(buffer);
        m_value = AtomicString(buffer, length());
        setIs8Bit(m_value.impl()->is8Bit());
    }

    clearFibers();

    // If we resolved a string that didn't previously exist, notify the heap that we've grown.
    if (m_value.impl()->hasOneRef())
        Heap::heap(this)->reportExtraMemoryAllocated(m_value.impl()->cost());
}
JSString* JSRopeString::getIndexSlowCase(ExecState* exec, unsigned i)
{
    ASSERT(isRope());
    resolveRope(exec);
    // Return a safe no-value result, this should never be used, since the excetion will be thrown.
    if (exec->exception())
        return jsEmptyString(exec);
    ASSERT(!isRope());
    RELEASE_ASSERT(i < m_value.length());
    return jsSingleCharacterSubstring(exec, m_value, i);
}
Exemple #4
0
TiString* TiString::getIndexSlowCase(TiExcState* exec, unsigned i)
{
    ASSERT(isRope());
    resolveRope(exec);
    // Return a safe no-value result, this should never be used, since the excetion will be thrown.
    if (exec->exception())
        return jsString(exec, "");
    ASSERT(!isRope());
    ASSERT(i < m_value.size());
    return jsSingleCharacterSubstring(exec, m_value, i);
}
Exemple #5
0
// This function construsts a substring out of a rope without flattening by reusing the existing fibers.
// This can reduce memory usage substantially. Since traversing ropes is slow the function will revert 
// back to flattening if the rope turns out to be long.
TiString* TiString::substringFromRope(TiExcState* exec, unsigned substringStart, unsigned substringLength)
{
    ASSERT(isRope());
    ASSERT(substringLength);
    
    TiGlobalData* globalData = &exec->globalData();

    UString substringFibers[3];
    
    unsigned fiberCount = 0;
    unsigned substringFiberCount = 0;
    unsigned substringEnd = substringStart + substringLength;
    unsigned fiberEnd = 0;

    RopeIterator end;
    for (RopeIterator it(m_fibers.data(), m_fiberCount); it != end; ++it) {
        ++fiberCount;
        StringImpl* fiberString = *it;
        unsigned fiberStart = fiberEnd;
        fiberEnd = fiberStart + fiberString->length();
        if (fiberEnd <= substringStart)
            continue;
        unsigned copyStart = std::max(substringStart, fiberStart);
        unsigned copyEnd = std::min(substringEnd, fiberEnd);
        if (copyStart == fiberStart && copyEnd == fiberEnd)
            substringFibers[substringFiberCount++] = UString(fiberString);
        else
            substringFibers[substringFiberCount++] = UString(StringImpl::create(fiberString, copyStart - fiberStart, copyEnd - copyStart));
        if (fiberEnd >= substringEnd)
            break;
        if (fiberCount > substringFromRopeCutoff || substringFiberCount >= 3) {
            // This turned out to be a really inefficient rope. Just flatten it.
            resolveRope(exec);
            return jsSubstring(&exec->globalData(), m_value, substringStart, substringLength);
        }
    }
    ASSERT(substringFiberCount && substringFiberCount <= 3);

    if (substringLength == 1) {
        ASSERT(substringFiberCount == 1);
        UChar c = substringFibers[0].characters()[0];
        if (c <= maxSingleCharacterString)
            return globalData->smallStrings.singleCharacterString(globalData, c);
    }
    if (substringFiberCount == 1)
        return new (globalData) TiString(globalData, substringFibers[0]);
    if (substringFiberCount == 2)
        return new (globalData) TiString(globalData, substringFibers[0], substringFibers[1]);
    return new (globalData) TiString(globalData, substringFibers[0], substringFibers[1], substringFibers[2]);
}