Commit 29b09028 authored by esprehn's avatar esprehn Committed by Commit bot

Don't lazy allocate the AtomicStringTable.

We can store the AtomicStringTable in a unique_ptr in the WTFThreadData
directly and then use the constructor and destructor to handle adding
and removing the strings. We can then return a reference too since
all WTFThreadData instances have an AtomicStringTable.

Future patches will move most of the AtomicString.cpp logic into the
AtomicStringTable class making the code easier to understand.

Review-Url: https://codereview.chromium.org/2103373002
Cr-Commit-Position: refs/heads/master@{#402684}
parent f6a80acd
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "wtf/WTFThreadData.h" #include "wtf/WTFThreadData.h"
#include "wtf/PtrUtil.h"
#include "wtf/text/TextCodecICU.h" #include "wtf/text/TextCodecICU.h"
namespace WTF { namespace WTF {
...@@ -34,18 +33,15 @@ namespace WTF { ...@@ -34,18 +33,15 @@ namespace WTF {
ThreadSpecific<WTFThreadData>* WTFThreadData::staticData; ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
WTFThreadData::WTFThreadData() WTFThreadData::WTFThreadData()
: m_atomicStringTable(nullptr) : m_atomicStringTable(new AtomicStringTable)
, m_atomicStringTableDestructor(nullptr)
, m_compressibleStringTable(nullptr) , m_compressibleStringTable(nullptr)
, m_compressibleStringTableDestructor(nullptr) , m_compressibleStringTableDestructor(nullptr)
, m_cachedConverterICU(wrapUnique(new ICUConverterWrapper)) , m_cachedConverterICU(new ICUConverterWrapper)
{ {
} }
WTFThreadData::~WTFThreadData() WTFThreadData::~WTFThreadData()
{ {
if (m_atomicStringTableDestructor)
m_atomicStringTableDestructor(m_atomicStringTable);
if (m_compressibleStringTableDestructor) if (m_compressibleStringTableDestructor)
m_compressibleStringTableDestructor(m_compressibleStringTable); m_compressibleStringTableDestructor(m_compressibleStringTable);
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "wtf/ThreadSpecific.h" #include "wtf/ThreadSpecific.h"
#include "wtf/Threading.h" #include "wtf/Threading.h"
#include "wtf/WTFExport.h" #include "wtf/WTFExport.h"
#include "wtf/text/AtomicStringTable.h"
#include "wtf/text/StringHash.h" #include "wtf/text/StringHash.h"
#include <memory> #include <memory>
...@@ -48,11 +49,8 @@ typedef void (*CompressibleStringTableDestructor)(CompressibleStringTable*); ...@@ -48,11 +49,8 @@ typedef void (*CompressibleStringTableDestructor)(CompressibleStringTable*);
namespace WTF { namespace WTF {
class AtomicStringTable;
struct ICUConverterWrapper; struct ICUConverterWrapper;
typedef void (*AtomicStringTableDestructor)(AtomicStringTable*);
class WTF_EXPORT WTFThreadData { class WTF_EXPORT WTFThreadData {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
WTF_MAKE_NONCOPYABLE(WTFThreadData); WTF_MAKE_NONCOPYABLE(WTFThreadData);
...@@ -60,9 +58,9 @@ public: ...@@ -60,9 +58,9 @@ public:
WTFThreadData(); WTFThreadData();
~WTFThreadData(); ~WTFThreadData();
AtomicStringTable* getAtomicStringTable() AtomicStringTable& getAtomicStringTable()
{ {
return m_atomicStringTable; return *m_atomicStringTable;
} }
blink::CompressibleStringTable* compressibleStringTable() blink::CompressibleStringTable* compressibleStringTable()
...@@ -73,15 +71,13 @@ public: ...@@ -73,15 +71,13 @@ public:
ICUConverterWrapper& cachedConverterICU() { return *m_cachedConverterICU; } ICUConverterWrapper& cachedConverterICU() { return *m_cachedConverterICU; }
private: private:
AtomicStringTable* m_atomicStringTable; std::unique_ptr<AtomicStringTable> m_atomicStringTable;
AtomicStringTableDestructor m_atomicStringTableDestructor;
blink::CompressibleStringTable* m_compressibleStringTable; blink::CompressibleStringTable* m_compressibleStringTable;
blink::CompressibleStringTableDestructor m_compressibleStringTableDestructor; blink::CompressibleStringTableDestructor m_compressibleStringTableDestructor;
std::unique_ptr<ICUConverterWrapper> m_cachedConverterICU; std::unique_ptr<ICUConverterWrapper> m_cachedConverterICU;
static ThreadSpecific<WTFThreadData>* staticData; static ThreadSpecific<WTFThreadData>* staticData;
friend WTFThreadData& wtfThreadData(); friend WTFThreadData& wtfThreadData();
friend class AtomicStringTable;
friend class blink::CompressibleStringTable; friend class blink::CompressibleStringTable;
}; };
......
...@@ -35,84 +35,14 @@ using namespace Unicode; ...@@ -35,84 +35,14 @@ using namespace Unicode;
static_assert(sizeof(AtomicString) == sizeof(String), "AtomicString and String must be same size"); static_assert(sizeof(AtomicString) == sizeof(String), "AtomicString and String must be same size");
class AtomicStringTable {
USING_FAST_MALLOC(AtomicStringTable);
WTF_MAKE_NONCOPYABLE(AtomicStringTable);
public:
static AtomicStringTable* create(WTFThreadData& data)
{
data.m_atomicStringTable = new AtomicStringTable;
data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
data.m_atomicStringTable->addStaticStrings();
return data.m_atomicStringTable;
}
StringImpl* addStringImpl(StringImpl* string)
{
if (!string->length())
return StringImpl::empty();
StringImpl* result = *m_table.add(string).storedValue;
if (!result->isAtomic())
result->setIsAtomic(true);
ASSERT(!string->isStatic() || result->isStatic());
return result;
}
HashSet<StringImpl*>& table()
{
return m_table;
}
private:
AtomicStringTable() { }
void addStaticStrings()
{
const StaticStringsTable& staticStrings = StringImpl::allStaticStrings();
StaticStringsTable::const_iterator it = staticStrings.begin();
for (; it != staticStrings.end(); ++it) {
addStringImpl(it->value);
}
}
static void destroy(AtomicStringTable* table)
{
HashSet<StringImpl*>::iterator end = table->m_table.end();
for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != end; ++iter) {
StringImpl* string = *iter;
if (!string->isStatic()) {
ASSERT(string->isAtomic());
string->setIsAtomic(false);
}
}
delete table;
}
HashSet<StringImpl*> m_table;
};
static inline AtomicStringTable& getAtomicStringTable()
{
// Once possible we should make this non-lazy (constructed in WTFThreadData's constructor).
WTFThreadData& data = wtfThreadData();
AtomicStringTable* table = data.getAtomicStringTable();
if (UNLIKELY(!table))
table = AtomicStringTable::create(data);
return *table;
}
static inline HashSet<StringImpl*>& atomicStrings() static inline HashSet<StringImpl*>& atomicStrings()
{ {
return getAtomicStringTable().table(); return wtfThreadData().getAtomicStringTable().table();
} }
void AtomicString::reserveTableCapacity(size_t size) void AtomicString::reserveTableCapacity(size_t size)
{ {
getAtomicStringTable().table().reserveCapacityForSize(size); wtfThreadData().getAtomicStringTable().table().reserveCapacityForSize(size);
} }
template<typename T, typename HashTranslator> template<typename T, typename HashTranslator>
...@@ -371,7 +301,7 @@ PassRefPtr<StringImpl> AtomicString::add(const LChar* s, unsigned length) ...@@ -371,7 +301,7 @@ PassRefPtr<StringImpl> AtomicString::add(const LChar* s, unsigned length)
PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* string) PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* string)
{ {
return getAtomicStringTable().addStringImpl(string); return wtfThreadData().getAtomicStringTable().addStringImpl(string);
} }
template<typename CharacterType> template<typename CharacterType>
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "wtf/text/AtomicStringTable.h"
namespace WTF {
AtomicStringTable::AtomicStringTable()
{
for (StringImpl* string : StringImpl::allStaticStrings().values())
addStringImpl(string);
}
AtomicStringTable::~AtomicStringTable()
{
for (StringImpl* string : m_table) {
if (!string->isStatic()) {
DCHECK(string->isAtomic());
string->setIsAtomic(false);
}
}
}
StringImpl* AtomicStringTable::addStringImpl(StringImpl* string)
{
if (!string->length())
return StringImpl::empty();
StringImpl* result = *m_table.add(string).storedValue;
if (!result->isAtomic())
result->setIsAtomic(true);
DCHECK(!string->isStatic() || result->isStatic());
return result;
}
} // namespace WTF
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WTF_AtomicStringTable_h
#define WTF_AtomicStringTable_h
#include "wtf/Allocator.h"
#include "wtf/HashSet.h"
#include "wtf/text/StringHash.h"
#include "wtf/text/StringImpl.h"
namespace WTF {
// The underlying storage that keeps the map of unique AtomicStrings. This is
// not thread safe and each WTFThreadData has one.
class AtomicStringTable {
USING_FAST_MALLOC(AtomicStringTable);
WTF_MAKE_NONCOPYABLE(AtomicStringTable);
public:
AtomicStringTable();
~AtomicStringTable();
StringImpl* addStringImpl(StringImpl*);
HashSet<StringImpl*>& table() { return m_table; }
private:
HashSet<StringImpl*> m_table;
};
} // namespace WTF
#endif
...@@ -131,6 +131,8 @@ ...@@ -131,6 +131,8 @@
'text/AtomicString.h', 'text/AtomicString.h',
'text/AtomicStringCF.cpp', 'text/AtomicStringCF.cpp',
'text/AtomicStringHash.h', 'text/AtomicStringHash.h',
'text/AtomicStringTable.cpp',
'text/AtomicStringTable.h',
'text/Base64.cpp', 'text/Base64.cpp',
'text/Base64.h', 'text/Base64.h',
'text/CString.cpp', 'text/CString.cpp',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment