PSA: All Oilpan trace() methods signatures are changing

135 views
Skip to first unread message

Kouhei Ueno

unread,
Feb 5, 2015, 12:04:28 AM2/5/15
to blink-dev
Hi blink-dev,

If you do not touch Oilpan objects, you can stop reading now.
TL;DR: From now on, use {DECLARE,DEFINE}_TRACE macros instead of directly declaring/defining trace() methods.

I would like to introduce change to Oilpan trace method signatures to support inlined tracing.
All current trace() methods declaration/definitions will be changed to use {DECLARE,DEFINE}_TRACE macros, which will add definition of trace(InlinedGlobalMarkingVisitor) in addition to current trace(Visitor*).
This will speed up GC marking by allowing Oilpan to trace object graph without virtual method call overhead.

For existing trace methods, I'll submit script generated changes to replace all (tracking bug).
For new GarbageCollected objects, please use DEFINE_TRACE macros instead of directly defining trace methods so that we can utilize inlined tracing:

Before: class X { virtual void trace(Visitor*) override; }
After: class X { DECLARE_TRACE(virtual,override); }

Before: class X { virtual void trace(Visitor*) {...} };
After: class X { DEFINE_INLINED_TRACE(virtual,) { ... } };

Before: void X::trace(Visitor* visitor) { ... }
After: DEFINE_TRACE(X) { ... }

Thanks,
kouhei

====

Below are details for those of you who are interested:

Background:
All GarbageCollected objects has a trace() method to indicate all garbage collected pointers the object contains.
The trace() method is invoked from GC to traverse and mark all live objects in the object graph.

Currently, the trace() method takes Visitor*, and invokes Visitor::mark() virtual method call per garbage collected object reference.
This was declared virtual so that we can use the same trace() methods to traverse the object graph for different purposes (e.g. instrumentation, debugging).

Optimization:
For >99% of the cases, we use trace() methods for marking live objects, and their virtual method call overhead is not negligible, as object marking is a small & simple bit flip operation.

InlinedGlobalMarkingVisitor exposes exact same interface as Visitor does, but has inlined mark() implementation. By having trace(InlinedMarkingVisitor), we can traverse and mark live objects without invoking any virtual method call.

Plan:
- We define trace(InlinedGlobalMarkingVisitor) in addition to trace(Visitor*) for all GC objects.
  - Helper macros {DECLARE,DEFINE}_TRACE would be used so that there will be minimal diff to the existing code.
  - The macro would expand a C++ template so that a single definition can be used for both trace(Visitor*) and trace(InlinedGlobalMarkingVisitor)
- Flip ENABLE(INLINED_TRACING) so that Oilpan marking will use trace(InlinedGlobalMarkingVisitor).
- Remove #if ENABLE(INLINED_TRACING) to clean up code after we confirmed a performance win.

Expected Results:
We expect 10-15% speed up in GC marking from this inlining Visitor::trace() calls optimization compared to ToT.

-- 
Kouhei Ueno

Kouhei Ueno

unread,
Feb 6, 2015, 2:12:59 AM2/6/15
to blink-dev
Small update. Macros are updated so that they look slightly more sane.
I'll update the Oilpan guide once the change sticks.

Before: class X { void trace(Visitor*); }
After: class X { DECLARE_TRACE(); }

Before: class X { virtual void trace(Visitor*) override; }
After: class X { DECLARE_VIRTUAL_TRACE(); }

Before: class X { void trace(Visitor*) {...} };
After: class X { DEFINE_INLINED_TRACE() { ... } };

Before: class X { virtual void trace(Visitor*) {...} };
After: class X { DEFINE_INLINED_VIRTUAL_TRACE() { ... } };

Before: void X::trace(Visitor* visitor) { ... }
After: DEFINE_TRACE(X) { ... }


--
Kouhei Ueno
Reply all
Reply to author
Forward
0 new messages