Changeset 241954 in webkit


Ignore:
Timestamp:
Feb 22, 2019 11:04:40 AM (5 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] SmallStringsStorage is unnecessary
https://bugs.webkit.org/show_bug.cgi?id=194939

Reviewed by Mark Lam.

SmallStrings hold common small JSStrings. Their underlying StringImpl is also held by SmallStringsStorage.
But it is duplicate since we can get StringImpl from small JSStrings. This patch removes SmallStringsStorage,
and get StringImpls from JSStrings if necessary.

We also add m_canAccessHeap flag to SmallStrings. At the time of VM destruction, JSStrings are destroyed when
VM's Heap is finalized. We must not touch JSStrings before VM's heap (and JSStrings in SmallStrings) is initialized,
and after VM's Heap is destroyed. We add this m_canAccessHeap flag to allow users to get StringImpl during the
this sensitive period. If m_canAccessHeap is false, we get StringImpl from AtomicStringImpl::add.

  • runtime/SmallStrings.cpp:

(JSC::SmallStrings::initializeCommonStrings):
(JSC::SmallStrings::singleCharacterStringRep):
(JSC::SmallStringsStorage::rep): Deleted.
(JSC::SmallStringsStorage::SmallStringsStorage): Deleted.
(JSC::SmallStrings::createSingleCharacterString): Deleted.

  • runtime/SmallStrings.h:

(JSC::SmallStrings::setCanAccessHeap):

  • runtime/VM.cpp:

(JSC::VM::VM):
(JSC::VM::~VM):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r241938 r241954  
     12019-02-22  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] SmallStringsStorage is unnecessary
     4        https://bugs.webkit.org/show_bug.cgi?id=194939
     5
     6        Reviewed by Mark Lam.
     7
     8        SmallStrings hold common small JSStrings. Their underlying StringImpl is also held by SmallStringsStorage.
     9        But it is duplicate since we can get StringImpl from small JSStrings. This patch removes SmallStringsStorage,
     10        and get StringImpls from JSStrings if necessary.
     11
     12        We also add m_canAccessHeap flag to SmallStrings. At the time of VM destruction, JSStrings are destroyed when
     13        VM's Heap is finalized. We must not touch JSStrings before VM's heap (and JSStrings in SmallStrings) is initialized,
     14        and after VM's Heap is destroyed. We add this m_canAccessHeap flag to allow users to get StringImpl during the
     15        this sensitive period. If m_canAccessHeap is false, we get StringImpl from AtomicStringImpl::add.
     16
     17        * runtime/SmallStrings.cpp:
     18        (JSC::SmallStrings::initializeCommonStrings):
     19        (JSC::SmallStrings::singleCharacterStringRep):
     20        (JSC::SmallStringsStorage::rep): Deleted.
     21        (JSC::SmallStringsStorage::SmallStringsStorage): Deleted.
     22        (JSC::SmallStrings::createSingleCharacterString): Deleted.
     23        * runtime/SmallStrings.h:
     24        (JSC::SmallStrings::setCanAccessHeap):
     25        * runtime/VM.cpp:
     26        (JSC::VM::VM):
     27        (JSC::VM::~VM):
     28
    1292019-02-22  Tadeu Zagallo  <tzagallo@apple.com>
    230
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp

    r241117 r241954  
    3535namespace JSC {
    3636
    37 class SmallStringsStorage {
    38     WTF_MAKE_NONCOPYABLE(SmallStringsStorage); WTF_MAKE_FAST_ALLOCATED;
    39 public:
    40     SmallStringsStorage();
    41 
    42     StringImpl& rep(unsigned char character)
    43     {
    44         return *m_reps[character].get();
    45     }
    46 
    47 private:
    48     static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
    49 
    50     RefPtr<StringImpl> m_reps[singleCharacterStringCount];
    51 };
    52 
    53 SmallStringsStorage::SmallStringsStorage()
    54 {
    55     for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
    56         const LChar string[] = { static_cast<LChar>(i) };
    57         m_reps[i] = AtomicStringImpl::add(StringImpl::create(string, 1).ptr());
    58     }
    59 }
    60 
    6137SmallStrings::SmallStrings()
    6238{
     
    7046{
    7147    createEmptyString(&vm);
    72     for (unsigned i = 0; i <= maxSingleCharacterString; ++i)
    73         createSingleCharacterString(&vm, i);
     48
     49    for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
     50        ASSERT(!m_singleCharacterStrings[i]);
     51        const LChar string[] = { static_cast<LChar>(i) };
     52        m_singleCharacterStrings[i] = JSString::createHasOtherOwner(vm, AtomicStringImpl::add(string, 1).releaseNonNull());
     53        ASSERT(m_needsToBeVisited);
     54    }
     55
    7456#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) initialize(&vm, m_##name, #name);
    7557    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE)
     
    7860    initialize(&vm, m_nullObjectString, "[object Null]");
    7961    initialize(&vm, m_undefinedObjectString, "[object Undefined]");
     62
     63    setInitialized(true);
    8064}
    8165
     
    10589}
    10690
    107 void SmallStrings::createSingleCharacterString(VM* vm, unsigned char character)
     91Ref<StringImpl> SmallStrings::singleCharacterStringRep(unsigned char character)
    10892{
    109     if (!m_storage)
    110         m_storage = std::make_unique<SmallStringsStorage>();
    111     ASSERT(!m_singleCharacterStrings[character]);
    112     m_singleCharacterStrings[character] = JSString::createHasOtherOwner(*vm, m_storage->rep(character));
    113     ASSERT(m_needsToBeVisited);
    114 }
    115 
    116 StringImpl& SmallStrings::singleCharacterStringRep(unsigned char character)
    117 {
    118     if (!m_storage)
    119         m_storage = std::make_unique<SmallStringsStorage>();
    120     return m_storage->rep(character);
     93    if (LIKELY(m_isInitialized))
     94        return *const_cast<StringImpl*>(m_singleCharacterStrings[character]->tryGetValueImpl());
     95    const LChar string[] = { static_cast<LChar>(character) };
     96    return AtomicStringImpl::add(string, 1).releaseNonNull();
    12197}
    12298
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.h

    r241117 r241954  
    5252class VM;
    5353class JSString;
    54 class SmallStringsStorage;
    5554class SlotVisitor;
    5655
     
    7372    }
    7473
    75     JS_EXPORT_PRIVATE WTF::StringImpl& singleCharacterStringRep(unsigned char character);
     74    JS_EXPORT_PRIVATE Ref<StringImpl> singleCharacterStringRep(unsigned char character);
     75
     76    void setIsInitialized(bool isInitialized) { m_isInitialized = isInitialized; }
    7677
    7778    JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
     
    128129
    129130    void createEmptyString(VM*);
    130     void createSingleCharacterString(VM*, unsigned char);
    131131
    132132    void initialize(VM*, JSString*&, const char* value);
     
    140140    JSString* m_undefinedObjectString { nullptr };
    141141    JSString* m_singleCharacterStrings[singleCharacterStringCount] { nullptr };
    142     std::unique_ptr<SmallStringsStorage> m_storage;
    143142    bool m_needsToBeVisited { true };
     143    bool m_isInitialized { false };
    144144};
    145145
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r241654 r241954  
    341341    JSLockHolder lock(this);
    342342    AtomicStringTable* existingEntryAtomicStringTable = Thread::current().setCurrentAtomicStringTable(m_atomicStringTable);
    343     propertyNames = new CommonIdentifiers(this);
    344343    structureStructure.set(*this, Structure::createStructure(*this));
    345344    structureRareDataStructure.set(*this, StructureRareData::createStructure(*this, 0, jsNull()));
     345    stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
     346
     347    smallStrings.initializeCommonStrings(*this);
     348
     349    propertyNames = new CommonIdentifiers(this);
    346350    terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
    347     stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
    348351    propertyNameEnumeratorStructure.set(*this, JSPropertyNameEnumerator::createStructure(*this, 0, jsNull()));
    349352    customGetterSetterStructure.set(*this, CustomGetterSetter::createStructure(*this, 0, jsNull()));
     
    402405    sentinelMapBucket.set(*this, JSMap::BucketType::createSentinel(*this));
    403406
    404     smallStrings.initializeCommonStrings(*this);
    405 
    406407    Thread::current().setCurrentAtomicStringTable(existingEntryAtomicStringTable);
    407408
     
    540541    ASSERT(currentThreadIsHoldingAPILock());
    541542    m_apiLock->willDestroyVM(this);
     543    smallStrings.setInitialized(false);
    542544    heap.lastChanceToFinalize();
    543545
Note: See TracChangeset for help on using the changeset viewer.