Skip to content

Another case of possibly deoptimizing use of arguments in libs #11001

Closed
@vsemozhetbyt

Description

@vsemozhetbyt

In this issue I've missed a case which is much more difficult to trace. That report has caused some fixes, so maybe this is also worth reporting.

However, some disclaimer is needed: I could get the theory or its application wrong here; I could miss or detect wrongly some cases; I am not sure if optimization is worth refactoring in each case. Moreover, spread is increasingly gaining speed now, so maybe upgrade to it is more worth efforts.

I. Definition

Leaking arguments is considered safe only within func.apply(context, arguments). However, this call site must be monomorphic. See the last warning in this chapter.

To be monomorphic, func must have the same hidden class. According to this comment, these functions have different hidden classes:

  • function with an additional property / function without this property
  • common function / bound function (via bind())
  • common function / arrow function
  • strict mode function / sloppy mode function

So, each func.apply(context, arguments) fragment should be checked for func monomorphism.

II. Example of deoptimization

This is the code to compare two cases with monomorphic and polymorphic call sites. In the comment below the code, you can see the time difference and deoptimization warning.

III. Types of cases

If I get it right, there are three group of cases here (from the most dangerous to the least dangerous):

  1. func is an argument gotten from a userland via public API (directly or via a call chain). We can't guarantee monomorphism here (for example, a user can give both common and arrow functions as arguments). So maybe in these cases arguments should be copied before the call, as in many other lib places.

  2. func is a declared public method. Here is a small danger still: a user can add a property to the public function at any time. Therefore, maybe these cases are worth to be refactored as well.

  3. func is a private function (declared or given as direct/indirect argument). The monomorphism of this func should be checked across all the code base chains.

IV. Occurrences in Node.js libs

  1. func is an argument gotten from a userland via public API
  1. func is a declared public method
  1. func is a private function. Most detected cases seem to be OK.

In addition, there are some cases I could not define which group they belong to and if they are monomorphic. I can't trace all the chain here (got out of memory and stack overflow in my mind).

Sorry for my bad English an overall mess in explanation.

// cc @nodejs/v8 , @bmeurer , @vhf

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceIssues and PRs related to the performance of Node.js.v8 engineIssues and PRs related to the V8 dependency.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions