Closed Bug 1037786 Opened 10 years ago Closed 10 years ago

JavaScript Warning: "mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create" {file: "resource://gre/modules/Preferences.jsm"

Categories

(Firefox OS Graveyard :: General, defect, P4)

ARM
Gonk (Firefox OS)
defect

Tracking

(b2g-v2.1 affected)

VERIFIED DUPLICATE of bug 982856
Tracking Status
b2g-v2.1 --- affected

People

(Reporter: gkw, Unassigned)

References

Details

(Keywords: perf, Whiteboard: [c=progress p= s= u=])

Boot up the phone while running `adb logcat`. While booting to the homescreen/lockscreen, there will be a JavaScript warnings shown:

JavaScript Warning: "mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create" {file: "resource://gre/modules/Preferences.jsm"

Not sure if this JavaScript warning should always show up, so setting needinfo? from Alive, a Firefox OS System module owner.

I am not connected to wifi and I have no SIM card. See bug 982856.

Tested on a Flame:
$ ./check_versions.sh
Gaia      c47094a26c87ba71a3da4bae54febd0da21f3393
Gecko     https://hg.mozilla.org/mozilla-central/rev/1b1296d00330
BuildID   20140711040202
Version   33.0a1
ro.build.version.incremental=109
ro.build.date=Mon Jun 16 16:51:29 CST 2014
B1TC00011220
Flags: needinfo?(alive)
> there will be a JavaScript warnings shown:

s/warnings/warning
See Also: → 982856
Another trivial one, wanna to take?
Flags: needinfo?(alive) → needinfo?(yliao)
Yes, thanks!
Assignee: nobody → yliao
Flags: needinfo?(yliao)
The bug seems to be a duplicate of https://bugzilla.mozilla.org/show_bug.cgi?id=982856. The warning was caused by line 378 in Gecko:
> 375 // Give the constructor the same prototype as its instances, so users can access
> 376 // preferences directly via the constructor without having to create an instance
> 377 // first.
> 378 Preferences.__proto__ = Preferences.prototype;

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

Additionally, usages of the deprecated __proto__ are all over the Gaia repo.

> var Module = function Module(params) {
>   Parent.call(this, params);
>   ...
> };

The deprecated __proto__ approach as follows:
> Module.prototype = {
>   __proto__: Parent.prototype,
>   
>   funcA: function () { ... },
> 
>   ...
> };

Could be replaced with:
> Module.prototype = Object.create(Parent.prototype);
> Module.funcA = functio () { ... };

However,
Flags: needinfo?(alive)
See Also: → 831696
However, a performance comparison of __proto__ and Object.create and the fact that __proto__ still exist in ES6 draft were discussed in bug 831696. It was suggested to keep the usage of __proto__. Should we make the change?

Here's another performance comparison FYI: http://jsperf.com/proto-versus-object-create/2

ES6
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.__proto__
Uhh, I didn't notice it's from gecko :/ Let's put it away for platform developer to decide what to do.
Flags: needinfo?(alive)
Assignee: yliao → nobody
Let's get some JS folks' eyes on this. Any thoughts on comment 5, Waldo/Jason?
Flags: needinfo?(jwalden+bmo)
Flags: needinfo?(jorendorff)
Well, here's a variation that shows __proto__ making your code more than 2x slower than if you used Object.create:

http://jsperf.com/proto-versus-object-create/3

I don't know why it's only 2x. In the JS shell on my machine, similar code using Object.create is nearly 100x faster than __proto__:

js> x = {m: function () { this.i++; }, i: 0}; var y = {__proto__: x, i: 0}; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
1594
js> x = {m: function () { this.i++; }, i: 0}; var y = {__proto__: x, i: 0}; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
1623
js> x = {m: function () { this.i++; }, i: 0}; var y = {__proto__: x, i: 0}; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
1712
js> x = {m: function () { this.i++; }, i: 0}; var y = {__proto__: x, i: 0}; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
1650

js> x = {m: function () { this.i++; }, i: 0}; var y = Object.create(x); y.i = 0; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
24
js> x = {m: function () { this.i++; }, i: 0}; var y = Object.create(x); y.i = 0; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
23
js> x = {m: function () { this.i++; }, i: 0}; var y = Object.create(x); y.i = 0; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
15
js> x = {m: function () { this.i++; }, i: 0}; var y = Object.create(x); y.i = 0; var t0 = Date.now(); for (var i = 0; i < 1000000; i++) y.m(); print(Date.now() - t0);
24

In other cases, the difference may be only 8%. It just depends.

We warn about __proto__ because it really does incur a totally pointless performance penalty in a lot of cases. Avoid it whenever possible.
Flags: needinfo?(jorendorff)
(In reply to Jason Orendorff [:jorendorff] from comment #8)
> We warn about __proto__ because it really does incur a totally pointless
> performance penalty in a lot of cases. Avoid it whenever possible.

Thanks Jason!

This sounds like we should audit Gaia to replace all __proto__usages with Object.create, esp since we seem to get easy performance wins of 8% up to 10,000% (100x).
Flags: needinfo?(jwalden+bmo) → needinfo?(yliao)
According to Jason's comment, bug 831696 should be reopen and should open bugs to identify the usage of __proto__ in Gaia. This one seems to be a duplicate of bug 982856. Mind if I proceed?
Flags: needinfo?(yliao) → needinfo?(alive)
(In reply to Yi-Fan Liao [:yifan][:yliao] from comment #10)
> According to Jason's comment, bug 831696 should be reopen and should open
> bugs to identify the usage of __proto__ in Gaia. This one seems to be a
> duplicate of bug 982856. Mind if I proceed?

My intention is fix the __proto__ usage in system app, so it's up to you to fix anything outside system app, but you will need to find someone else to review.
Flags: needinfo?(alive)
Assignee: nobody → yliao
See Also: → 1039931
Changed component to general for platform developer to work on this one. Opened bug 1039931 for the fix in Gaia system app.
Assignee: yliao → nobody
Component: Gaia::System → General
Keywords: perf
Whiteboard: [c=progress p= s= u=]
Priority: -- → P4
Unassigned. Not an FxOS bug. Duping.
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → DUPLICATE
V.Duplicate
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.