Commit ed2be895 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Try moving from closures to direct calls. (#7679)

Rumours have it that this is faster now.

Fixes https://github.com/flutter/flutter/issues/5154
parent f1cdf570
......@@ -1095,9 +1095,6 @@ class PipelineOwner {
}
}
// See _performLayout.
void _doNothing() { }
/// An object in the render tree.
///
/// The [RenderObject] class hierarchy is the core of the rendering
......@@ -1212,7 +1209,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// Initializes internal fields for subclasses.
RenderObject() {
_needsCompositing = isRepaintBoundary || alwaysNeedsCompositing;
_performLayout = performLayout;
}
/// Cause the entire subtree rooted at the given [RenderObject] to be marked
......@@ -1227,7 +1223,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
///
/// * [BindingBase.reassembleApplication].
void reassemble() {
_performLayout = performLayout;
markNeedsLayout();
markNeedsCompositingBitsUpdate();
markNeedsPaint();
......@@ -1608,7 +1603,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return true;
});
try {
_performLayout();
performLayout();
markNeedsSemanticsUpdate();
} catch (e, stack) {
_debugReportException('performLayout', e, stack);
......@@ -1732,7 +1727,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return true;
});
try {
_performLayout();
performLayout();
markNeedsSemanticsUpdate();
assert(() { debugAssertDoesMeetConstraints(); return true; });
} catch (e, stack) {
......@@ -1803,11 +1798,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
@protected
void performLayout();
// We cache a closure to performLayout so that the callsite is monomorphic.
// Initializing this field with _buildNothing helps the compiler prove that
// this field always holds a closure.
VoidCallback _performLayout = _doNothing;
/// Allows mutations to be made to this object's child list (and any
/// descendants) as well as to any other dirty nodes in the render tree owned
/// by the same [PipelineOwner] as this object. The `callback` argument is
......
......@@ -2820,9 +2820,6 @@ typedef Widget WidgetBuilder(BuildContext context);
/// Used by [LazyBlockBuilder.builder].
typedef Widget IndexedWidgetBuilder(BuildContext context, int index);
// See ComponentElement._builder.
Widget _buildNothing(BuildContext context) => null;
/// An [Element] that composes other [Element]s.
///
/// Rather than creating a [RenderObject] directly, a [ComponentElement] creates
......@@ -2833,10 +2830,6 @@ abstract class ComponentElement extends BuildableElement {
/// Creates an element that uses the given widget as its configuration.
ComponentElement(Widget widget) : super(widget);
// Initializing this field with _buildNothing helps the compiler prove that
// this field always holds a closure.
WidgetBuilder _builder = _buildNothing;
Element _child;
@override
......@@ -2869,13 +2862,13 @@ abstract class ComponentElement extends BuildableElement {
assert(_debugSetAllowIgnoredCallsToMarkNeedsBuild(true));
Widget built;
try {
built = _builder(this);
built = build();
debugWidgetBuilderValue(widget, built);
} catch (e, stack) {
_debugReportException('building $this', e, stack);
built = new ErrorWidget(e);
} finally {
// We delay marking the element as clean until after calling _builder so
// We delay marking the element as clean until after calling build() so
// that attempts to markNeedsBuild() during build() will be ignored.
_dirty = false;
assert(_debugSetAllowIgnoredCallsToMarkNeedsBuild(false));
......@@ -2896,6 +2889,9 @@ abstract class ComponentElement extends BuildableElement {
});
}
@protected
Widget build();
@override
void visitChildren(ElementVisitor visitor) {
if (_child != null)
......@@ -2912,27 +2908,21 @@ abstract class ComponentElement extends BuildableElement {
/// An [Element] that uses a [StatelessWidget] as its configuration.
class StatelessElement extends ComponentElement {
/// Creates an element that uses the given widget as its configuration.
StatelessElement(StatelessWidget widget) : super(widget) {
_builder = widget.build;
}
StatelessElement(StatelessWidget widget) : super(widget);
@override
StatelessWidget get widget => super.widget;
@override
Widget build() => widget.build(this);
@override
void update(StatelessWidget newWidget) {
super.update(newWidget);
assert(widget == newWidget);
_builder = widget.build;
_dirty = true;
rebuild();
}
@override
void _reassemble() {
_builder = widget.build;
super._reassemble();
}
}
/// An [Element] that uses a [StatefulWidget] as its configuration.
......@@ -2953,13 +2943,14 @@ class StatefulElement extends ComponentElement {
});
assert(_state._element == null);
_state._element = this;
assert(_builder == _buildNothing);
_builder = _state.build;
assert(_state._config == null);
_state._config = widget;
assert(_state._debugLifecycleState == _StateLifecycle.created);
}
@override
Widget build() => state.build(this);
/// The [State] instance associated with this location in the tree.
///
/// There is a one-to-one relationship between [State] objects and the
......@@ -2970,7 +2961,6 @@ class StatefulElement extends ComponentElement {
@override
void _reassemble() {
_builder = state.build;
state.reassemble();
super._reassemble();
}
......@@ -3100,20 +3090,13 @@ class StatefulElement extends ComponentElement {
/// An [Element] that uses a [ProxyElement] as its configuration.
abstract class ProxyElement extends ComponentElement {
/// Initializes fields for subclasses.
ProxyElement(ProxyWidget widget) : super(widget) {
_builder = _build;
}
ProxyElement(ProxyWidget widget) : super(widget);
@override
ProxyWidget get widget => super.widget;
Widget _build(BuildContext context) => widget.child;
@override
void _reassemble() {
_builder = _build;
super._reassemble();
}
Widget build() => widget.child;
@override
void update(ProxyWidget newWidget) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment