- UChar* position = buffer + m_length;
-
- // Start with the current RopeImpl.
- Vector<RopeImpl::Fiber, 32> workQueue;
- RopeImpl::Fiber currentFiber;
- for (unsigned i = 0; i < (m_fiberCount - 1); ++i)
- workQueue.append(m_other.m_fibers[i]);
- currentFiber = m_other.m_fibers[m_fiberCount - 1];
- while (true) {
- if (RopeImpl::isRope(currentFiber)) {
- RopeImpl* rope = static_cast<RopeImpl*>(currentFiber);
- // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
- // (we will be working backwards over the rope).
- unsigned fiberCountMinusOne = rope->fiberCount() - 1;
- for (unsigned i = 0; i < fiberCountMinusOne; ++i)
- workQueue.append(rope->fibers()[i]);
- currentFiber = rope->fibers()[fiberCountMinusOne];
- } else {
- UStringImpl* string = static_cast<UStringImpl*>(currentFiber);
- unsigned length = string->length();
- position -= length;
- UStringImpl::copyChars(position, string->characters(), length);
-
- // Was this the last item in the work queue?
- if (workQueue.isEmpty()) {
- // Create a string from the UChar buffer, clear the rope RefPtr.
- ASSERT(buffer == position);
- for (unsigned i = 0; i < m_fiberCount; ++i) {
- RopeImpl::deref(m_other.m_fibers[i]);
- m_other.m_fibers[i] = 0;
- }
- m_fiberCount = 0;
-
- ASSERT(!isRope());
- return;
- }
-
- // No! - set the next item up to process.
- currentFiber = workQueue.last();
- workQueue.removeLast();
+
+ if (is8Bit()) {
+ LChar buffer[maxLengthForOnStackResolve];
+ resolveRopeInternal8(buffer);
+ m_value = AtomicString(buffer, m_length);
+ } else {
+ UChar buffer[maxLengthForOnStackResolve];
+ resolveRopeInternal16(buffer);
+ m_value = AtomicString(buffer, m_length);
+ }
+
+ 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)->reportExtraMemoryCost(m_value.impl()->cost());
+}
+
+void JSRopeString::clearFibers() const
+{
+ for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i)
+ m_fibers[i].clear();
+}
+
+AtomicStringImpl* JSRopeString::resolveRopeToExistingAtomicString(ExecState* exec) const
+{
+ if (m_length > maxLengthForOnStackResolve) {
+ resolveRope(exec);
+ if (AtomicStringImpl* existingAtomicString = AtomicString::find(m_value.impl())) {
+ m_value = *existingAtomicString;
+ clearFibers();
+ return existingAtomicString;