summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/StructureTransitionTable.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/StructureTransitionTable.h')
-rw-r--r--Source/JavaScriptCore/runtime/StructureTransitionTable.h57
1 files changed, 50 insertions, 7 deletions
diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
index da78e1b..adebad2 100644
--- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -27,8 +27,8 @@
#define StructureTransitionTable_h
#include "UString.h"
+#include "WeakGCMap.h"
#include <wtf/HashFunctions.h>
-#include <wtf/HashMap.h>
#include <wtf/HashTraits.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
@@ -69,7 +69,21 @@ class StructureTransitionTable {
static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
};
- typedef HashMap<Hash::Key, Structure*, Hash, HashTraits> TransitionMap;
+ struct WeakGCMapFinalizerCallback {
+ static void* finalizerContextFor(Hash::Key)
+ {
+ return 0;
+ }
+
+ static inline Hash::Key keyForFinalizer(void* context, Structure* structure)
+ {
+ return keyForWeakGCMapFinalizer(context, structure);
+ }
+ };
+
+ typedef WeakGCMap<Hash::Key, Structure, WeakGCMapFinalizerCallback, Hash, HashTraits> TransitionMap;
+
+ static Hash::Key keyForWeakGCMapFinalizer(void* context, Structure*);
public:
StructureTransitionTable()
@@ -81,9 +95,11 @@ public:
{
if (!isUsingSingleSlot())
delete map();
+ else
+ clearSingleTransition();
}
- inline void add(Structure*);
+ inline void add(JSGlobalData&, Structure*);
inline void remove(Structure*);
inline bool contains(StringImpl* rep, unsigned attributes) const;
inline Structure* get(StringImpl* rep, unsigned attributes) const;
@@ -100,9 +116,18 @@ private:
return reinterpret_cast<TransitionMap*>(m_data);
}
+ HandleSlot slot() const
+ {
+ ASSERT(isUsingSingleSlot());
+ return reinterpret_cast<HandleSlot>(m_data & ~UsingSingleSlotFlag);
+ }
+
void setMap(TransitionMap* map)
{
ASSERT(isUsingSingleSlot());
+
+ if (HandleSlot slot = this->slot())
+ HandleHeap::heapFor(slot)->deallocate(slot);
// This implicitly clears the flag that indicates we're using a single transition
m_data = reinterpret_cast<intptr_t>(map);
@@ -113,13 +138,31 @@ private:
Structure* singleTransition() const
{
ASSERT(isUsingSingleSlot());
- return reinterpret_cast<Structure*>(m_data & ~UsingSingleSlotFlag);
+ if (HandleSlot slot = this->slot()) {
+ if (*slot)
+ return reinterpret_cast<Structure*>(slot->asCell());
+ }
+ return 0;
}
-
- void setSingleTransition(Structure* structure)
+
+ void clearSingleTransition()
{
ASSERT(isUsingSingleSlot());
- m_data = reinterpret_cast<intptr_t>(structure) | UsingSingleSlotFlag;
+ if (HandleSlot slot = this->slot())
+ HandleHeap::heapFor(slot)->deallocate(slot);
+ }
+
+ void setSingleTransition(JSGlobalData& globalData, Structure* structure)
+ {
+ ASSERT(isUsingSingleSlot());
+ HandleSlot slot = this->slot();
+ if (!slot) {
+ slot = globalData.allocateGlobalHandle();
+ HandleHeap::heapFor(slot)->makeWeak(slot, 0, 0);
+ m_data = reinterpret_cast<intptr_t>(slot) | UsingSingleSlotFlag;
+ }
+ HandleHeap::heapFor(slot)->writeBarrier(slot, reinterpret_cast<JSCell*>(structure));
+ *slot = reinterpret_cast<JSCell*>(structure);
}
intptr_t m_data;