diff --git a/src/box/alter.cc b/src/box/alter.cc index dbbbcbc44b134ab5e43de12a2a28217e2d6ca2fd..bb4254878c63fa6524724ed96fa226ce62e77283 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -537,11 +537,13 @@ space_format_decode(const char *data, uint32_t *out_count, *fields = NULL; return 0; } - size_t size = count * sizeof(struct field_def); + size_t size; struct field_def *region_defs = - (struct field_def *) region_alloc(region, size); + region_alloc_array(region, typeof(region_defs[0]), count, + &size); if (region_defs == NULL) { - diag_set(OutOfMemory, size, "region", "struct field_def"); + diag_set(OutOfMemory, size, "region_alloc_array", + "region_defs"); return -1; } /* @@ -2452,10 +2454,12 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) * comparators must be updated. */ struct key_def **keys; - size_t bsize = old_space->index_count * sizeof(keys[0]); - keys = (struct key_def **) region_alloc(&fiber()->gc, bsize); + size_t bsize; + keys = region_alloc_array(&fiber()->gc, typeof(keys[0]), + old_space->index_count, &bsize); if (keys == NULL) { - diag_set(OutOfMemory, bsize, "region", "new slab"); + diag_set(OutOfMemory, bsize, "region_alloc_array", + "keys"); return -1; } for (uint32_t i = 0; i < old_space->index_count; ++i) @@ -2733,10 +2737,12 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event) * index and a space format, defined by a user. */ struct key_def **keys; - size_t bsize = old_space->index_count * sizeof(keys[0]); - keys = (struct key_def **) region_alloc(&fiber()->gc, bsize); + size_t bsize; + keys = region_alloc_array(&fiber()->gc, typeof(keys[0]), + old_space->index_count, &bsize); if (keys == NULL) { - diag_set(OutOfMemory, bsize, "region", "new slab"); + diag_set(OutOfMemory, bsize, "region_alloc_array", + "keys"); return -1; } for (uint32_t i = 0, j = 0; i < old_space->index_count; ++i) { @@ -5009,11 +5015,13 @@ decode_fk_links(struct tuple *tuple, uint32_t *out_count, return NULL; } *out_count = count; - size_t size = count * sizeof(struct field_link); + size_t size; struct field_link *region_links = - (struct field_link *)region_alloc(&fiber()->gc, size); + region_alloc_array(&fiber()->gc, typeof(region_links[0]), count, + &size); if (region_links == NULL) { - diag_set(OutOfMemory, size, "region", "struct field_link"); + diag_set(OutOfMemory, size, "region_alloc_array", + "region_links"); return NULL; } memset(region_links, 0, size); @@ -5054,7 +5062,9 @@ fk_constraint_def_new_from_tuple(struct tuple *tuple, uint32_t errcode) name_len, errcode); if (links == NULL) return NULL; - size_t fk_def_sz = fk_constraint_def_sizeof(link_count, name_len); + uint32_t links_offset; + size_t fk_def_sz = fk_constraint_def_sizeof(link_count, name_len, + &links_offset); struct fk_constraint_def *fk_def = (struct fk_constraint_def *) malloc(fk_def_sz); if (fk_def == NULL) { @@ -5065,8 +5075,7 @@ fk_constraint_def_new_from_tuple(struct tuple *tuple, uint32_t errcode) auto def_guard = make_scoped_guard([=] { free(fk_def); }); memcpy(fk_def->name, name, name_len); fk_def->name[name_len] = '\0'; - fk_def->links = (struct field_link *)((char *)&fk_def->name + - name_len + 1); + fk_def->links = (struct field_link *)((char *)fk_def + links_offset); memcpy(fk_def->links, links, link_count * sizeof(struct field_link)); fk_def->field_count = link_count; if (tuple_field_u32(tuple, BOX_FK_CONSTRAINT_FIELD_CHILD_ID, diff --git a/src/box/applier.cc b/src/box/applier.cc index c6deeff1bdde951b1e0ab5d8f6fb4b1eca76b96c..df48b47962d2abf98328d13178341a10d4f2e482 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -588,13 +588,12 @@ applier_read_tx_row(struct applier *applier) { struct ev_io *coio = &applier->io; struct ibuf *ibuf = &applier->ibuf; - - struct applier_tx_row *tx_row = (struct applier_tx_row *) - region_alloc(&fiber()->gc, sizeof(struct applier_tx_row)); + size_t size; + struct applier_tx_row *tx_row = + region_alloc_object(&fiber()->gc, typeof(*tx_row), &size); if (tx_row == NULL) - tnt_raise(OutOfMemory, sizeof(struct applier_tx_row), - "region", "struct applier_tx_row"); + tnt_raise(OutOfMemory, size, "region_alloc_object", "tx_row"); struct xrow_header *row = &tx_row->row; @@ -809,13 +808,14 @@ applier_apply_tx(struct stailq *rows) /* We are ready to submit txn to wal. */ struct trigger *on_rollback, *on_commit; - on_rollback = (struct trigger *)region_alloc(&txn->region, - sizeof(struct trigger)); - on_commit = (struct trigger *)region_alloc(&txn->region, - sizeof(struct trigger)); + size_t size; + on_rollback = region_alloc_object(&txn->region, typeof(*on_rollback), + &size); + on_commit = region_alloc_object(&txn->region, typeof(*on_commit), + &size); if (on_rollback == NULL || on_commit == NULL) { - diag_set(OutOfMemory, sizeof(struct trigger), - "region_alloc", "on_rollback/on_commit"); + diag_set(OutOfMemory, size, "region_alloc_object", + "on_rollback/on_commit"); goto rollback; } diff --git a/src/box/bind.c b/src/box/bind.c index bbc1f56df203b6370f6a300e6f38c02eb71d6af6..d45a0f9a7da57b470568b434af4adfa814dd5e0d 100644 --- a/src/box/bind.c +++ b/src/box/bind.c @@ -137,10 +137,11 @@ sql_bind_list_decode(const char *data, struct sql_bind **out_bind) } struct region *region = &fiber()->gc; uint32_t used = region_used(region); - size_t size = sizeof(struct sql_bind) * bind_count; - struct sql_bind *bind = (struct sql_bind *) region_alloc(region, size); + size_t size; + struct sql_bind *bind = region_alloc_array(region, typeof(bind[0]), + bind_count, &size); if (bind == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "struct sql_bind"); + diag_set(OutOfMemory, size, "region_alloc_array", "bind"); return -1; } for (uint32_t i = 0; i < bind_count; ++i) { diff --git a/src/box/ck_constraint.c b/src/box/ck_constraint.c index ff3f05587c4273089d3e50ff2d32031c4d5a2a1a..b629a73eb2de8da2879104e58cfd7178e005cfc3 100644 --- a/src/box/ck_constraint.c +++ b/src/box/ck_constraint.c @@ -190,12 +190,13 @@ ck_constraint_on_replace_trigger(struct trigger *trigger, void *event) struct space *space = stmt->space; assert(space != NULL); - uint32_t field_ref_sz = sizeof(struct vdbe_field_ref) + - sizeof(uint32_t) * space->def->field_count; - struct vdbe_field_ref *field_ref = - region_alloc(&fiber()->gc, field_ref_sz); + struct vdbe_field_ref *field_ref; + size_t size = sizeof(field_ref->slots[0]) * space->def->field_count + + sizeof(*field_ref); + field_ref = (struct vdbe_field_ref *) + region_aligned_alloc(&fiber()->gc, size, alignof(*field_ref)); if (field_ref == NULL) { - diag_set(OutOfMemory, field_ref_sz, "region_alloc", + diag_set(OutOfMemory, size, "region_aligned_alloc", "field_ref"); return -1; } diff --git a/src/box/field_map.c b/src/box/field_map.c index 1876bdd952cf644df6ab0821fd0c1843c1e6fa52..5f46619413d7e6750809aff95735e8fe794096cc 100644 --- a/src/box/field_map.c +++ b/src/box/field_map.c @@ -43,10 +43,12 @@ field_map_builder_create(struct field_map_builder *builder, builder->slots = NULL; return 0; } - uint32_t sz = builder->slot_count * sizeof(builder->slots[0]); - builder->slots = region_alloc(region, sz); + uint32_t sz; + builder->slots = region_alloc_array(region, typeof(builder->slots[0]), + builder->slot_count, &sz); if (builder->slots == NULL) { - diag_set(OutOfMemory, sz, "region_alloc", "field_map"); + diag_set(OutOfMemory, sz, "region_alloc_array", + "builder->slots"); return -1; } memset((char *)builder->slots, 0, sz); @@ -61,11 +63,12 @@ field_map_builder_slot_extent_new(struct field_map_builder *builder, { struct field_map_builder_slot_extent *extent; assert(!builder->slots[offset_slot].has_extent); - uint32_t sz = sizeof(struct field_map_builder_slot_extent) + - multikey_count * sizeof(uint32_t); - extent = region_alloc(region, sz); + uint32_t sz = sizeof(*extent) + + multikey_count * sizeof(extent->offset[0]); + extent = (struct field_map_builder_slot_extent *) + region_aligned_alloc(region, sz, alignof(*extent)); if (extent == NULL) { - diag_set(OutOfMemory, sz, "region", "extent"); + diag_set(OutOfMemory, sz, "region_aligned_alloc", "extent"); return NULL; } memset(extent, 0, sz); diff --git a/src/box/fk_constraint.h b/src/box/fk_constraint.h index b1e0cfb843d2caa56144d7583b5ccb65f4d52a4a..dcc5363c0dcc66f0a29370685b021a5e910d5353 100644 --- a/src/box/fk_constraint.h +++ b/src/box/fk_constraint.h @@ -32,7 +32,8 @@ */ #include <stdbool.h> #include <stdint.h> - +#include "trivia/util.h" +#include "small/slab_arena.h" #include "small/rlist.h" #if defined(__cplusplus) @@ -125,15 +126,18 @@ struct fk_constraint { * |----------------------------------| * | name + \0 | * |----------------------------------| + * | memory align padding | + * |----------------------------------| * | links | * +----------------------------------+ */ static inline size_t -fk_constraint_def_sizeof(uint32_t link_count, uint32_t name_len) +fk_constraint_def_sizeof(uint32_t link_count, uint32_t name_len, + uint32_t *links_offset) { - return sizeof(struct fk_constraint_def) + - link_count * sizeof(struct field_link) + - name_len + 1; + *links_offset = small_align(sizeof(struct fk_constraint_def) + + name_len + 1, alignof(struct field_link)); + return *links_offset + link_count * sizeof(struct field_link); } static inline bool diff --git a/src/box/index_def.c b/src/box/index_def.c index 85128b1a53e7a4d4236ffa2b903365f4ae199b87..98029612c482f0ed81187ae594a48bcb5b65cb49 100644 --- a/src/box/index_def.c +++ b/src/box/index_def.c @@ -255,11 +255,12 @@ index_def_to_key_def(struct rlist *index_defs, int *size) struct index_def *index_def; rlist_foreach_entry(index_def, index_defs, link) key_count++; - size_t sz = sizeof(struct key_def *) * key_count; - struct key_def **keys = (struct key_def **) region_alloc(&fiber()->gc, - sz); + size_t bsize; + struct key_def **keys = + region_alloc_array(&fiber()->gc, typeof(keys[0]), key_count, + &bsize); if (keys == NULL) { - diag_set(OutOfMemory, sz, "region_alloc", "keys"); + diag_set(OutOfMemory, bsize, "region_alloc_array", "keys"); return NULL; } *size = key_count; diff --git a/src/box/key_def.c b/src/box/key_def.c index 3e3782163f78a0c6b8ff9aaf9be4f50aa1a72604..18af44961d46369c1d2525e9cb0c2be31d280c37 100644 --- a/src/box/key_def.c +++ b/src/box/key_def.c @@ -847,11 +847,12 @@ key_def_find_pk_in_cmp_def(const struct key_def *cmp_def, size_t region_svp = region_used(region); /* First, dump primary key parts as is. */ - struct key_part_def *parts = region_alloc(region, - pk_def->part_count * sizeof(*parts)); + size_t size; + struct key_part_def *parts = + region_alloc_array(region, typeof(parts[0]), pk_def->part_count, + &size); if (parts == NULL) { - diag_set(OutOfMemory, pk_def->part_count * sizeof(*parts), - "region", "key def parts"); + diag_set(OutOfMemory, size, "region_alloc_array", "parts"); goto out; } if (key_def_dump_parts(pk_def, parts, region) != 0) diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c index b4c464af704215c68b275727ee70dab37d6d0103..926a0a61caf094342a147e04ab984506b7e57b05 100644 --- a/src/box/lua/execute.c +++ b/src/box/lua/execute.c @@ -404,15 +404,16 @@ lua_sql_bind_list_decode(struct lua_State *L, struct sql_bind **out_bind, } struct region *region = &fiber()->gc; uint32_t used = region_used(region); - size_t size = sizeof(struct sql_bind) * bind_count; + size_t size; /* * Memory allocated here will be freed in * sql_stmt_finalize() or in txn_commit()/txn_rollback() if * there is an active transaction. */ - struct sql_bind *bind = (struct sql_bind *) region_alloc(region, size); + struct sql_bind *bind = region_alloc_array(region, typeof(bind[0]), + bind_count, &size); if (bind == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "bind"); + diag_set(OutOfMemory, size, "region_alloc_array", "bind"); return -1; } for (uint32_t i = 0; i < bind_count; ++i) { diff --git a/src/box/lua/key_def.c b/src/box/lua/key_def.c index d8f96162d51eed18389103bd7fbdababfb1c7c0a..1a99fab63dcac96e350407fc5783c36974e09a4c 100644 --- a/src/box/lua/key_def.c +++ b/src/box/lua/key_def.c @@ -438,13 +438,14 @@ lbox_key_def_new(struct lua_State *L) "[, collation = <string>]}, ...}"); uint32_t part_count = lua_objlen(L, 1); - const ssize_t parts_size = sizeof(struct key_part_def) * part_count; struct region *region = &fiber()->gc; size_t region_svp = region_used(region); - struct key_part_def *parts = region_alloc(region, parts_size); + size_t size; + struct key_part_def *parts = + region_alloc_array(region, typeof(parts[0]), part_count, &size); if (parts == NULL) { - diag_set(OutOfMemory, parts_size, "region", "parts"); + diag_set(OutOfMemory, size, "region_alloc_array", "parts"); return luaT_error(L); } if (part_count == 0) { diff --git a/src/box/lua/misc.cc b/src/box/lua/misc.cc index ae8fbb6826d5f7112b24691c289cd0ac8b0b23bc..5da84b35a653af50e63a3a99e2cd75be36cfeef0 100644 --- a/src/box/lua/misc.cc +++ b/src/box/lua/misc.cc @@ -184,13 +184,13 @@ lbox_tuple_format_new(struct lua_State *L) uint32_t count = lua_objlen(L, 1); if (count == 0) return lbox_push_tuple_format(L, tuple_format_runtime); - size_t size = count * sizeof(struct field_def); + size_t size; struct region *region = &fiber()->gc; size_t region_svp = region_used(region); - struct field_def *fields = - (struct field_def *)region_alloc(region, size); + struct field_def *fields = region_alloc_array(region, typeof(fields[0]), + count, &size); if (fields == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "fields"); + diag_set(OutOfMemory, size, "region_alloc_array", "fields"); return luaT_error(L); } for (uint32_t i = 0; i < count; ++i) { diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c index e155ecd65659bbe94360abc15f93c35bdeaf272f..76ff3fcd7d511a78e90df9c0fa44eb0fe4cc7e44 100644 --- a/src/box/memtx_tree.c +++ b/src/box/memtx_tree.c @@ -804,10 +804,11 @@ struct func_key_undo { struct func_key_undo * func_key_undo_new(struct region *region) { - struct func_key_undo *undo = - (struct func_key_undo *)region_alloc(region, sizeof(*undo)); + size_t size; + struct func_key_undo *undo = region_alloc_object(region, typeof(*undo), + &size); if (undo == NULL) { - diag_set(OutOfMemory, sizeof(*undo), "region", "undo"); + diag_set(OutOfMemory, size, "region_alloc_object", "undo"); return NULL; } return undo; diff --git a/src/box/space_def.c b/src/box/space_def.c index 0ff51b9a76bfcd39bdc890f8c55cedbb9f9a045e..efb1c8ee96806aa87e26f4ab901d6c1c6bd6da79 100644 --- a/src/box/space_def.c +++ b/src/box/space_def.c @@ -71,10 +71,11 @@ space_def_sizeof(uint32_t name_len, const struct field_def *fields, } } } - - *fields_offset = sizeof(struct space_def) + name_len + 1; + *fields_offset = small_align(sizeof(struct space_def) + name_len + 1, + alignof(typeof(fields[0]))); *names_offset = *fields_offset + field_count * sizeof(struct field_def); - *def_expr_offset = *names_offset + field_strs_size; + *def_expr_offset = small_align(*names_offset + field_strs_size, + alignof(uint64_t)); return *def_expr_offset + def_exprs_size; } diff --git a/src/box/sql.c b/src/box/sql.c index fc1386f528d0e54717cef386c601ef3144db2bca..555fcfd1f907f7d60279e3bb8dfc051571ae190d 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -341,13 +341,17 @@ sql_ephemeral_space_create(uint32_t field_count, struct sql_key_info *key_info) uint32_t name_len = strlen("_COLUMN_") + 11; uint32_t size = field_count * (sizeof(struct field_def) + name_len) + part_count * sizeof(struct key_part_def); - struct field_def *fields = region_alloc(region, size); + struct field_def *fields = region_aligned_alloc(region, size, + alignof(fields[0])); if (fields == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "fields"); + diag_set(OutOfMemory, size, "region_aligned_alloc", "fields"); return NULL; } struct key_part_def *ephemer_key_parts = (void *)fields + field_count * sizeof(struct field_def); + static_assert(alignof(*fields) == alignof(*ephemer_key_parts), + "allocated in one block, and should have the same " + "alignment"); char *names = (char *)ephemer_key_parts + part_count * sizeof(struct key_part_def); for (uint32_t i = 0; i < field_count; ++i) { @@ -1234,9 +1238,10 @@ sql_ephemeral_space_def_new(struct Parse *parser, const char *name) uint32_t dummy; size_t size = space_def_sizeof(name_len, NULL, 0, &dummy, &dummy, &dummy); - def = (struct space_def *)region_alloc(&parser->region, size); + def = (struct space_def *)region_aligned_alloc(&parser->region, size, + alignof(*def)); if (def == NULL) { - diag_set(OutOfMemory, size, "region_alloc", + diag_set(OutOfMemory, size, "region_aligned_alloc", "sql_ephemeral_space_def_new"); parser->is_aborted = true; return NULL; @@ -1252,10 +1257,11 @@ sql_ephemeral_space_def_new(struct Parse *parser, const char *name) struct space * sql_ephemeral_space_new(Parse *parser, const char *name) { - size_t sz = sizeof(struct space); - struct space *space = (struct space *) region_alloc(&parser->region, sz); + size_t sz; + struct space *space = region_alloc_object(&parser->region, + typeof(*space), &sz); if (space == NULL) { - diag_set(OutOfMemory, sz, "region", "space"); + diag_set(OutOfMemory, sz, "region_alloc_object", "space"); parser->is_aborted = true; return NULL; } diff --git a/src/box/sql/build.c b/src/box/sql/build.c index b1f9fedb018ab1875f65b8deeff2f194fe1c6d03..0b60d2ee76e1a4ce1c231fbe7e612b06ab9e0775 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -260,12 +260,12 @@ sql_field_retrieve(Parse *parser, struct space_def *space_def, uint32_t id) uint32_t columns_new = space_def->exact_field_count; columns_new = (columns_new > 0) ? 2 * columns_new : 1; struct region *region = &parser->region; - field = region_alloc(region, columns_new * - sizeof(space_def->fields[0])); + size_t size; + field = region_alloc_array(region, typeof(field[0]), + columns_new, &size); if (field == NULL) { - diag_set(OutOfMemory, columns_new * - sizeof(space_def->fields[0]), - "region_alloc", "sql_field_retrieve"); + diag_set(OutOfMemory, size, "region_alloc_array", + "field"); parser->is_aborted = true; return NULL; } @@ -609,10 +609,12 @@ sql_create_check_contraint(struct Parse *parser) uint32_t expr_str_offset; uint32_t ck_def_sz = ck_constraint_def_sizeof(name_len, expr_str_len, &expr_str_offset); - struct ck_constraint_parse *ck_parse = - region_alloc(region, sizeof(*ck_parse) + ck_def_sz); + struct ck_constraint_parse *ck_parse; + size_t total = sizeof(*ck_parse) + ck_def_sz; + ck_parse = (struct ck_constraint_parse *) + region_aligned_alloc(region, total, alignof(*ck_parse)); if (ck_parse == NULL) { - diag_set(OutOfMemory, sizeof(*ck_parse) + ck_def_sz, "region", + diag_set(OutOfMemory, total, "region_aligned_alloc", "ck_parse"); parser->is_aborted = true; return; @@ -620,6 +622,9 @@ sql_create_check_contraint(struct Parse *parser) struct ck_constraint_def *ck_def = (struct ck_constraint_def *)((char *)ck_parse + sizeof(*ck_parse)); + static_assert(alignof(*ck_def) == alignof(*ck_parse), + "allocated in one block and should have the same " + "alignment"); ck_parse->ck_def = ck_def; rlist_create(&ck_parse->link); @@ -1869,11 +1874,13 @@ sql_create_foreign_key(struct Parse *parse_context) goto tnt_error; } } else { + size_t size; struct fk_constraint_parse *fk_parse = - region_alloc(&parse_context->region, sizeof(*fk_parse)); + region_alloc_object(&parse_context->region, + typeof(*fk_parse), &size); if (fk_parse == NULL) { - diag_set(OutOfMemory, sizeof(*fk_parse), "region_alloc", - "struct fk_constraint_parse"); + diag_set(OutOfMemory, size, "region_alloc_object", + "fk_parse"); goto tnt_error; } memset(fk_parse, 0, sizeof(*fk_parse)); @@ -1957,12 +1964,15 @@ sql_create_foreign_key(struct Parse *parse_context) } } int name_len = strlen(constraint_name); - size_t fk_def_sz = fk_constraint_def_sizeof(child_cols_count, name_len); - struct fk_constraint_def *fk_def = region_alloc(&parse_context->region, - fk_def_sz); + uint32_t links_offset; + size_t fk_def_sz = fk_constraint_def_sizeof(child_cols_count, name_len, + &links_offset); + struct fk_constraint_def *fk_def = (struct fk_constraint_def *) + region_aligned_alloc(&parse_context->region, fk_def_sz, + alignof(*fk_def)); if (fk_def == NULL) { - diag_set(OutOfMemory, fk_def_sz, "region", - "struct fk_constraint_def"); + diag_set(OutOfMemory, fk_def_sz, "region_aligned_alloc", + "fk_def"); goto tnt_error; } int actions = create_fk_def->actions; @@ -1973,7 +1983,7 @@ sql_create_foreign_key(struct Parse *parse_context) fk_def->match = (enum fk_constraint_match) (create_fk_def->match); fk_def->on_update = (enum fk_constraint_action) ((actions >> 8) & 0xff); fk_def->on_delete = (enum fk_constraint_action) (actions & 0xff); - fk_def->links = (struct field_link *) ((char *) fk_def->name + name_len + 1); + fk_def->links = (struct field_link *)((char *)fk_def + links_offset); /* Fill links map. */ for (uint32_t i = 0; i < fk_def->field_count; ++i) { if (!is_self_referenced && parent_cols == NULL) { @@ -2260,11 +2270,13 @@ index_fill_def(struct Parse *parse, struct index *index, int rc = -1; struct key_def *key_def = NULL; - struct key_part_def *key_parts = region_alloc(&fiber()->gc, - sizeof(*key_parts) * expr_list->nExpr); + size_t size; + struct key_part_def *key_parts = + region_alloc_array(&fiber()->gc, typeof(key_parts[0]), + expr_list->nExpr, &size); if (key_parts == NULL) { - diag_set(OutOfMemory, sizeof(*key_parts) * expr_list->nExpr, - "region", "key parts"); + diag_set(OutOfMemory, size, "region_alloc_array", + "key_parts"); goto tnt_error; } for (int i = 0; i < expr_list->nExpr; i++) { @@ -2514,10 +2526,10 @@ sql_create_index(struct Parse *parse) { parse->is_aborted = true; } } - - index = (struct index *) region_alloc(&parse->region, sizeof(*index)); + size_t size; + index = region_alloc_object(&parse->region, typeof(*index), &size); if (index == NULL) { - diag_set(OutOfMemory, sizeof(*index), "region", "index"); + diag_set(OutOfMemory, size, "region_alloc_object", "index"); parse->is_aborted = true; goto exit_create_index; } diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 2c510940bf418b56b3d18b55055a93034e3adfaa..4715ffabbea884988e8e5b17440ac4eab889af9e 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -85,10 +85,11 @@ static struct Mem * vdbemem_alloc_on_region(uint32_t count) { struct region *region = &fiber()->gc; - struct Mem *ret = region_alloc(region, count * sizeof(*ret)); + size_t size; + struct Mem *ret = region_alloc_array(region, typeof(*ret), count, + &size); if (ret == NULL) { - diag_set(OutOfMemory, count * sizeof(*ret), - "region_alloc", "ret"); + diag_set(OutOfMemory, size, "region_alloc_array", "ret"); return NULL; } memset(ret, 0, count * sizeof(*ret)); diff --git a/src/box/sql/select.c b/src/box/sql/select.c index f39484013b9966f82a9ad455e33cbdf25e7009b3..0b7358af490e115788c252be260083174a7c1dc4 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -1773,11 +1773,12 @@ generate_column_metadata(struct Parse *pParse, struct SrcList *pTabList, if (pParse->colNamesSet || db->mallocFailed) return; assert(v != 0); - size_t var_pos_sz = pParse->nVar * sizeof(uint32_t); - uint32_t *var_pos = (uint32_t *) region_alloc(&pParse->region, - var_pos_sz); + size_t size; + uint32_t *var_pos = + region_alloc_array(&pParse->region, typeof(var_pos[0]), + pParse->nVar, &size); if (var_pos == NULL) { - diag_set(OutOfMemory, var_pos_sz, "region", "var_pos"); + diag_set(OutOfMemory, size, "region_alloc_array", "var_pos"); return; } assert(pTabList != 0); @@ -1910,9 +1911,10 @@ sqlColumnsFromExprList(Parse * parse, ExprList * expr_list, */ assert(space_def->fields == NULL); struct region *region = &parse->region; + size_t size; space_def->fields = - region_alloc(region, - column_count * sizeof(space_def->fields[0])); + region_alloc_array(region, typeof(space_def->fields[0]), + column_count, &size); if (space_def->fields == NULL) { sqlOomFault(db); goto cleanup; diff --git a/src/box/sql/update.c b/src/box/sql/update.c index d25262c21ab3403f89f7b95dd2f1e6ab3a4b82b7..24c7cfa271651f6819d09ec7be5f9aab853a99f4 100644 --- a/src/box/sql/update.c +++ b/src/box/sql/update.c @@ -120,10 +120,10 @@ sqlUpdate(Parse * pParse, /* The parser context */ int pk_cursor = pParse->nTab++; pTabList->a[0].iCursor = pk_cursor; struct index *pPk = space_index(space, 0); - i = sizeof(int) * def->field_count; - aXRef = (int *) region_alloc(&pParse->region, i); + aXRef = region_alloc_array(&pParse->region, typeof(aXRef[0]), + def->field_count, &i); if (aXRef == NULL) { - diag_set(OutOfMemory, i, "region_alloc", "aXRef"); + diag_set(OutOfMemory, i, "region_alloc_array", "aXRef"); goto update_cleanup; } memset(aXRef, -1, i); diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 7a42602a2198d0642c11ed77d641414d80ef2f04..5bc106b5dd3b22772086510ccb71301e46be8fc9 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -605,11 +605,11 @@ static int vdbe_add_new_autoinc_id(struct Vdbe *vdbe, int64_t id) { assert(vdbe != NULL); - struct autoinc_id_entry *id_entry = region_alloc(&fiber()->gc, - sizeof(*id_entry)); + size_t size; + struct autoinc_id_entry *id_entry = + region_alloc_object(&fiber()->gc, typeof(*id_entry), &size); if (id_entry == NULL) { - diag_set(OutOfMemory, sizeof(*id_entry), "region_alloc", - "id_entry"); + diag_set(OutOfMemory, size, "region_alloc_object", "id_entry"); return -1; } id_entry->id = id; diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c index 5bc27f134817daba105ae92079352330f0fd5ed6..6d87688653155ea58fc25c7ac0b281be50247896 100644 --- a/src/box/sql/wherecode.c +++ b/src/box/sql/wherecode.c @@ -1084,10 +1084,13 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W * predicates, so we consider term as sequence * of AND'ed predicates. */ - size_t addrs_sz = sizeof(int) * nEq; - int *seek_addrs = region_alloc(&pParse->region, addrs_sz); + size_t addrs_sz; + int *seek_addrs = region_alloc_array(&pParse->region, + typeof(seek_addrs[0]), nEq, + &addrs_sz); if (seek_addrs == NULL) { - diag_set(OutOfMemory, addrs_sz, "region", "seek_addrs"); + diag_set(OutOfMemory, addrs_sz, "region_alloc_array", + "seek_addrs"); pParse->is_aborted = true; return 0; } diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c index beaeb0fe7c588710abdf7bb51a6ad920d3b28cf7..68ec2a749925f5225c477cbe9c647f7feaabfc16 100644 --- a/src/box/tuple_format.c +++ b/src/box/tuple_format.c @@ -981,7 +981,8 @@ tuple_format_iterator_create(struct tuple_format_iterator *it, if (validate) it->required_fields_sz = bitmap_size(format->total_field_count); uint32_t total_sz = frames_sz + 2 * it->required_fields_sz; - struct mp_frame *frames = region_alloc(region, total_sz); + struct mp_frame *frames = region_aligned_alloc(region, total_sz, + alignof(frames[0])); if (frames == NULL) { diag_set(OutOfMemory, total_sz, "region", "tuple_format_iterator"); diff --git a/src/box/txn.c b/src/box/txn.c index b81693c0aad09f79981b2157b85a3c5919a2ff33..123520166a5b395d2393b02c3080a3603a124674 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -802,13 +802,15 @@ struct txn_savepoint * txn_savepoint_new(struct txn *txn, const char *name) { assert(txn == in_txn()); - size_t svp_sz = sizeof(struct txn_savepoint); int name_len = name != NULL ? strlen(name) : 0; - svp_sz += name_len; - struct txn_savepoint *svp = - (struct txn_savepoint *) region_alloc(&txn->region, svp_sz); + struct txn_savepoint *svp; + static_assert(sizeof(svp->name) == 1, + "name member already has 1 byte for 0 termination"); + size_t size = sizeof(*svp) + name_len; + svp = (struct txn_savepoint *)region_aligned_alloc(&txn->region, size, + alignof(*svp)); if (svp == NULL) { - diag_set(OutOfMemory, svp_sz, "region", "svp"); + diag_set(OutOfMemory, size, "region_aligned_alloc", "svp"); return NULL; } svp->stmt = stailq_last(&txn->stmts); diff --git a/src/box/user.cc b/src/box/user.cc index fe05558862c8aa4ef85522aaa896502904173c00..198bf828ba86d398ec0a12b5c85d423a0edb140f 100644 --- a/src/box/user.cc +++ b/src/box/user.cc @@ -192,11 +192,11 @@ user_grant_priv(struct user *user, struct priv_def *def) { struct priv_def *old = privset_search(&user->privs, def); if (old == NULL) { - size_t size = sizeof(struct priv_def); - old = (struct priv_def *) - region_alloc(&user->pool, size); + size_t size; + old = region_alloc_object(&user->pool, typeof(*old), &size); if (old == NULL) { - diag_set(OutOfMemory, size, "region", "struct priv_def"); + diag_set(OutOfMemory, size, "region_alloc_object", + "old"); return -1; } *old = *def; diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 3a582b6fedf3aa71355387471c6aa75fe9e20606..e7669452ecf1de8b99bc7d70a61c8d8c709022be 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -603,10 +603,11 @@ vinyl_engine_create_space(struct engine *engine, struct space_def *def, rlist_foreach_entry(index_def, key_list, link) key_count++; struct key_def **keys; - size_t size = sizeof(*keys) * key_count; - keys = region_alloc(&fiber()->gc, size); + size_t size; + keys = region_alloc_array(&fiber()->gc, typeof(keys[0]), key_count, + &size); if (keys == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "keys"); + diag_set(OutOfMemory, size, "region_alloc_array", "keys"); free(space); return NULL; } @@ -4439,19 +4440,22 @@ vy_deferred_delete_on_replace(struct trigger *trigger, void *event) * which will propagate the WAL row LSN to * the LSM tree. */ - struct trigger *on_commit = region_alloc(&txn->region, - sizeof(*on_commit)); + size_t size; + struct trigger *on_commit = + region_alloc_object(&txn->region, typeof(*on_commit), + &size); if (on_commit == NULL) { - diag_set(OutOfMemory, sizeof(*on_commit), - "region", "struct trigger"); + diag_set(OutOfMemory, size, "region_alloc_object", + "on_commit"); rc = -1; break; } - struct trigger *on_rollback = region_alloc(&txn->region, - sizeof(*on_commit)); + struct trigger *on_rollback = + region_alloc_object(&txn->region, typeof(*on_rollback), + &size); if (on_rollback == NULL) { - diag_set(OutOfMemory, sizeof(*on_commit), - "region", "struct trigger"); + diag_set(OutOfMemory, size, "region_alloc_object", + "on_rollback"); rc = -1; break; } diff --git a/src/box/vy_log.c b/src/box/vy_log.c index 9ead066aff2beaec8fe01a0bb8cfdf6c4ed13f50..311985c721d8c67334fbf177d81523987533d785 100644 --- a/src/box/vy_log.c +++ b/src/box/vy_log.c @@ -621,12 +621,13 @@ vy_log_record_decode(struct vy_log_record *record, case VY_LOG_KEY_DEF: { struct region *region = &fiber()->gc; uint32_t part_count = mp_decode_array(&pos); - struct key_part_def *parts = region_alloc(region, - sizeof(*parts) * part_count); + size_t size; + struct key_part_def *parts = + region_alloc_array(region, typeof(parts[0]), + part_count, &size); if (parts == NULL) { - diag_set(OutOfMemory, - sizeof(*parts) * part_count, - "region", "struct key_part_def"); + diag_set(OutOfMemory, size, + "region_alloc_array", "parts"); return -1; } if (key_def_decode_parts(parts, part_count, &pos, @@ -701,18 +702,18 @@ static struct vy_log_record * vy_log_record_dup(struct region *pool, const struct vy_log_record *src) { size_t used = region_used(pool); - - struct vy_log_record *dst = region_alloc(pool, sizeof(*dst)); + size_t size; + struct vy_log_record *dst = region_alloc_object(pool, typeof(*dst), + &size); if (dst == NULL) { - diag_set(OutOfMemory, sizeof(*dst), - "region", "struct vy_log_record"); + diag_set(OutOfMemory, size, "region_alloc_object", "dst"); goto err; } *dst = *src; if (src->begin != NULL) { const char *data = src->begin; mp_next(&data); - size_t size = data - src->begin; + size = data - src->begin; dst->begin = region_alloc(pool, size); if (dst->begin == NULL) { diag_set(OutOfMemory, size, "region", @@ -724,7 +725,7 @@ vy_log_record_dup(struct region *pool, const struct vy_log_record *src) if (src->end != NULL) { const char *data = src->end; mp_next(&data); - size_t size = data - src->end; + size = data - src->end; dst->end = region_alloc(pool, size); if (dst->end == NULL) { diag_set(OutOfMemory, size, "region", @@ -734,12 +735,12 @@ vy_log_record_dup(struct region *pool, const struct vy_log_record *src) memcpy((char *)dst->end, src->end, size); } if (src->key_def != NULL) { - size_t size = src->key_def->part_count * - sizeof(struct key_part_def); - dst->key_parts = region_alloc(pool, size); + dst->key_parts = + region_alloc_array(pool, typeof(dst->key_parts[0]), + src->key_def->part_count, &size); if (dst->key_parts == NULL) { - diag_set(OutOfMemory, size, "region", - "struct key_part_def"); + diag_set(OutOfMemory, size, "region_alloc_array", + "def->key_parts"); goto err; } if (key_def_dump_parts(src->key_def, dst->key_parts, pool) != 0) diff --git a/src/box/vy_point_lookup.c b/src/box/vy_point_lookup.c index ecdcde7db87c387aca6d9965acd01a6f149be7ca..80b5c59334a860ee972db9411136aff37283b59b 100644 --- a/src/box/vy_point_lookup.c +++ b/src/box/vy_point_lookup.c @@ -167,11 +167,12 @@ vy_point_lookup_scan_slices(struct vy_lsm *lsm, const struct vy_read_view **rv, ITER_EQ, key); assert(range != NULL); int slice_count = range->slice_count; - struct vy_slice **slices = (struct vy_slice **) - region_alloc(&fiber()->gc, slice_count * sizeof(*slices)); + size_t size; + struct vy_slice **slices = + region_alloc_array(&fiber()->gc, typeof(slices[0]), slice_count, + &size); if (slices == NULL) { - diag_set(OutOfMemory, slice_count * sizeof(*slices), - "region", "slices array"); + diag_set(OutOfMemory, size, "region_alloc_array", "slices"); return -1; } int i = 0; diff --git a/src/box/xrow_update_map.c b/src/box/xrow_update_map.c index ff53a9ac41348977699ffc9a77f2e8a99e09252c..57fb27f183df25860d200ce61d99880b3378a3e0 100644 --- a/src/box/xrow_update_map.c +++ b/src/box/xrow_update_map.c @@ -63,10 +63,11 @@ struct xrow_update_map_item { static inline struct xrow_update_map_item * xrow_update_map_item_alloc(void) { - struct xrow_update_map_item *item = (struct xrow_update_map_item *) - region_alloc(&fiber()->gc, sizeof(*item)); + size_t size; + struct xrow_update_map_item *item = + region_alloc_object(&fiber()->gc, typeof(*item), &size); if (item == NULL) - diag_set(OutOfMemory, sizeof(*item), "region_alloc", "item"); + diag_set(OutOfMemory, size, "region_alloc_object", "item"); return item; } diff --git a/src/box/xrow_update_route.c b/src/box/xrow_update_route.c index 122f0329ec8aa4ecb3509e06774526fe25c727b9..0352aec635981764d5ec8cfc6e92447402ecf635 100644 --- a/src/box/xrow_update_route.c +++ b/src/box/xrow_update_route.c @@ -244,10 +244,11 @@ xrow_update_route_branch(struct xrow_update_field *field, bool transform_root = (saved_old_offset == 0); struct xrow_update_field *next_hop; if (!transform_root) { - next_hop = (struct xrow_update_field *) - region_alloc(&fiber()->gc, sizeof(*next_hop)); + size_t size; + next_hop = region_alloc_object(&fiber()->gc, typeof(*next_hop), + &size); if (next_hop == NULL) { - diag_set(OutOfMemory, sizeof(*next_hop), "region_alloc", + diag_set(OutOfMemory, size, "region_alloc_object", "next_hop"); return NULL; } diff --git a/src/lib/core/backtrace.cc b/src/lib/core/backtrace.cc index b5531a5969261a5ef1412e76ee00b075484a2150..946420885bed7347a4ab245ebc8e80d7ebd2c5f4 100644 --- a/src/lib/core/backtrace.cc +++ b/src/lib/core/backtrace.cc @@ -110,9 +110,9 @@ get_proc_name(unw_cursor_t *unw_cur, unw_word_t *offset, bool skip_cache) } else { unw_get_proc_name(unw_cur, proc_name, sizeof(proc_name), offset); - - entry = (struct proc_cache_entry *) - region_alloc(&cache_region, sizeof(struct proc_cache_entry)); + size_t size; + entry = region_alloc_object(&cache_region, typeof(*entry), + &size); if (entry == NULL) goto error; node.key = ip; diff --git a/src/lua/popen.c b/src/lua/popen.c index 18c8282f1dd8bcbf8f722237dd849045c30a6794..354429f32e844a65fb1aa4112ff064b0310fa8ed 100644 --- a/src/lua/popen.c +++ b/src/lua/popen.c @@ -778,11 +778,12 @@ luaT_popen_parse_env(struct lua_State *L, int idx, struct region *region) idx = lua_gettop(L) + idx + 1; size_t capacity = POPEN_LUA_ENV_CAPACITY_DEFAULT; - size_t size = capacity * sizeof(char *); size_t region_svp = region_used(region); - char **env = region_alloc(region, size); + size_t size; + char **env = region_alloc_array(region, typeof(env[0]), capacity, + &size); if (env == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "env array"); + diag_set(OutOfMemory, size, "region_alloc_array", "env"); return NULL; } size_t nr_env = 0; @@ -829,10 +830,10 @@ luaT_popen_parse_env(struct lua_State *L, int idx, struct region *region) * the traverse again and fill `env` array. */ capacity = nr_env + 1; - size = capacity * sizeof(char *); - if ((env = region_alloc(region, size)) == NULL) { + env = region_alloc_array(region, typeof(env[0]), capacity, &size); + if (env == NULL) { region_truncate(region, region_svp); - diag_set(OutOfMemory, size, "region_alloc", "env array"); + diag_set(OutOfMemory, size, "region_alloc_array", "env"); return NULL; } nr_env = 0; @@ -1039,10 +1040,11 @@ luaT_popen_parse_argv(struct lua_State *L, int idx, struct popen_opts *opts, if (opts->flags & POPEN_FLAG_SHELL) opts->nr_argv += 2; - size_t size = sizeof(char *) * opts->nr_argv; - opts->argv = region_alloc(region, size); + size_t size; + opts->argv = region_alloc_array(region, typeof(opts->argv[0]), + opts->nr_argv, &size); if (opts->argv == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "argv"); + diag_set(OutOfMemory, size, "region_alloc_array", "opts->argv"); return -1; }