Bug 1289318 - Part 2: Make Promise reaction records their own object type with a constructor and all. r?efaust draft
authorTill Schneidereit <till@tillschneidereit.net>
Wed, 03 Aug 2016 17:31:13 +0200
changeset 400695 e6681331ef9d56cba16468697bc837dabdb22439
parent 400694 0ee9448a059bc0c0f74a28ebfc56a0c39e1451fb
child 400696 94d70296f22a8b1e3e1b707ce1a004d137d20a56
push id26245
push userbmo:till@tillschneidereit.net
push dateMon, 15 Aug 2016 14:02:13 +0000
reviewersefaust
bugs1289318
milestone51.0a1
Bug 1289318 - Part 2: Make Promise reaction records their own object type with a constructor and all. r?efaust That allows them to be unboxed, saving 32 bytes per instance. It's nicer, too. MozReview-Commit-ID: HHvb5PihUUD
js/src/builtin/Promise.js
--- a/js/src/builtin/Promise.js
+++ b/js/src/builtin/Promise.js
@@ -1,16 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // ES6, 25.4.1.2.
 // This object is used to verify that an object is a PromiseReaction record.
 var PromiseReactionRecordProto = {__proto__: null};
+function PromiseReactionRecord(promise, resolve, reject, handler, incumbentGlobal) {
+    this.promise = promise;
+    this.resolve = resolve;
+    this.reject = reject;
+    this.handler = handler;
+    this.incumbentGlobal = incumbentGlobal;
+}
 
+MakeConstructible(PromiseReactionRecord, PromiseReactionRecordProto);
 
 // ES6, 25.4.1.3.
 function CreateResolvingFunctions(promise) {
     // The callbacks created here can deal with Promises wrapped in cross-
     // compartment wrappers. That's required because in some circumstances,
     // they're created in a higher-privileged compartment from the Promise,
     // so they can be invoked seamlessly by code in that compartment.
     //
@@ -642,23 +650,18 @@ function AddPromiseReaction(slot, depend
     let reactions = UnsafeGetReservedSlot(this, slot);
 
     // The reactions slot might've been reset because the Promise was resolved.
     if (!reactions) {
         assert(GetPromiseState(this) !== PROMISE_STATE_PENDING,
                "Pending promises must have reactions lists.");
         return;
     }
-    _DefineDataProperty(reactions, reactions.length, {
-                            __proto__: PromiseReactionRecordProto,
-                            promise: dependentPromise,
-                            reject: onReject,
-                            resolve: onResolve,
-                            handler: handler
-                        });
+    let reaction = new PromiseReactionRecord(promise, reject, resolve, handler, null);
+    _DefineDataProperty(reactions, reactions.length, reaction);
 }
 
 // ES6, 25.4.4.4.
 function Promise_static_reject(r) {
     // Step 1.
     let C = this;
 
     // Step 2.
@@ -880,34 +883,28 @@ function PerformPromiseThen(promise, onF
         onFulfilled = PROMISE_HANDLER_IDENTITY;
 
     // Step 4.
     if (!IsCallable(onRejected))
         onRejected = PROMISE_HANDLER_THROWER;
 
     let incumbentGlobal = _GetObjectFromIncumbentGlobal();
     // Step 5.
-    let fulfillReaction = {
-        __proto__: PromiseReactionRecordProto,
-        resolve: resultCapability.resolve,
-        reject: resultCapability.reject,
-        promise: resultCapability.promise,
-        handler: onFulfilled,
-        incumbentGlobal
-    };
+    let fulfillReaction = new PromiseReactionRecord(resultCapability.promise,
+                                                    resultCapability.resolve,
+                                                    resultCapability.reject,
+                                                    onFulfilled,
+                                                    incumbentGlobal);
 
     // Step 6.
-    let rejectReaction = {
-        __proto__: PromiseReactionRecordProto,
-        resolve: resultCapability.resolve,
-        reject: resultCapability.reject,
-        promise: resultCapability.promise,
-        handler: onRejected,
-        incumbentGlobal
-    };
+    let rejectReaction = new PromiseReactionRecord(resultCapability.promise,
+                                                   resultCapability.resolve,
+                                                   resultCapability.reject,
+                                                   onRejected,
+                                                   incumbentGlobal);
 
     // Step 7.
     let state = GetPromiseState(promise);
     if (state === PROMISE_STATE_PENDING) {
         // Step 7.a.
         let fulfillReactions = UnsafeGetObjectFromReservedSlot(promise,
                                                                PROMISE_FULFILL_REACTIONS_SLOT);
         _DefineDataProperty(fulfillReactions, fulfillReactions.length, fulfillReaction);