1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-21 00:35:08 +00:00
serenity/Userland/Libraries/LibJS/Bytecode
Linus Groh 4fa5748093 LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.

Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.

To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:

Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455

After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37

This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).

The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:

    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();

test262 reports no changes in either direction, apart from a speedup :^)
2021-10-05 10:15:14 +01:00
..
Pass LibJS: Remove unused header includes 2021-08-01 08:10:16 +02:00
ASTCodegen.cpp LibJS: Fix that in Bytecode mode functions where not created anymore 2021-09-30 15:37:56 +01:00
BasicBlock.cpp LibJS: Add a basic pass manager and add some basic passes 2021-06-15 22:06:33 +04:30
BasicBlock.h LibJS: Make basic block size customizable 2021-06-15 22:06:33 +04:30
Generator.cpp LibJS: Remove unused header includes 2021-08-01 08:10:16 +02:00
Generator.h LibJS: Implement generator functions (only in bytecode mode) 2021-06-11 00:30:09 +02:00
Instruction.cpp LibJS: Move Instruction::length() to the Op.h header 2021-06-09 09:24:32 +02:00
Instruction.h LibJS: Rename {Abstract,Typed => Loosely,Strictly}{Equals,Inequals} 2021-09-24 09:13:57 +02:00
Interpreter.cpp LibJS: Also set ExecutionContext::realm in Bytecode::Interpreter::run() 2021-09-13 21:06:18 +01:00
Interpreter.h LibJS: Allocate a Realm next to GlobalObject in Interpreter::create() 2021-09-12 11:10:20 +01:00
Label.h LibJS: Add a basic pass manager and add some basic passes 2021-06-15 22:06:33 +04:30
Op.cpp LibJS: Add an optimization to avoid needless arguments object creation 2021-10-05 10:15:14 +01:00
Op.h LibJS: Rename {Abstract,Typed => Loosely,Strictly}{Equals,Inequals} 2021-09-24 09:13:57 +02:00
PassManager.h LibJS: Add a basic pass manager and add some basic passes 2021-06-15 22:06:33 +04:30
Register.h LibJS: Always keep the global object in bytecode VM register $1 2021-06-10 21:59:49 +02:00
StringTable.cpp LibJS: Store strings in a string table 2021-06-09 17:42:52 +02:00
StringTable.h LibJS: Store strings in a string table 2021-06-09 17:42:52 +02:00