Hello WebKittens,

We did long-wanted refactoring: JSC runtime functions start getting lexical 
realm JSGlobalObject* instead of ExecState*.
Since this slightly changes how we interact with JSC, we would like to show 
what is changed.

This refactoring involves several changes.

1. JSC interface starts getting JSGlobalObject* instead of ExecState*.
2. ExecState* is consistently renamed to CallFrame*. And it is used only when 
CallFrame* is actually required (accessing arguments etc.) And the name 
`ExecState*` is removed from the tree.

Previously we are using `ExecState*`. But this caused multiple problems so far. 
Here is the motivation behind this change.

1. Fix so many bugs in JSC, and makes JSC’s inlining finally sane

ExecState* is simply wrong in various cases. We are getting lexical 
JSGlobalObject* by calling `ExecState::lexicalGlobalObject()`. But it returns 
wrong value if the current function is inlined in DFG/FTL. ExecState is 
pointing the whole function’s CallFrame. And returned `JSGlobalObject*` is 
lexical JSGlobalObject* of top-most function. If inlined function has different 
lexical JSGlobalObject* from the top-most one, we are getting wrong 
JSGlobalObject*. Getting `CodeBlock*` from ExecState* is also wrong. We had 
multiple places that is getting CodeBlock to get strict-mode flag, and this 
code does not consider about inlining. Instead, we pass lexical JSGlobalObject* 
explicitly. This change makes fixing these issues very easy.

2. Clear separation between CallFrame* and JSGlobalObject*, making API clean

CallFrame* is only used when we actually want to access CallFrame* (to get 
arguments etc.). Previously, we are using CallFrame* as an useful abstraction 
to offer an access to various things including lexical JSGlobalObject*. But 
since this is CallFrame*, it exist only after executing some JS code. So if we 
want to call JSC C++ runtime functions without JS code (calling JS runtime 
things directly from C++ world), we do not have ExecState* at all at that time. 
To make it OK, we invented `globalExec()`, which is saying CallFrame*, but in 
fact, it was not a CallFrame*. It exists only for calling these C++ runtime 
functions when CallFrame* does not exist yet. This is ugly and we really wanted 
to remove this. It is now finally removed in 99% of code. Through this 
refactoring, we found multiple places that is accessing |thisValue| etc. while 
it should not have any CallFrame*. So they are accessing wrong thing because 
CallFrame* offers the way to access the wrong thing. We should not offer such a 
wrong abstraction.
And now, we can pass lexical JSGlobalObject* explicitly. Previously, we do not 
have a good way to create ExecState* conveniently. So we just randomly pass 
accessible ExecState* to C++ runtime functions. This looks working, but it is 
wrong when we consider about lexical JSGlobalObject* carefully. Now interface 
explicitly requires lexical JSGlobalObject*, so we can pass the correct 
JSGlobalObject* explicitly.

3. Steps towards putting all JSCells into IsoSubspace

JSC had very fancy hack: all callable JS cells must be small enough (it can be 
allocated in MarkedBlock). This was originally required to make 
`ExecState::vm()` function super fast. We are calling this so frequently and we 
needed to keep it fast. And we can make it fast if we have such a weird 
guarantee. But it turned out that this assumption is not good one for the world 
putting all JSCells into IsoSubspace. We would like to introduce some 
optimizations to IsoSubspace to make it scalable to various JSCell types. But 
this optimization requires that the above assumption is discarded. To make it 
work, we do this refactoring and now we get VM& from JSGlobalObject instead of 
ExecState.

I’m now doing some follow-up work which makes things more solid. And I’m 
planning to do some minor refactoring, like, naming things consistently etc.
I’m also planning to fix various bugs found while doing this refactoring.
And…, this change paves the way to (3), which I’m currently focusing on :)

Best regards,
Yusuke Suzuki
_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev

Reply via email to