X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..81345200c95645a1b0d2635520f96ad55dfde63f:/runtime/SmallStrings.cpp?ds=sidebyside diff --git a/runtime/SmallStrings.cpp b/runtime/SmallStrings.cpp index 6c73df2..a4bdb0c 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,111 +26,108 @@ #include "config.h" #include "SmallStrings.h" +#include "HeapRootVisitor.h" #include "JSGlobalObject.h" #include "JSString.h" - +#include "JSCInlines.h" #include +#include +#include namespace JSC { -static const unsigned numCharactersToStore = 0x100; -class SmallStringsStorage : Noncopyable { +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() { - for (unsigned i = 0; i < numCharactersToStore; ++i) - m_characters[i] = i; - - m_base.rc = numCharactersToStore + 1; - m_base.buf = m_characters; - m_base.len = numCharactersToStore; - m_base.offset = 0; - m_base._hash = 0; - m_base.m_baseString = 0; - m_base.preCapacity = 0; - m_base.usedPreCapacity = 0; - m_base.reportedCost = 0; - - // 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(); - - 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] = AtomicString::add(PassRefPtr(StringImpl::createSubstringSharingImpl(baseString, i, 1)).get()); } } 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 + , m_nullObjectString(nullptr) + , m_undefinedObjectString(nullptr) { - 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); + for (unsigned i = 0; i <= maxSingleCharacterString; ++i) + createSingleCharacterString(&vm, i); +#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 + initialize(&vm, m_nullObjectString, "[object Null]"); + initialize(&vm, m_undefinedObjectString, "[object Undefined]"); } -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); + for (unsigned i = 0; i <= maxSingleCharacterString; ++i) + visitor.appendUnbarrieredPointer(m_singleCharacterStrings + i); +#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 + visitor.appendUnbarrieredPointer(&m_nullObjectString); + visitor.appendUnbarrieredPointer(&m_undefinedObjectString); } -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::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