Changeset 235852 in webkit


Ignore:
Timestamp:
Sep 10, 2018 11:19:09 AM (6 years ago)
Author:
yusukesuzuki@slowstart.org
Message:

[WTF] Add Markable<T, Traits>
https://bugs.webkit.org/show_bug.cgi?id=189231

Reviewed by Sam Weinig.

Source/WebCore:

Use Markable<Seconds> and Markable<WallTime> in ResourceResponseBase.
Since these fields are parsed results from http header fields, Seconds::nan() and WallTime::nan()
can be used as an empty value for these fields. Thus we can use Markable because it uses
these nan values as an empty values (they are configured by Seconds::MarkableTraits and WallTime::MarkableTraits).
This reduces the size of ResourceResponseBase from 448 to 416.

  • platform/network/ResourceResponseBase.h:

Source/WTF:

We can represent a value with nullopt by using std::optional<T>. However, std::optional<T> has storage efficiency
problem. It always has a bool indicating that the value is nullopt or not. If we have a following class,

class A {

std::optional<WallTime> m_timeA;
std::optional<WallTime> m_timeB;
std::optional<WallTime> m_timeC;

};

This class has significant amount of padding between m_timeA / m_timeB, m_timeB / m_timeC due to the above bool.

If we know that WallTime has a value that represents invalid, we can use it instead and save the storage.
This is very similar problem to our HashTable implementation. In our HashTable implementation, we need Deleted
and Empty value, which can represent Deleted and Empty values without sacrificing storage efficiency.

We should have similar mechanism here. In this patch, we have WTF::Markable<T, Traits>. Traits offers
Traits::isEmptyValue(value) and Traits::emptyValue(). Then, we use this empty value instead of having bool
flag. This way, we can make sizeof(WTF::Markable<T>) == sizeof(T).

This idea is inspired from https://github.com/akrzemi1/markable. But we would like to have WTF::Markable<T>
here instead of importing it since we would like to have (1) integrated interfaces with std::optional<T> and (2)
aligned function names to HashTraits' isEmptyValue and emptyValue.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/CMakeLists.txt:
  • wtf/Markable.h: Added.

(WTF::std::underlying_type<EnumType>::type>::max): EnumMarkableTraits can be used as an MarkableTraits for enum
values. We can specify a constant value as an empty value.
(WTF::IntegralMarkableTraits::isEmptyValue):
(WTF::IntegralMarkableTraits::emptyValue): IntegralMarkableTraits can be used as an MarkableTraits for integral
types including int etc.
(WTF::Markable::Markable):
(WTF::Markable::operator bool const):
(WTF::Markable::reset):
(WTF::Markable::value const):
(WTF::Markable::value):
(WTF::Markable::operator-> const):
(WTF::Markable::operator->):
(WTF::Markable::operator* const):
(WTF::Markable::operator*):
(WTF::Markable::operator std::optional<T>):
(WTF::Markable::operator std::optional<T> const): This operator allows us to cast Markable<T> to
std::optional<T>.

  • wtf/MonotonicTime.h:

(WTF::MonotonicTime::MarkableTraits::isEmptyValue):
(WTF::MonotonicTime::MarkableTraits::emptyValue): MarkableTraits for MonotonicTime. MonotonicTime::nan() is used
as an empty value.

  • wtf/Seconds.h:

(WTF::Seconds::MarkableTraits::isEmptyValue):
(WTF::Seconds::MarkableTraits::emptyValue): MarkableTraits for Seconds. Seconds::nan() is used as an empty value.

  • wtf/WallTime.h:

(WTF::WallTime::nan):
(WTF::WallTime::MarkableTraits::isEmptyValue):
(WTF::WallTime::MarkableTraits::emptyValue): MarkableTraits for WallTime. WallTime::nan() is used as an empty value.

Tools:

Add tests for Markable.

  • TestWebKitAPI/CMakeLists.txt:
  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WTF/Markable.cpp: Added.

(TestWebKitAPI::TEST):

Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r235841 r235852  
     12018-09-10  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [WTF] Add Markable<T, Traits>
     4        https://bugs.webkit.org/show_bug.cgi?id=189231
     5
     6        Reviewed by Sam Weinig.
     7
     8        We can represent a value with nullopt by using std::optional<T>. However, std::optional<T> has storage efficiency
     9        problem. It always has a bool indicating that the value is nullopt or not. If we have a following class,
     10
     11            class A {
     12                std::optional<WallTime> m_timeA;
     13                std::optional<WallTime> m_timeB;
     14                std::optional<WallTime> m_timeC;
     15            };
     16
     17        This class has significant amount of padding between m_timeA / m_timeB, m_timeB / m_timeC due to the above bool.
     18
     19        If we know that WallTime has a value that represents invalid, we can use it instead and save the storage.
     20        This is very similar problem to our HashTable implementation. In our HashTable implementation, we need Deleted
     21        and Empty value, which can represent Deleted and Empty values without sacrificing storage efficiency.
     22
     23        We should have similar mechanism here. In this patch, we have WTF::Markable<T, Traits>. Traits offers
     24        `Traits::isEmptyValue(value)` and `Traits::emptyValue()`. Then, we use this empty value instead of having bool
     25        flag. This way, we can make `sizeof(WTF::Markable<T>) == sizeof(T)`.
     26
     27        This idea is inspired from https://github.com/akrzemi1/markable. But we would like to have WTF::Markable<T>
     28        here instead of importing it since we would like to have (1) integrated interfaces with std::optional<T> and (2)
     29        aligned function names to HashTraits' `isEmptyValue` and `emptyValue`.
     30
     31        * WTF.xcodeproj/project.pbxproj:
     32        * wtf/CMakeLists.txt:
     33        * wtf/Markable.h: Added.
     34        (WTF::std::underlying_type<EnumType>::type>::max): EnumMarkableTraits can be used as an MarkableTraits for enum
     35        values. We can specify a constant value as an empty value.
     36        (WTF::IntegralMarkableTraits::isEmptyValue):
     37        (WTF::IntegralMarkableTraits::emptyValue): IntegralMarkableTraits can be used as an MarkableTraits for integral
     38        types including int etc.
     39        (WTF::Markable::Markable):
     40        (WTF::Markable::operator bool const):
     41        (WTF::Markable::reset):
     42        (WTF::Markable::value const):
     43        (WTF::Markable::value):
     44        (WTF::Markable::operator-> const):
     45        (WTF::Markable::operator->):
     46        (WTF::Markable::operator* const):
     47        (WTF::Markable::operator*):
     48        (WTF::Markable::operator std::optional<T>):
     49        (WTF::Markable::operator std::optional<T> const): This operator allows us to cast Markable<T> to
     50        std::optional<T>.
     51        * wtf/MonotonicTime.h:
     52        (WTF::MonotonicTime::MarkableTraits::isEmptyValue):
     53        (WTF::MonotonicTime::MarkableTraits::emptyValue): MarkableTraits for MonotonicTime. MonotonicTime::nan() is used
     54        as an empty value.
     55        * wtf/Seconds.h:
     56        (WTF::Seconds::MarkableTraits::isEmptyValue):
     57        (WTF::Seconds::MarkableTraits::emptyValue): MarkableTraits for Seconds. Seconds::nan() is used as an empty value.
     58        * wtf/WallTime.h:
     59        (WTF::WallTime::nan):
     60        (WTF::WallTime::MarkableTraits::isEmptyValue):
     61        (WTF::WallTime::MarkableTraits::emptyValue): MarkableTraits for WallTime. WallTime::nan() is used as an empty value.
     62
    1632018-09-09  Fujii Hironori  <Hironori.Fujii@sony.com>
    264
  • trunk/Source/WTF/WTF.xcodeproj/project.pbxproj

    r235547 r235852  
    633633                E3A32BC21FC830E2007D7E76 /* JSValueMalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSValueMalloc.cpp; sourceTree = "<group>"; };
    634634                E3A32BC31FC830E2007D7E76 /* JSValueMalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueMalloc.h; sourceTree = "<group>"; };
     635                304CA4E41375437EBE931D03 /* Markable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Markable.h; sourceTree = "<group>"; };
    635636                E3CF76902115D6BA0091DE48 /* CompactPointerTuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompactPointerTuple.h; sourceTree = "<group>"; };
    636637                E3E158251EADA53C004A079D /* SystemFree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemFree.h; sourceTree = "<group>"; };
     
    965966                                A8A472C7151A825B004123FF /* MainThread.h */,
    966967                                1A233C7C17DAA6E300A93ACF /* MallocPtr.h */,
     968                                304CA4E41375437EBE931D03 /* Markable.h */,
    967969                                A8A472C9151A825B004123FF /* MathExtras.h */,
    968970                                1447AEC818FCE59400B3D7FF /* mbmalloc.cpp */,
  • trunk/Source/WTF/wtf/CMakeLists.txt

    r235547 r235852  
    123123    MainThread.h
    124124    MallocPtr.h
     125    Markable.h
    125126    MathExtras.h
    126127    MediaTime.h
  • trunk/Source/WTF/wtf/MonotonicTime.h

    r229174 r235852  
    166166    }
    167167
     168    struct MarkableTraits;
     169
    168170private:
    169171    constexpr MonotonicTime(double rawValue)
     
    173175
    174176    double m_value { 0 };
     177};
     178
     179struct MonotonicTime::MarkableTraits {
     180    static bool isEmptyValue(MonotonicTime time)
     181    {
     182        return std::isnan(time.m_value);
     183    }
     184
     185    static constexpr MonotonicTime emptyValue()
     186    {
     187        return MonotonicTime::nan();
     188    }
    175189};
    176190
  • trunk/Source/WTF/wtf/Seconds.h

    r229209 r235852  
    248248    }
    249249
     250    struct MarkableTraits;
     251
    250252private:
    251253    double m_value { 0 };
     
    254256WTF_EXPORT_PRIVATE void sleep(Seconds);
    255257
     258struct Seconds::MarkableTraits {
     259    static bool isEmptyValue(Seconds seconds)
     260    {
     261        return std::isnan(seconds.value());
     262    }
     263
     264    static constexpr Seconds emptyValue()
     265    {
     266        return Seconds::nan();
     267    }
     268};
     269
    256270inline namespace seconds_literals {
    257271
  • trunk/Source/WTF/wtf/WallTime.h

    r228942 r235852  
    5757   
    5858    static constexpr WallTime infinity() { return fromRawSeconds(std::numeric_limits<double>::infinity()); }
     59    static constexpr WallTime nan() { return fromRawSeconds(std::numeric_limits<double>::quiet_NaN()); }
    5960   
    6061    constexpr Seconds secondsSinceEpoch() const { return Seconds(m_value); }
     
    133134        return *this;
    134135    }
     136
     137    struct MarkableTraits;
     138
    135139private:
    136140    constexpr WallTime(double rawValue)
     
    140144
    141145    double m_value { 0 };
     146};
     147
     148struct WallTime::MarkableTraits {
     149    static bool isEmptyValue(WallTime time)
     150    {
     151        return std::isnan(time.m_value);
     152    }
     153
     154    static constexpr WallTime emptyValue()
     155    {
     156        return WallTime::nan();
     157    }
    142158};
    143159
  • trunk/Source/WebCore/ChangeLog

    r235850 r235852  
     12018-09-10  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [WTF] Add Markable<T, Traits>
     4        https://bugs.webkit.org/show_bug.cgi?id=189231
     5
     6        Reviewed by Sam Weinig.
     7
     8        Use Markable<Seconds> and Markable<WallTime> in ResourceResponseBase.
     9        Since these fields are parsed results from http header fields, Seconds::nan() and WallTime::nan()
     10        can be used as an empty value for these fields. Thus we can use Markable because it uses
     11        these nan values as an empty values (they are configured by Seconds::MarkableTraits and WallTime::MarkableTraits).
     12        This reduces the size of ResourceResponseBase from 448 to 416.
     13
     14        * platform/network/ResourceResponseBase.h:
     15
    1162018-09-07  Matt Rajca  <mrajca@apple.com>
    217
  • trunk/Source/WebCore/platform/network/ResourceResponseBase.h

    r234422 r235852  
    3333#include "ParsedContentRange.h"
    3434#include "URL.h"
     35#include <wtf/Markable.h>
    3536#include <wtf/WallTime.h>
    3637
     
    215216
    216217private:
    217     mutable std::optional<Seconds> m_age;
    218     mutable std::optional<WallTime> m_date;
    219     mutable std::optional<WallTime> m_expires;
    220     mutable std::optional<WallTime> m_lastModified;
     218    mutable Markable<Seconds, Seconds::MarkableTraits> m_age;
     219    mutable Markable<WallTime, WallTime::MarkableTraits> m_date;
     220    mutable Markable<WallTime, WallTime::MarkableTraits> m_expires;
     221    mutable Markable<WallTime, WallTime::MarkableTraits> m_lastModified;
    221222    mutable ParsedContentRange m_contentRange;
    222223    mutable CacheControlDirectives m_cacheControlDirectives;
  • trunk/Tools/ChangeLog

    r235851 r235852  
     12018-09-10  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [WTF] Add Markable<T, Traits>
     4        https://bugs.webkit.org/show_bug.cgi?id=189231
     5
     6        Reviewed by Sam Weinig.
     7
     8        Add tests for Markable.
     9
     10        * TestWebKitAPI/CMakeLists.txt:
     11        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     12        * TestWebKitAPI/Tests/WTF/Markable.cpp: Added.
     13        (TestWebKitAPI::TEST):
     14
    1152018-09-10  Simon Fraser  <simon.fraser@apple.com>
    216
  • trunk/Tools/TestWebKitAPI/CMakeLists.txt

    r235718 r235852  
    124124    ${TESTWEBKITAPI_DIR}/Tests/WTF/Logger.cpp
    125125    ${TESTWEBKITAPI_DIR}/Tests/WTF/MD5.cpp
     126    ${TESTWEBKITAPI_DIR}/Tests/WTF/Markable.cpp
    126127    ${TESTWEBKITAPI_DIR}/Tests/WTF/MathExtras.cpp
    127128    ${TESTWEBKITAPI_DIR}/Tests/WTF/MediaTime.cpp
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r235850 r235852  
    4242                0F2C20B81DCD545000542D9E /* Time.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C20B71DCD544800542D9E /* Time.cpp */; };
    4343                0F30CB5C1FCE1796004B5323 /* ConcurrentPtrHashSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F30CB5B1FCE1792004B5323 /* ConcurrentPtrHashSet.cpp */; };
     44                4909EE3A2D09480C88982D56 /* Markable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC79F168BE454E579E417B05 /* Markable.cpp */; };
    4445                0F3B94A71A77267400DE3272 /* WKWebViewEvaluateJavaScript.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B94A51A77266C00DE3272 /* WKWebViewEvaluateJavaScript.mm */; };
    4546                0F4FFA9E1ED3AA8500F7111F /* SnapshotViaRenderInContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F4FFA9D1ED3AA8500F7111F /* SnapshotViaRenderInContext.mm */; };
     
    12371238                0F2C20B71DCD544800542D9E /* Time.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Time.cpp; sourceTree = "<group>"; };
    12381239                0F30CB5B1FCE1792004B5323 /* ConcurrentPtrHashSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConcurrentPtrHashSet.cpp; sourceTree = "<group>"; };
     1240                EC79F168BE454E579E417B05 /* Markable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Markable.cpp; sourceTree = "<group>"; };
    12391241                0F3B94A51A77266C00DE3272 /* WKWebViewEvaluateJavaScript.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewEvaluateJavaScript.mm; sourceTree = "<group>"; };
    12401242                0F4FFA9D1ED3AA8500F7111F /* SnapshotViaRenderInContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SnapshotViaRenderInContext.mm; sourceTree = "<group>"; };
     
    30153017                                A57D54F41F3395D000A97AA7 /* Logger.cpp */,
    30163018                                A57D54F51F3395D000A97AA7 /* Logger.h */,
     3019                                EC79F168BE454E579E417B05 /* Markable.cpp */,
    30173020                                B4039F9C15E6D8B3007255D6 /* MathExtras.cpp */,
    30183021                                CD5393C71757BA9700C07123 /* MD5.cpp */,
     
    36003603                                7C83DF1D1D0A590C00FEBCF3 /* Lock.cpp in Sources */,
    36013604                                A57D54F61F3395D000A97AA7 /* Logger.cpp in Sources */,
     3605                                4909EE3A2D09480C88982D56 /* Markable.cpp in Sources */,
    36023606                                7C83DEED1D0A590C00FEBCF3 /* MathExtras.cpp in Sources */,
    36033607                                7C83DEEF1D0A590C00FEBCF3 /* MD5.cpp in Sources */,
Note: See TracChangeset for help on using the changeset viewer.