src/hb-ft.cc | 114 ++++++++++++-------------- src/hb-glib.cc | 50 +++++------ src/hb-icu.cc | 59 +++++-------- src/hb-machinery-private.hh | 192 +++++++++++++++++++++++++++++--------------- src/hb-ot-font.cc | 57 +++++-------- src/hb-ot-layout-private.hh | 2 src/hb-shape.cc | 75 ++++++++--------- src/hb-shaper.cc | 78 ++++++++--------- src/hb-ucdn.cc | 51 +++++------ src/hb-uniscribe.cc | 3 10 files changed, 356 insertions(+), 325 deletions(-)
New commits: commit 747d2564e6bdcc15cf6a197e543fb732924159c5 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 17:32:10 2018 -0700 [lazy] Port more diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 2a7ef7ba..a179eea9 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -698,7 +698,6 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> inline Returned * get_unconst (void) const { return const_cast<Returned *> (Funcs::convert (get_stored ())); } /* To be possibly overloaded by subclasses. */ - static inline const Returned* convert (const Stored *p) { return p; } static inline Returned* convert (Stored *p) { return p; } /* By default null/init/fini the object. */ diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc index e487582e..e423f255 100644 --- a/src/hb-shaper.cc +++ b/src/hb-shaper.cc @@ -26,7 +26,7 @@ #include "hb-private.hh" #include "hb-shaper-private.hh" -#include "hb-atomic-private.hh" +#include "hb-machinery-private.hh" static const hb_shaper_pair_t all_shapers[] = { @@ -36,52 +36,28 @@ static const hb_shaper_pair_t all_shapers[] = { }; -/* Thread-safe, lock-free, shapers */ +static void free_static_shapers (void); -static hb_atomic_ptr_t<const hb_shaper_pair_t> static_shapers; - -#ifdef HB_USE_ATEXIT -static -void free_static_shapers (void) +static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t, + hb_shapers_lazy_loader_t> { -retry: - const hb_shaper_pair_t *shapers = static_shapers.get (); - if (unlikely (!static_shapers.cmpexch (shapers, nullptr))) - goto retry; - - if (unlikely (shapers != all_shapers)) - free ((void *) shapers); -} -#endif - -const hb_shaper_pair_t * -_hb_shapers_get (void) -{ -retry: - hb_shaper_pair_t *shapers = const_cast<hb_shaper_pair_t *> (static_shapers.get ()); - - if (unlikely (!shapers)) + static inline hb_shaper_pair_t *create (void) { char *env = getenv ("HB_SHAPER_LIST"); - if (!env || !*env) { - (void) static_shapers.cmpexch (nullptr, &all_shapers[0]); - return (const hb_shaper_pair_t *) all_shapers; - } + if (!env || !*env) + return nullptr; - /* Not found; allocate one. */ - shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers)); + hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers)); if (unlikely (!shapers)) - { - (void) static_shapers.cmpexch (nullptr, &all_shapers[0]); - return (const hb_shaper_pair_t *) all_shapers; - } + return nullptr; memcpy (shapers, all_shapers, sizeof (all_shapers)); /* Reorder shaper list to prefer requested shapers. */ unsigned int i = 0; char *end, *p = env; - for (;;) { + for (;;) + { end = strchr (p, ','); if (!end) end = p + strlen (p); @@ -103,16 +79,32 @@ retry: p = end + 1; } - if (unlikely (!static_shapers.cmpexch (nullptr, shapers))) - { - free (shapers); - goto retry; - } - #ifdef HB_USE_ATEXIT - atexit (free_static_shapers); /* First person registers atexit() callback. */ + atexit (free_static_shapers); #endif + + return shapers; + } + static inline void destroy (const hb_shaper_pair_t *p) + { + free ((void *) p); } + static inline const hb_shaper_pair_t *get_null (void) + { + return all_shapers; + } +} static_shapers; - return shapers; +#ifdef HB_USE_ATEXIT +static +void free_static_shapers (void) +{ + static_shapers.free_instance (); +} +#endif + +const hb_shaper_pair_t * +_hb_shapers_get (void) +{ + return static_shapers.get_unconst (); } diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 22beb909..5810977d 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -190,7 +190,8 @@ hb_ScriptPlaceOpenType( } -struct hb_uniscribe_shaper_funcs_t { +struct hb_uniscribe_shaper_funcs_t +{ SIOT ScriptItemizeOpenType; SSOT ScriptShapeOpenType; SPOT ScriptPlaceOpenType; commit 7bd508a0c4ce426f474bfcc729cb39207dd1f7b4 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 17:19:55 2018 -0700 [lazy] Rename free() diff --git a/src/hb-ft.cc b/src/hb-ft.cc index e716ec91..01341b60 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -454,7 +454,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft static void free_static_ft_funcs (void) { - static_ft_funcs.free (); + static_ft_funcs.free_instance (); } #endif @@ -714,7 +714,7 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_ptr_t<FT_ static void free_static_ft_library (void) { - static_ft_library.free (); + static_ft_library.free_instance (); } #endif diff --git a/src/hb-glib.cc b/src/hb-glib.cc index af7a0fd3..342891d9 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -394,7 +394,7 @@ static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader static void free_static_glib_funcs (void) { - static_glib_funcs.free (); + static_glib_funcs.free_instance (); } #endif diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 551069fa..380a99c8 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -383,7 +383,7 @@ static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ static void free_static_icu_funcs (void) { - static_icu_funcs.free (); + static_icu_funcs.free_instance (); } #endif diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index e60e3bec..2a7ef7ba 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -637,7 +637,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> { do_destroy (instance.get ()); } - inline void free (void) + inline void free_instance (void) { retry: Stored *p = instance.get (); @@ -720,7 +720,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> static inline void destroy (Stored *p) { p->fini (); - ::free (p); + free (p); } private: diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 0b14ff1e..9da8fc7d 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -264,7 +264,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot static void free_static_ot_funcs (void) { - static_ot_funcs.free (); + static_ot_funcs.free_instance (); } #endif diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 22a2020b..86aa59ab 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -50,7 +50,7 @@ static void free_static_shaper_list (void); static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, - hb_shaper_list_lazy_loader_t> + hb_shaper_list_lazy_loader_t> { static inline const char ** create (void) { @@ -72,7 +72,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, } static inline void destroy (const char **l) { - ::free (l); + free (l); } static inline const char ** get_null (void) { @@ -85,7 +85,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, static void free_static_shaper_list (void) { - static_shaper_list.free (); + static_shaper_list.free_instance (); } #endif diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index 6b1bb804..7b26e512 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -267,7 +267,7 @@ static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader static void free_static_ucdn_funcs (void) { - static_ucdn_funcs.free (); + static_ucdn_funcs.free_instance (); } #endif commit a3b97db910662e26bafe6e6bc1c36b437f4ed931 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 17:14:32 2018 -0700 [lazy] Port more to it diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 01734f8f..22a2020b 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -32,6 +32,7 @@ #include "hb-shape-plan-private.hh" #include "hb-buffer-private.hh" #include "hb-font-private.hh" +#include "hb-machinery-private.hh" /** * SECTION:hb-shape @@ -45,21 +46,50 @@ * contains the output glyphs and their positions. **/ -static hb_atomic_ptr_t <const char **> static_shaper_list; + +static void free_static_shaper_list (void); + +static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, + hb_shaper_list_lazy_loader_t> +{ + static inline const char ** create (void) + { + const char **shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *)); + if (unlikely (!shaper_list)) + return nullptr; + + const hb_shaper_pair_t *shapers = _hb_shapers_get (); + unsigned int i; + for (i = 0; i < HB_SHAPERS_COUNT; i++) + shaper_list[i] = shapers[i].name; + shaper_list[i] = nullptr; + +#ifdef HB_USE_ATEXIT + atexit (free_static_shaper_list); +#endif + + return shaper_list; + } + static inline void destroy (const char **l) + { + ::free (l); + } + static inline const char ** get_null (void) + { + static const char *nil_shaper_list[] = {nullptr}; + return nil_shaper_list; + } +} static_shaper_list; #ifdef HB_USE_ATEXIT static void free_static_shaper_list (void) { -retry: - const char **shaper_list = static_shaper_list.get (); - if (unlikely (!static_shaper_list.cmpexch (shaper_list, nullptr))) - goto retry; - - free (shaper_list); + static_shaper_list.free (); } #endif + /** * hb_shape_list_shapers: * @@ -73,36 +103,7 @@ retry: const char ** hb_shape_list_shapers (void) { -retry: - const char **shaper_list = static_shaper_list.get (); - - if (unlikely (!shaper_list)) - { - /* Not found; allocate one. */ - shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *)); - if (unlikely (!shaper_list)) { - static const char *nil_shaper_list[] = {nullptr}; - return nil_shaper_list; - } - - const hb_shaper_pair_t *shapers = _hb_shapers_get (); - unsigned int i; - for (i = 0; i < HB_SHAPERS_COUNT; i++) - shaper_list[i] = shapers[i].name; - shaper_list[i] = nullptr; - - if (unlikely (!static_shaper_list.cmpexch (nullptr, shaper_list))) - { - free (shaper_list); - goto retry; - } - -#ifdef HB_USE_ATEXIT - atexit (free_static_shaper_list); /* First person registers atexit() callback. */ -#endif - } - - return shaper_list; + return static_shaper_list.get_unconst (); } commit 6901090945d7e16102f3a2b168465434032b9a09 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:57:06 2018 -0700 [lazy] Make hb_lazy_loader_t<> more usable diff --git a/src/hb-ft.cc b/src/hb-ft.cc index eea2da13..e716ec91 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -685,9 +685,8 @@ hb_ft_font_create_referenced (FT_Face ft_face) static void free_static_ft_library (void); -static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_ft_library_lazy_loader_t, - void, 0, - hb_remove_ptr_t<FT_Library>::value> +static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_ptr_t<FT_Library>::value, + hb_ft_library_lazy_loader_t> { static inline FT_Library create (void) { @@ -705,7 +704,7 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_ft_library_lazy_ { FT_Done_FreeType (l); } - static inline const FT_Library get_null (void) + static inline FT_Library get_null (void) { return nullptr; } diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index d40f9d9c..e60e3bec 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -610,20 +610,27 @@ struct hb_data_wrapper_t template <> struct hb_data_wrapper_t<void, 0> { - template <typename Stored, typename Subclass> + template <typename Stored, typename Funcs> inline Stored * call_create (void) const { - return Subclass::create (); + return Funcs::create (); } }; -template <typename Subclass, - typename Data, - unsigned int WheresData, - typename Returned, +template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; }; +template <typename T2> struct hb_non_void_t<void, T2> { typedef T2 value; }; + +template <typename Returned, + typename Subclass = void, + typename Data = void, + unsigned int WheresData = 0, typename Stored = Returned> struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> { + typedef typename hb_non_void_t<Subclass, + hb_lazy_loader_t<Returned,Subclass,Data,WheresData,Stored> + >::value Funcs; + inline void init0 (void) {} /* Init, when memory is already set to 0. No-op for us. */ inline void init (void) { instance.set_relaxed (nullptr); } inline void fini (void) @@ -641,15 +648,15 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> inline Stored * do_create (void) const { - Stored *p = this->template call_create<Stored, Subclass> (); + Stored *p = this->template call_create<Stored, Funcs> (); if (unlikely (!p)) - p = const_cast<Stored *> (Subclass::get_null ()); + p = const_cast<Stored *> (Funcs::get_null ()); return p; } static inline void do_destroy (Stored *p) { - if (p && p != Subclass::get_null ()) - Subclass::destroy (p); + if (p && p != Funcs::get_null ()) + Funcs::destroy (p); } inline const Returned * operator -> (void) const { return get (); } @@ -687,8 +694,8 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> do_destroy (p); } - inline const Returned * get (void) const { return Subclass::convert (get_stored ()); } - inline Returned * get_unconst (void) const { return const_cast<Returned *> (Subclass::convert (get_stored ())); } + inline const Returned * get (void) const { return Funcs::convert (get_stored ()); } + inline Returned * get_unconst (void) const { return const_cast<Returned *> (Funcs::convert (get_stored ())); } /* To be possibly overloaded by subclasses. */ static inline const Returned* convert (const Stored *p) { return p; } @@ -703,6 +710,13 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> p->init (data); return p; } + static inline Stored *create (void) + { + Stored *p = (Stored *) calloc (1, sizeof (Stored)); + if (likely (p)) + p->init (); + return p; + } static inline void destroy (Stored *p) { p->fini (); @@ -717,14 +731,15 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> /* Specializations. */ template <unsigned int WheresFace, typename T> -struct hb_face_lazy_loader_t : hb_lazy_loader_t<hb_face_lazy_loader_t<WheresFace, T>, - hb_face_t, WheresFace, - T> {}; +struct hb_face_lazy_loader_t : hb_lazy_loader_t<T, + hb_face_lazy_loader_t<WheresFace, T>, + hb_face_t, WheresFace> {}; template <typename T, unsigned int WheresFace> -struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, WheresFace>, +struct hb_table_lazy_loader_t : hb_lazy_loader_t<T, + hb_table_lazy_loader_t<T, WheresFace>, hb_face_t, WheresFace, - T, hb_blob_t> + hb_blob_t> { static inline hb_blob_t *create (hb_face_t *face) { @@ -750,9 +765,7 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, Where }; template <typename Subclass> -struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, - void, 0, - hb_font_funcs_t> +struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<hb_font_funcs_t, Subclass> { static inline void destroy (hb_font_funcs_t *p) { @@ -764,9 +777,7 @@ struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, } }; template <typename Subclass> -struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, - void, 0, - hb_unicode_funcs_t> +struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<hb_unicode_funcs_t, Subclass> { static inline void destroy (hb_unicode_funcs_t *p) { commit bb905e9afcc3eb28a22ba78c09e661a814d04c1f Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:40:08 2018 -0700 [lazy] Minor diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 193f5ed2..d40f9d9c 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -693,7 +693,21 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> /* To be possibly overloaded by subclasses. */ static inline const Returned* convert (const Stored *p) { return p; } static inline Returned* convert (Stored *p) { return p; } + + /* By default null/init/fini the object. */ static inline const Stored* get_null (void) { return &Null(Stored); } + static inline Stored *create (Data *data) + { + Stored *p = (Stored *) calloc (1, sizeof (Stored)); + if (likely (p)) + p->init (data); + return p; + } + static inline void destroy (Stored *p) + { + p->fini (); + ::free (p); + } private: /* Must only have one pointer. */ @@ -703,23 +717,9 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> /* Specializations. */ template <unsigned int WheresFace, typename T> -struct hb_object_lazy_loader_t : hb_lazy_loader_t<hb_object_lazy_loader_t<WheresFace, T>, +struct hb_face_lazy_loader_t : hb_lazy_loader_t<hb_face_lazy_loader_t<WheresFace, T>, hb_face_t, WheresFace, - T> -{ - static inline T *create (hb_face_t *face) - { - T *p = (T *) calloc (1, sizeof (T)); - if (likely (p)) - p->init (face); - return p; - } - static inline void destroy (T *p) - { - p->fini (); - free (p); - } -}; + T> {}; template <typename T, unsigned int WheresFace> struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, WheresFace>, @@ -751,8 +751,8 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, Where template <typename Subclass> struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, - void, 0, - hb_font_funcs_t> + void, 0, + hb_font_funcs_t> { static inline void destroy (hb_font_funcs_t *p) { diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index cac18095..0b14ff1e 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -71,10 +71,10 @@ struct hb_ot_font_t OT::vmtx::accelerator_t v_metrics; hb_face_t *face; /* MUST be JUST before the lazy loaders. */ - hb_object_lazy_loader_t<1, OT::glyf::accelerator_t> glyf; - hb_object_lazy_loader_t<2, OT::CBDT::accelerator_t> cbdt; - hb_object_lazy_loader_t<3, OT::post::accelerator_t> post; - hb_object_lazy_loader_t<4, OT::kern::accelerator_t> kern; + hb_face_lazy_loader_t<1, OT::glyf::accelerator_t> glyf; + hb_face_lazy_loader_t<2, OT::CBDT::accelerator_t> cbdt; + hb_face_lazy_loader_t<3, OT::post::accelerator_t> post; + hb_face_lazy_loader_t<4, OT::kern::accelerator_t> kern; }; commit 3945cd78a96bdd287e203a0261bac490df1314b0 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:33:48 2018 -0700 Minor diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 3c1181be..193f5ed2 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -719,10 +719,6 @@ struct hb_object_lazy_loader_t : hb_lazy_loader_t<hb_object_lazy_loader_t<Wheres p->fini (); free (p); } - static inline const T *get_null (void) - { - return &Null(T); - } }; template <typename T, unsigned int WheresFace> commit c21a1b95dffedb6ed66b384f4adf07e6d05d4b9f Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:30:39 2018 -0700 [icu] Use get_relaxed for normalizer access We've had the proper barriers already. No need for more with every access. diff --git a/src/hb-icu.cc b/src/hb-icu.cc index a2cd7dd4..551069fa 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -178,7 +178,7 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, { #if U_ICU_VERSION_MAJOR_NUM >= 49 { - UChar32 ret = unorm2_composePair (normalizer.get (), a, b); + UChar32 ret = unorm2_composePair (normalizer.get_relaxed (), a, b); if (ret < 0) return false; *ab = ret; return true; @@ -226,7 +226,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, UChar decomposed[4]; int len; UErrorCode icu_err = U_ZERO_ERROR; - len = unorm2_getRawDecomposition (normalizer.get (), ab, decomposed, + len = unorm2_getRawDecomposition (normalizer.get_relaxed (), ab, decomposed, ARRAY_LENGTH (decomposed), &icu_err); if (U_FAILURE (icu_err) || len < 0) return false; commit 125fefa2a6b23cf7eb4559904b23aff3731d5dba Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:29:41 2018 -0700 [icu] Fix for breakage after recent change diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 7b2c4d6e..a2cd7dd4 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -352,6 +352,16 @@ static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ { static inline hb_unicode_funcs_t *create (void) { +#if U_ICU_VERSION_MAJOR_NUM >= 49 + retry: + if (!normalizer.get ()) + { + UErrorCode icu_err = U_ZERO_ERROR; + if (unlikely (!normalizer.cmpexch (nullptr, unorm2_getNFCInstance (&icu_err)))) + goto retry; + } +#endif + hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); #define HB_UNICODE_FUNC_IMPLEMENT(name) \ commit 53442be1edc73993bdcaffc4b895c07f1ea03ba0 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:20:11 2018 -0700 [lazy] Use for ft_library diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 5ac9a3e9..eea2da13 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -461,7 +461,7 @@ void free_static_ft_funcs (void) static hb_font_funcs_t * _hb_ft_get_font_funcs (void) { - return const_cast<hb_font_funcs_t *> (static_ft_funcs.get ()); + return static_ft_funcs.get_unconst (); } static void @@ -683,47 +683,46 @@ hb_ft_font_create_referenced (FT_Face ft_face) } -/* Thread-safe, lock-free, FT_Library */ +static void free_static_ft_library (void); -static hb_atomic_ptr_t<FT_Library> ft_library; +static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_ft_library_lazy_loader_t, + void, 0, + hb_remove_ptr_t<FT_Library>::value> +{ + static inline FT_Library create (void) + { + FT_Library l; + if (FT_Init_FreeType (&l)) + return nullptr; + +#ifdef HB_USE_ATEXIT + atexit (free_static_ft_library); +#endif + + return l; + } + static inline void destroy (FT_Library l) + { + FT_Done_FreeType (l); + } + static inline const FT_Library get_null (void) + { + return nullptr; + } +} static_ft_library; #ifdef HB_USE_ATEXIT static -void free_ft_library (void) +void free_static_ft_library (void) { -retry: - FT_Library library = ft_library.get (); - if (unlikely (!ft_library.cmpexch (library, nullptr))) - goto retry; - - FT_Done_FreeType (library); + static_ft_library.free (); } #endif static FT_Library get_ft_library (void) { -retry: - FT_Library library = ft_library.get (); - - if (unlikely (!library)) - { - /* Not found; allocate one. */ - if (FT_Init_FreeType (&library)) - return nullptr; - - if (unlikely (!ft_library.cmpexch (nullptr, library))) - { - FT_Done_FreeType (library); - goto retry; - } - -#ifdef HB_USE_ATEXIT - atexit (free_ft_library); /* First person registers atexit() callback. */ -#endif - } - - return library; + return static_ft_library.get_unconst (); } static void diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 6ce9a351..af7a0fd3 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -401,7 +401,7 @@ void free_static_glib_funcs (void) hb_unicode_funcs_t * hb_glib_get_unicode_funcs (void) { - return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_glib_funcs.get ())); + return hb_unicode_funcs_reference (static_glib_funcs.get_unconst ()); } diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 0442d92a..7b2c4d6e 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -380,5 +380,5 @@ void free_static_icu_funcs (void) hb_unicode_funcs_t * hb_icu_get_unicode_funcs (void) { - return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_icu_funcs.get ())); + return hb_unicode_funcs_reference (static_icu_funcs.get_unconst ()); } diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 6221fe59..3c1181be 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -667,7 +667,6 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> if (unlikely (!p)) { p = do_create (); - assert (p); if (unlikely (!this->instance.cmpexch (nullptr, p))) { do_destroy (p); @@ -689,6 +688,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> } inline const Returned * get (void) const { return Subclass::convert (get_stored ()); } + inline Returned * get_unconst (void) const { return const_cast<Returned *> (Subclass::convert (get_stored ())); } /* To be possibly overloaded by subclasses. */ static inline const Returned* convert (const Stored *p) { return p; } diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index f181b076..cac18095 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -271,7 +271,7 @@ void free_static_ot_funcs (void) static hb_font_funcs_t * _hb_ot_get_font_funcs (void) { - return const_cast<hb_font_funcs_t *> (static_ot_funcs.get ()); + return static_ot_funcs.get_unconst (); } diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index 1945a1cf..6b1bb804 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -275,5 +275,5 @@ extern "C" HB_INTERNAL hb_unicode_funcs_t * hb_ucdn_get_unicode_funcs (void) { - return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_ucdn_funcs.get ())); + return hb_unicode_funcs_reference (static_ucdn_funcs.get_unconst ()); } commit 7a8d480378af4094645dfb1527a61a94b4786b54 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 16:00:13 2018 -0700 [lazy] Add .free() diff --git a/src/hb-ft.cc b/src/hb-ft.cc index c58cd87c..5ac9a3e9 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -454,7 +454,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft static void free_static_ft_funcs (void) { - static_ft_funcs.fini (); + static_ft_funcs.free (); } #endif diff --git a/src/hb-glib.cc b/src/hb-glib.cc index a5a82d47..6ce9a351 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -394,7 +394,7 @@ static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader static void free_static_glib_funcs (void) { - static_glib_funcs.fini (); + static_glib_funcs.free (); } #endif diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 99e3d2cb..0442d92a 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -373,7 +373,7 @@ static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ static void free_static_icu_funcs (void) { - static_icu_funcs.fini (); + static_icu_funcs.free (); } #endif diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index b26ca710..6221fe59 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -628,6 +628,10 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> inline void init (void) { instance.set_relaxed (nullptr); } inline void fini (void) { + do_destroy (instance.get ()); + } + inline void free (void) + { retry: Stored *p = instance.get (); if (unlikely (p && !this->instance.cmpexch (p, nullptr))) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 1fb18c48..f181b076 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -264,7 +264,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot static void free_static_ot_funcs (void) { - static_ot_funcs.fini (); + static_ot_funcs.free (); } #endif diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index c58db05a..1945a1cf 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -267,7 +267,7 @@ static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader static void free_static_ucdn_funcs (void) { - static_ucdn_funcs.fini (); + static_ucdn_funcs.free (); } #endif commit c7ca30a5337cb660e650d51ddd17d389909357c2 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 13:46:53 2018 -0700 [ot/ft] Port font_funcs statis to lazy-loader diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 5ab2a887..c58cd87c 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -32,6 +32,7 @@ #include "hb-ft.h" #include "hb-font-private.hh" +#include "hb-machinery-private.hh" #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H @@ -416,30 +417,13 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, return true; } -static hb_atomic_ptr_t<hb_font_funcs_t> static_ft_funcs; +static void free_static_ft_funcs (void); -#ifdef HB_USE_ATEXIT -static -void free_static_ft_funcs (void) -{ -retry: - hb_font_funcs_t *ft_funcs = static_ft_funcs.get (); - if (unlikely (!static_ft_funcs.cmpexch (ft_funcs, nullptr))) - goto retry; - - hb_font_funcs_destroy (ft_funcs); -} -#endif - -static void -_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) +static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft_font_funcs_lazy_loader_t> { -retry: - hb_font_funcs_t *funcs = static_ft_funcs.get (); - - if (unlikely (!funcs)) + static inline hb_font_funcs_t *create (void) { - funcs = hb_font_funcs_create (); + hb_font_funcs_t *funcs = hb_font_funcs_create (); hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); @@ -458,21 +442,35 @@ retry: hb_font_funcs_make_immutable (funcs); - if (unlikely (!static_ft_funcs. cmpexch (nullptr, funcs))) - { - hb_font_funcs_destroy (funcs); - goto retry; - } +#ifdef HB_USE_ATEXIT + atexit (free_static_ft_funcs); +#endif + + return funcs; + } +} static_ft_funcs; #ifdef HB_USE_ATEXIT - atexit (free_static_ft_funcs); /* First person registers atexit() callback. */ +static +void free_static_ft_funcs (void) +{ + static_ft_funcs.fini (); +} #endif - }; +static hb_font_funcs_t * +_hb_ft_get_font_funcs (void) +{ + return const_cast<hb_font_funcs_t *> (static_ft_funcs.get ()); +} + +static void +_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) +{ bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL; hb_font_set_funcs (font, - funcs, + _hb_ft_get_font_funcs (), _hb_ft_font_create (ft_face, symbol, unref), _hb_ft_font_destroy); } diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 873596de..b26ca710 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -750,6 +750,20 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, Where }; template <typename Subclass> +struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, + void, 0, + hb_font_funcs_t> +{ + static inline void destroy (hb_font_funcs_t *p) + { + hb_font_funcs_destroy (p); + } + static inline const hb_font_funcs_t *get_null (void) + { + return hb_font_funcs_get_empty (); + } +}; +template <typename Subclass> struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, void, 0, hb_unicode_funcs_t> diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 0284a45b..1fb18c48 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -29,6 +29,7 @@ #include "hb-ot.h" #include "hb-font-private.hh" +#include "hb-machinery-private.hh" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" @@ -225,30 +226,14 @@ hb_ot_get_font_v_extents (hb_font_t *font, return ot_font->v_metrics.has_font_extents; } -static hb_atomic_ptr_t <hb_font_funcs_t> static_ot_funcs; -#ifdef HB_USE_ATEXIT -static -void free_static_ot_funcs (void) -{ -retry: - hb_font_funcs_t *ot_funcs = static_ot_funcs.get (); - if (unlikely (!static_ot_funcs.cmpexch (ot_funcs, nullptr))) - goto retry; +static void free_static_ot_funcs (void); - hb_font_funcs_destroy (ot_funcs); -} -#endif - -static hb_font_funcs_t * -_hb_ot_get_font_funcs (void) +static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t> { -retry: - hb_font_funcs_t *funcs = static_ot_funcs.get (); - - if (unlikely (!funcs)) + static inline hb_font_funcs_t *create (void) { - funcs = hb_font_funcs_create (); + hb_font_funcs_t *funcs = hb_font_funcs_create (); hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); @@ -267,18 +252,26 @@ retry: hb_font_funcs_make_immutable (funcs); - if (unlikely (!static_ot_funcs.cmpexch (nullptr, funcs))) - { - hb_font_funcs_destroy (funcs); - goto retry; - } +#ifdef HB_USE_ATEXIT + atexit (free_static_ot_funcs); +#endif + + return funcs; + } +} static_ot_funcs; #ifdef HB_USE_ATEXIT - atexit (free_static_ot_funcs); /* First person registers atexit() callback. */ +static +void free_static_ot_funcs (void) +{ + static_ot_funcs.fini (); +} #endif - }; - return funcs; +static hb_font_funcs_t * +_hb_ot_get_font_funcs (void) +{ + return const_cast<hb_font_funcs_t *> (static_ot_funcs.get ()); } commit cb3fc3685c03c8ed07bcf05188f5d6c582fd5aaa Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 13:39:01 2018 -0700 [ucdn/glib/icu] Port unicode_funcs statics to lazy-loader diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 4bb6f08f..a5a82d47 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -31,6 +31,7 @@ #include "hb-glib.h" #include "hb-unicode-private.hh" +#include "hb-machinery-private.hh" #if !GLIB_CHECK_VERSION(2,29,14) @@ -364,30 +365,15 @@ hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, return utf8_decomposed_len; } -static hb_atomic_ptr_t<hb_unicode_funcs_t> static_glib_funcs; -#ifdef HB_USE_ATEXIT -static -void free_static_glib_funcs (void) -{ -retry: - hb_unicode_funcs_t *glib_funcs = static_glib_funcs.get (); - if (unlikely (!static_glib_funcs.cmpexch (glib_funcs, nullptr))) - goto retry; - hb_unicode_funcs_destroy (glib_funcs); -} -#endif +static void free_static_glib_funcs (void); -hb_unicode_funcs_t * -hb_glib_get_unicode_funcs (void) +static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_glib_unicode_funcs_lazy_loader_t> { -retry: - hb_unicode_funcs_t *funcs = static_glib_funcs.get (); - - if (unlikely (!funcs)) + static inline hb_unicode_funcs_t *create (void) { - funcs = hb_unicode_funcs_create (nullptr); + hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); #define HB_UNICODE_FUNC_IMPLEMENT(name) \ hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr); @@ -396,20 +382,30 @@ retry: hb_unicode_funcs_make_immutable (funcs); - if (unlikely (!static_glib_funcs.cmpexch (nullptr, funcs))) - { - hb_unicode_funcs_destroy (funcs); - goto retry; - } +#ifdef HB_USE_ATEXIT + atexit (free_static_glib_funcs); +#endif + + return funcs; + } +} static_glib_funcs; #ifdef HB_USE_ATEXIT - atexit (free_static_glib_funcs); /* First person registers atexit() callback. */ +static +void free_static_glib_funcs (void) +{ + static_glib_funcs.fini (); +} #endif - }; - return hb_unicode_funcs_reference (funcs); +hb_unicode_funcs_t * +hb_glib_get_unicode_funcs (void) +{ + return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_glib_funcs.get ())); } + + #if GLIB_CHECK_VERSION(2,31,10) static void diff --git a/src/hb-icu.cc b/src/hb-icu.cc index ce58de0c..99e3d2cb 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -32,6 +32,7 @@ #include "hb-icu.h" #include "hb-unicode-private.hh" +#include "hb-machinery-private.hh" #include <unicode/uchar.h> #include <unicode/unorm2.h> @@ -345,39 +346,13 @@ hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, } -static hb_atomic_ptr_t<hb_unicode_funcs_t> static_icu_funcs; +static void free_static_icu_funcs (void); -#ifdef HB_USE_ATEXIT -static -void free_static_icu_funcs (void) -{ -retry: - hb_unicode_funcs_t *icu_funcs = static_icu_funcs.get (); - if (unlikely (!static_icu_funcs.cmpexch (icu_funcs, nullptr))) - goto retry; - - hb_unicode_funcs_destroy (icu_funcs); -} -#endif - -hb_unicode_funcs_t * -hb_icu_get_unicode_funcs (void) +static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_icu_unicode_funcs_lazy_loader_t> { -retry: - hb_unicode_funcs_t *funcs = static_icu_funcs.get (); - - if (unlikely (!funcs)) + static inline hb_unicode_funcs_t *create (void) { -#if U_ICU_VERSION_MAJOR_NUM >= 49 - if (!normalizer.get ()) - { - UErrorCode icu_err = U_ZERO_ERROR; - /* We ignore failure in getNFCInstace(). */ - (void) normalizer.cmpexch (nullptr, unorm2_getNFCInstance (&icu_err)); - } -#endif - - funcs = hb_unicode_funcs_create (nullptr); + hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); #define HB_UNICODE_FUNC_IMPLEMENT(name) \ hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, nullptr, nullptr); @@ -386,16 +361,24 @@ retry: hb_unicode_funcs_make_immutable (funcs); - if (unlikely (!static_icu_funcs.cmpexch (nullptr, funcs))) - { - hb_unicode_funcs_destroy (funcs); - goto retry; - } +#ifdef HB_USE_ATEXIT + atexit (free_static_icu_funcs); +#endif + + return funcs; + } +} static_icu_funcs; #ifdef HB_USE_ATEXIT - atexit (free_static_icu_funcs); /* First person registers atexit() callback. */ +static +void free_static_icu_funcs (void) +{ + static_icu_funcs.fini (); +} #endif - }; - return hb_unicode_funcs_reference (funcs); +hb_unicode_funcs_t * +hb_icu_get_unicode_funcs (void) +{ + return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_icu_funcs.get ())); } diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 1eeae4b2..873596de 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -632,17 +632,17 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> Stored *p = instance.get (); if (unlikely (p && !this->instance.cmpexch (p, nullptr))) goto retry; - destroy (p); + do_destroy (p); } - inline Stored * create (void) const + inline Stored * do_create (void) const { Stored *p = this->template call_create<Stored, Subclass> (); if (unlikely (!p)) p = const_cast<Stored *> (Subclass::get_null ()); return p; } - static inline void destroy (Stored *p) + static inline void do_destroy (Stored *p) { if (p && p != Subclass::get_null ()) Subclass::destroy (p); @@ -662,11 +662,11 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> Stored *p = this->instance.get (); if (unlikely (!p)) { - p = create (); + p = do_create (); assert (p); if (unlikely (!this->instance.cmpexch (nullptr, p))) { - destroy (p); + do_destroy (p); goto retry; } } @@ -681,13 +681,14 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> Stored *p = this->instance.get (); if (unlikely (!this->instance.cmpexch (p, instance_))) goto retry; - destroy (p); + do_destroy (p); } inline const Returned * get (void) const { return Subclass::convert (get_stored ()); } /* To be possibly overloaded by subclasses. */ static inline const Returned* convert (const Stored *p) { return p; } + static inline Returned* convert (Stored *p) { return p; } static inline const Stored* get_null (void) { return &Null(Stored); } private: @@ -748,5 +749,20 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, Where } }; +template <typename Subclass> +struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass, + void, 0, + hb_unicode_funcs_t> +{ + static inline void destroy (hb_unicode_funcs_t *p) + { + hb_unicode_funcs_destroy (p); + } + static inline const hb_unicode_funcs_t *get_null (void) + { + return hb_unicode_funcs_get_empty (); + } +}; + #endif /* HB_MACHINERY_PRIVATE_HH */ diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index b414b1d6..c58db05a 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -17,6 +17,7 @@ #include "hb-private.hh" #include "hb-unicode-private.hh" +#include "hb-machinery-private.hh" #include "ucdn.h" @@ -238,31 +239,14 @@ hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED, return ucdn_compat_decompose(u, decomposed); } -static hb_atomic_ptr_t<hb_unicode_funcs_t> static_ucdn_funcs; -#ifdef HB_USE_ATEXIT -static -void free_static_ucdn_funcs (void) -{ -retry: - hb_unicode_funcs_t *ucdn_funcs = static_ucdn_funcs.get (); - if (unlikely (!static_ucdn_funcs.cmpexch (ucdn_funcs, nullptr))) - goto retry; +static void free_static_ucdn_funcs (void); - hb_unicode_funcs_destroy (ucdn_funcs); -} -#endif - -extern "C" HB_INTERNAL -hb_unicode_funcs_t * -hb_ucdn_get_unicode_funcs (void) +static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t> { -retry: - hb_unicode_funcs_t *funcs = static_ucdn_funcs.get (); - - if (unlikely (!funcs)) + static inline hb_unicode_funcs_t *create (void) { - funcs = hb_unicode_funcs_create (nullptr); + hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); #define HB_UNICODE_FUNC_IMPLEMENT(name) \ hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr); @@ -271,16 +255,25 @@ retry: hb_unicode_funcs_make_immutable (funcs); - if (unlikely (!static_ucdn_funcs.cmpexch (nullptr, funcs))) - { - hb_unicode_funcs_destroy (funcs); - goto retry; - } +#ifdef HB_USE_ATEXIT + atexit (free_static_ucdn_funcs); +#endif + + return funcs; + } +} static_ucdn_funcs; #ifdef HB_USE_ATEXIT - atexit (free_static_ucdn_funcs); /* First person registers atexit() callback. */ +static +void free_static_ucdn_funcs (void) +{ + static_ucdn_funcs.fini (); +} #endif - }; - return hb_unicode_funcs_reference (funcs); +extern "C" HB_INTERNAL +hb_unicode_funcs_t * +hb_ucdn_get_unicode_funcs (void) +{ + return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_ucdn_funcs.get ())); } commit 1b6b481262465ae1865c66c4d499b4b2c8d297fb Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 13:16:40 2018 -0700 [lazy] Allow calling fini() multiple times diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 9edd2be5..1eeae4b2 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -626,7 +626,14 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> { inline void init0 (void) {} /* Init, when memory is already set to 0. No-op for us. */ inline void init (void) { instance.set_relaxed (nullptr); } - inline void fini (void) { destroy (instance.get ()); } + inline void fini (void) + { + retry: + Stored *p = instance.get (); + if (unlikely (p && !this->instance.cmpexch (p, nullptr))) + goto retry; + destroy (p); + } inline Stored * create (void) const { commit 918ad9f5d9b85384f24157523272a4ffc1927d16 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 13:12:29 2018 -0700 [lazy] More diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index da6e941c..9edd2be5 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -590,18 +590,51 @@ struct BEInt<Type, 4> * Lazy loaders. */ +template <typename Data, unsigned int WheresData> +struct hb_data_wrapper_t +{ + static_assert (WheresData > 0, ""); + + inline Data * get_data (void) const + { + return *(((Data **) this) - WheresData); + } + + template <typename Stored, typename Subclass> + inline Stored * call_create (void) const + { + Data *data = this->get_data (); + return likely (data) ? Subclass::create (data) : nullptr; + } +}; +template <> +struct hb_data_wrapper_t<void, 0> +{ + template <typename Stored, typename Subclass> + inline Stored * call_create (void) const + { + return Subclass::create (); + } +}; + template <typename Subclass, typename Data, unsigned int WheresData, typename Returned, typename Stored = Returned> -struct hb_lazy_loader_t +struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> { - static_assert (WheresData > 0, ""); - inline void init0 (void) {} /* Init, when memory is already set to 0. No-op for us. */ inline void init (void) { instance.set_relaxed (nullptr); } inline void fini (void) { destroy (instance.get ()); } + + inline Stored * create (void) const + { + Stored *p = this->template call_create<Stored, Subclass> (); + if (unlikely (!p)) + p = const_cast<Stored *> (Subclass::get_null ()); + return p; + } static inline void destroy (Stored *p) { if (p && p != Subclass::get_null ()) @@ -622,11 +655,7 @@ struct hb_lazy_loader_t Stored *p = this->instance.get (); if (unlikely (!p)) { - Data *data = get_data (); - if (likely (data)) - p = Subclass::create (data); - if (unlikely (!p)) - p = const_cast<Stored *> (Subclass::get_null ()); + p = create (); assert (p); if (unlikely (!this->instance.cmpexch (nullptr, p))) { commit 5abdf5eebadf9a4fbd50c1a893c9654de74d22ac Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 12:40:24 2018 -0700 [lazy] More shuffle diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index ea6dfa48..da6e941c 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -599,40 +599,38 @@ struct hb_lazy_loader_t { static_assert (WheresData > 0, ""); - /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - inline const Subclass* thiz (void) const { return static_cast<const Subclass *> (this); } - inline Subclass* thiz (void) { return static_cast<Subclass *> (this); } - inline void init0 (void) {} /* Init, when memory is already set to 0. No-op for us. */ - inline void init (void) + inline void init (void) { instance.set_relaxed (nullptr); } + inline void fini (void) { destroy (instance.get ()); } + static inline void destroy (Stored *p) { - instance.set_relaxed (nullptr); + if (p && p != Subclass::get_null ()) + Subclass::destroy (p); } - inline void fini (void) + + inline const Returned * operator -> (void) const { return get (); } + inline const Returned & operator * (void) const { return *get (); } + + inline Data * get_data (void) const { - Stored *p = this->instance.get (); - if (p) - thiz ()->destroy (p); + return *(((Data **) this) - WheresData); } - inline const Returned * operator -> (void) const { return thiz ()->get (); } - inline const Returned & operator * (void) const { return *thiz ()->get (); } - inline Stored * get_stored (void) const { retry: Stored *p = this->instance.get (); if (unlikely (!p)) { - Data *data= *(((Data **) this) - WheresData); - if (likely (!p)) - p = thiz ()->create (data); + Data *data = get_data (); + if (likely (data)) + p = Subclass::create (data); if (unlikely (!p)) - p = thiz ()->create (nullptr); /* Produce nil object. */ + p = const_cast<Stored *> (Subclass::get_null ()); assert (p); if (unlikely (!this->instance.cmpexch (nullptr, p))) { - thiz ()->destroy (p); + destroy (p); goto retry; } } @@ -645,23 +643,16 @@ struct hb_lazy_loader_t * However, to make TSan, etc, happy, we using cmpexch. */ retry: Stored *p = this->instance.get (); - if (p) - { - if (unlikely (!this->instance.cmpexch (p, instance_))) - goto retry; - thiz ()->destroy (p); - } + if (unlikely (!this->instance.cmpexch (p, instance_))) + goto retry; + destroy (p); } - inline const Returned * get (void) const - { - return thiz ()->convert (get_stored ()); - } + inline const Returned * get (void) const { return Subclass::convert (get_stored ()); } - static inline const Returned* convert (const Stored *p) - { - return p; - } + /* To be possibly overloaded by subclasses. */ + static inline const Returned* convert (const Stored *p) { return p; } + static inline const Stored* get_null (void) { return &Null(Stored); } private: /* Must only have one pointer. */ @@ -677,22 +668,19 @@ struct hb_object_lazy_loader_t : hb_lazy_loader_t<hb_object_lazy_loader_t<Wheres { static inline T *create (hb_face_t *face) { - if (unlikely (!face)) - return const_cast<T *> (&Null(T)); T *p = (T *) calloc (1, sizeof (T)); - if (unlikely (!p)) - p = const_cast<T *> (&Null(T)); - else + if (likely (p)) p->init (face); return p; } static inline void destroy (T *p) { - if (p != &Null(T)) - { - p->fini(); - free (p); - } + p->fini (); + free (p); + } + static inline const T *get_null (void) + { + return &Null(T); } }; @@ -701,18 +689,18 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, Where hb_face_t, WheresFace, T, hb_blob_t> { - static_assert (WheresFace > 0, ""); - static inline hb_blob_t *create (hb_face_t *face) { - if (unlikely (!face)) - return hb_blob_get_empty (); return hb_sanitize_context_t ().reference_table<T> (face); } static inline void destroy (hb_blob_t *p) { hb_blob_destroy (p); } + static inline const hb_blob_t *get_null (void) + { + return hb_blob_get_empty (); + } static inline const T* convert (const hb_blob_t *blob) { return blob->as<T> (); commit 5d9863be6ecf873033cbab732207dd420f3866e7 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Aug 12 12:27:47 2018 -0700 Minor diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index beb61fa9..ea6dfa48 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -696,11 +696,13 @@ struct hb_object_lazy_loader_t : hb_lazy_loader_t<hb_object_lazy_loader_t<Wheres } }; -template <unsigned int WheresFace, typename T> -struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<WheresFace, T>, +template <typename T, unsigned int WheresFace> +struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, WheresFace>, hb_face_t, WheresFace, T, hb_blob_t> { + static_assert (WheresFace > 0, ""); + static inline hb_blob_t *create (hb_face_t *face) { if (unlikely (!face)) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index de1adda5..612bc7fc 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -205,7 +205,7 @@ struct hb_ot_layout_t hb_face_t *face; /* MUST be JUST before the lazy loaders. */ #define HB_OT_LAYOUT_TABLE(Namespace, Type) \ - hb_table_lazy_loader_t<HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type), struct Namespace::Type> Type; + hb_table_lazy_loader_t<struct Namespace::Type, HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type)> Type; HB_OT_LAYOUT_TABLES #undef HB_OT_LAYOUT_TABLE } table; _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz