Ignore:
Timestamp:
Nov 20, 2014, 3:28:41 PM (11 years ago)
Author:
[email protected]
Message:

Add Heap verification infrastructure.
<https://webkit.org/b/138851>

Reviewed by Geoffrey Garen.

The verification infrastructure code is always built in but disabled by
default. When disabled, the cost is minimal:

  1. Heap has a m_verifier field.
  2. GC does a few "if (m_verifier)" checks that should fail.
  3. HeapVerifier takes up code space though not used.

When enabled:

  1. The HeapVerifier will keep N number of GC cycle data. Each GC cycle will contain a "before marking" and "after marking" live object list. The GC cycles is a circular buffer. Only data for the last N GC cycles will be retained.
  2. During GC, the current GC cycle's live objects lists will be populated before and after marking.
  3. The current GC cycle's live object lists will be validated before GC, after marking, and after GC.

Currently, the only validation being done is to verify that object
butterflies are allocated from valid blocks in the Storage (aka Copied)
space.

(JSC::Heap::Heap):
(JSC::Heap::collect):

  • heap/Heap.h:
  • heap/HeapVerifier.cpp: Added.

(JSC::LiveObjectList::findObject):
(JSC::HeapVerifier::HeapVerifier):
(JSC::HeapVerifier::collectionTypeName):
(JSC::HeapVerifier::phaseName):
(JSC::getButterflyDetails):
(JSC::HeapVerifier::initializeGCCycle):
(JSC::GatherLiveObjFunctor::GatherLiveObjFunctor):
(JSC::GatherLiveObjFunctor::operator()):
(JSC::HeapVerifier::gatherLiveObjects):
(JSC::HeapVerifier::liveObjectListForGathering):
(JSC::trimDeadObjectsFromList):
(JSC::HeapVerifier::trimDeadObjects):
(JSC::HeapVerifier::verifyButterflyIsInStorageSpace):
(JSC::HeapVerifier::verify):
(JSC::HeapVerifier::reportObject):
(JSC::HeapVerifier::checkIfRecorded):

  • heap/HeapVerifier.h: Added.

(JSC::LiveObjectData::LiveObjectData):
(JSC::LiveObjectList::LiveObjectList):
(JSC::LiveObjectList::reset):
(JSC::HeapVerifier::GCCycle::GCCycle):
(JSC::HeapVerifier::GCCycle::collectionTypeName):
(JSC::HeapVerifier::incrementCycle):
(JSC::HeapVerifier::currentCycle):
(JSC::HeapVerifier::cycleForIndex):

  • runtime/Options.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r176219 r176424  
    3636#include "HeapRootVisitor.h"
    3737#include "HeapStatistics.h"
     38#include "HeapVerifier.h"
    3839#include "IncrementalSweeper.h"
    3940#include "Interpreter.h"
     
    340341{
    341342    m_storageSpace.init();
     343    if (Options::verifyHeap())
     344        m_verifier = std::make_unique<HeapVerifier>(this, Options::numberOfGCCyclesToRecordForVerification());
    342345}
    343346
     
    10051008
    10061009    double gcStartTime = WTF::monotonicallyIncreasingTime();
     1010    if (m_verifier) {
     1011        // Verify that live objects from the last GC cycle haven't been corrupted by
     1012        // mutators before we begin this new GC cycle.
     1013        m_verifier->verify(HeapVerifier::Phase::BeforeGC);
     1014
     1015        m_verifier->initializeGCCycle();
     1016        m_verifier->gatherLiveObjects(HeapVerifier::Phase::BeforeMarking);
     1017    }
    10071018
    10081019    deleteOldCode(gcStartTime);
     
    10131024    markRoots(gcStartTime);
    10141025
     1026    if (m_verifier) {
     1027        m_verifier->gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
     1028        m_verifier->verify(HeapVerifier::Phase::AfterMarking);
     1029    }
    10151030    JAVASCRIPTCORE_GC_MARKED();
    10161031
     
    10351050    didFinishCollection(gcStartTime);
    10361051    resumeCompilerThreads();
     1052
     1053    if (m_verifier) {
     1054        m_verifier->trimDeadObjects();
     1055        m_verifier->verify(HeapVerifier::Phase::AfterGC);
     1056    }
    10371057
    10381058    if (Options::logGC()) {
Note: See TracChangeset for help on using the changeset viewer.