[HarfBuzz] harfbuzz: Branch 'master' - 16 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Mon Aug 13 00:37:15 UTC 2018
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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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 <behdad at 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;
More information about the HarfBuzz
mailing list