Skip to content

Commit 27aec01

Browse files
committed
Move mutable property definitions from the prototype to the constructor for
better performance in v8.
1 parent 5c7b721 commit 27aec01

File tree

1 file changed

+111
-127
lines changed

1 file changed

+111
-127
lines changed

javascript/webdriver/promise.js

+111-127
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,75 @@ webdriver.promise.ControlFlow = function(opt_timer) {
10441044
* @private {!Array.<!webdriver.promise.Task_>}
10451045
*/
10461046
this.history_ = [];
1047+
1048+
/**
1049+
* Tracks the active execution frame for this instance. Lazily initialized
1050+
* when the first task is scheduled.
1051+
* @private {webdriver.promise.Frame_}
1052+
*/
1053+
this.activeFrame_ = null;
1054+
1055+
/**
1056+
* A reference to the frame in which new tasks should be scheduled. If
1057+
* {@code null}, tasks will be scheduled within the active frame. When forcing
1058+
* a function to run in the context of a new frame, this pointer is used to
1059+
* ensure tasks are scheduled within the newly created frame, even though it
1060+
* won't be active yet.
1061+
* @private {webdriver.promise.Frame_}
1062+
* @see {#runInNewFrame_}
1063+
*/
1064+
this.schedulingFrame_ = null;
1065+
1066+
/**
1067+
* Timeout ID set when the flow is about to shutdown without any errors
1068+
* being detected. Upon shutting down, the flow will emit an
1069+
* {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
1070+
* always follow a brief timeout in order to catch latent errors from the last
1071+
* completed task. If this task had a callback registered, but no errback, and
1072+
* the task fails, the unhandled failure would not be reported by the promise
1073+
* system until the next turn of the event loop:
1074+
*
1075+
* // Schedule 1 task that fails.
1076+
* var result = webriver.promise.controlFlow().schedule('example',
1077+
* function() { return webdriver.promise.rejected('failed'); });
1078+
* // Set a callback on the result. This delays reporting the unhandled
1079+
* // failure for 1 turn of the event loop.
1080+
* result.then(goog.nullFunction);
1081+
*
1082+
* @private {?number}
1083+
*/
1084+
this.shutdownId_ = null;
1085+
1086+
/**
1087+
* Interval ID for this instance's event loop.
1088+
* @private {?number}
1089+
*/
1090+
this.eventLoopId_ = null;
1091+
1092+
/**
1093+
* The number of "pending" promise rejections.
1094+
*
1095+
* <p>Each time a promise is rejected and is not handled by a listener, it
1096+
* will schedule a 0-based timeout to check if it is still unrejected in the
1097+
* next turn of the JS-event loop. This allows listeners to attach to, and
1098+
* handle, the rejected promise at any point in same turn of the event loop
1099+
* that the promise was rejected.
1100+
*
1101+
* <p>When this flow's own event loop triggers, it will not run if there
1102+
* are any outstanding promise rejections. This allows unhandled promises to
1103+
* be reported before a new task is started, ensuring the error is reported
1104+
* to the current task queue.
1105+
*
1106+
* @private {number}
1107+
*/
1108+
this.pendingRejections_ = 0;
1109+
1110+
/**
1111+
* The number of aborted frames since the last time a task was executed or a
1112+
* frame completed successfully.
1113+
* @private {number}
1114+
*/
1115+
this.numAbortedFrames_ = 0;
10471116
};
10481117
goog.inherits(webdriver.promise.ControlFlow, webdriver.EventEmitter);
10491118

@@ -1118,81 +1187,6 @@ webdriver.promise.ControlFlow.EventType = {
11181187
webdriver.promise.ControlFlow.EVENT_LOOP_FREQUENCY = 10;
11191188

11201189

1121-
/**
1122-
* Tracks the active execution frame for this instance. Lazily initialized
1123-
* when the first task is scheduled.
1124-
* @private {webdriver.promise.Frame_}
1125-
*/
1126-
webdriver.promise.ControlFlow.prototype.activeFrame_ = null;
1127-
1128-
1129-
/**
1130-
* A reference to the frame in which new tasks should be scheduled. If
1131-
* {@code null}, tasks will be scheduled within the active frame. When forcing
1132-
* a function to run in the context of a new frame, this pointer is used to
1133-
* ensure tasks are scheduled within the newly created frame, even though it
1134-
* won't be active yet.
1135-
* @private {webdriver.promise.Frame_}
1136-
* @see {#runInNewFrame_}
1137-
*/
1138-
webdriver.promise.ControlFlow.prototype.schedulingFrame_ = null;
1139-
1140-
1141-
/**
1142-
* Timeout ID set when the flow is about to shutdown without any errors
1143-
* being detected. Upon shutting down, the flow will emit an
1144-
* {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
1145-
* always follow a brief timeout in order to catch latent errors from the last
1146-
* completed task. If this task had a callback registered, but no errback, and
1147-
* the task fails, the unhandled failure would not be reported by the promise
1148-
* system until the next turn of the event loop:
1149-
*
1150-
* // Schedule 1 task that fails.
1151-
* var result = webriver.promise.controlFlow().schedule('example',
1152-
* function() { return webdriver.promise.rejected('failed'); });
1153-
* // Set a callback on the result. This delays reporting the unhandled
1154-
* // failure for 1 turn of the event loop.
1155-
* result.then(goog.nullFunction);
1156-
*
1157-
* @private {?number}
1158-
*/
1159-
webdriver.promise.ControlFlow.prototype.shutdownId_ = null;
1160-
1161-
1162-
/**
1163-
* Interval ID for this instance's event loop.
1164-
* @private {?number}
1165-
*/
1166-
webdriver.promise.ControlFlow.prototype.eventLoopId_ = null;
1167-
1168-
1169-
/**
1170-
* The number of "pending" promise rejections.
1171-
*
1172-
* <p>Each time a promise is rejected and is not handled by a listener, it will
1173-
* schedule a 0-based timeout to check if it is still unrejected in the next
1174-
* turn of the JS-event loop. This allows listeners to attach to, and handle,
1175-
* the rejected promise at any point in same turn of the event loop that the
1176-
* promise was rejected.
1177-
*
1178-
* <p>When this flow's own event loop triggers, it will not run if there
1179-
* are any outstanding promise rejections. This allows unhandled promises to
1180-
* be reported before a new task is started, ensuring the error is reported to
1181-
* the current task queue.
1182-
*
1183-
* @private {number}
1184-
*/
1185-
webdriver.promise.ControlFlow.prototype.pendingRejections_ = 0;
1186-
1187-
1188-
/**
1189-
* The number of aborted frames since the last time a task was executed or a
1190-
* frame completed successfully.
1191-
* @private {number}
1192-
*/
1193-
webdriver.promise.ControlFlow.prototype.numAbortedFrames_ = 0;
1194-
1195-
11961190
/**
11971191
* Resets this instance, clearing its queue and removing all event listeners.
11981192
*/
@@ -1762,17 +1756,13 @@ webdriver.promise.ControlFlow.prototype.abortNow_ = function(error) {
17621756
*/
17631757
webdriver.promise.Node_ = function(flow) {
17641758
webdriver.promise.Deferred.call(this, null, flow);
1759+
1760+
/** @private {webdriver.promise.Node_} */
1761+
this.parent_ = null;
17651762
};
17661763
goog.inherits(webdriver.promise.Node_, webdriver.promise.Deferred);
17671764

17681765

1769-
/**
1770-
* This node's parent.
1771-
* @private {webdriver.promise.Node_}
1772-
*/
1773-
webdriver.promise.Node_.prototype.parent_ = null;
1774-
1775-
17761766
/** @return {webdriver.promise.Node_} This node's parent. */
17771767
webdriver.promise.Node_.prototype.getParent = function() {
17781768
return this.parent_;
@@ -1831,56 +1821,50 @@ webdriver.promise.Frame_ = function(flow) {
18311821
* @private {!Array.<!(webdriver.promise.Frame_|webdriver.promise.Task_)>}
18321822
*/
18331823
this.children_ = [];
1834-
};
1835-
goog.inherits(webdriver.promise.Frame_, webdriver.promise.Node_);
1836-
18371824

1838-
/**
1839-
* The task currently being executed within this frame.
1840-
* @private {webdriver.promise.Task_}
1841-
*/
1842-
webdriver.promise.Frame_.prototype.pendingTask_ = null;
1843-
1844-
1845-
/**
1846-
* Whether this frame is active. A frame is considered active once one of its
1847-
* descendants has been removed for execution.
1848-
*
1849-
* Adding a sub-frame as a child to an active frame is an indication that
1850-
* a callback to a {@link webdriver.promise.Deferred} is being invoked and any
1851-
* tasks scheduled within it should have priority over previously scheduled
1852-
* tasks:
1853-
* <code><pre>
1854-
* var flow = webdriver.promise.controlFlow();
1855-
* flow.execute('start here', goog.nullFunction).then(function() {
1856-
* flow.execute('this should execute 2nd', goog.nullFunction);
1857-
* });
1858-
* flow.execute('this should execute last', goog.nullFunction);
1859-
* </pre></code>
1860-
*
1861-
* @private {boolean}
1862-
*/
1863-
webdriver.promise.Frame_.prototype.isActive_ = false;
18641825

1826+
/** @private {webdriver.promise.Node_} */
1827+
this.lastInsertedChild_ = null;
18651828

1866-
/**
1867-
* Whether this frame is currently locked. A locked frame represents a callback
1868-
* or task function which has run to completion and scheduled all of its tasks.
1869-
*
1870-
* <p>Once a frame becomes {@link #isActive_ active}, any new frames which are
1871-
* added represent callbacks on a {@link webdriver.promise.Deferred}, whose
1872-
* tasks must be given priority over previously scheduled tasks.
1873-
*
1874-
* @private {boolean}
1875-
*/
1876-
webdriver.promise.Frame_.prototype.isLocked_ = false;
1829+
/**
1830+
* The task currently being executed within this frame.
1831+
* @private {webdriver.promise.Task_}
1832+
*/
1833+
this.pendingTask_ = null;
18771834

1835+
/**
1836+
* Whether this frame is active. A frame is considered active once one of its
1837+
* descendants has been removed for execution.
1838+
*
1839+
* Adding a sub-frame as a child to an active frame is an indication that
1840+
* a callback to a {@link webdriver.promise.Deferred} is being invoked and any
1841+
* tasks scheduled within it should have priority over previously scheduled
1842+
* tasks:
1843+
* <code><pre>
1844+
* var flow = webdriver.promise.controlFlow();
1845+
* flow.execute('start here', goog.nullFunction).then(function() {
1846+
* flow.execute('this should execute 2nd', goog.nullFunction);
1847+
* });
1848+
* flow.execute('this should execute last', goog.nullFunction);
1849+
* </pre></code>
1850+
*
1851+
* @private {boolean}
1852+
*/
1853+
this.isActive_ = false;
18781854

1879-
/**
1880-
* A reference to the last node inserted in this frame.
1881-
* @private {webdriver.promise.Node_}
1882-
*/
1883-
webdriver.promise.Frame_.prototype.lastInsertedChild_ = null;
1855+
/**
1856+
* Whether this frame is currently locked. A locked frame represents a callback
1857+
* or task function which has run to completion and scheduled all of its tasks.
1858+
*
1859+
* <p>Once a frame becomes {@link #isActive_ active}, any new frames which are
1860+
* added represent callbacks on a {@link webdriver.promise.Deferred}, whose
1861+
* tasks must be given priority over previously scheduled tasks.
1862+
*
1863+
* @private {boolean}
1864+
*/
1865+
this.isLocked_ = false;
1866+
};
1867+
goog.inherits(webdriver.promise.Frame_, webdriver.promise.Node_);
18841868

18851869

18861870
/**

0 commit comments

Comments
 (0)