1 /* 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef RopeImpl_h 27 #define RopeImpl_h 28 29 #include <wtf/text/StringImpl.h> 30 31 namespace JSC { 32 33 class RopeImpl : public StringImplBase { 34 public: 35 // A RopeImpl is composed from a set of smaller strings called Fibers. 36 // Each Fiber in a rope is either StringImpl or another RopeImpl. 37 typedef StringImplBase* Fiber; 38 39 // Creates a RopeImpl comprising of 'fiberCount' Fibers. 40 // The RopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the RopeImpl. tryCreateUninitialized(unsigned fiberCount)41 static PassRefPtr<RopeImpl> tryCreateUninitialized(unsigned fiberCount) 42 { 43 void* allocation; 44 if (tryFastMalloc(sizeof(RopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation)) 45 return adoptRef(new (allocation) RopeImpl(fiberCount)); 46 return 0; 47 } 48 isRope(Fiber fiber)49 static bool isRope(Fiber fiber) 50 { 51 return !fiber->isStringImpl(); 52 } 53 deref(Fiber fiber)54 static void deref(Fiber fiber) 55 { 56 if (isRope(fiber)) 57 static_cast<RopeImpl*>(fiber)->deref(); 58 else 59 static_cast<StringImpl*>(fiber)->deref(); 60 } 61 initializeFiber(unsigned & index,Fiber fiber)62 void initializeFiber(unsigned &index, Fiber fiber) 63 { 64 m_fibers[index++] = fiber; 65 fiber->ref(); 66 m_length += fiber->length(); 67 } 68 fiberCount()69 unsigned fiberCount() { return m_size; } fibers()70 Fiber* fibers() { return m_fibers; } 71 deref()72 ALWAYS_INLINE void deref() 73 { 74 m_refCountAndFlags -= s_refCountIncrement; 75 if (!(m_refCountAndFlags & s_refCountMask)) 76 destructNonRecursive(); 77 } 78 79 private: RopeImpl(unsigned fiberCount)80 RopeImpl(unsigned fiberCount) 81 : StringImplBase(ConstructNonStringImpl) 82 , m_size(fiberCount) 83 { 84 } 85 86 void destructNonRecursive(); 87 void derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue); 88 hasOneRef()89 bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; } 90 91 unsigned m_size; 92 Fiber m_fibers[1]; 93 }; 94 95 } 96 97 #endif 98