summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime/Structure.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/runtime/Structure.h')
-rw-r--r--JavaScriptCore/runtime/Structure.h86
1 files changed, 27 insertions, 59 deletions
diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h
index 95cf94c..f480051 100644
--- a/JavaScriptCore/runtime/Structure.h
+++ b/JavaScriptCore/runtime/Structure.h
@@ -106,20 +106,20 @@ namespace JSC {
bool isUsingInlineStorage() const;
size_t get(const Identifier& propertyName);
- size_t get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue);
+ size_t get(const StringImpl* rep, unsigned& attributes, JSCell*& specificValue);
size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
{
ASSERT(!propertyName.isNull());
- return get(propertyName.ustring().rep(), attributes, specificValue);
+ return get(propertyName.impl(), attributes, specificValue);
}
bool transitionedFor(const JSCell* specificValue)
{
return m_specificValueInPrevious == specificValue;
}
- bool hasTransition(UString::Rep*, unsigned attributes);
+ bool hasTransition(StringImpl*, unsigned attributes);
bool hasTransition(const Identifier& propertyName, unsigned attributes)
{
- return hasTransition(propertyName._ustring.rep(), attributes);
+ return hasTransition(propertyName.impl(), attributes);
}
bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
@@ -179,6 +179,20 @@ namespace JSC {
// Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
return m_offset == noOffset ? 0 : m_offset + 1;
}
+
+ typedef std::pair<Structure*, Structure*> Transition;
+ typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable;
+
+ inline bool transitionTableContains(const StructureTransitionTableHash::Key& key, JSCell* specificValue);
+ inline void transitionTableRemove(const StructureTransitionTableHash::Key& key, JSCell* specificValue);
+ inline void transitionTableAdd(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue);
+ inline bool transitionTableHasTransition(const StructureTransitionTableHash::Key& key) const;
+ inline Structure* transitionTableGet(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const;
+
+ TransitionTable* transitionTable() const { ASSERT(!m_isUsingSingleSlot); return m_transitions.m_table; }
+ inline void setTransitionTable(TransitionTable* table);
+ Structure* singleTransition() const { ASSERT(m_isUsingSingleSlot); return m_transitions.m_singleTransition; }
+ void setSingleTransition(Structure* structure) { ASSERT(m_isUsingSingleSlot); m_transitions.m_singleTransition = structure; }
bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
@@ -196,10 +210,14 @@ namespace JSC {
mutable RefPtr<StructureChain> m_cachedPrototypeChain;
RefPtr<Structure> m_previous;
- RefPtr<UString::Rep> m_nameInPrevious;
+ RefPtr<StringImpl> m_nameInPrevious;
JSCell* m_specificValueInPrevious;
- StructureTransitionTable table;
+ // 'm_isUsingSingleSlot' indicates whether we are using the single transition optimisation.
+ union {
+ TransitionTable* m_table;
+ Structure* m_singleTransition;
+ } m_transitions;
WeakGCPtr<JSPropertyNameIterator> m_enumerationCache;
@@ -224,7 +242,8 @@ namespace JSC {
#endif
unsigned m_specificFunctionThrashCount : 2;
unsigned m_anonymousSlotCount : 5;
- // 5 free bits
+ unsigned m_isUsingSingleSlot : 1;
+ // 4 free bits
};
inline size_t Structure::get(const Identifier& propertyName)
@@ -235,7 +254,7 @@ namespace JSC {
if (!m_propertyTable)
return WTF::notFound;
- UString::Rep* rep = propertyName._ustring.rep();
+ StringImpl* rep = propertyName.impl();
unsigned i = rep->existingHash();
@@ -271,58 +290,7 @@ namespace JSC {
return m_propertyTable->entries()[entryIndex - 1].offset;
}
}
-
- bool StructureTransitionTable::contains(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
- {
- if (usingSingleTransitionSlot()) {
- Structure* existingTransition = singleTransition();
- return existingTransition && existingTransition->m_nameInPrevious.get() == key.first
- && existingTransition->m_attributesInPrevious == key.second
- && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0);
- }
- TransitionTable::iterator find = table()->find(key);
- if (find == table()->end())
- return false;
-
- return find->second.first || find->second.second->transitionedFor(specificValue);
- }
- Structure* StructureTransitionTable::get(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const
- {
- if (usingSingleTransitionSlot()) {
- Structure* existingTransition = singleTransition();
- if (existingTransition && existingTransition->m_nameInPrevious.get() == key.first
- && existingTransition->m_attributesInPrevious == key.second
- && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0))
- return existingTransition;
- return 0;
- }
-
- Transition transition = table()->get(key);
- if (transition.second && transition.second->transitionedFor(specificValue))
- return transition.second;
- return transition.first;
- }
-
- bool StructureTransitionTable::hasTransition(const StructureTransitionTableHash::Key& key) const
- {
- if (usingSingleTransitionSlot()) {
- Structure* transition = singleTransition();
- return transition && transition->m_nameInPrevious == key.first
- && transition->m_attributesInPrevious == key.second;
- }
- return table()->contains(key);
- }
-
- void StructureTransitionTable::reifySingleTransition()
- {
- ASSERT(usingSingleTransitionSlot());
- Structure* existingTransition = singleTransition();
- TransitionTable* transitionTable = new TransitionTable;
- setTransitionTable(transitionTable);
- if (existingTransition)
- add(std::make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious);
- }
} // namespace JSC
#endif // Structure_h