Title: [170436] branches/ftlopt/Source/_javascript_Core
Revision
170436
Author
mhahnenb...@apple.com
Date
2014-06-25 14:15:37 -0700 (Wed, 25 Jun 2014)

Log Message

Structure bit fields should have a consistent format
https://bugs.webkit.org/show_bug.cgi?id=134307

Reviewed by Filip Pizlo.

Currently we use C-style bit fields for a number of member variables in Structure to save space. 
This makes it difficult to load these fields in the JIT. We should instead use our own bitfield 
format to make it easy to load and test these variables in JIT code.

* runtime/JSObject.cpp:
(JSC::JSObject::putDirectNonIndexAccessor):
(JSC::JSObject::reifyStaticFunctionsForDelete):
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::contains):
(JSC::StructureTransitionTable::get):
(JSC::StructureTransitionTable::add):
(JSC::Structure::Structure):
(JSC::Structure::materializePropertyMap):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::despecifyFunctionTransition):
(JSC::Structure::toDictionaryTransition):
(JSC::Structure::freezeTransition):
(JSC::Structure::preventExtensionsTransition):
(JSC::Structure::takePropertyTableOrCloneIfPinned):
(JSC::Structure::nonPropertyTransition):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::addPropertyWithoutTransition):
(JSC::Structure::pin):
(JSC::Structure::allocateRareData):
(JSC::Structure::cloneRareDataFrom):
(JSC::Structure::getConcurrently):
(JSC::Structure::putSpecificValue):
(JSC::Structure::getPropertyNamesFromStructure):
(JSC::Structure::visitChildren):
(JSC::Structure::checkConsistency):
* runtime/Structure.h:
(JSC::Structure::isExtensible):
(JSC::Structure::isDictionary):
(JSC::Structure::isUncacheableDictionary):
(JSC::Structure::propertyAccessesAreCacheable):
(JSC::Structure::previousID):
(JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck):
(JSC::Structure::setContainsReadOnlyProperties):
(JSC::Structure::disableSpecificFunctionTracking):
(JSC::Structure::objectToStringValue):
(JSC::Structure::setObjectToStringValue):
(JSC::Structure::setPreviousID):
(JSC::Structure::clearPreviousID):
(JSC::Structure::previous):
(JSC::Structure::rareData):
(JSC::Structure::didTransition): Deleted.
(JSC::Structure::hasGetterSetterProperties): Deleted.
(JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto): Deleted.
(JSC::Structure::setHasGetterSetterProperties): Deleted.
(JSC::Structure::hasNonEnumerableProperties): Deleted.
(JSC::Structure::staticFunctionsReified): Deleted.
(JSC::Structure::setStaticFunctionsReified): Deleted.
* runtime/StructureInlines.h:
(JSC::Structure::setEnumerationCache):
(JSC::Structure::enumerationCache):
(JSC::Structure::checkOffsetConsistency):

Modified Paths

Diff

Modified: branches/ftlopt/Source/_javascript_Core/ChangeLog (170435 => 170436)


--- branches/ftlopt/Source/_javascript_Core/ChangeLog	2014-06-25 21:04:17 UTC (rev 170435)
+++ branches/ftlopt/Source/_javascript_Core/ChangeLog	2014-06-25 21:15:37 UTC (rev 170436)
@@ -1,3 +1,67 @@
+2014-06-25  Mark Hahnenberg  <mhahnenb...@apple.com>
+
+        Structure bit fields should have a consistent format
+        https://bugs.webkit.org/show_bug.cgi?id=134307
+
+        Reviewed by Filip Pizlo.
+
+        Currently we use C-style bit fields for a number of member variables in Structure to save space. 
+        This makes it difficult to load these fields in the JIT. We should instead use our own bitfield 
+        format to make it easy to load and test these variables in JIT code.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectNonIndexAccessor):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::contains):
+        (JSC::StructureTransitionTable::get):
+        (JSC::StructureTransitionTable::add):
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::freezeTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::takePropertyTableOrCloneIfPinned):
+        (JSC::Structure::nonPropertyTransition):
+        (JSC::Structure::flattenDictionaryStructure):
+        (JSC::Structure::addPropertyWithoutTransition):
+        (JSC::Structure::pin):
+        (JSC::Structure::allocateRareData):
+        (JSC::Structure::cloneRareDataFrom):
+        (JSC::Structure::getConcurrently):
+        (JSC::Structure::putSpecificValue):
+        (JSC::Structure::getPropertyNamesFromStructure):
+        (JSC::Structure::visitChildren):
+        (JSC::Structure::checkConsistency):
+        * runtime/Structure.h:
+        (JSC::Structure::isExtensible):
+        (JSC::Structure::isDictionary):
+        (JSC::Structure::isUncacheableDictionary):
+        (JSC::Structure::propertyAccessesAreCacheable):
+        (JSC::Structure::previousID):
+        (JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck):
+        (JSC::Structure::setContainsReadOnlyProperties):
+        (JSC::Structure::disableSpecificFunctionTracking):
+        (JSC::Structure::objectToStringValue):
+        (JSC::Structure::setObjectToStringValue):
+        (JSC::Structure::setPreviousID):
+        (JSC::Structure::clearPreviousID):
+        (JSC::Structure::previous):
+        (JSC::Structure::rareData):
+        (JSC::Structure::didTransition): Deleted.
+        (JSC::Structure::hasGetterSetterProperties): Deleted.
+        (JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto): Deleted.
+        (JSC::Structure::setHasGetterSetterProperties): Deleted.
+        (JSC::Structure::hasNonEnumerableProperties): Deleted.
+        (JSC::Structure::staticFunctionsReified): Deleted.
+        (JSC::Structure::setStaticFunctionsReified): Deleted.
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setEnumerationCache):
+        (JSC::Structure::enumerationCache):
+        (JSC::Structure::checkOffsetConsistency):
+
 2014-06-24  Mark Lam  <mark....@apple.com>
 
         [ftlopt] Renamed DebuggerActivation to DebuggerScope.

Modified: branches/ftlopt/Source/_javascript_Core/runtime/JSObject.cpp (170435 => 170436)


--- branches/ftlopt/Source/_javascript_Core/runtime/JSObject.cpp	2014-06-25 21:04:17 UTC (rev 170435)
+++ branches/ftlopt/Source/_javascript_Core/runtime/JSObject.cpp	2014-06-25 21:15:37 UTC (rev 170436)
@@ -1239,7 +1239,7 @@
     if (attributes & ReadOnly)
         structure->setContainsReadOnlyProperties();
 
-    structure->setHasGetterSetterProperties(propertyName == vm.propertyNames->underscoreProto);
+    structure->setHasGetterSetterPropertiesWithProtoCheck(propertyName == vm.propertyNames->underscoreProto);
 }
 
 bool JSObject::hasProperty(ExecState* exec, PropertyName propertyName) const
@@ -1617,7 +1617,7 @@
     // If this object's ClassInfo has no static properties, then nothing to reify!
     // We can safely set the flag to avoid the expensive check again in the future.
     if (!classInfo()->hasStaticProperties()) {
-        structure(vm)->setStaticFunctionsReified();
+        structure(vm)->setStaticFunctionsReified(true);
         return;
     }
 
@@ -1635,7 +1635,7 @@
         }
     }
 
-    structure(vm)->setStaticFunctionsReified();
+    structure(vm)->setStaticFunctionsReified(true);
 }
 
 bool JSObject::removeDirect(VM& vm, PropertyName propertyName)

Modified: branches/ftlopt/Source/_javascript_Core/runtime/Structure.cpp (170435 => 170436)


--- branches/ftlopt/Source/_javascript_Core/runtime/Structure.cpp	2014-06-25 21:04:17 UTC (rev 170435)
+++ branches/ftlopt/Source/_javascript_Core/runtime/Structure.cpp	2014-06-25 21:15:37 UTC (rev 170436)
@@ -71,7 +71,7 @@
 {
     if (isUsingSingleSlot()) {
         Structure* transition = singleTransition();
-        return transition && transition->m_nameInPrevious == rep && transition->m_attributesInPrevious == attributes;
+        return transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes;
     }
     return map()->get(std::make_pair(rep, attributes));
 }
@@ -80,7 +80,7 @@
 {
     if (isUsingSingleSlot()) {
         Structure* transition = singleTransition();
-        return (transition && transition->m_nameInPrevious == rep && transition->m_attributesInPrevious == attributes) ? transition : 0;
+        return (transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes) ? transition : 0;
     }
     return map()->get(std::make_pair(rep, attributes));
 }
@@ -107,7 +107,7 @@
     // 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
-    map()->set(std::make_pair(structure->m_nameInPrevious.get(), +structure->m_attributesInPrevious), structure);
+    map()->set(std::make_pair(structure->m_nameInPrevious.get(), +structure->attributesInPrevious()), structure);
 }
 
 void Structure::dumpStatistics()
@@ -165,21 +165,23 @@
     , m_transitionWatchpointSet(IsWatched)
     , m_offset(invalidOffset)
     , m_inlineCapacity(inlineCapacity)
-    , m_dictionaryKind(NoneDictionaryKind)
-    , m_isPinnedPropertyTable(false)
-    , m_hasGetterSetterProperties(classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasNonEnumerableProperties(false)
-    , m_attributesInPrevious(0)
-    , m_specificFunctionThrashCount(0)
-    , m_preventExtensions(false)
-    , m_didTransition(false)
-    , m_staticFunctionReified(false)
-    , m_hasRareData(false)
+    , m_bitField(0)
 {
+    setDictionaryKind(NoneDictionaryKind);
+    setIsPinnedPropertyTable(false);
+    setHasGetterSetterProperties(classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    setHasNonEnumerableProperties(false);
+    setAttributesInPrevious(0);
+    setSpecificFunctionThrashCount(0);
+    setPreventExtensions(false);
+    setDidTransition(false);
+    setStaticFunctionsReified(false);
+    setHasRareData(false);
+
     ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
     ASSERT(static_cast<PropertyOffset>(inlineCapacity) < firstOutOfLineOffset);
-    ASSERT(!m_hasRareData);
+    ASSERT(!hasRareData());
     ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
     ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
 }
@@ -193,18 +195,20 @@
     , m_transitionWatchpointSet(IsWatched)
     , m_offset(invalidOffset)
     , m_inlineCapacity(0)
-    , m_dictionaryKind(NoneDictionaryKind)
-    , m_isPinnedPropertyTable(false)
-    , m_hasGetterSetterProperties(m_classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasNonEnumerableProperties(false)
-    , m_attributesInPrevious(0)
-    , m_specificFunctionThrashCount(0)
-    , m_preventExtensions(false)
-    , m_didTransition(false)
-    , m_staticFunctionReified(false)
-    , m_hasRareData(false)
+    , m_bitField(0)
 {
+    setDictionaryKind(NoneDictionaryKind);
+    setIsPinnedPropertyTable(false);
+    setHasGetterSetterProperties(m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    setHasNonEnumerableProperties(false);
+    setAttributesInPrevious(0);
+    setSpecificFunctionThrashCount(0);
+    setPreventExtensions(false);
+    setDidTransition(false);
+    setStaticFunctionsReified(false);
+    setHasRareData(false);
+
     TypeInfo typeInfo = TypeInfo(CellType, OverridesVisitChildren | StructureIsImmortal);
     m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo);
     m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
@@ -220,24 +224,26 @@
     , m_transitionWatchpointSet(IsWatched)
     , m_offset(invalidOffset)
     , m_inlineCapacity(previous->m_inlineCapacity)
-    , m_dictionaryKind(previous->m_dictionaryKind)
-    , m_isPinnedPropertyTable(false)
-    , m_hasGetterSetterProperties(previous->m_hasGetterSetterProperties)
-    , m_hasReadOnlyOrGetterSetterPropertiesExcludingProto(previous->m_hasReadOnlyOrGetterSetterPropertiesExcludingProto)
-    , m_hasNonEnumerableProperties(previous->m_hasNonEnumerableProperties)
-    , m_attributesInPrevious(0)
-    , m_specificFunctionThrashCount(previous->m_specificFunctionThrashCount)
-    , m_preventExtensions(previous->m_preventExtensions)
-    , m_didTransition(true)
-    , m_staticFunctionReified(previous->m_staticFunctionReified)
-    , m_hasRareData(false)
+    , m_bitField(0)
 {
+    setDictionaryKind(previous->dictionaryKind());
+    setIsPinnedPropertyTable(false);
+    setHasGetterSetterProperties(previous->hasGetterSetterProperties());
+    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(previous->hasReadOnlyOrGetterSetterPropertiesExcludingProto());
+    setHasNonEnumerableProperties(previous->hasNonEnumerableProperties());
+    setAttributesInPrevious(0);
+    setSpecificFunctionThrashCount(previous->specificFunctionThrashCount());
+    setPreventExtensions(previous->preventExtensions());
+    setDidTransition(true);
+    setStaticFunctionsReified(previous->staticFunctionsReified());
+    setHasRareData(false);
+
     TypeInfo typeInfo = previous->typeInfo();
     m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingTypeIncludingHistory(), typeInfo);
     m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
 
     ASSERT(!previous->typeInfo().structureIsImmortal());
-    if (previous->m_hasRareData && previous->rareData()->needsCloning())
+    if (previous->hasRareData() && previous->rareData()->needsCloning())
         cloneRareDataFrom(vm, previous);
     else if (previous->previousID())
         m_previousOrRareData.set(vm, this, previous->previousID());
@@ -313,7 +319,7 @@
         structure = structures[i];
         if (!structure->m_nameInPrevious)
             continue;
-        PropertyMapEntry entry(vm, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get());
+        PropertyMapEntry entry(vm, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->attributesInPrevious(), structure->m_specificValueInPrevious.get());
         propertyTable()->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
     }
     
@@ -420,7 +426,7 @@
     ASSERT(structure->isObject());
     ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
     
-    if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+    if (structure->specificFunctionThrashCount() == maxSpecificFunctionThrashCount)
         specificValue = 0;
 
     int maxTransitionLength;
@@ -440,7 +446,7 @@
     transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
     transition->setPreviousID(vm, transition, structure);
     transition->m_nameInPrevious = propertyName.uid();
-    transition->m_attributesInPrevious = attributes;
+    transition->setAttributesInPrevious(attributes);
     transition->m_specificValueInPrevious.setMayBeNull(vm, transition, specificValue);
     transition->propertyTable().set(vm, transition, structure->takePropertyTableOrCloneIfPinned(vm, transition));
     transition->m_offset = structure->m_offset;
@@ -487,10 +493,10 @@
 
 Structure* Structure::despecifyFunctionTransition(VM& vm, Structure* structure, PropertyName replaceFunction)
 {
-    ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
+    ASSERT(structure->specificFunctionThrashCount() < maxSpecificFunctionThrashCount);
     Structure* transition = create(vm, structure);
 
-    ++transition->m_specificFunctionThrashCount;
+    transition->setSpecificFunctionThrashCount(transition->specificFunctionThrashCount() + 1);
 
     DeferGC deferGC(vm.heap);
     structure->materializePropertyMapIfNecessary(vm, deferGC);
@@ -498,7 +504,7 @@
     transition->m_offset = structure->m_offset;
     transition->pin();
 
-    if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+    if (transition->specificFunctionThrashCount() == maxSpecificFunctionThrashCount)
         transition->despecifyAllFunctions(vm);
     else {
         bool removed = transition->despecifyFunction(vm, replaceFunction);
@@ -542,7 +548,7 @@
     structure->materializePropertyMapIfNecessary(vm, deferGC);
     transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
     transition->m_offset = structure->m_offset;
-    transition->m_dictionaryKind = kind;
+    transition->setDictionaryKind(kind);
     transition->pin();
 
     transition->checkOffsetConsistency();
@@ -583,7 +589,7 @@
         PropertyTable::iterator iter = transition->propertyTable()->begin();
         PropertyTable::iterator end = transition->propertyTable()->end();
         if (iter != end)
-            transition->m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+            transition->setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
         for (; iter != end; ++iter)
             iter->attributes |= iter->attributes & Accessor ? DontDelete : (DontDelete | ReadOnly);
     }
@@ -605,7 +611,7 @@
     structure->materializePropertyMapIfNecessary(vm, deferGC);
     transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
     transition->m_offset = structure->m_offset;
-    transition->m_preventExtensions = true;
+    transition->setPreventExtensions(true);
     transition->pin();
 
     transition->checkOffsetConsistency();
@@ -617,7 +623,7 @@
     DeferGC deferGC(vm.heap);
     materializePropertyMapIfNecessaryForPinning(vm, deferGC);
     
-    if (m_isPinnedPropertyTable)
+    if (isPinnedPropertyTable())
         return propertyTable()->copy(vm, owner, propertyTable()->size() + 1);
     
     // Hold the lock while stealing the table - so that getConcurrently() on another thread
@@ -645,14 +651,14 @@
     }
     
     if (Structure* existingTransition = structure->m_transitionTable.get(0, attributes)) {
-        ASSERT(existingTransition->m_attributesInPrevious == attributes);
+        ASSERT(existingTransition->attributesInPrevious() == attributes);
         ASSERT(existingTransition->indexingTypeIncludingHistory() == indexingType);
         return existingTransition;
     }
     
     Structure* transition = create(vm, structure);
     transition->setPreviousID(vm, transition, structure);
-    transition->m_attributesInPrevious = attributes;
+    transition->setAttributesInPrevious(attributes);
     transition->m_blob.setIndexingType(indexingType);
     transition->propertyTable().set(vm, transition, structure->takePropertyTableOrCloneIfPinned(vm, transition));
     transition->m_offset = structure->m_offset;
@@ -735,7 +741,7 @@
         checkOffsetConsistency();
     }
 
-    m_dictionaryKind = NoneDictionaryKind;
+    setDictionaryKind(NoneDictionaryKind);
 
     // If the object had a Butterfly but after flattening/compacting we no longer have need of it,
     // we need to zero it out because the collector depends on the Structure to know the size for copying.
@@ -749,7 +755,7 @@
 {
     ASSERT(!enumerationCache());
 
-    if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+    if (specificFunctionThrashCount() == maxSpecificFunctionThrashCount)
         specificValue = 0;
 
     DeferGC deferGC(vm.heap);
@@ -775,28 +781,28 @@
 void Structure::pin()
 {
     ASSERT(propertyTable());
-    m_isPinnedPropertyTable = true;
+    setIsPinnedPropertyTable(true);
     clearPreviousID();
     m_nameInPrevious.clear();
 }
 
 void Structure::allocateRareData(VM& vm)
 {
-    ASSERT(!m_hasRareData);
+    ASSERT(!hasRareData());
     StructureRareData* rareData = StructureRareData::create(vm, previous());
     m_previousOrRareData.set(vm, this, rareData);
-    m_hasRareData = true;
-    ASSERT(m_hasRareData);
+    setHasRareData(true);
+    ASSERT(hasRareData());
 }
 
 void Structure::cloneRareDataFrom(VM& vm, const Structure* other)
 {
-    ASSERT(!m_hasRareData);
-    ASSERT(other->m_hasRareData);
+    ASSERT(!hasRareData());
+    ASSERT(other->hasRareData());
     StructureRareData* newRareData = StructureRareData::clone(vm, other->rareData());
     m_previousOrRareData.set(vm, this, newRareData);
-    m_hasRareData = true;
-    ASSERT(m_hasRareData);
+    setHasRareData(true);
+    ASSERT(hasRareData());
 }
 
 #if DUMP_PROPERTYMAP_STATS
@@ -866,7 +872,7 @@
         if (structure->m_nameInPrevious.get() != uid)
             continue;
         
-        attributes = structure->m_attributesInPrevious;
+        attributes = structure->attributesInPrevious();
         specificValue = structure->m_specificValueInPrevious.get();
         return structure->m_offset;
     }
@@ -929,7 +935,7 @@
 
     checkConsistency();
     if (attributes & DontEnum)
-        m_hasNonEnumerableProperties = true;
+        setHasNonEnumerableProperties(true);
 
     StringImpl* rep = propertyName.uid();
 
@@ -987,7 +993,7 @@
 
     PropertyTable::iterator end = propertyTable()->end();
     for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
-        ASSERT(m_hasNonEnumerableProperties || !(iter->attributes & DontEnum));
+        ASSERT(hasNonEnumerableProperties() || !(iter->attributes & DontEnum));
         if (!iter->key->isEmptyUnique() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) {
             if (knownUnique)
                 propertyNames.addKnownUnique(iter->key);
@@ -1019,7 +1025,7 @@
     visitor.append(&thisObject->m_previousOrRareData);
     visitor.append(&thisObject->m_specificValueInPrevious);
 
-    if (thisObject->m_isPinnedPropertyTable) {
+    if (thisObject->isPinnedPropertyTable()) {
         ASSERT(thisObject->m_propertyTableUnsafe);
         visitor.append(&thisObject->m_propertyTableUnsafe);
     } else if (thisObject->m_propertyTableUnsafe)
@@ -1181,7 +1187,7 @@
     if (!propertyTable())
         return;
 
-    if (!m_hasNonEnumerableProperties) {
+    if (!hasNonEnumerableProperties()) {
         PropertyTable::iterator end = propertyTable()->end();
         for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
             ASSERT(!(iter->attributes & DontEnum));

Modified: branches/ftlopt/Source/_javascript_Core/runtime/Structure.h (170435 => 170436)


--- branches/ftlopt/Source/_javascript_Core/runtime/Structure.h	2014-06-25 21:04:17 UTC (rev 170435)
+++ branches/ftlopt/Source/_javascript_Core/runtime/Structure.h	2014-06-25 21:15:37 UTC (rev 170436)
@@ -127,8 +127,7 @@
 
     JS_EXPORT_PRIVATE bool isSealed(VM&);
     JS_EXPORT_PRIVATE bool isFrozen(VM&);
-    bool isExtensible() const { return !m_preventExtensions; }
-    bool didTransition() const { return m_didTransition; }
+    bool isExtensible() const { return !preventExtensions(); }
     bool putWillGrowOutOfLineStorage();
     JS_EXPORT_PRIVATE size_t suggestedNewOutOfLineStorageCapacity(); 
 
@@ -143,10 +142,10 @@
     PropertyOffset removePropertyWithoutTransition(VM&, PropertyName);
     void setPrototypeWithoutTransition(VM& vm, JSValue prototype) { m_prototype.set(vm, this, prototype); }
         
-    bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
-    bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
+    bool isDictionary() const { return dictionaryKind() != NoneDictionaryKind; }
+    bool isUncacheableDictionary() const { return dictionaryKind() == UncachedDictionaryKind; }
 
-    bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
+    bool propertyAccessesAreCacheable() { return dictionaryKind() != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
 
     // We use SlowPath in GetByIdStatus for structures that may get new impure properties later to prevent
     // DFG from inlining property accesses since structures don't transition when a new impure property appears.
@@ -193,7 +192,7 @@
     Structure* previousID() const
     {
         ASSERT(structure()->classInfo() == info());
-        if (m_hasRareData)
+        if (hasRareData())
             return rareData()->previousID();
         return previous();
     }
@@ -268,21 +267,15 @@
     PropertyOffset getConcurrently(VM&, StringImpl* uid);
     PropertyOffset getConcurrently(VM&, StringImpl* uid, unsigned& attributes, JSCell*& specificValue);
 
-    bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
-    bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
-    void setHasGetterSetterProperties(bool is__proto__)
+    void setHasGetterSetterPropertiesWithProtoCheck(bool is__proto__)
     {
-        m_hasGetterSetterProperties = true;
+        setHasGetterSetterProperties(true);
         if (!is__proto__)
-            m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+            setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
     }
-    void setContainsReadOnlyProperties()
-    {
-        m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
-    }
 
-    bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
-        
+    void setContainsReadOnlyProperties() { setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true); }
+
     bool isEmpty() const
     {
         ASSERT(checkOffsetConsistency());
@@ -290,7 +283,7 @@
     }
 
     JS_EXPORT_PRIVATE void despecifyDictionaryFunction(VM&, PropertyName);
-    void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
+    void disableSpecificFunctionTracking() { setSpecificFunctionThrashCount(maxSpecificFunctionThrashCount); }
 
     void setEnumerationCache(VM&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
     JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
@@ -298,28 +291,18 @@
 
     JSString* objectToStringValue()
     {
-        if (!m_hasRareData)
+        if (!hasRareData())
             return 0;
         return rareData()->objectToStringValue();
     }
 
     void setObjectToStringValue(VM& vm, const JSCell* owner, JSString* value)
     {
-        if (!m_hasRareData)
+        if (!hasRareData())
             allocateRareData(vm);
         rareData()->setObjectToStringValue(vm, owner, value);
     }
 
-    bool staticFunctionsReified()
-    {
-        return m_staticFunctionReified;
-    }
-
-    void setStaticFunctionsReified()
-    {
-        m_staticFunctionReified = true;
-    }
-
     const ClassInfo* classInfo() const { return m_classInfo; }
 
     static ptrdiff_t structureIDOffset()
@@ -400,6 +383,36 @@
     DECLARE_EXPORT_INFO;
 
 private:
+    typedef enum { 
+        NoneDictionaryKind = 0,
+        CachedDictionaryKind = 1,
+        UncachedDictionaryKind = 2
+    } DictionaryKind;
+
+public:
+#define DEFINE_BITFIELD(type, lowerName, upperName, width, offset) \
+    static const uint32_t s_##lowerName##Shift = offset;\
+    static const uint32_t s_##lowerName##Mask = ((1 << (width - 1)) | ((1 << (width - 1)) - 1));\
+    type lowerName() const { return static_cast<type>((m_bitField >> offset) & s_##lowerName##Mask); }\
+    void set##upperName(type newValue) \
+    {\
+        m_bitField &= ~(s_##lowerName##Mask << offset);\
+        m_bitField |= (newValue & s_##lowerName##Mask) << offset;\
+    }
+
+    DEFINE_BITFIELD(DictionaryKind, dictionaryKind, DictionaryKind, 2, 0);
+    DEFINE_BITFIELD(bool, isPinnedPropertyTable, IsPinnedPropertyTable, 1, 2);
+    DEFINE_BITFIELD(bool, hasGetterSetterProperties, HasGetterSetterProperties, 1, 3);
+    DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4);
+    DEFINE_BITFIELD(bool, hasNonEnumerableProperties, HasNonEnumerableProperties, 1, 5);
+    DEFINE_BITFIELD(unsigned, attributesInPrevious, AttributesInPrevious, 14, 6);
+    DEFINE_BITFIELD(unsigned, specificFunctionThrashCount, SpecificFunctionThrashCount, 2, 20);
+    DEFINE_BITFIELD(bool, preventExtensions, PreventExtensions, 1, 22);
+    DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 23);
+    DEFINE_BITFIELD(bool, staticFunctionsReified, StaticFunctionsReified, 1, 24);
+    DEFINE_BITFIELD(bool, hasRareData, HasRareData, 1, 25);
+
+private:
     friend class LLIntOffsetsExtractor;
 
     JS_EXPORT_PRIVATE Structure(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
@@ -416,11 +429,6 @@
     // to unlock it.
     void findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);
     
-    typedef enum { 
-        NoneDictionaryKind = 0,
-        CachedDictionaryKind = 1,
-        UncachedDictionaryKind = 2
-    } DictionaryKind;
     static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind);
 
     PropertyOffset putSpecificValue(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
@@ -455,7 +463,7 @@
 
     void setPreviousID(VM& vm, Structure* transition, Structure* structure)
     {
-        if (m_hasRareData)
+        if (hasRareData())
             rareData()->setPreviousID(vm, transition, structure);
         else
             m_previousOrRareData.set(vm, transition, structure);
@@ -463,7 +471,7 @@
 
     void clearPreviousID()
     {
-        if (m_hasRareData)
+        if (hasRareData())
             rareData()->clearPreviousID();
         else
             m_previousOrRareData.clear();
@@ -482,13 +490,13 @@
 
     Structure* previous() const
     {
-        ASSERT(!m_hasRareData);
+        ASSERT(!hasRareData());
         return static_cast<Structure*>(m_previousOrRareData.get());
     }
 
     StructureRareData* rareData() const
     {
-        ASSERT(m_hasRareData);
+        ASSERT(hasRareData());
         return static_cast<StructureRareData*>(m_previousOrRareData.get());
     }
         
@@ -533,18 +541,8 @@
     uint8_t m_inlineCapacity;
     
     ConcurrentJITLock m_lock;
-    
-    unsigned m_dictionaryKind : 2;
-    bool m_isPinnedPropertyTable : 1;
-    bool m_hasGetterSetterProperties : 1;
-    bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
-    bool m_hasNonEnumerableProperties : 1;
-    unsigned m_attributesInPrevious : 14;
-    unsigned m_specificFunctionThrashCount : 2;
-    unsigned m_preventExtensions : 1;
-    unsigned m_didTransition : 1;
-    unsigned m_staticFunctionReified : 1;
-    bool m_hasRareData : 1;
+
+    uint32_t m_bitField;
 };
 
 } // namespace JSC

Modified: branches/ftlopt/Source/_javascript_Core/runtime/StructureInlines.h (170435 => 170436)


--- branches/ftlopt/Source/_javascript_Core/runtime/StructureInlines.h	2014-06-25 21:04:17 UTC (rev 170435)
+++ branches/ftlopt/Source/_javascript_Core/runtime/StructureInlines.h	2014-06-25 21:15:37 UTC (rev 170436)
@@ -135,14 +135,14 @@
 inline void Structure::setEnumerationCache(VM& vm, JSPropertyNameIterator* enumerationCache)
 {
     ASSERT(!isDictionary());
-    if (!m_hasRareData)
+    if (!hasRareData())
         allocateRareData(vm);
     rareData()->setEnumerationCache(vm, this, enumerationCache);
 }
 
 inline JSPropertyNameIterator* Structure::enumerationCache()
 {
-    if (!m_hasRareData)
+    if (!hasRareData())
         return 0;
     return rareData()->enumerationCache();
 }
@@ -228,7 +228,7 @@
     PropertyTable* propertyTable = m_propertyTableUnsafe.get();
 
     if (!propertyTable) {
-        ASSERT(!m_isPinnedPropertyTable);
+        ASSERT(!isPinnedPropertyTable());
         return true;
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to