+bool StructureTransitionTable::contains(StringImpl* rep, unsigned attributes) const
+{
+ if (isUsingSingleSlot()) {
+ Structure* transition = singleTransition();
+ return transition && transition->m_nameInPrevious == rep && transition->m_attributesInPrevious == attributes;
+ }
+ return map()->contains(make_pair(rep, attributes));
+}
+
+inline Structure* StructureTransitionTable::get(StringImpl* rep, unsigned attributes) const
+{
+ if (isUsingSingleSlot()) {
+ Structure* transition = singleTransition();
+ return (transition && transition->m_nameInPrevious == rep && transition->m_attributesInPrevious == attributes) ? transition : 0;
+ }
+ return map()->get(make_pair(rep, attributes));
+}
+
+inline void StructureTransitionTable::remove(Structure* structure)
+{
+ if (isUsingSingleSlot()) {
+ // If more than one transition had been added, then we wouldn't be in
+ // single slot mode (even despecifying a from a specific value triggers
+ // map mode).
+ // As such, the passed structure *must* be the existing transition.
+ ASSERT(singleTransition() == structure);
+ clearSingleTransition();
+ } else {
+ // Check whether a mapping exists for structure's key, and whether the
+ // entry is structure (the latter check may fail if we initially had a
+ // transition with a specific value, and this has been despecified).
+
+ // Newer versions of the STL have an std::make_pair function that takes rvalue references.
+ // When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
+ // See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details
+ TransitionMap::iterator entry = map()->find(make_pair(structure->m_nameInPrevious, +structure->m_attributesInPrevious));
+ if (entry != map()->end() && structure == entry.get().second)
+ map()->remove(entry);
+ }
+}
+
+inline void StructureTransitionTable::add(JSGlobalData& globalData, Structure* structure)
+{
+ if (isUsingSingleSlot()) {
+ Structure* existingTransition = singleTransition();
+
+ // This handles the first transition being added.
+ if (!existingTransition) {
+ setSingleTransition(globalData, structure);
+ return;
+ }
+
+ // This handles the second transition being added
+ // (or the first transition being despecified!)
+ setMap(new TransitionMap());
+ add(globalData, existingTransition);
+ }
+
+ // Add the structure to the map.
+
+ // Newer versions of the STL have an std::make_pair function that takes rvalue references.
+ // When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
+ // See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details
+ std::pair<TransitionMap::iterator, bool> result = map()->add(globalData, make_pair(structure->m_nameInPrevious, +structure->m_attributesInPrevious), structure);
+ if (!result.second) {
+ // There already is an entry! - we should only hit this when despecifying.
+ ASSERT(result.first.get().second->m_specificValueInPrevious);
+ ASSERT(!structure->m_specificValueInPrevious);
+ map()->set(result.first, structure);
+ }
+}