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) |