Commit graph

1815 commits

Author SHA1 Message Date
Andreas Kling
4444bcabde LibJS: Make Reference aware of DeclarativeEnvironment indices
VM::resolve_binding() can now return a Reference that knows the exact
binding index if it's pointing into a DeclarativeEnvironment.

Reading/writing through the Reference will now use direct environment
access when possible.
2021-10-07 00:23:36 +02:00
Andreas Kling
540ce075b6 LibJS: Add direct (indexed) binding accessors to DeclarativeEnvironment
This patch adds two DeclarativeEnvironment APIs:

- get_binding_value_direct()
- set_mutable_binding_direct()

These work identically to their non-direct-suffixed counterparts, but
take an index instead of a bound name. This will allow someone who has
a binding index to get/set that binding directly without any additional
hash lookups.
2021-10-07 00:23:36 +02:00
Andreas Kling
cb696eff08 LibJS: Make Environment::has_binding() optionally return binding index
If the caller wants to use the binding index for anything, if there is
such a thing, it can now be obtained via an optional out-parameter.
2021-10-07 00:23:36 +02:00
Andreas Kling
6ef5464015 LibJS: Make DeclarativeEnvironment store bindings in a Vector
The previous storage for DeclarativeEnvironment looked like this:

    HashMap<FlyString, Binding> m_bindings;

This patch changes that to:

    HashMap<FlyString, size_t> m_names;
    Vector<Binding> m_bindings;

The main goal here is to give each binding an index that can ultimately
be cached and used for optimized environment accesses.
2021-10-07 00:23:36 +02:00
Linus Groh
78fd8c1ca2 LibJS: Make escape_regexp_pattern() a RegExpObject member function
Similarly to regexp_initialize() this can be a member function instead
of taking a RegExpObject argument.
Having it available outside RegExpPrototype is also useful for other
things that need RegExp.prototype.source behavior - e.g. the REPL for
pretty-printing.
2021-10-05 18:35:49 +01:00
Andreas Kling
83bd675477 LibJS: Make WeakContainer pruning do less work
Instead of iterating *all* swept cells when pruning weak containers,
only iterate the cells actually *in* the container.

Also, instead of compiling a list of all swept cells, we can simply
check the Cell::state() flag to know if something should be pruned.
2021-10-05 18:52:00 +02:00
Andreas Kling
6108bac606 LibJS: Only do a single property lookup in internal_get_own_property()
Instead of checking storage_has(), followed by storage_get(), we can do
storage_get() directly and avoid a redundant property lookup.

This exposed a bug in SimpleIndexedPropertyStorage::get() which would
previously succeed for array holes.
2021-10-05 15:15:29 +02:00
Linus Groh
8074bdc049 LibJS: Skip declarative env in block statement without lexical decls
The idea here is simple: If the block statement doesn't contain any
lexical declarations, we don't need to allocate, initialize and
eventually garbage collect a new declarative environment.
This even makes lookups across nested blocks slightly faster as we don't
have to traverse a chain of empty environments anymore - instead, the
execution context just stores the outermost non-empty one.

This doesn't speed up test-js considerably, but has a noticeable effect
on test262 and real-world web content :^)
2021-10-05 14:52:53 +02:00
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
Linus Groh
fcb355f193 LibJS: Set arguments_object_needed = false if scope_body == nullptr
For obvious reasons.
2021-10-05 10:15:14 +01:00
Linus Groh
b2bded390a LibJS: Stop iterating lexically declared names once 'arguments' is found
In ECMAScriptFunctionObject::function_declaration_instantiation() we
iterate over all lexically declared names of the function scope body to
determine whether any of them is named 'arguments', because we don't
need to create an arguments object in that case. We can also stop at
that point, because the decision won't change anymore.
2021-10-05 10:15:14 +01:00
Linus Groh
3ab22c8012 LibJS: Rename needs_argument_object to arguments_object_needed
- It's an "arguments object", not "argument object"
- This is what the spec calls it (argumentsObjectNeeded)
2021-10-05 10:15:14 +01:00
Andreas Kling
d872f0d503 LibJS: Avoid an unnecessary String in create_mapped_arguments_object() 2021-10-04 22:54:50 +02:00
Andreas Kling
f4180b7269 LibJS: Avoid an unnecessary String in create_list_from_array_like() 2021-10-04 22:54:50 +02:00
Linus Groh
32b620c62d LibJS: Convert atomic_compare_exchange_impl() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
74e29fa60b LibJS: Convert perform_atomic_operation() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Linus Groh
f95560b21a LibJS: Convert atomic_read_modify_write() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
6cef1dfa6d LibJS: Convert validate_atomic_access() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
12ac2338aa LibJS: Convert validate_integer_typed_array() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
253d9a38d1 LibJS: Convert typed_array_create() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
04ff12740c LibJS: Convert initialize_typed_array_from_list() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
d551e0e55e LibJS: Convert init_typed_array_from_array_like() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
8e3957767e LibJS: Convert init_typed_array_from_typed_array() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
7f86c32d62 LibJS: Convert init_typed_array_from_array_buffer() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
3655aee543 LibJS: Convert validate_typed_array() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
d7d73f9100 LibJS: Convert to_property_descriptor() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
2f42675ebd LibJS: Convert ordinary_set_with_own_descriptor() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Linus Groh
3b59a4577d LibJS: Convert define_properties() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Linus Groh
0a49a2db60 LibJS: Convert set_immutable_prototype() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Andreas Kling
0cb4d48283 LibJS: Remove unused ExecutionContext::arguments_object 2021-10-03 23:58:21 +02:00
Linus Groh
1f7068ace9 LibJS: Remove unused TemporaryChange include from Object.cpp 2021-10-03 21:40:07 +01:00
Linus Groh
e5b8544762 LibJS: Convert enumerable_own_property_names() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
3af559ee8a LibJS: Convert test_integrity_level() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
ed5a9aa038 LibJS: Convert set_integrity_level() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
3be26f56db LibJS: Convert has_own_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
f38a5957bf LibJS: Convert has_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
a29b7a3ec7 LibJS: Convert delete_property_or_throw() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
fe86b04b42 LibJS: Convert define_property_or_throw() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
ebf57df431 LibJS: Convert create_non_enum_data_p_or_throw() to ThrowCompletionOr
The actual name is a bit longer, but you know what I mean :^)
2021-10-03 20:14:03 +01:00
Linus Groh
364dd42fc8 LibJS: Convert create_data_property_or_throw() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
bb2499cd7a LibJS: Convert create_method_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
fb443b3fb4 LibJS: Convert create_data_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
1d45541278 LibJS: Convert Object::set() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
b7e5f08e56 LibJS: Convert Object::get() to ThrowCompletionOr
To no one's surprise, this patch is pretty big - this is possibly the
most used AO of all of them. Definitely worth it though.
2021-10-03 20:14:03 +01:00
Linus Groh
9b6c09e2c4 LibJS: Convert is_extensible() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
fa2ac5b759 LibJS: Convert ordinary_to_primitive() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-03 20:14:03 +01:00
Linus Groh
867b19affb LibJS: Convert install_error_cause() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
4d5bd092ea LibJS: Use MUST() where applicable 2021-10-03 20:14:03 +01:00
Linus Groh
7cd3f7de61 LibJS: Add a MUST() macro, like TRY() but for the spec's ! shortcut 2021-10-03 20:14:03 +01:00
davidot
04454efa72 LibJS: Fix improper usages of forward as flagged by SonarCloud 2021-10-03 17:42:05 +02:00