Skip to content

Commit 0e4da5d

Browse files
committed
py/obj.h: Code size and perf improvements for make_new as a slot.
The check for make_new (i.e. used to determine something's type) is now more complicated due to the slot access. Change inlining of a few frequently-used helpers to overall improve code size and performance.
1 parent 19323f8 commit 0e4da5d

File tree

6 files changed

+26
-13
lines changed

6 files changed

+26
-13
lines changed

py/obj.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *);
524524
#define MP_TYPE_FLAG_ITERNEXT (0x0080)
525525
#define MP_TYPE_FLAG_ITERNEXT_CUSTOM (0x0100)
526526
#define MP_TYPE_FLAG_ITERNEXT_STREAM (MP_TYPE_FLAG_ITERNEXT | MP_TYPE_FLAG_ITERNEXT_CUSTOM)
527+
#define MP_TYPE_FLAG_INSTANCE_TYPE (0x0200)
527528

528529
typedef enum {
529530
PRINT_STR = 0,
@@ -899,7 +900,7 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type);
899900
#define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_exact_type(o, &mp_type_int))
900901
#define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_exact_type(o, &mp_type_str))
901902
#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, binary_op) == mp_obj_str_binary_op))
902-
#define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, make_new) == mp_obj_dict_make_new)
903+
bool mp_obj_is_dict_or_ordereddict(mp_obj_t o);
903904
#define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function))
904905

905906
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
@@ -1015,7 +1016,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in);
10151016
mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in);
10161017

10171018
// exception
1018-
#define mp_obj_is_native_exception_instance(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), make_new) == mp_obj_exception_make_new)
1019+
bool mp_obj_is_native_exception_instance(mp_obj_t self_in);
10191020
bool mp_obj_is_exception_type(mp_obj_t self_in);
10201021
bool mp_obj_is_exception_instance(mp_obj_t self_in);
10211022
bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type);

py/objdict.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "py/objtype.h"
3434
#include "py/objstr.h"
3535

36+
bool mp_obj_is_dict_or_ordereddict(mp_obj_t o) {
37+
return mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, make_new) == mp_obj_dict_make_new;
38+
}
39+
3640
const mp_obj_dict_t mp_const_empty_dict_obj = {
3741
.base = { .type = &mp_type_dict },
3842
.map = {

py/objexcept.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in) {
111111
#endif
112112
#endif // MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
113113

114+
bool mp_obj_is_native_exception_instance(mp_obj_t self_in) {
115+
return MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(self_in), make_new) == mp_obj_exception_make_new;
116+
}
117+
114118
STATIC mp_obj_exception_t *get_native_exception(mp_obj_t self_in) {
115119
assert(mp_obj_is_exception_instance(self_in));
116120
if (mp_obj_is_native_exception_instance(self_in)) {

py/objstr.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ STATIC void str_check_arg_type(const mp_obj_type_t *self_type, const mp_obj_t ar
6363
}
6464
}
6565

66+
STATIC void check_is_str_or_bytes(mp_obj_t self_in) {
67+
mp_check_self(mp_obj_is_str_or_bytes(self_in));
68+
}
69+
6670
/******************************************************************************/
6771
/* str */
6872

@@ -468,7 +472,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
468472
}
469473

470474
STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
471-
mp_check_self(mp_obj_is_str_or_bytes(self_in));
475+
check_is_str_or_bytes(self_in);
472476
const mp_obj_type_t *self_type = mp_obj_get_type(self_in);
473477
const mp_obj_type_t *ret_type = self_type;
474478

@@ -724,7 +728,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj, 1, 3, str_rsplit);
724728

725729
STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) {
726730
const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
727-
mp_check_self(mp_obj_is_str_or_bytes(args[0]));
731+
check_is_str_or_bytes(args[0]);
728732

729733
// check argument type
730734
str_check_arg_type(self_type, args[1]);
@@ -820,7 +824,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith);
820824
enum { LSTRIP, RSTRIP, STRIP };
821825

822826
STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) {
823-
mp_check_self(mp_obj_is_str_or_bytes(args[0]));
827+
check_is_str_or_bytes(args[0]);
824828
const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
825829

826830
const byte *chars_to_del;
@@ -1422,7 +1426,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
14221426
}
14231427

14241428
mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
1425-
mp_check_self(mp_obj_is_str_or_bytes(args[0]));
1429+
check_is_str_or_bytes(args[0]);
14261430

14271431
GET_STR_DATA_LEN(args[0], str, len);
14281432
int arg_i = 0;
@@ -1433,7 +1437,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(str_format_obj, 1, mp_obj_str_format);
14331437

14341438
#if MICROPY_PY_BUILTINS_STR_OP_MODULO
14351439
STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict) {
1436-
mp_check_self(mp_obj_is_str_or_bytes(pattern));
1440+
check_is_str_or_bytes(pattern);
14371441

14381442
GET_STR_DATA_LEN(pattern, str, len);
14391443
#if MICROPY_ERROR_REPORTING > MICROPY_ERROR_REPORTING_TERSE
@@ -1639,7 +1643,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
16391643
// The implementation is optimized, returning the original string if there's
16401644
// nothing to replace.
16411645
STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) {
1642-
mp_check_self(mp_obj_is_str_or_bytes(args[0]));
1646+
check_is_str_or_bytes(args[0]);
16431647

16441648
mp_int_t max_rep = -1;
16451649
if (n_args == 4) {
@@ -1742,7 +1746,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace);
17421746
#if MICROPY_PY_BUILTINS_STR_COUNT
17431747
STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) {
17441748
const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
1745-
mp_check_self(mp_obj_is_str_or_bytes(args[0]));
1749+
check_is_str_or_bytes(args[0]);
17461750

17471751
// check argument type
17481752
str_check_arg_type(self_type, args[1]);
@@ -1782,7 +1786,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count);
17821786

17831787
#if MICROPY_PY_BUILTINS_STR_PARTITION
17841788
STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) {
1785-
mp_check_self(mp_obj_is_str_or_bytes(self_in));
1789+
check_is_str_or_bytes(self_in);
17861790
const mp_obj_type_t *self_type = mp_obj_get_type(self_in);
17871791
str_check_arg_type(self_type, arg);
17881792

py/objtype.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
11261126

11271127
// Basic validation of base classes
11281128
uint16_t base_flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE
1129-
| MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST;
1129+
| MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST | MP_TYPE_FLAG_INSTANCE_TYPE;
11301130
size_t bases_len;
11311131
mp_obj_t *bases_items;
11321132
mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items);

py/objtype.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *cls, const mp_obj_ty
4646
bool mp_obj_instance_is_callable(mp_obj_t self_in);
4747
mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
4848

49-
#define mp_obj_is_instance_type(type) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(type, make_new) == mp_obj_instance_make_new)
50-
#define mp_obj_is_native_type(type) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(type, make_new) != mp_obj_instance_make_new)
49+
#define mp_obj_is_instance_type(type) ((type)->flags & MP_TYPE_FLAG_INSTANCE_TYPE)
50+
#define mp_obj_is_native_type(type) (!((type)->flags & MP_TYPE_FLAG_INSTANCE_TYPE))
5151
// this needs to be exposed for the above macros to work correctly
5252
mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
5353

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy