Bug 211328 - Allow Bitmap to use up to a UCPURegister word size for internal bit storage.
Summary: Allow Bitmap to use up to a UCPURegister word size for internal bit storage.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mark Lam
URL:
Keywords: InRadar
Depends on: 211340
Blocks:
  Show dependency treegraph
 
Reported: 2020-05-01 18:58 PDT by Mark Lam
Modified: 2020-05-05 10:13 PDT (History)
16 users (show)

See Also:


Attachments
proposed patch. (7.92 KB, patch)
2020-05-01 19:21 PDT, Mark Lam
no flags Details | Formatted Diff | Diff
proposed patch. (8.16 KB, patch)
2020-05-01 19:30 PDT, Mark Lam
no flags Details | Formatted Diff | Diff
proposed patch. (8.58 KB, patch)
2020-05-01 19:39 PDT, Mark Lam
ysuzuki: review+
Details | Formatted Diff | Diff
patch for landing. (8.16 KB, patch)
2020-05-01 22:51 PDT, Mark Lam
no flags Details | Formatted Diff | Diff
proposed patch. (58.40 KB, patch)
2020-05-04 23:06 PDT, Mark Lam
no flags Details | Formatted Diff | Diff
proposed patch w/ Win build fixes. (58.40 KB, patch)
2020-05-04 23:44 PDT, Mark Lam
ysuzuki: review+
Details | Formatted Diff | Diff
patch for landing. (59.03 KB, patch)
2020-05-05 00:25 PDT, Mark Lam
no flags Details | Formatted Diff | Diff
patch for landing. (59.03 KB, patch)
2020-05-05 08:41 PDT, Mark Lam
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Lam 2020-05-01 18:58:08 PDT
Previously, it was fixed at uint32_t.  This patch also allows it to use smaller ints (uint8_t, and uint16_t) if they will suffice.
Comment 1 Radar WebKit Bug Importer 2020-05-01 18:58:46 PDT
<rdar://problem/62755865>
Comment 2 Mark Lam 2020-05-01 19:21:40 PDT
Created attachment 398270 [details]
proposed patch.
Comment 3 Mark Lam 2020-05-01 19:30:35 PDT
Created attachment 398271 [details]
proposed patch.
Comment 4 Mark Lam 2020-05-01 19:39:16 PDT
Created attachment 398272 [details]
proposed patch.
Comment 5 Yusuke Suzuki 2020-05-01 20:03:00 PDT
Comment on attachment 398272 [details]
proposed patch.

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

r=me

> Source/WTF/wtf/Bitmap.h:51
> +template<size_t size, typename = std::true_type>
> +struct BitmapWordType {
> +    using type = UCPURegister;
> +};
> +
> +template<size_t size>
> +struct BitmapWordType<size, std::enable_if_t<(size <= 8), std::true_type>> {
> +    using type = uint8_t;
> +};
> +
> +template<size_t size>
> +struct BitmapWordType<size, std::enable_if_t<(size > 8 && size <= 16), std::true_type>> {
> +    using type = uint16_t;
> +};
> +
> +template<size_t size>
> +struct BitmapWordType<size, std::enable_if_t<(size > 16 && size <= 32 && sizeof(UCPURegister) > sizeof(uint32_t)), std::true_type>> {
> +    using type = uint32_t;
> +};
> +
> +template<size_t bitmapSize, typename WordType = typename BitmapWordType<bitmapSize>::type>

You can use std::conditional<>.

template<size_t size>
using BitmapWordType = std::conditional_t<size <= 8,
    uint8_t,
    std::conditional_t<size <= 16,
        uint16_t,
        std::conditional_t<size <= 32 && sizeof(UCPURegister) > sizeof(uint32_t),
            uint32_t,
            UCPURegister>>>;

And,

template<size_t bitmapSize, typename WordType = BitmapWordType<bitmapSize>>
Comment 6 Yusuke Suzuki 2020-05-01 20:08:27 PDT
Also, can you ensure that using `uint8_t`, `uint16_t` is better than using `uint32_t` in ARM etc. in terms of performance? And is it OK to use `uint8_t` and `uint16_t` while Bitmap needs to support concurrentTestAndSet etc.?
Comment 7 Yusuke Suzuki 2020-05-01 20:10:50 PDT
Comment on attachment 398272 [details]
proposed patch.

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

>> Source/WTF/wtf/Bitmap.h:51
>> +template<size_t bitmapSize, typename WordType = typename BitmapWordType<bitmapSize>::type>
> 
> You can use std::conditional<>.
> 
> template<size_t size>
> using BitmapWordType = std::conditional_t<size <= 8,
>     uint8_t,
>     std::conditional_t<size <= 16,
>         uint16_t,
>         std::conditional_t<size <= 32 && sizeof(UCPURegister) > sizeof(uint32_t),
>             uint32_t,
>             UCPURegister>>>;
> 
> And,
> 
> template<size_t bitmapSize, typename WordType = BitmapWordType<bitmapSize>>

Because of concurrentTestAndSet etc. I think Bitmap is assuming WordSize for a default type. I think it is better that we just specialize Bitmap with UCPURegister only when we want and keep Bitmap's default parameter `uint32_t`. What do you think of?
Comment 8 Mark Lam 2020-05-01 21:37:10 PDT
(In reply to Yusuke Suzuki from comment #7)
> Because of concurrentTestAndSet etc. I think Bitmap is assuming WordSize for
> a default type. I think it is better that we just specialize Bitmap with
> UCPURegister only when we want and keep Bitmap's default parameter
> `uint32_t`. What do you think of?

I talked to Yusuke offline.  We'll stick with uint32_t for Bitmap of size 32 or under.  We'll use UCPURegister for larger bitmaps.
Comment 9 Mark Lam 2020-05-01 22:51:21 PDT
Created attachment 398280 [details]
patch for landing.
Comment 10 Mark Lam 2020-05-02 10:01:47 PDT
I can reproduce the editing/undo-manager/undo-manager-delete-stale-undo-items.html failure locally is without my patch.  Filed https://bugs.webkit.org/show_bug.cgi?id=211340.
Comment 11 Mark Lam 2020-05-02 10:04:25 PDT
Thanks for the review.  Landed in r261050: <http://trac.webkit.org/r261050>.
Comment 12 Mark Lam 2020-05-02 12:08:11 PDT
Landed missing file in r261051: <http://trac.webkit.org/r261051>.
Comment 13 Mark Lam 2020-05-02 14:24:07 PDT
Rolled out in r261055: <http://trac.webkit.org/r261055> while I investigate what's going on with editing/undo-manager/undo-manager-delete-stale-undo-items.html.
Comment 14 Saam Barati 2020-05-03 18:46:11 PDT
Comment on attachment 398280 [details]
patch for landing.

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

> Source/WTF/wtf/StdIntExtras.h:34
> +#if USE(JSVALUE64)
> +using CPURegister = int64_t;
> +using UCPURegister = uint64_t;

nit: I know this is how things used to be, but it really doesn't feel like this should be keyed of JSVALUE64
Comment 15 Saam Barati 2020-05-03 18:47:08 PDT
Comment on attachment 398280 [details]
patch for landing.

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

> Source/WTF/wtf/Bitmap.h:33
> +template<size_t size>
> +using BitmapWordType = std::conditional_t<(size <= 32 && sizeof(UCPURegister) > sizeof(uint32_t)), uint32_t, UCPURegister>;

Why not have this inside the class?
Comment 16 Mark Lam 2020-05-03 18:50:29 PDT
Comment on attachment 398280 [details]
patch for landing.

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

>> Source/WTF/wtf/Bitmap.h:33
>> +using BitmapWordType = std::conditional_t<(size <= 32 && sizeof(UCPURegister) > sizeof(uint32_t)), uint32_t, UCPURegister>;
> 
> Why not have this inside the class?

Because it is used to provide the default type of the BitMap class.  Or do you mean why not just use the std::conditional as the default value?  Because it is a very long expression, and therefore makes the code less readable.

>> Source/WTF/wtf/StdIntExtras.h:34
>> +using UCPURegister = uint64_t;
> 
> nit: I know this is how things used to be, but it really doesn't feel like this should be keyed of JSVALUE64

Got any better suggestions?
Comment 17 Saam Barati 2020-05-04 11:00:33 PDT
Comment on attachment 398280 [details]
patch for landing.

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

>>> Source/WTF/wtf/Bitmap.h:33
>>> +using BitmapWordType = std::conditional_t<(size <= 32 && sizeof(UCPURegister) > sizeof(uint32_t)), uint32_t, UCPURegister>;
>> 
>> Why not have this inside the class?
> 
> Because it is used to provide the default type of the BitMap class.  Or do you mean why not just use the std::conditional as the default value?  Because it is a very long expression, and therefore makes the code less readable.

I see, sorry. I misread the pre-existing code.

>>> Source/WTF/wtf/StdIntExtras.h:34
>>> +using UCPURegister = uint64_t;
>> 
>> nit: I know this is how things used to be, but it really doesn't feel like this should be keyed of JSVALUE64
> 
> Got any better suggestions?

arm64 || x86_64?
Comment 18 Mark Lam 2020-05-04 23:06:38 PDT
Created attachment 398474 [details]
proposed patch.
Comment 19 Mark Lam 2020-05-04 23:44:39 PDT
Created attachment 398478 [details]
proposed patch w/ Win build fixes.
Comment 20 Yusuke Suzuki 2020-05-04 23:57:19 PDT
Comment on attachment 398474 [details]
proposed patch.

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

r=me with comment

> Source/WTF/wtf/PlatformCPU.h:320
> +/* CPU general purpose register width. */
> +#if CPU(ARM64) || CPU(X86_64) || CPU(MIPS64) || CPU(PPC64)
> +#define WTF_CPU_REGISTER64 1
> +#elif CPU(ARM) || CPU(X86) || CPU(MIPS) || CPU(PPC)
> +#define WTF_CPU_REGISTER32 1
> +#else
> +#error "Unknown register width"

This does not work since we support CPU(UNKNOWN) too.
I think that REGISTER64 and JSVALUE64 must be the same. If you define REGISTER64 here, I think we should define JSVALUE64 as,

#if CPU(REGISTER64)
#define WTF_USE_JSVALUE64
...

Can we just define this as,

#if !defined(WTF_CPU_REGISTER64) && !defined(WTF_CPU_REGISTER32)
#if CPU(ADDRESS64) || CPU(ARM64)
#define WTF_CPU_REGISTER64 1
#else
#define WTF_CPU_REGISTER32 1
#endif
#endif

And define USE_JSVALUE64 as,

#if CPU(REGISTER64)
#define USE_JSVALUE64
#else
#define USE_JSVALUE32
#endif
Comment 21 Yusuke Suzuki 2020-05-04 23:58:15 PDT
Comment on attachment 398474 [details]
proposed patch.

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

>> Source/WTF/wtf/PlatformCPU.h:320
>> +#error "Unknown register width"
> 
> This does not work since we support CPU(UNKNOWN) too.
> I think that REGISTER64 and JSVALUE64 must be the same. If you define REGISTER64 here, I think we should define JSVALUE64 as,
> 
> #if CPU(REGISTER64)
> #define WTF_USE_JSVALUE64
> ...
> 
> Can we just define this as,
> 
> #if !defined(WTF_CPU_REGISTER64) && !defined(WTF_CPU_REGISTER32)
> #if CPU(ADDRESS64) || CPU(ARM64)
> #define WTF_CPU_REGISTER64 1
> #else
> #define WTF_CPU_REGISTER32 1
> #endif
> #endif
> 
> And define USE_JSVALUE64 as,
> 
> #if CPU(REGISTER64)
> #define USE_JSVALUE64
> #else
> #define USE_JSVALUE32
> #endif

#if CPU(REGISTER64)
#define USE_JSVALUE64 1
#else
#define USE_JSVALUE32 1
#endif
Comment 22 Mark Lam 2020-05-05 00:25:07 PDT
Created attachment 398484 [details]
patch for landing.

Thanks for the review.  I've applied the suggested change to the definition of CPU(REGISTER64) and CPU(REGISTER32).
Comment 23 Mark Lam 2020-05-05 08:41:53 PDT
Created attachment 398512 [details]
patch for landing.
Comment 24 Mark Lam 2020-05-05 10:09:17 PDT
Landed in r261179: <http://trac.webkit.org/r261179>.