Ignore:
Timestamp:
May 4, 2015, 1:42:10 PM (10 years ago)
Author:
[email protected]
Message:

Optimize WeakBlock's "reap" and "visit" operations.
<https://webkit.org/b/144585>

Reviewed by Geoffrey Garen.

WeakBlock was using Heap::isLive(void*) to determine the liveness of weak pointees.
That function was really written with conservative roots marking in mind, and will do a bunch
of sanity and bounds checks.

For weaks, we know that the pointer will have been a valid cell pointer into a block
of appropriate cell size, so we can skip a lot of the checks.

We now keep a pointer to the MarkedBlock in each WeakBlock. That way we no longer have to do
MarkedBlock::blockFor() for every single cell when iterating.

Note that a WeakBlock's MarkedBlock pointer becomes null when we detach a logically empty
WeakBlock from its WeakSet and transfer ownership to Heap. At that point, the block will never
be pointing to any live cells, and the only operation that will run on the block is sweep().

Finally, MarkedBlock allows liveness queries in three states: Marked, Retired, and Allocated.
In Allocated state, all cells are reported as live. This state will reset to Marked on next GC.
This patch uses that knowledge to avoid branching on the MarkedBlock's state for every cell.

This is a ~3x speedup of visit() and a ~2x speedup of reap() on Dromaeo/dom-modify, netting
what looks like a 1% speedup locally.

  • heap/MarkedBlock.cpp:

(JSC::MarkedBlock::MarkedBlock): Pass *this to the WeakSet's ctor.

  • heap/MarkedBlock.h:

(JSC::MarkedBlock::isMarkedOrNewlyAllocated): Added, stripped-down version of isLive() when the
block's state is known to be either Marked or Retired.

(JSC::MarkedBlock::isAllocated): Added, tells WeakBlock it's okay to skip reap/visit since isLive()
would report that all cells are live anyway.

  • heap/WeakBlock.cpp:

(JSC::WeakBlock::create):
(JSC::WeakBlock::WeakBlock): Stash a MarkedBlock* on each WeakBlock.

(JSC::WeakBlock::visit):
(JSC::WeakBlock::reap): Optimized these two to avoid a bunch of pointer arithmetic and branches.

  • heap/WeakBlock.h:

(JSC::WeakBlock::disconnectMarkedBlock): Added.

  • heap/WeakSet.cpp:

(JSC::WeakSet::sweep): Call the above when removing a WeakBlock from WeakSet and transferring
ownership to Heap until it can die peacefully.

(JSC::WeakSet::addAllocator):

  • heap/WeakSet.h:

(JSC::WeakSet::WeakSet): Give WeakSet a MarkedBlock& for passing on to WeakBlocks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/heap/WeakSet.h

    r156794 r183769  
    3232
    3333class Heap;
     34class MarkedBlock;
    3435class WeakImpl;
    3536
     
    4142    static void deallocate(WeakImpl*);
    4243
    43     WeakSet(VM*);
     44    WeakSet(VM*, MarkedBlock&);
    4445    ~WeakSet();
    4546    void lastChanceToFinalize();
     
    6667    DoublyLinkedList<WeakBlock> m_blocks;
    6768    VM* m_vm;
     69    MarkedBlock& m_markedBlock;
    6870};
    6971
    70 inline WeakSet::WeakSet(VM* vm)
     72inline WeakSet::WeakSet(VM* vm, MarkedBlock& markedBlock)
    7173    : m_allocator(0)
    7274    , m_nextAllocator(0)
    7375    , m_vm(vm)
     76    , m_markedBlock(markedBlock)
    7477{
    7578}
Note: See TracChangeset for help on using the changeset viewer.