• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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