Ignore:
Timestamp:
Sep 2, 2011, 10:14:04 PM (14 years ago)
Author:
[email protected]
Message:

ValueProfile does not make it safe to introspect cell values
after garbage collection
https://bugs.webkit.org/show_bug.cgi?id=67354

Reviewed by Gavin Barraclough.

ValueProfile buckets are now weak references, implemented using a
light-weight weak reference mechanism that this patch also adds (the
WeakReferenceHarvester). If a cell stored in a ValueProfile bucket
is not marked, then the bucket is transformed into a Structure
pointer. If the Structure is not marked either, then it is turned
into a ClassInfo pointer.

(JSC::CodeBlock::~CodeBlock):
(JSC::CodeBlock::visitAggregate):
(JSC::CodeBlock::visitWeakReferences):

  • bytecode/CodeBlock.h:
  • bytecode/ValueProfile.h:

(JSC::ValueProfile::ValueProfile):
(JSC::ValueProfile::classInfo):
(JSC::ValueProfile::numberOfInt32s):
(JSC::ValueProfile::numberOfDoubles):
(JSC::ValueProfile::numberOfCells):
(JSC::ValueProfile::numberOfArrays):
(JSC::ValueProfile::probabilityOfArray):
(JSC::ValueProfile::WeakBucket::WeakBucket):
(JSC::ValueProfile::WeakBucket::operator!):
(JSC::ValueProfile::WeakBucket::isEmpty):
(JSC::ValueProfile::WeakBucket::isClassInfo):
(JSC::ValueProfile::WeakBucket::isStructure):
(JSC::ValueProfile::WeakBucket::asStructure):
(JSC::ValueProfile::WeakBucket::asClassInfo):
(JSC::ValueProfile::WeakBucket::getClassInfo):

  • heap/Heap.cpp:

(JSC::Heap::harvestWeakReferences):
(JSC::Heap::markRoots):

  • heap/Heap.h:
  • heap/MarkStack.cpp:

(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::harvestWeakReferences):

  • heap/MarkStack.h:

(JSC::MarkStack::addWeakReferenceHarvester):
(JSC::MarkStack::MarkStack):
(JSC::MarkStack::appendUnbarrieredPointer):

  • heap/SlotVisitor.h:
  • heap/WeakReferenceHarvester.h: Added.

(JSC::WeakReferenceHarvester::WeakReferenceHarvester):
(JSC::WeakReferenceHarvester::~WeakReferenceHarvester):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r93466 r94477  
    14341434{
    14351435#if ENABLE(VERBOSE_VALUE_PROFILE)
    1436     printf("ValueProfile for %p:\n", this);
     1436    fprintf(stderr, "ValueProfile for %p:\n", this);
    14371437    for (unsigned i = 0; i < numberOfValueProfiles(); ++i) {
    14381438        ValueProfile* profile = valueProfile(i);
    14391439        if (profile->bytecodeOffset < 0) {
    14401440            ASSERT(profile->bytecodeOffset == -1);
    1441             printf("   arg = %u: ", i + 1);
     1441            fprintf(stderr, "   arg = %u: ", i + 1);
    14421442        } else
    1443             printf("   bc = %d: ", profile->bytecodeOffset);
    1444         printf("samples = %u, int32 = %u, double = %u, cell = %u\n",
    1445                profile->numberOfSamples(),
    1446                profile->probabilityOfInt32(),
    1447                profile->probabilityOfDouble(),
    1448                profile->probabilityOfCell());
     1443            fprintf(stderr, "   bc = %d: ", profile->bytecodeOffset);
     1444        fprintf(stderr,
     1445                "samples = %u, int32 = %u, double = %u, cell = %u, array = %u\n",
     1446                profile->numberOfSamples(),
     1447                profile->probabilityOfInt32(),
     1448                profile->probabilityOfDouble(),
     1449                profile->probabilityOfCell(),
     1450                profile->probabilityOfArray());
    14491451    }
    14501452#endif
     
    15161518void CodeBlock::visitAggregate(SlotVisitor& visitor)
    15171519{
     1520    bool handleWeakReferences = false;
     1521   
    15181522    visitor.append(&m_globalObject);
    15191523    visitor.append(&m_ownerExecutable);
     
    15631567    }
    15641568#endif
     1569
     1570#if ENABLE(VALUE_PROFILER)
     1571    for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) {
     1572        ValueProfile* profile = valueProfile(profileIndex);
     1573       
     1574        for (unsigned index = 0; index < ValueProfile::numberOfBuckets; ++index) {
     1575            if (!profile->buckets[index]) {
     1576                if (!!profile->weakBuckets[index])
     1577                    handleWeakReferences = true;
     1578                continue;
     1579            }
     1580           
     1581            if (!JSValue::decode(profile->buckets[index]).isCell()) {
     1582                profile->weakBuckets[index] = ValueProfile::WeakBucket();
     1583                continue;
     1584            }
     1585           
     1586            handleWeakReferences = true;
     1587        }
     1588    }
     1589#endif
     1590   
     1591    if (handleWeakReferences)
     1592        visitor.addWeakReferenceHarvester(this);
     1593}
     1594
     1595void CodeBlock::visitWeakReferences(SlotVisitor&)
     1596{
     1597#if ENABLE(VALUE_PROFILER)
     1598    for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) {
     1599        ValueProfile* profile = valueProfile(profileIndex);
     1600       
     1601        for (unsigned index = 0; index < ValueProfile::numberOfBuckets; ++index) {
     1602            if (!!profile->buckets[index]) {
     1603                JSValue value = JSValue::decode(profile->buckets[index]);
     1604                if (!value.isCell())
     1605                    continue;
     1606               
     1607                JSCell* cell = value.asCell();
     1608                if (Heap::isMarked(cell))
     1609                    continue;
     1610               
     1611                profile->buckets[index] = JSValue::encode(JSValue());
     1612                profile->weakBuckets[index] = cell->structure();
     1613            }
     1614           
     1615            ValueProfile::WeakBucket weak = profile->weakBuckets[index];
     1616            if (!weak || weak.isClassInfo())
     1617                continue;
     1618           
     1619            ASSERT(weak.isStructure());
     1620            if (Heap::isMarked(weak.asStructure()))
     1621                continue;
     1622           
     1623            profile->weakBuckets[index] = weak.asStructure()->classInfo();
     1624        }
     1625    }
     1626#endif
    15651627}
    15661628
Note: See TracChangeset for help on using the changeset viewer.