• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2008 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  #include "config.h"
27  #include "SmallStrings.h"
28  
29  #include "JSGlobalObject.h"
30  #include "JSString.h"
31  
32  #include <wtf/Noncopyable.h>
33  
34  namespace JSC {
35  static const unsigned numCharactersToStore = 0x100;
36  
37  class SmallStringsStorage : Noncopyable {
38  public:
39      SmallStringsStorage();
40  
rep(unsigned char character)41      UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
42  
43  private:
44      UChar m_characters[numCharactersToStore];
45      UString::BaseString m_base;
46      UString::Rep m_reps[numCharactersToStore];
47  };
48  
SmallStringsStorage()49  SmallStringsStorage::SmallStringsStorage()
50  {
51      for (unsigned i = 0; i < numCharactersToStore; ++i)
52          m_characters[i] = i;
53  
54      m_base.rc = numCharactersToStore + 1;
55      m_base.buf = m_characters;
56      m_base.len = numCharactersToStore;
57      m_base.offset = 0;
58      m_base._hash = 0;
59      m_base.m_baseString = 0;
60      m_base.preCapacity = 0;
61      m_base.usedPreCapacity = 0;
62      m_base.reportedCost = 0;
63  
64      // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
65      m_base.usedCapacity = numCharactersToStore + 1;
66      m_base.capacity = numCharactersToStore + 1;
67      m_base.checkConsistency();
68  
69      memset(&m_reps, 0, sizeof(m_reps));
70      for (unsigned i = 0; i < numCharactersToStore; ++i) {
71          m_reps[i].offset = i;
72          m_reps[i].len = 1;
73          m_reps[i].rc = 1;
74          m_reps[i].setBaseString(&m_base);
75          m_reps[i].checkConsistency();
76      }
77  }
78  
SmallStrings()79  SmallStrings::SmallStrings()
80      : m_emptyString(0)
81      , m_storage(0)
82  {
83      COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
84  
85      for (unsigned i = 0; i < numCharactersToStore; ++i)
86          m_singleCharacterStrings[i] = 0;
87  }
88  
~SmallStrings()89  SmallStrings::~SmallStrings()
90  {
91  }
92  
mark()93  void SmallStrings::mark()
94  {
95      if (m_emptyString && !m_emptyString->marked())
96          m_emptyString->mark();
97      for (unsigned i = 0; i < numCharactersToStore; ++i) {
98          if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked())
99              m_singleCharacterStrings[i]->mark();
100      }
101  }
102  
count() const103  unsigned SmallStrings::count() const
104  {
105      unsigned count = 0;
106      if (m_emptyString)
107          ++count;
108      for (unsigned i = 0; i < numCharactersToStore; ++i) {
109          if (m_singleCharacterStrings[i])
110              ++count;
111      }
112      return count;
113  }
114  
createEmptyString(JSGlobalData * globalData)115  void SmallStrings::createEmptyString(JSGlobalData* globalData)
116  {
117      ASSERT(!m_emptyString);
118      m_emptyString = new (globalData) JSString(globalData, "", JSString::HasOtherOwner);
119  }
120  
createSingleCharacterString(JSGlobalData * globalData,unsigned char character)121  void SmallStrings::createSingleCharacterString(JSGlobalData* globalData, unsigned char character)
122  {
123      if (!m_storage)
124          m_storage.set(new SmallStringsStorage);
125      ASSERT(!m_singleCharacterStrings[character]);
126      m_singleCharacterStrings[character] = new (globalData) JSString(globalData, m_storage->rep(character), JSString::HasOtherOwner);
127  }
128  
singleCharacterStringRep(unsigned char character)129  UString::Rep* SmallStrings::singleCharacterStringRep(unsigned char character)
130  {
131      if (!m_storage)
132          m_storage.set(new SmallStringsStorage);
133      return m_storage->rep(character);
134  }
135  
136  } // namespace JSC
137