Avoid calling [[Get]](..., "prototype") when constructing built-ins and callee == newTarget

RESOLVED FIXED in Firefox 56

Status

()

Core
JavaScript Engine
RESOLVED FIXED
10 months ago
10 months ago

People

(Reporter: anba, Assigned: anba)

Tracking

Trunk
mozilla56
Points:
---

Firefox Tracking Flags

(firefox56 fixed)

Details

Attachments

(1 attachment, 1 obsolete attachment)

(Assignee)

Description

10 months ago
We can skip the [[Get]] for the "prototype" property when callee == newTarget is true.
(Assignee)

Comment 1

10 months ago
Created attachment 8884341 [details] [diff] [review]
bug1379222.patch

Replaces the GetPrototypeFrom[Callable]Constructor() call in built-in constructors with the new GetPrototypeFromBuiltinConstructor() method. GetPrototypeFromBuiltinConstructor() only calls GetPrototypeFromConstructor() when we're constructing and the callee is different from newTarget. The "prototype" property of built-in constructors is non-writable and non-configurable, so it's okay to skip reading it when not needed.

Drive-by changes:
- TypedArrayObjectTemplate#makeInstance(): Only call GetBuiltinPrototype when the return value is actually used.
- WeakMap_construct: Replace CreateThis() with NewObjectWithClassProto(), which means WeakMaps are now using OBJECT2_BACKGROUND instead of OBJECT4_BACKGROUND. Was there a specific reason WeakMaps used OBJECT4_BACKGROUND for their allocation-kind?
Attachment #8884341 - Flags: review?(jdemooij)
(Assignee)

Comment 2

10 months ago
The patch improves this µ-benchmark from 110ms to 85ms for me:

    var t = Date.now();
    for (var i = 0; i < 1000000; ++i) {
        new Boolean();
    }
    print(Date.now() - t);

Comment 3

10 months ago
Comment on attachment 8884341 [details] [diff] [review]
bug1379222.patch

Review of attachment 8884341 [details] [diff] [review]:
-----------------------------------------------------------------

Good finds! Thanks for fixing.

::: js/src/jsnum.cpp
@@ +503,5 @@
>  
> +    if (!args.isConstructing()) {
> +        if (args.length() > 0) {
> +            args.rval().set(args[0]);
> +        } else {

Nit: no {} here

::: js/src/jsobj.cpp
@@ +1002,5 @@
>      return true;
>  }
>  
>  bool
> +js::GetPrototypeFromBuiltinConstructor(JSContext* cx, const CallArgs& args, MutableHandleObject proto)

Please move this into jsobj.h and make it MOZ_ALWAYS_INLINE? In most cases this will be just 1 or 2 branches and the call overhead will be more than that.

GetPrototypeFromConstructor can stay out of line, as that's the less interesting case.
Attachment #8884341 - Flags: review?(jdemooij) → review+
(Assignee)

Comment 4

10 months ago
Created attachment 8884806 [details] [diff] [review]
bug1379222.patch

Updated per review comments, carrying r+.


(In reply to Jan de Mooij [:jandem] from comment #3)
> ::: js/src/jsobj.cpp
> @@ +1002,5 @@
> >      return true;
> >  }
> >  
> >  bool
> > +js::GetPrototypeFromBuiltinConstructor(JSContext* cx, const CallArgs& args, MutableHandleObject proto)
> 
> Please move this into jsobj.h and make it MOZ_ALWAYS_INLINE? In most cases
> this will be just 1 or 2 branches and the call overhead will be more than
> that.
> 
> GetPrototypeFromConstructor can stay out of line, as that's the less
> interesting case.

Good suggestion, thanks! This seems to improve the µ-benchmark from comment #2 by another 10ms.
Attachment #8884341 - Attachment is obsolete: true
Attachment #8884806 - Flags: review+

Comment 6

10 months ago
Pushed by ryanvm@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/0d0c4418614b
Avoid [[Get]] for "prototype" property when calling builtin constructors. r=jandem
Keywords: checkin-needed

Comment 7

10 months ago
bugherder
https://hg.mozilla.org/mozilla-central/rev/0d0c4418614b
Status: ASSIGNED → RESOLVED
Last Resolved: 10 months ago
status-firefox56: --- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
You need to log in before you can comment on or make changes to this bug.