Ignore:
Timestamp:
Aug 10, 2009, 9:35:02 PM (16 years ago)
Author:
[email protected]
Message:

Stack overflow crash in JavaScript garbage collector mark pass
https://bugs.webkit.org/show_bug.cgi?id=12216

Reviewed by Gavin Barraclough and Sam Weinig

Make the GC mark phase iterative by using an explicit mark stack.
To do this marking any single object is performed in multiple stages

  • The object is appended to the MarkStack, this sets the marked bit for the object using the new markDirect() function, and then returns
  • When the MarkStack is drain()ed the object is popped off the stack and markChildren(MarkStack&) is called on the object to collect all of its children. drain() then repeats until the stack is empty.

Additionally I renamed a number of methods from 'mark' to 'markAggregate'
in order to make it more clear that marking of those object was not
going to result in an actual recursive mark.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/JSArray.cpp

    r46598 r47022  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    3  *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2003 Peter Kelly ([email protected])
    55 *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
     
    602602}
    603603
    604 void JSArray::mark()
    605 {
    606     JSObject::mark();
     604void JSArray::markChildren(MarkStack& markStack)
     605{
     606    JSObject::markChildren(markStack);
    607607
    608608    ArrayStorage* storage = m_storage;
    609609
    610610    unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
    611     for (unsigned i = 0; i < usedVectorLength; ++i) {
    612         JSValue value = storage->m_vector[i];
    613         if (value && !value.marked())
    614             value.mark();
    615     }
     611    markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues);
    616612
    617613    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
    618614        SparseArrayValueMap::iterator end = map->end();
    619         for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
    620             JSValue value = it->second;
    621             if (!value.marked())
    622                 value.mark();
    623         }
     615        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
     616            markStack.append(it->second);
    624617    }
    625618}
Note: See TracChangeset for help on using the changeset viewer.