Loading include/my_sys.h +2 −1 Original line number Diff line number Diff line Loading @@ -725,7 +725,8 @@ extern void my_free_lock(byte *ptr,myf flags); #define my_free_lock(A,B) my_free((A),(B)) #endif #define alloc_root_inited(A) ((A)->min_malloc != 0) #define clear_alloc_root(A) bzero((void *) (A), sizeof(MEM_ROOT)) #define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8) #define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; } while(0) extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size); extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size); Loading mysys/my_alloc.c +32 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,27 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG /* Initialize memory root SYNOPSIS init_alloc_root() mem_root - memory root to initialize block_size - size of chunks (blocks) used for memory allocation (It is external size of chunk i.e. it should include memory required for internal structures, thus it should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE) pre_alloc_size - if non-0, then size of block that should be pre-allocated during memory root initialization. DESCRIPTION This function prepares memory root for further use, sets initial size of chunk for memory allocation and pre-allocates first block if specified. Altough error can happen during execution of this function if pre_alloc_size is non-0 it won't be reported. Instead it will be reported as error in first alloc_root() on this memory root. */ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { Loading @@ -29,7 +50,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, DBUG_PRINT("enter",("root: 0x%lx", mem_root)); mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; Loading @@ -54,9 +75,9 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, SYNOPSIS reset_root_defaults() mem_root memory root to change defaults of block_size new value of block size. Must be greater than ~68 bytes (the exact value depends on platform and compilation flags) block_size new value of block size. Must be greater or equal than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about 68 bytes and depends on platform and compilation flags) pre_alloc_size new size of preallocated block. If not zero, must be equal to or greater than block size, otherwise means 'no prealloc'. Loading @@ -70,7 +91,9 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, void reset_root_defaults(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; DBUG_ASSERT(alloc_root_inited(mem_root)); mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { Loading Loading @@ -123,6 +146,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) DBUG_ENTER("alloc_root"); DBUG_PRINT("enter",("root: 0x%lx", mem_root)); DBUG_ASSERT(alloc_root_inited(mem_root)); Size+=ALIGN_SIZE(sizeof(USED_MEM)); if (!(next = (USED_MEM*) my_malloc(Size,MYF(MY_WME)))) { Loading @@ -140,6 +165,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) reg1 USED_MEM *next= 0; reg2 USED_MEM **prev; DBUG_ASSERT(alloc_root_inited(mem_root)); Size= ALIGN_SIZE(Size); if ((*(prev= &mem_root->free)) != NULL) { Loading sql/opt_range.cc +6 −2 Original line number Diff line number Diff line Loading @@ -2554,7 +2554,8 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1); MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC); QUICK_SELECT *quick= new QUICK_SELECT(thd, table, ref->key); KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; QUICK_RANGE *range; Loading @@ -2566,7 +2567,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { if (thd->is_fatal_error) goto err; // out of memory return quick; // empty range goto ok; // empty range } if (!(range= new QUICK_RANGE())) Loading Loading @@ -2613,9 +2614,12 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) goto err; } ok: my_pthread_setspecific_ptr(THR_MALLOC, old_root); return quick; err: my_pthread_setspecific_ptr(THR_MALLOC, old_root); delete quick; return 0; } Loading sql/sql_class.cc +46 −23 Original line number Diff line number Diff line Loading @@ -221,7 +221,6 @@ THD::THD() init(); /* Initialize sub structures */ clear_alloc_root(&transaction.mem_root); init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); user_connect=(USER_CONN *)0; hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, Loading Loading @@ -258,6 +257,7 @@ THD::THD() transaction.trans_log.end_of_file= max_binlog_cache_size; } #endif init_alloc_root(&transaction.mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); { ulong tmp=sql_rnd_with_mutex(); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); Loading Loading @@ -303,10 +303,10 @@ void THD::init(void) void THD::init_for_queries() { ha_enable_transaction(this,TRUE); init_sql_alloc(&mem_root, variables.query_alloc_block_size, reset_root_defaults(&mem_root, variables.query_alloc_block_size, variables.query_prealloc_size); init_sql_alloc(&transaction.mem_root, reset_root_defaults(&transaction.mem_root, variables.trans_alloc_block_size, variables.trans_prealloc_size); } Loading Loading @@ -1332,6 +1332,17 @@ void select_dumpvar::cleanup() } /* Create arena for already constructed THD. SYNOPSYS Item_arena() thd - thread for which arena is created DESCRIPTION Create arena for already existing THD using its variables as parameters for memory root initialization. */ Item_arena::Item_arena(THD* thd) :free_list(0), state(INITIALIZED) Loading @@ -1342,24 +1353,31 @@ Item_arena::Item_arena(THD* thd) } /* This constructor is called when Item_arena is a subobject of THD */ /* Create arena and optionally initialize memory root. Item_arena::Item_arena() :free_list(0), state(CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } SYNOPSYS Item_arena() init_mem_root - whenever we need to initialize memory root DESCRIPTION Create arena and optionally initialize memory root with minimal possible parameters. NOTE We use this constructor when arena is part of THD, but reinitialize its memory root in THD::init_for_queries() before execution of real statements. */ Item_arena::Item_arena(bool init_mem_root) :free_list(0), state(INITIALIZED) state(CONVENTIONAL_EXECUTION) { if (init_mem_root) clear_alloc_root(&mem_root); init_alloc_root(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); } Item_arena::Type Item_arena::type() const { DBUG_ASSERT("Item_arena::type()" == "abstract"); Loading @@ -1367,10 +1385,6 @@ Item_arena::Type Item_arena::type() const } Item_arena::~Item_arena() {} /* Statement functions */ Loading @@ -1394,7 +1408,8 @@ Statement::Statement(THD *thd) */ Statement::Statement() :id(0), :Item_arena((bool)TRUE), id(0), set_query_id(1), allow_sum_func(0), /* initialized later */ lex(&main_lex), Loading Loading @@ -1462,8 +1477,16 @@ void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup) { set->set_item_arena(this); set_item_arena(backup); // reset backup mem_root to avoid its freeing init_alloc_root(&backup->mem_root, 0, 0); #ifdef NOT_NEEDED_NOW /* Reset backup mem_root to avoid its freeing. Since Item_arena's mem_root is freed only when it is part of Statement we need this only if we use some Statement's arena as backup storage. But we do this only with THD::stmt_backup and this Statement is specially handled in this respect. So this code is not really needed now. */ clear_alloc_root(&backup->mem_root); #endif } void Item_arena::set_item_arena(Item_arena *set) Loading sql/sql_class.h +14 −2 Original line number Diff line number Diff line Loading @@ -441,11 +441,23 @@ class Item_arena STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE }; /* This constructor is used only when Item_arena is created as backup storage for another instance of Item_arena. */ Item_arena() {}; /* Create arena for already constructed THD using its variables as parameters for memory root initialization. */ Item_arena(THD *thd); Item_arena(); /* Create arena and optionally init memory root with minimal values. Particularly used if Item_arena is part of Statement. */ Item_arena(bool init_mem_root); virtual Type type() const; virtual ~Item_arena(); virtual ~Item_arena() {}; inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } Loading Loading
include/my_sys.h +2 −1 Original line number Diff line number Diff line Loading @@ -725,7 +725,8 @@ extern void my_free_lock(byte *ptr,myf flags); #define my_free_lock(A,B) my_free((A),(B)) #endif #define alloc_root_inited(A) ((A)->min_malloc != 0) #define clear_alloc_root(A) bzero((void *) (A), sizeof(MEM_ROOT)) #define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8) #define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; } while(0) extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size); extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size); Loading
mysys/my_alloc.c +32 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,27 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG /* Initialize memory root SYNOPSIS init_alloc_root() mem_root - memory root to initialize block_size - size of chunks (blocks) used for memory allocation (It is external size of chunk i.e. it should include memory required for internal structures, thus it should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE) pre_alloc_size - if non-0, then size of block that should be pre-allocated during memory root initialization. DESCRIPTION This function prepares memory root for further use, sets initial size of chunk for memory allocation and pre-allocates first block if specified. Altough error can happen during execution of this function if pre_alloc_size is non-0 it won't be reported. Instead it will be reported as error in first alloc_root() on this memory root. */ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { Loading @@ -29,7 +50,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, DBUG_PRINT("enter",("root: 0x%lx", mem_root)); mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; Loading @@ -54,9 +75,9 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, SYNOPSIS reset_root_defaults() mem_root memory root to change defaults of block_size new value of block size. Must be greater than ~68 bytes (the exact value depends on platform and compilation flags) block_size new value of block size. Must be greater or equal than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about 68 bytes and depends on platform and compilation flags) pre_alloc_size new size of preallocated block. If not zero, must be equal to or greater than block size, otherwise means 'no prealloc'. Loading @@ -70,7 +91,9 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, void reset_root_defaults(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; DBUG_ASSERT(alloc_root_inited(mem_root)); mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { Loading Loading @@ -123,6 +146,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) DBUG_ENTER("alloc_root"); DBUG_PRINT("enter",("root: 0x%lx", mem_root)); DBUG_ASSERT(alloc_root_inited(mem_root)); Size+=ALIGN_SIZE(sizeof(USED_MEM)); if (!(next = (USED_MEM*) my_malloc(Size,MYF(MY_WME)))) { Loading @@ -140,6 +165,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) reg1 USED_MEM *next= 0; reg2 USED_MEM **prev; DBUG_ASSERT(alloc_root_inited(mem_root)); Size= ALIGN_SIZE(Size); if ((*(prev= &mem_root->free)) != NULL) { Loading
sql/opt_range.cc +6 −2 Original line number Diff line number Diff line Loading @@ -2554,7 +2554,8 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1); MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC); QUICK_SELECT *quick= new QUICK_SELECT(thd, table, ref->key); KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; QUICK_RANGE *range; Loading @@ -2566,7 +2567,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { if (thd->is_fatal_error) goto err; // out of memory return quick; // empty range goto ok; // empty range } if (!(range= new QUICK_RANGE())) Loading Loading @@ -2613,9 +2614,12 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) goto err; } ok: my_pthread_setspecific_ptr(THR_MALLOC, old_root); return quick; err: my_pthread_setspecific_ptr(THR_MALLOC, old_root); delete quick; return 0; } Loading
sql/sql_class.cc +46 −23 Original line number Diff line number Diff line Loading @@ -221,7 +221,6 @@ THD::THD() init(); /* Initialize sub structures */ clear_alloc_root(&transaction.mem_root); init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); user_connect=(USER_CONN *)0; hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, Loading Loading @@ -258,6 +257,7 @@ THD::THD() transaction.trans_log.end_of_file= max_binlog_cache_size; } #endif init_alloc_root(&transaction.mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); { ulong tmp=sql_rnd_with_mutex(); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); Loading Loading @@ -303,10 +303,10 @@ void THD::init(void) void THD::init_for_queries() { ha_enable_transaction(this,TRUE); init_sql_alloc(&mem_root, variables.query_alloc_block_size, reset_root_defaults(&mem_root, variables.query_alloc_block_size, variables.query_prealloc_size); init_sql_alloc(&transaction.mem_root, reset_root_defaults(&transaction.mem_root, variables.trans_alloc_block_size, variables.trans_prealloc_size); } Loading Loading @@ -1332,6 +1332,17 @@ void select_dumpvar::cleanup() } /* Create arena for already constructed THD. SYNOPSYS Item_arena() thd - thread for which arena is created DESCRIPTION Create arena for already existing THD using its variables as parameters for memory root initialization. */ Item_arena::Item_arena(THD* thd) :free_list(0), state(INITIALIZED) Loading @@ -1342,24 +1353,31 @@ Item_arena::Item_arena(THD* thd) } /* This constructor is called when Item_arena is a subobject of THD */ /* Create arena and optionally initialize memory root. Item_arena::Item_arena() :free_list(0), state(CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } SYNOPSYS Item_arena() init_mem_root - whenever we need to initialize memory root DESCRIPTION Create arena and optionally initialize memory root with minimal possible parameters. NOTE We use this constructor when arena is part of THD, but reinitialize its memory root in THD::init_for_queries() before execution of real statements. */ Item_arena::Item_arena(bool init_mem_root) :free_list(0), state(INITIALIZED) state(CONVENTIONAL_EXECUTION) { if (init_mem_root) clear_alloc_root(&mem_root); init_alloc_root(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); } Item_arena::Type Item_arena::type() const { DBUG_ASSERT("Item_arena::type()" == "abstract"); Loading @@ -1367,10 +1385,6 @@ Item_arena::Type Item_arena::type() const } Item_arena::~Item_arena() {} /* Statement functions */ Loading @@ -1394,7 +1408,8 @@ Statement::Statement(THD *thd) */ Statement::Statement() :id(0), :Item_arena((bool)TRUE), id(0), set_query_id(1), allow_sum_func(0), /* initialized later */ lex(&main_lex), Loading Loading @@ -1462,8 +1477,16 @@ void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup) { set->set_item_arena(this); set_item_arena(backup); // reset backup mem_root to avoid its freeing init_alloc_root(&backup->mem_root, 0, 0); #ifdef NOT_NEEDED_NOW /* Reset backup mem_root to avoid its freeing. Since Item_arena's mem_root is freed only when it is part of Statement we need this only if we use some Statement's arena as backup storage. But we do this only with THD::stmt_backup and this Statement is specially handled in this respect. So this code is not really needed now. */ clear_alloc_root(&backup->mem_root); #endif } void Item_arena::set_item_arena(Item_arena *set) Loading
sql/sql_class.h +14 −2 Original line number Diff line number Diff line Loading @@ -441,11 +441,23 @@ class Item_arena STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE }; /* This constructor is used only when Item_arena is created as backup storage for another instance of Item_arena. */ Item_arena() {}; /* Create arena for already constructed THD using its variables as parameters for memory root initialization. */ Item_arena(THD *thd); Item_arena(); /* Create arena and optionally init memory root with minimal values. Particularly used if Item_arena is part of Statement. */ Item_arena(bool init_mem_root); virtual Type type() const; virtual ~Item_arena(); virtual ~Item_arena() {}; inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } Loading