Bug 194634 - [JSC] Should have default NativeJITCode
Summary: [JSC] Should have default NativeJITCode
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks: 193606
  Show dependency treegraph
 
Reported: 2019-02-13 19:15 PST by Yusuke Suzuki
Modified: 2019-02-14 13:38 PST (History)
7 users (show)

See Also:


Attachments
Patch (3.34 KB, patch)
2019-02-14 02:02 PST, Yusuke Suzuki
mark.lam: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2019-02-13 19:15:42 PST
We are creating so many NativeJITCode which are identical... Just calling trampoline.
Comment 1 Yusuke Suzuki 2019-02-13 19:16:00 PST
It takes 14KB in JSGlobalObject initialization.
Comment 2 Yusuke Suzuki 2019-02-14 02:02:15 PST
Created attachment 362006 [details]
Patch
Comment 3 Caio Lima 2019-02-14 03:00:41 PST
Comment on attachment 362006 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=362006&action=review

Informal review here. Patch LGTM, but I have some questions.

> Source/JavaScriptCore/runtime/VM.cpp:693
> +    static NativeJITCode* result;

It is a little nit picking, but maybe would be good initialise this to nullptr.

> Source/JavaScriptCore/runtime/VM.cpp:695
> +    std::call_once(onceKey, [&] {

I was wondering why do you prefer this instead of:

```
if (!result)
    result = new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk, NoIntrinsic);

return makeRef(*result);
...
```
Comment 4 Caio Lima 2019-02-14 03:35:57 PST
Comment on attachment 362006 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=362006&action=review

> Source/JavaScriptCore/runtime/VM.cpp:698
> +    return makeRef(*result);

IIUC, NativeJITCode is ThreadSafeRefCounted. How do we guarantee that ```result``` will always pointing to a valid object? Once last ```NativeExecutable``` is destroyed, it will also destroy NativeJITCode, but ```result``` will be pointing to an invalid address.
Comment 5 Mark Lam 2019-02-14 09:36:47 PST
Comment on attachment 362006 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=362006&action=review

r=me with ref fix.

>> Source/JavaScriptCore/runtime/VM.cpp:693
>> +    static NativeJITCode* result;
> 
> It is a little nit picking, but maybe would be good initialise this to nullptr.

I think statics already null by default.

>> Source/JavaScriptCore/runtime/VM.cpp:695
>> +    std::call_once(onceKey, [&] {
> 
> I was wondering why do you prefer this instead of:
> 
> ```
> if (!result)
>     result = new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk, NoIntrinsic);
> 
> return makeRef(*result);
> ...
> ```

A process may instantiate more than 1 VMs on multiple threads.  Hence, std::call_once is necessary.

>> Source/JavaScriptCore/runtime/VM.cpp:698
>> +    return makeRef(*result);
> 
> IIUC, NativeJITCode is ThreadSafeRefCounted. How do we guarantee that ```result``` will always pointing to a valid object? Once last ```NativeExecutable``` is destroyed, it will also destroy NativeJITCode, but ```result``` will be pointing to an invalid address.

I think Caio is correct here.  This can happen if the VM is destroyed before we create any new VMs.  Let's ref the NativeJITCode inside the std::call_once so that it will never be deref'ed to 0.
Comment 6 Caio Lima 2019-02-14 10:50:14 PST
Comment on attachment 362006 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=362006&action=review

>>> Source/JavaScriptCore/runtime/VM.cpp:695
>>> +    std::call_once(onceKey, [&] {
>> 
>> I was wondering why do you prefer this instead of:
>> 
>> ```
>> if (!result)
>>     result = new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk, NoIntrinsic);
>> 
>> return makeRef(*result);
>> ...
>> ```
> 
> A process may instantiate more than 1 VMs on multiple threads.  Hence, std::call_once is necessary.

Thx for the explanation!

>>> Source/JavaScriptCore/runtime/VM.cpp:698
>>> +    return makeRef(*result);
>> 
>> IIUC, NativeJITCode is ThreadSafeRefCounted. How do we guarantee that ```result``` will always pointing to a valid object? Once last ```NativeExecutable``` is destroyed, it will also destroy NativeJITCode, but ```result``` will be pointing to an invalid address.
> 
> I think Caio is correct here.  This can happen if the VM is destroyed before we create any new VMs.  Let's ref the NativeJITCode inside the std::call_once so that it will never be deref'ed to 0.

Is it possible to write a test to cover such case?
Comment 7 Mark Lam 2019-02-14 10:52:13 PST
Comment on attachment 362006 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=362006&action=review

>>> Source/JavaScriptCore/runtime/VM.cpp:698
>>> +    return makeRef(*result);
>> 
>> IIUC, NativeJITCode is ThreadSafeRefCounted. How do we guarantee that ```result``` will always pointing to a valid object? Once last ```NativeExecutable``` is destroyed, it will also destroy NativeJITCode, but ```result``` will be pointing to an invalid address.
> 
> I think Caio is correct here.  This can happen if the VM is destroyed before we create any new VMs.  Let's ref the NativeJITCode inside the std::call_once so that it will never be deref'ed to 0.

Yusuke pointed out that this is already handled by makeRef().  Note: he's not using adoptRef().  So all is well.
Comment 8 Yusuke Suzuki 2019-02-14 10:55:29 PST
Comment on attachment 362006 [details]
Patch

Thank you for your review!
Comment 9 Yusuke Suzuki 2019-02-14 11:10:32 PST
Committed r241557: <https://trac.webkit.org/changeset/241557>
Comment 10 Radar WebKit Bug Importer 2019-02-14 11:14:20 PST
<rdar://problem/48080631>