1/* 2 * Copyright (C) 2008, 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#include "config.h" 27#include "SmallStrings.h" 28 29#include "HeapRootVisitor.h" 30#include "JSGlobalObject.h" 31#include "JSString.h" 32#include "JSCInlines.h" 33#include <wtf/Noncopyable.h> 34#include <wtf/PassOwnPtr.h> 35#include <wtf/text/StringImpl.h> 36 37namespace JSC { 38 39class SmallStringsStorage { 40 WTF_MAKE_NONCOPYABLE(SmallStringsStorage); WTF_MAKE_FAST_ALLOCATED; 41public: 42 SmallStringsStorage(); 43 44 StringImpl* rep(unsigned char character) 45 { 46 return m_reps[character].get(); 47 } 48 49private: 50 static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1; 51 52 RefPtr<StringImpl> m_reps[singleCharacterStringCount]; 53}; 54 55SmallStringsStorage::SmallStringsStorage() 56{ 57 LChar* characterBuffer = 0; 58 RefPtr<StringImpl> baseString = StringImpl::createUninitialized(singleCharacterStringCount, characterBuffer); 59 for (unsigned i = 0; i < singleCharacterStringCount; ++i) { 60 characterBuffer[i] = i; 61 m_reps[i] = AtomicString::add(PassRefPtr<StringImpl>(StringImpl::createSubstringSharingImpl(baseString, i, 1)).get()); 62 } 63} 64 65SmallStrings::SmallStrings() 66 : m_emptyString(0) 67#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) , m_##name(0) 68 JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE) 69#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE 70 , m_nullObjectString(nullptr) 71 , m_undefinedObjectString(nullptr) 72{ 73 COMPILE_ASSERT(singleCharacterStringCount == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage); 74 75 for (unsigned i = 0; i < singleCharacterStringCount; ++i) 76 m_singleCharacterStrings[i] = 0; 77} 78 79void SmallStrings::initializeCommonStrings(VM& vm) 80{ 81 createEmptyString(&vm); 82 for (unsigned i = 0; i <= maxSingleCharacterString; ++i) 83 createSingleCharacterString(&vm, i); 84#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) initialize(&vm, m_##name, #name); 85 JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE) 86#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE 87 initialize(&vm, m_nullObjectString, "[object Null]"); 88 initialize(&vm, m_undefinedObjectString, "[object Undefined]"); 89} 90 91void SmallStrings::visitStrongReferences(SlotVisitor& visitor) 92{ 93 visitor.appendUnbarrieredPointer(&m_emptyString); 94 for (unsigned i = 0; i <= maxSingleCharacterString; ++i) 95 visitor.appendUnbarrieredPointer(m_singleCharacterStrings + i); 96#define JSC_COMMON_STRINGS_ATTRIBUTE_VISIT(name) visitor.appendUnbarrieredPointer(&m_##name); 97 JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_VISIT) 98#undef JSC_COMMON_STRINGS_ATTRIBUTE_VISIT 99 visitor.appendUnbarrieredPointer(&m_nullObjectString); 100 visitor.appendUnbarrieredPointer(&m_undefinedObjectString); 101} 102 103SmallStrings::~SmallStrings() 104{ 105} 106 107void SmallStrings::createEmptyString(VM* vm) 108{ 109 ASSERT(!m_emptyString); 110 m_emptyString = JSString::createHasOtherOwner(*vm, StringImpl::empty()); 111} 112 113void SmallStrings::createSingleCharacterString(VM* vm, unsigned char character) 114{ 115 if (!m_storage) 116 m_storage = adoptPtr(new SmallStringsStorage); 117 ASSERT(!m_singleCharacterStrings[character]); 118 m_singleCharacterStrings[character] = JSString::createHasOtherOwner(*vm, PassRefPtr<StringImpl>(m_storage->rep(character))); 119} 120 121StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character) 122{ 123 if (!m_storage) 124 m_storage = adoptPtr(new SmallStringsStorage); 125 return m_storage->rep(character); 126} 127 128void SmallStrings::initialize(VM* vm, JSString*& string, const char* value) const 129{ 130 string = JSString::create(*vm, StringImpl::create(value)); 131} 132 133} // namespace JSC 134