Chromium Code Reviews| Index: Source/platform/heap/Visitor.cpp |
| diff --git a/Source/platform/heap/Visitor.cpp b/Source/platform/heap/Visitor.cpp |
| index 2119b23af627afbe162eb31f86cddbf1a4864682..fe6b82bf950be9ab08a61ee2767e3ecf0b7a497e 100644 |
| --- a/Source/platform/heap/Visitor.cpp |
| +++ b/Source/platform/heap/Visitor.cpp |
| @@ -36,13 +36,63 @@ |
| namespace blink { |
| -// gcInfoIndex should start from 1. |
| -// Since atomicIncrement(&s_gcInfoIndex) (which is defined in |
| -// RETURN_GCINFO_INDEX) returns an incremented value of s_gcInfoIndex, |
| -// the initial value of s_gcInfoIndex should be set to 0. |
| -int s_gcInfoIndex = 0; |
| +// GCInfo indices start from 1 for heap objects, with 0 being treated |
| +// specially as the index for freelist entries and large heap objects. |
| +int GCInfoTable::s_gcInfoIndex = 0; |
| + |
| +size_t GCInfoTable::s_gcInfoTableSize = 0; |
| GCInfo const** s_gcInfoTable = nullptr; |
| +size_t GCInfoTable::allocateGCInfoSlot() |
| +{ |
| + // FIXME: if multiple threads attempt to allocate the initial object |
| + // for a given type, there'll be a write race on updating the 'static' |
| + // holding its index. Duplicate GCInfo slots might be written for the |
|
haraken
2015/01/07 15:45:43
ah, this is a good point...
BTW, I begin to wonde
sof
2015/01/07 18:57:48
Yes, -fno-threadsafe-statics would be in effect th
|
| + // object, which is benign, but verify that the index update race is |
| + // acceptable. |
| + int index = atomicIncrement(&s_gcInfoIndex); |
| + size_t gcInfoIndex = static_cast<size_t>(index); |
| + ASSERT(gcInfoIndex < GCInfoTable::maxIndex); |
| + if (gcInfoIndex >= s_gcInfoTableSize) |
| + resize(gcInfoIndex); |
| + |
| + return gcInfoIndex; |
| +} |
| + |
| +void GCInfoTable::resize(size_t index) |
| +{ |
| + AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); |
| + MutexLocker locker(mutex); |
| + |
| + // Keep a lock while expanding the shared table; check |
| + // if another thread have already resized. |
| + if (index < s_gcInfoTableSize) |
| + return; |
| + |
| + // (Light) experimentation suggests that Blink doesn't need |
| + // more than this while handling content on popular web properties. |
| + const size_t initialSize = 512; |
| + |
| + size_t newSize = s_gcInfoTableSize ? 2 * s_gcInfoTableSize : initialSize; |
| + ASSERT(newSize < GCInfoTable::maxIndex); |
| + s_gcInfoTable = reinterpret_cast<GCInfo const**>(realloc(s_gcInfoTable, newSize * sizeof(GCInfo))); |
| + ASSERT(s_gcInfoTable); |
| + memset(reinterpret_cast<uint8_t*>(s_gcInfoTable) + s_gcInfoTableSize * sizeof(GCInfo), 0, (newSize - s_gcInfoTableSize) * sizeof(GCInfo)); |
| + s_gcInfoTableSize = newSize; |
| +} |
| + |
| +void GCInfoTable::init() |
| +{ |
| + RELEASE_ASSERT(!s_gcInfoTable); |
| + resize(0); |
| +} |
| + |
| +void GCInfoTable::shutdown() |
| +{ |
| + free(s_gcInfoTable); |
| + s_gcInfoTable = nullptr; |
| +} |
| + |
| int Visitor::m_traceDepth = 0; |
| #if ENABLE(ASSERT) |