Hello Sergei!

Thanks for a fast response.

I'll give you the answers to the point, and later will get to the fixes that you mentioned.

On Fri, 6 Dec 2024 at 17:19, Sergei Golubchik <serg@mariadb.org> wrote:
Hi, Nikita,

Despite the commit has in the title, comments below apply to four
commits:

$ git log --oneline  7d5165894282^..0f6fd23e1604
0f6fd23e160 cleanup: add new(thd) to Sql_alloc and Item
e0afb5f08b5 cleanup: further replace thd->alloc() with operator new
8daea2e14b2 cleanup: add operator new(size_t, const THD*) for single-object allocations
7d516589428 cleanup: add operator new[](size_t, const THD*)

On Dec 06, Nikita Malyavin wrote:
> diff --git a/sql/sql_class.h b/sql/sql_class.h
> index aff02df69ec..299c8298606 100644
> --- a/sql/sql_class.h
> +++ b/sql/sql_class.h
> @@ -1279,11 +1279,5 @@ class Query_arena
>    { return state == STMT_CONVENTIONAL_EXECUTION; }

>    template <typename T=char>
> -  inline T* alloc(size_t size) const
> -  {
> -    return (T*)alloc_root(mem_root, sizeof(T)*size);
> -  }
> -
> -  template <typename T=char>
>    inline T* calloc(size_t size) const

Hmm, you didn't remove thd->calloc<>()

Well, I could do that, the calloc analogue looks like

new (thd) char[size] ();

Note the brackets before the semicolon -- they force zero 
initialization for scalar types, as well as for POD types:

new (thd) pod_t[size] ();

As far as I understand, it forces calling a default constructor
of a POD type or a scalar, which is a zero initialization.

For non-POD types, the default constructor is always called.

But I thought that maybe it can be found too odious for our developer community ☺️
So I decided to see how it goes with single THD:alloc() first:)


> -  static void *operator new[](size_t size) throw ()
> +  static void *operator new[](size_t size) noexcept
>    {
>      return thd_alloc(_current_thd(), size);
>    }
> -  static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
> +
> +  static void *operator new[](size_t size, const THD *thd) noexcept;
> +  static void *operator new(size_t size, const THD *thd) noexcept;
> +
> +  static void *operator new[](size_t size, MEM_ROOT *mem_root) noexcept
>    { return alloc_root(mem_root, size); }
> -  static void *operator new(size_t size, MEM_ROOT *mem_root) throw()
> +  static void *operator new(size_t size, MEM_ROOT *mem_root) noexcept
>    { return alloc_root(mem_root, size); }
>    static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); }
>    static void operator delete(void *, MEM_ROOT *){}
> diff --git a/sql/sql_class.cc b/sql/sql_class.cc
> index 7847389dabc..37869da63ae 100644
> --- a/sql/sql_class.cc
> +++ b/sql/sql_class.cc
> @@ -8831,3 +8831,46 @@ LEX_CSTRING make_string(THD *thd, const char *start_ptr,
>    size_t length= end_ptr - start_ptr;
>    return {strmake_root(thd->mem_root, start_ptr, length), length};
>  }
> +void* operator new(size_t size, const Query_arena *thd) noexcept
> +{
> +  return alloc_root(thd->mem_root, size);
> +}
> +
> +void operator delete[](void *ptr, const Query_arena *thd) noexcept
> +{}
> +
> +void operator delete(void *ptr, const Query_arena *thd) noexcept
> +{}

if you put them into sql_class.h - will they be inlined?

Apparently, one can't put a global operator new/delete definition into a header:
then a linker finds duplicates:( 
I didn't find a solution for that. But I'm sure it'll be inlined with -flto and O1 or O2.


--
Yours truly,
Nikita Malyavin