void Structure::materializePropertyMap(VM& vm) { ASSERT(structure()->classInfo() == info()); ASSERT(!propertyTable()); Vector<Structure*, 8> structures; Structure* structure; PropertyTable* table; findStructuresAndMapForMaterialization(structures, structure, table); if (table) { table = table->copy(vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)); structure->m_lock.unlock(); } // Must hold the lock on this structure, since we will be modifying this structure's // property map. We don't want getConcurrently() to see the property map in a half-baked // state. GCSafeConcurrentJITLocker locker(m_lock, vm.heap); if (!table) createPropertyMap(locker, vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)); else propertyTable().set(vm, this, table); for (size_t i = structures.size(); i--;) { structure = structures[i]; if (!structure->m_nameInPrevious) continue; PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->attributesInPrevious()); propertyTable()->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange); } checkOffsetConsistency(); }
void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor) { PropertyTable* thisObject = jsCast<PropertyTable*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); JSCell::visitChildren(thisObject, visitor); PropertyTable::iterator end = thisObject->end(); for (PropertyTable::iterator ptr = thisObject->begin(); ptr != end; ++ptr) visitor.append(&ptr->specificValue); }
PropertyTable::PropertyTable(const PropertyTable &other) : QObject() { // Reparent. setParent(other.parent()); // We just copy one container from another. m_properties = other.m_properties; }
PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity, const PropertyTable& other) : JSCell(vm, vm.propertyTableStructure.get()) , m_indexSize(sizeForCapacity(initialCapacity)) , m_indexMask(m_indexSize - 1) , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize()))) , m_keyCount(0) , m_deletedCount(0) { ASSERT(isPowerOf2(m_indexSize)); ASSERT(initialCapacity >= other.m_keyCount); const_iterator end = other.end(); for (const_iterator iter = other.begin(); iter != end; ++iter) { ASSERT(canInsert()); reinsert(*iter); iter->key->ref(); } // Copy the m_deletedOffsets vector. Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get(); if (otherDeletedOffsets) m_deletedOffsets = std::make_unique<Vector<PropertyOffset>>(*otherDeletedOffsets); }
void Structure::willStoreValueSlow( VM& vm, PropertyName propertyName, JSValue value, bool shouldOptimize, InferredTypeTable::StoredPropertyAge age) { ASSERT(!isCompilationThread()); ASSERT(structure()->classInfo() == info()); ASSERT(!hasBeenDictionary()); // Create the inferred type table before doing anything else, so that we don't GC after we have already // grabbed a pointer into the property map. InferredTypeTable* table = m_inferredTypeTable.get(); if (!table) { table = InferredTypeTable::create(vm); WTF::storeStoreFence(); m_inferredTypeTable.set(vm, this, table); } // This only works if we've got a property table. PropertyTable* propertyTable; materializePropertyMapIfNecessary(vm, propertyTable); // We must be calling this after having created the given property or confirmed that it was present // already, so we must have a property table now. ASSERT(propertyTable); // ... and the property must be present. PropertyMapEntry* entry = propertyTable->get(propertyName.uid()); ASSERT(entry); if (shouldOptimize) entry->hasInferredType = table->willStoreValue(vm, propertyName, value, age); else { table->makeTop(vm, propertyName, age); entry->hasInferredType = false; } }
PropertyTable* PropertyTable::clone(VM& vm, JSCell* owner, unsigned initialCapacity, const PropertyTable& other) { PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, owner, initialCapacity, other); table->finishCreation(vm); return table; }
PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity) { PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity); table->finishCreation(vm); return table; }
PropertyTable* PropertyTable::clone(VM& vm, const PropertyTable& other) { PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, other); table->finishCreation(vm); return table; }