Changeset 241954 in webkit
- Timestamp:
- Feb 22, 2019 11:04:40 AM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r241938 r241954 1 2019-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 1 29 2019-02-22 Tadeu Zagallo <tzagallo@apple.com> 2 30 -
trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp
r241117 r241954 35 35 namespace JSC { 36 36 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 61 37 SmallStrings::SmallStrings() 62 38 { … … 70 46 { 71 47 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 74 56 #define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) initialize(&vm, m_##name, #name); 75 57 JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE) … … 78 60 initialize(&vm, m_nullObjectString, "[object Null]"); 79 61 initialize(&vm, m_undefinedObjectString, "[object Undefined]"); 62 63 setInitialized(true); 80 64 } 81 65 … … 105 89 } 106 90 107 void SmallStrings::createSingleCharacterString(VM* vm,unsigned char character)91 Ref<StringImpl> SmallStrings::singleCharacterStringRep(unsigned char character) 108 92 { 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(); 121 97 } 122 98 -
trunk/Source/JavaScriptCore/runtime/SmallStrings.h
r241117 r241954 52 52 class VM; 53 53 class JSString; 54 class SmallStringsStorage;55 54 class SlotVisitor; 56 55 … … 73 72 } 74 73 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; } 76 77 77 78 JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; } … … 128 129 129 130 void createEmptyString(VM*); 130 void createSingleCharacterString(VM*, unsigned char);131 131 132 132 void initialize(VM*, JSString*&, const char* value); … … 140 140 JSString* m_undefinedObjectString { nullptr }; 141 141 JSString* m_singleCharacterStrings[singleCharacterStringCount] { nullptr }; 142 std::unique_ptr<SmallStringsStorage> m_storage;143 142 bool m_needsToBeVisited { true }; 143 bool m_isInitialized { false }; 144 144 }; 145 145 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r241654 r241954 341 341 JSLockHolder lock(this); 342 342 AtomicStringTable* existingEntryAtomicStringTable = Thread::current().setCurrentAtomicStringTable(m_atomicStringTable); 343 propertyNames = new CommonIdentifiers(this);344 343 structureStructure.set(*this, Structure::createStructure(*this)); 345 344 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); 346 350 terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull())); 347 stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));348 351 propertyNameEnumeratorStructure.set(*this, JSPropertyNameEnumerator::createStructure(*this, 0, jsNull())); 349 352 customGetterSetterStructure.set(*this, CustomGetterSetter::createStructure(*this, 0, jsNull())); … … 402 405 sentinelMapBucket.set(*this, JSMap::BucketType::createSentinel(*this)); 403 406 404 smallStrings.initializeCommonStrings(*this);405 406 407 Thread::current().setCurrentAtomicStringTable(existingEntryAtomicStringTable); 407 408 … … 540 541 ASSERT(currentThreadIsHoldingAPILock()); 541 542 m_apiLock->willDestroyVM(this); 543 smallStrings.setInitialized(false); 542 544 heap.lastChanceToFinalize(); 543 545
Note: See TracChangeset
for help on using the changeset viewer.