+PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object)
+{
+ ASSERT(isDictionary());
+ if (isUncacheableDictionary()) {
+ ASSERT(m_propertyTable);
+ Vector<PropertyMapEntry*> sortedPropertyEntries(m_propertyTable->keyCount);
+ PropertyMapEntry** p = sortedPropertyEntries.data();
+ unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+ for (unsigned i = 1; i <= entryCount; i++) {
+ if (m_propertyTable->entries()[i].key)
+ *p++ = &m_propertyTable->entries()[i];
+ }
+ size_t propertyCount = p - sortedPropertyEntries.data();
+ qsort(sortedPropertyEntries.data(), propertyCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices);
+ sortedPropertyEntries.resize(propertyCount);
+
+ // We now have the properties currently defined on this object
+ // in the order that they are expected to be in, but we need to
+ // reorder the storage, so we have to copy the current values out
+ Vector<JSValue> values(propertyCount);
+ unsigned anonymousSlotCount = m_anonymousSlotCount;
+ for (unsigned i = 0; i < propertyCount; i++) {
+ PropertyMapEntry* entry = sortedPropertyEntries[i];
+ values[i] = object->getDirectOffset(entry->offset);
+ // Update property table to have the new property offsets
+ entry->offset = anonymousSlotCount + i;
+ entry->index = i;
+ }
+
+ // Copy the original property values into their final locations
+ for (unsigned i = 0; i < propertyCount; i++)
+ object->putDirectOffset(anonymousSlotCount + i, values[i]);
+
+ if (m_propertyTable->deletedOffsets) {
+ delete m_propertyTable->deletedOffsets;
+ m_propertyTable->deletedOffsets = 0;
+ }
+ }