Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& 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.uid(), 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->outOfLineSize() > transition->outOfLineCapacity()) transition->growOutOfLineCapacity(); 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.uid(); 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->outOfLineSize() > transition->outOfLineCapacity()) transition->growOutOfLineCapacity(); transition->m_offset = offset; checkOffset(transition->m_offset, transition->inlineCapacity()); structure->m_transitionTable.add(globalData, transition); return transition; }
Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure* structure, NonPropertyTransition transitionKind) { unsigned attributes = toAttributes(transitionKind); IndexingType indexingType = newIndexingType(structure->indexingTypeIncludingHistory(), transitionKind); if (JSGlobalObject* globalObject = structure->m_globalObject.get()) { if (globalObject->isOriginalArrayStructure(structure)) { Structure* result = globalObject->originalArrayStructureForIndexingType(indexingType); if (result->indexingTypeIncludingHistory() == indexingType) { structure->notifyTransitionFromThisStructure(); return result; } } } if (Structure* existingTransition = structure->m_transitionTable.get(0, attributes)) { ASSERT(existingTransition->m_attributesInPrevious == attributes); ASSERT(existingTransition->indexingTypeIncludingHistory() == indexingType); return existingTransition; } Structure* transition = create(globalData, structure); transition->m_previous.set(globalData, transition, structure); transition->m_attributesInPrevious = attributes; transition->m_indexingType = indexingType; transition->m_offset = structure->m_offset; checkOffset(transition->m_offset, transition->inlineCapacity()); 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(); } structure->m_transitionTable.add(globalData, transition); return transition; }