X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/ba379fdc102753d6be2c4d937058fe40257329fe..4be4e30906bcb8ee30b4d189205cb70bad6707ce:/runtime/SmallStrings.cpp diff --git a/runtime/SmallStrings.cpp b/runtime/SmallStrings.cpp index 87b49f0..5f35cca 100644 --- a/runtime/SmallStrings.cpp +++ b/runtime/SmallStrings.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,103 +26,112 @@ #include "config.h" #include "SmallStrings.h" +#include "HeapRootVisitor.h" #include "JSGlobalObject.h" #include "JSString.h" - +#include "Operations.h" #include +#include +#include namespace JSC { -static const unsigned numCharactersToStore = 0x100; -class SmallStringsStorage : Noncopyable { +static inline void finalize(JSString*& string) +{ + if (!string || Heap::isMarked(string)) + return; + string = 0; +} + +class SmallStringsStorage { + WTF_MAKE_NONCOPYABLE(SmallStringsStorage); WTF_MAKE_FAST_ALLOCATED; public: SmallStringsStorage(); - UString::Rep* rep(unsigned char character) { return &m_reps[character]; } + StringImpl* rep(unsigned char character) + { + return m_reps[character].get(); + } private: - UChar m_characters[numCharactersToStore]; - UString::BaseString m_base; - UString::Rep m_reps[numCharactersToStore]; + static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1; + + RefPtr m_reps[singleCharacterStringCount]; }; SmallStringsStorage::SmallStringsStorage() - : m_base(m_characters, numCharactersToStore) { - m_base.rc = numCharactersToStore + 1; - // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it - m_base.usedCapacity = numCharactersToStore + 1; - m_base.capacity = numCharactersToStore + 1; - m_base.checkConsistency(); - - for (unsigned i = 0; i < numCharactersToStore; ++i) - m_characters[i] = i; - - memset(&m_reps, 0, sizeof(m_reps)); - for (unsigned i = 0; i < numCharactersToStore; ++i) { - m_reps[i].offset = i; - m_reps[i].len = 1; - m_reps[i].rc = 1; - m_reps[i].setBaseString(&m_base); - m_reps[i].checkConsistency(); + LChar* characterBuffer = 0; + RefPtr baseString = StringImpl::createUninitialized(singleCharacterStringCount, characterBuffer); + for (unsigned i = 0; i < singleCharacterStringCount; ++i) { + characterBuffer[i] = i; + m_reps[i] = StringImpl::create(baseString, i, 1); } } SmallStrings::SmallStrings() : m_emptyString(0) - , m_storage(0) +#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) , m_##name(0) + JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE) +#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE { - COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage); + COMPILE_ASSERT(singleCharacterStringCount == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage); - for (unsigned i = 0; i < numCharactersToStore; ++i) + for (unsigned i = 0; i < singleCharacterStringCount; ++i) m_singleCharacterStrings[i] = 0; } -SmallStrings::~SmallStrings() +void SmallStrings::initializeCommonStrings(VM& vm) { + createEmptyString(&vm); +#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) initialize(&vm, m_##name, #name); + JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE) +#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE } -void SmallStrings::mark() +void SmallStrings::visitStrongReferences(SlotVisitor& visitor) { - if (m_emptyString && !m_emptyString->marked()) - m_emptyString->mark(); - for (unsigned i = 0; i < numCharactersToStore; ++i) { - if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked()) - m_singleCharacterStrings[i]->mark(); - } + visitor.appendUnbarrieredPointer(&m_emptyString); +#define JSC_COMMON_STRINGS_ATTRIBUTE_VISIT(name) visitor.appendUnbarrieredPointer(&m_##name); + JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_VISIT) +#undef JSC_COMMON_STRINGS_ATTRIBUTE_VISIT } -unsigned SmallStrings::count() const +SmallStrings::~SmallStrings() { - unsigned count = 0; - if (m_emptyString) - ++count; - for (unsigned i = 0; i < numCharactersToStore; ++i) { - if (m_singleCharacterStrings[i]) - ++count; - } - return count; } -void SmallStrings::createEmptyString(JSGlobalData* globalData) +void SmallStrings::finalizeSmallStrings() +{ + finalize(m_emptyString); + for (unsigned i = 0; i < singleCharacterStringCount; ++i) + finalize(m_singleCharacterStrings[i]); +} + +void SmallStrings::createEmptyString(VM* vm) { ASSERT(!m_emptyString); - m_emptyString = new (globalData) JSString(globalData, "", JSString::HasOtherOwner); + m_emptyString = JSString::createHasOtherOwner(*vm, StringImpl::empty()); } -void SmallStrings::createSingleCharacterString(JSGlobalData* globalData, unsigned char character) +void SmallStrings::createSingleCharacterString(VM* vm, unsigned char character) { if (!m_storage) - m_storage.set(new SmallStringsStorage); + m_storage = adoptPtr(new SmallStringsStorage); ASSERT(!m_singleCharacterStrings[character]); - m_singleCharacterStrings[character] = new (globalData) JSString(globalData, m_storage->rep(character), JSString::HasOtherOwner); + m_singleCharacterStrings[character] = JSString::createHasOtherOwner(*vm, PassRefPtr(m_storage->rep(character))); } -UString::Rep* SmallStrings::singleCharacterStringRep(unsigned char character) +StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character) { if (!m_storage) - m_storage.set(new SmallStringsStorage); + m_storage = adoptPtr(new SmallStringsStorage); return m_storage->rep(character); } +void SmallStrings::initialize(VM* vm, JSString*& string, const char* value) const +{ + string = JSString::create(*vm, StringImpl::create(value)); +} + } // namespace JSC