Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { // If we have a specific function, we may have got to this point if there is // already a transition with the correct property name and attributes, but // specialized to a different function. In this case we just want to give up // and despecialize the transition. // In this case we clear the value of specificFunction which will result // in us adding a non-specific transition, and any subsequent lookup in // Structure::addPropertyTransitionToExistingStructure will just use that. if (specificValue && structure->m_transitionTable.contains(propertyName.impl(), attributes)) specificValue = 0; ASSERT(!structure->isDictionary()); ASSERT(structure->isObject()); ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) specificValue = 0; if (structure->transitionCount() > s_maxTransitionLength) { Structure* transition = toCacheableDictionaryTransition(globalData, structure); ASSERT(structure != transition); offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) transition->growPropertyStorageCapacity(); return transition; } Structure* transition = create(globalData, structure); transition->m_cachedPrototypeChain.setMayBeNull(globalData, transition, structure->m_cachedPrototypeChain.get()); transition->m_previous.set(globalData, transition, structure); transition->m_nameInPrevious = propertyName.impl(); transition->m_attributesInPrevious = attributes; transition->m_specificValueInPrevious.setMayBeNull(globalData, transition, specificValue); if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) transition->m_propertyTable = structure->m_propertyTable->copy(globalData, transition, structure->m_propertyTable->size() + 1); else transition->m_propertyTable = structure->m_propertyTable.release(); } else { if (structure->m_previous) transition->materializePropertyMap(globalData); else transition->createPropertyMap(); } offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) transition->growPropertyStorageCapacity(); transition->m_offset = offset; structure->m_transitionTable.add(globalData, transition); return transition; }