@@ -148,6 +148,8 @@ with (), thus:
148148/* * Maximum number of retries to allocate memory. */
149149extern const size_t alloc_max_retries;
150150
151+ constexpr uint32_t INVALID_AUTOEVENT_IDX = 0xFFFFFFFFU ;
152+
151153/* * Keys for registering allocations with performance schema.
152154Pointers to these variables are supplied to PFS code via the pfs_info[]
153155array and the PFS code initializes them via PSI_MEMORY_CALL(register_memory)().
@@ -180,11 +182,11 @@ ut_new_boot();
180182
181183/* *
182184Retrieve a memory key (registered with PFS),
183- given filename hash of the caller
185+ given AUTOEVENT_IDX of the caller
184186
185- @param[in] filename_hash - FILENAME_HASH value of the caller
187+ @param[in] autoevent_idx - AUTOEVENT_IDX value of the caller
186188@return registered memory key or PSI_NOT_INSTRUMENTED */
187- PSI_memory_key ut_new_get_key_by_file (uint32_t filename_hash );
189+ PSI_memory_key ut_new_get_key_by_file (uint32_t autoevent_idx );
188190
189191#endif /* UNIV_PFS_MEMORY */
190192
@@ -293,7 +295,7 @@ class ut_allocator {
293295 )
294296{
295297#ifdef UNIV_PFS_MEMORY
296- const PSI_memory_key other_key = other.get_mem_key (0 );
298+ const PSI_memory_key other_key = other.get_mem_key ();
297299
298300m_key = (other_key != mem_key_std)
299301? other_key
@@ -315,7 +317,7 @@ class ut_allocator {
315317#endif /* UNIV_PFS_MEMORY */
316318}
317319
318- pointer allocate (size_type n) { return allocate (n, NULL , 0 ); }
320+ pointer allocate (size_type n) { return allocate (n, NULL , INVALID_AUTOEVENT_IDX ); }
319321
320322/* * Allocate a chunk of memory that can hold 'n_elements' objects of
321323type 'T' and trace the allocation.
@@ -335,7 +337,7 @@ class ut_allocator {
335337const_pointer,
336338uint32_t
337339#ifdef UNIV_PFS_MEMORY
338- filename_hash /* filename hash of the caller */
340+ autoevent_idx /* AUTOEVENT_IDX of the caller */
339341#endif
340342,
341343bool set_to_zero = false ,
@@ -397,7 +399,7 @@ class ut_allocator {
397399#ifdef UNIV_PFS_MEMORY
398400ut_new_pfx_t * pfx = static_cast <ut_new_pfx_t *>(ptr);
399401
400- allocate_trace (total_bytes, filename_hash , pfx);
402+ allocate_trace (total_bytes, autoevent_idx , pfx);
401403
402404return (reinterpret_cast <pointer>(pfx + 1 ));
403405#else
@@ -479,15 +481,15 @@ class ut_allocator {
479481reallocate (
480482void * ptr,
481483size_type n_elements,
482- uint32_t filename_hash )
484+ uint32_t autoevent_idx )
483485{
484486if (n_elements == 0 ) {
485487deallocate (static_cast <pointer>(ptr));
486488return (NULL );
487489}
488490
489491if (ptr == NULL ) {
490- return (allocate (n_elements, NULL , filename_hash , false , false ));
492+ return (allocate (n_elements, NULL , autoevent_idx , false , false ));
491493}
492494
493495if (n_elements > max_size ()) {
@@ -530,7 +532,7 @@ class ut_allocator {
530532deallocate_trace (pfx_new);
531533
532534/* pfx_new is set here to describe the new block. */
533- allocate_trace (total_bytes, filename_hash , pfx_new);
535+ allocate_trace (total_bytes, autoevent_idx , pfx_new);
534536
535537return (reinterpret_cast <pointer>(pfx_new + 1 ));
536538}
@@ -546,10 +548,10 @@ class ut_allocator {
546548pointer
547549new_array (
548550size_type n_elements,
549- uint32_t filename_hash
551+ uint32_t autoevent_idx
550552)
551553{
552- T* p = allocate (n_elements, NULL , filename_hash , false , false );
554+ T* p = allocate (n_elements, NULL , autoevent_idx , false , false );
553555
554556if (p == NULL ) {
555557return (NULL );
@@ -688,16 +690,16 @@ class ut_allocator {
688690@return performance schema key */
689691PSI_memory_key
690692get_mem_key (
691- uint32_t filename_hash ) const
693+ uint32_t autoevent_idx = INVALID_AUTOEVENT_IDX ) const
692694{
693695if (m_key != PSI_NOT_INSTRUMENTED) {
694696return (m_key);
695697}
696698
697- if (filename_hash == 0 ) {
699+ if (autoevent_idx == INVALID_AUTOEVENT_IDX ) {
698700return (mem_key_std);
699701}
700- const PSI_memory_key key = ut_new_get_key_by_file (filename_hash );
702+ const PSI_memory_key key = ut_new_get_key_by_file (autoevent_idx );
701703
702704if (key != PSI_NOT_INSTRUMENTED) {
703705return (key);
@@ -739,16 +741,16 @@ class ut_allocator {
739741 corresponds to "file", that will be used (see ut_new_boot())
7407424. Otherwise, the name associated with mem_key_other will be used.
741743@param[in] size number of bytes that were allocated
742- @param[in]filename_hash FILENAME_HASH of the caller
744+ @param[in]autoevent_idx autoevent_idx of the caller
743745@param[out] pfx placeholder to store the info which will be
744746needed when freeing the memory */
745747void
746748allocate_trace (
747749size_t size,
748- const uint32_t filename_hash ,
750+ const uint32_t autoevent_idx ,
749751ut_new_pfx_t * pfx)
750752{
751- const PSI_memory_key key = get_mem_key (filename_hash );
753+ const PSI_memory_key key = get_mem_key (autoevent_idx );
752754
753755pfx->m_key = PSI_MEMORY_CALL (memory_alloc)(key, size, & pfx->m_owner );
754756pfx->m_size = size;
@@ -801,36 +803,124 @@ operator!=(
801803/*
802804 constexpr trickery ahead.
803805
804- Retrieve the FILENAME_HASH = djb2(basename_noext(__FILE__)) at the compile time.
805- We use the number rather than __FILE__ because integers is better to deal with
806- (hashing, searching) that C style strings.
806+ Compute AUTOEVENT_IDX at compile time.
807+ (index in the auto_event_names array, corresponding to basename of __FILE__)
808+
809+ The tricks are necessary to reduce the cost of lookup the
810+ PSI_memory_key for auto event.
807811*/
808812
809- static constexpr const char * basename_helper (const char * s, const char * last_slash)
813+ static constexpr const char * cexpr_basename_helper (const char * s, const char * last_slash)
810814{
811815 return
812- *s == ' \0 ' ? last_slash :
813- *s == ' /' || *s == ' \\ ' ? basename_helper (s + 1 , s + 1 ) :
814- basename_helper (s + 1 , last_slash);
816+ *s == ' \0 ' ? last_slash :
817+ *s == ' /' || *s == ' \\ ' ? cexpr_basename_helper (s + 1 , s + 1 ) :
818+ cexpr_basename_helper (s + 1 , last_slash);
819+ }
820+
821+ static constexpr const char * cexpr_basename (const char * filename)
822+ {
823+ return cexpr_basename_helper (filename, filename);
815824}
816825
817- static constexpr const char * ut_basename ( const char *filename )
826+ static constexpr bool cexpr_strequal_ignore_dot ( const char * a, const char * b )
818827{
819- return basename_helper (filename, filename);
828+ return *a == 0 || *a == ' .' ? (*b == 0 || *b == ' .' )
829+ : *a == *b ? cexpr_strequal_ignore_dot (a + 1 , b + 1 ) : false ;
820830}
821831
822- /* * Compute djb2 hash for a string. Stop at '.' , or '\0' */
823- constexpr uint32_t ut_filename_hash (const char *s, uint32_t h= 5381 )
832+ constexpr const char * const auto_event_names[] =
833+ {
834+ " btr0btr" ,
835+ " btr0buf" ,
836+ " btr0bulk" ,
837+ " btr0cur" ,
838+ " btr0pcur" ,
839+ " btr0sea" ,
840+ " buf0buf" ,
841+ " buf0dblwr" ,
842+ " buf0dump" ,
843+ " dict0dict" ,
844+ " dict0mem" ,
845+ " dict0stats" ,
846+ " eval0eval" ,
847+ " fil0crypt" ,
848+ " fil0fil" ,
849+ " fsp0file" ,
850+ " fts0ast" ,
851+ " fts0blex" ,
852+ " fts0config" ,
853+ " fts0file" ,
854+ " fts0fts" ,
855+ " fts0opt" ,
856+ " fts0pars" ,
857+ " fts0que" ,
858+ " fts0sql" ,
859+ " fts0tlex" ,
860+ " gis0sea" ,
861+ " ha_innodb" ,
862+ " ha0ha" ,
863+ " handler0alter" ,
864+ " hash0hash" ,
865+ " i_s" ,
866+ " lexyy" ,
867+ " lock0lock" ,
868+ " mem0mem" ,
869+ " os0event" ,
870+ " os0file" ,
871+ " pars0lex" ,
872+ " rem0rec" ,
873+ " row0ftsort" ,
874+ " row0import" ,
875+ " row0log" ,
876+ " row0merge" ,
877+ " row0mysql" ,
878+ " row0sel" ,
879+ " srv0start" ,
880+ " sync0arr" ,
881+ " sync0debug" ,
882+ " sync0rw" ,
883+ " sync0start" ,
884+ " sync0types" ,
885+ " trx0i_s" ,
886+ " trx0i_s" ,
887+ " trx0roll" ,
888+ " trx0rseg" ,
889+ " trx0seg" ,
890+ " trx0trx" ,
891+ " trx0undo" ,
892+ " ut0list" ,
893+ " ut0mem" ,
894+ " ut0new" ,
895+ " ut0pool" ,
896+ " ut0rbt" ,
897+ " ut0wqueue" ,
898+ " xtrabackup" ,
899+ nullptr
900+ };
901+
902+ constexpr uint32_t cexpr_lookup_auto_event_name (const char * name, uint32_t idx = 0 )
824903{
825- return *s == 0 || *s == ' .' ? h :
826- ut_filename_hash (s + 1 , static_cast <uint32_t >(uint64_t {33 } * h + *s));
904+ return !auto_event_names[idx] ? INVALID_AUTOEVENT_IDX :
905+ cexpr_strequal_ignore_dot (name, auto_event_names[idx]) ? idx :
906+ cexpr_lookup_auto_event_name (name, idx + 1 );
827907}
828908
829- /* Force constexpr to be evaluated at compile time.*/
830- #define FORCE_CONSTEXPR (expr )[&]() \
831- { static constexpr auto x = (expr); return x; }()
909+ /*
910+ The AUTOEVENT_IDX macro.
911+
912+ Note, that there is a static_assert that checks whether
913+ basename of the __FILE is not registered in the auto_event_names array.
914+ If you run into this assert, add the basename to the array.
832915
833- #define FILENAME_HASH FORCE_CONSTEXPR (ut_filename_hash(ut_basename(__FILE__)))
916+ Weird looking lambda is used to force the evaluation at the compile time.
917+ */
918+ #define AUTOEVENT_IDX []()\
919+ {\
920+ constexpr auto idx = cexpr_lookup_auto_event_name (cexpr_basename (__FILE__)); \
921+ static_assert (idx != INVALID_AUTOEVENT_IDX, " auto_event_names contains no entry for " __FILE__);\
922+ return idx; \
923+ }()
834924
835925
836926/* * Allocate, trace the allocation and construct an object.
@@ -850,7 +940,7 @@ pointer must be passed to UT_DELETE() when no longer needed.
850940object if the passed in pointer is NULL, e.g. if allocate() has
851941failed to allocate memory and has returned NULL. */ \
852942::new (ut_allocator<byte>(key).allocate( \
853- sizeof expr, NULL , FILENAME_HASH , false , false )) expr
943+ sizeof expr, NULL , AUTOEVENT_IDX , false , false )) expr
854944
855945/* * Allocate, trace the allocation and construct an object.
856946Use this macro instead of 'new' within InnoDB and instead of UT_NEW()
@@ -872,6 +962,7 @@ We can't instantiate ut_allocator without having the type of the object, thus
872962we redirect this to a templated function. */
873963#define UT_DELETE (ptr ) ut_delete(ptr)
874964
965+
875966/* * Destroy and account object created by UT_NEW() or UT_NEW_NOKEY().
876967@param[in,out] ptr pointer to the object */
877968template <typename T>
@@ -898,7 +989,7 @@ The returned pointer must be passed to UT_DELETE_ARRAY().
898989@param[in] key performance schema memory tracing key
899990@return pointer to the first allocated object or NULL */
900991#define UT_NEW_ARRAY (type, n_elements, key ) \
901- ut_allocator<type>(key).new_array(n_elements, FILENAME_HASH )
992+ ut_allocator<type>(key).new_array(n_elements, AUTOEVENT_IDX )
902993
903994/* * Allocate and account 'n_elements' objects of type 'type'.
904995Use this macro to allocate memory within InnoDB instead of 'new[]' and
@@ -929,31 +1020,31 @@ ut_delete_array(
9291020
9301021#define ut_malloc (n_bytes, key )static_cast <void *>( \
9311022ut_allocator<byte>(key).allocate( \
932- n_bytes, NULL , FILENAME_HASH , false , false ))
1023+ n_bytes, NULL , AUTOEVENT_IDX , false , false ))
9331024
9341025#define ut_malloc_dontdump (n_bytes, key ) static_cast <void *>( \
9351026ut_allocator<byte>(key).allocate_large( \
9361027n_bytes, NULL , true ))
9371028
9381029#define ut_zalloc (n_bytes, key )static_cast <void *>( \
9391030ut_allocator<byte>(key).allocate( \
940- n_bytes, NULL , FILENAME_HASH , true , false ))
1031+ n_bytes, NULL , AUTOEVENT_IDX , true , false ))
9411032
9421033#define ut_malloc_nokey (n_bytes )static_cast <void *>( \
9431034ut_allocator<byte>(PSI_NOT_INSTRUMENTED).allocate( \
944- n_bytes, NULL , FILENAME_HASH , false , false ))
1035+ n_bytes, NULL , AUTOEVENT_IDX , false , false ))
9451036
9461037#define ut_zalloc_nokey (n_bytes )static_cast <void *>( \
9471038ut_allocator<byte>(PSI_NOT_INSTRUMENTED).allocate( \
948- n_bytes, NULL , FILENAME_HASH , true , false ))
1039+ n_bytes, NULL , AUTOEVENT_IDX , true , false ))
9491040
9501041#define ut_zalloc_nokey_nofatal (n_bytes )static_cast <void *>( \
9511042ut_allocator<byte, false >(PSI_NOT_INSTRUMENTED).allocate( \
952- n_bytes, NULL , FILENAME_HASH , true , false ))
1043+ n_bytes, NULL , AUTOEVENT_IDX , true , false ))
9531044
9541045#define ut_realloc (ptr, n_bytes )static_cast <void *>( \
9551046ut_allocator<byte>(PSI_NOT_INSTRUMENTED).reallocate( \
956- ptr, n_bytes, FILENAME_HASH ))
1047+ ptr, n_bytes, AUTOEVENT_IDX ))
9571048
9581049#define ut_free (ptr ) ut_allocator<byte>(PSI_NOT_INSTRUMENTED).deallocate( \
9591050reinterpret_cast <byte*>(ptr))
0 commit comments