From 1ec1e59c5d621d4cbee8e33ff0d10ee6cef2a356 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Thu, 25 Mar 2021 19:51:08 +0900 Subject: [PATCH] Pull some little tricks for performance --- src/kuroko/util.h | 26 +++++++++++++------------- src/kuroko/vm.h | 1 + src/obj_list.c | 8 ++++---- src/obj_tuple.c | 2 +- src/threads.c | 2 +- src/vm.c | 4 ++-- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/kuroko/util.h b/src/kuroko/util.h index bd77b74..97baf7e 100644 --- a/src/kuroko/util.h +++ b/src/kuroko/util.h @@ -24,31 +24,31 @@ #define ADD_BASE_CLASS(obj, name, baseClass) krk_makeClass(vm.builtins, &obj, name, baseClass) -#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", \ +#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", \ krk_typeName(argv[0]), _method_name); } while (0) -#define METHOD_TAKES_NONE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \ +#define METHOD_TAKES_NONE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \ _method_name, (argc-1)); } while (0) -#define METHOD_TAKES_EXACTLY(n) do { if (argc != (n+1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ +#define METHOD_TAKES_EXACTLY(n) do { if (unlikely(argc != (n+1))) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ _method_name, "exactly", n, (n != 1) ? "s" : "", (argc-1)); } while (0) -#define METHOD_TAKES_AT_LEAST(n) do { if (argc < (n+1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ +#define METHOD_TAKES_AT_LEAST(n) do { if (unlikely(argc < (n+1))) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ _method_name, "at least", n, (n != 1) ? "s" : "", (argc-1)); } while (0) -#define METHOD_TAKES_AT_MOST(n) do { if (argc > (n+1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ +#define METHOD_TAKES_AT_MOST(n) do { if (unlikely(argc > (n+1))) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ _method_name, "at most", n, (n != 1) ? "s" : "", (argc-1)); } while (0) -#define FUNCTION_TAKES_NONE() do { if (argc != 0) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \ +#define FUNCTION_TAKES_NONE() do { if (unlikely(argc != 0)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \ _method_name, (argc)); } while (0) -#define FUNCTION_TAKES_EXACTLY(n) do { if (argc != n) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ +#define FUNCTION_TAKES_EXACTLY(n) do { if (unlikely(argc != n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ _method_name, "exactly", n, (n != 1) ? "s" : "", (argc)); } while (0) -#define FUNCTION_TAKES_AT_LEAST(n) do { if (argc < n) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ +#define FUNCTION_TAKES_AT_LEAST(n) do { if (unlikely(argc < n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ _method_name, "at least", n, (n != 1) ? "s" : "", (argc)); } while (0) -#define FUNCTION_TAKES_AT_MOST(n) do { if (argc > n) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ +#define FUNCTION_TAKES_AT_MOST(n) do { if (unlikely(argc > n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ _method_name, "at most", n, (n != 1) ? "s" : "", (argc)); } while (0) #define TYPE_ERROR(expected,value) krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'", \ @@ -57,8 +57,8 @@ #define NOT_ENOUGH_ARGS(name) krk_runtimeError(vm.exceptions->argumentError, "") #define CHECK_ARG(i, type, ctype, name) \ - if (argc < (i+1)) return NOT_ENOUGH_ARGS(name); \ - if (!IS_ ## type (argv[i])) return TYPE_ERROR(type,argv[i]); \ + if (unlikely(argc < (i+1))) return NOT_ENOUGH_ARGS(name); \ + if (unlikely(!IS_ ## type (argv[i]))) return TYPE_ERROR(type,argv[i]); \ ctype name __attribute__((unused)) = AS_ ## type (argv[i]) #define FUNC_NAME(klass, name) _ ## klass ## _ ## name @@ -177,7 +177,7 @@ static inline KrkValue discardStringBuilder(struct StringBuilder * sb) { #define IS_float(o) (IS_FLOATING(o)) #define AS_float(o) (AS_FLOATING(o)) -#define IS_list(o) krk_isInstanceOf(o,vm.baseClasses->listClass) +#define IS_list(o) ((IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->listClass) || krk_isInstanceOf(o,vm.baseClasses->listClass)) #define AS_list(o) (KrkList*)AS_OBJECT(o) #define IS_tuple(o) IS_TUPLE(o) @@ -198,7 +198,7 @@ static inline KrkValue discardStringBuilder(struct StringBuilder * sb) { #define IS_striterator(o) (krk_isInstanceOf(o,vm.baseClasses->striteratorClass)) #define AS_striterator(o) (AS_INSTANCE(o)) -#define IS_dict(o) krk_isInstanceOf(o,vm.baseClasses->dictClass) +#define IS_dict(o) ((IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->dictClass) || krk_isInstanceOf(o,vm.baseClasses->dictClass)) #define AS_dict(o) (KrkDict*)AS_OBJECT(o) #define IS_dictitems(o) krk_isInstanceOf(o,vm.baseClasses->dictitemsClass) diff --git a/src/kuroko/vm.h b/src/kuroko/vm.h index 39e61ec..a85b585 100644 --- a/src/kuroko/vm.h +++ b/src/kuroko/vm.h @@ -240,6 +240,7 @@ typedef struct KrkVM { #define KRK_GLOBAL_CLEAN_OUTPUT (1 << 10) #define KRK_GLOBAL_CALLGRIND (1 << 11) #define KRK_GLOBAL_REPORT_GC_COLLECTS (1 << 12) +#define KRK_GLOBAL_THREADS (1 << 13) #ifdef ENABLE_THREADING # define threadLocal __thread diff --git a/src/obj_list.c b/src/obj_list.c index 50dc17b..b7c84c2 100644 --- a/src/obj_list.c +++ b/src/obj_list.c @@ -50,20 +50,20 @@ KrkValue krk_list_of(int argc, KrkValue argv[], int hasKw) { KRK_METHOD(list,__getitem__,{ METHOD_TAKES_EXACTLY(1); CHECK_ARG(1,int,krk_integer_type,index); - pthread_rwlock_rdlock(&self->rwlock); + if (vm.globalFlags & KRK_GLOBAL_THREADS) pthread_rwlock_rdlock(&self->rwlock); LIST_WRAP_INDEX(); KrkValue result = self->values.values[index]; - pthread_rwlock_unlock(&self->rwlock); + if (vm.globalFlags & KRK_GLOBAL_THREADS) pthread_rwlock_unlock(&self->rwlock); return result; }) KRK_METHOD(list,__setitem__,{ METHOD_TAKES_EXACTLY(2); CHECK_ARG(1,int,krk_integer_type,index); - pthread_rwlock_rdlock(&self->rwlock); + if (vm.globalFlags & KRK_GLOBAL_THREADS) pthread_rwlock_rdlock(&self->rwlock); LIST_WRAP_INDEX(); self->values.values[index] = argv[2]; - pthread_rwlock_unlock(&self->rwlock); + if (vm.globalFlags & KRK_GLOBAL_THREADS) pthread_rwlock_unlock(&self->rwlock); }) KRK_METHOD(list,append,{ diff --git a/src/obj_tuple.c b/src/obj_tuple.c index 644c4b4..e252b0b 100644 --- a/src/obj_tuple.c +++ b/src/obj_tuple.c @@ -157,7 +157,7 @@ KRK_METHOD(tuple,__hash__,{ if (krk_hashValue(self->values.values[i], &step)) goto _unhashable; self->obj.hash ^= step; } - self->flags = self->flags | 1; + self->obj.flags |= KRK_OBJ_FLAGS_VALID_HASH; return INTEGER_VAL(self->obj.hash); _unhashable: return NONE_VAL(); diff --git a/src/threads.c b/src/threads.c index 17a0875..1ac8202 100644 --- a/src/threads.c +++ b/src/threads.c @@ -68,7 +68,7 @@ static volatile int _threadLock = 0; static void * _startthread(void * _threadObj) { memset(&krk_currentThread, 0, sizeof(KrkThreadState)); krk_currentThread.frames = calloc(KRK_CALL_FRAMES_MAX,sizeof(KrkCallFrame)); - + vm.globalFlags |= KRK_GLOBAL_THREADS; _obtain_lock(_threadLock); if (vm.threads->next) { krk_currentThread.next = vm.threads->next; diff --git a/src/vm.c b/src/vm.c index f701320..c2e5de2 100644 --- a/src/vm.c +++ b/src/vm.c @@ -508,10 +508,10 @@ int krk_isInstanceOf(KrkValue obj, KrkClass * type) { return 0; } -static int checkArgumentCount(KrkClosure * closure, int argCount) { +static inline int checkArgumentCount(KrkClosure * closure, int argCount) { int minArgs = closure->function->requiredArgs; int maxArgs = minArgs + closure->function->keywordArgs; - if (argCount < minArgs || argCount > maxArgs) { + if (unlikely(argCount < minArgs || argCount > maxArgs)) { krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", closure->function->name ? closure->function->name->chars : "", (minArgs == maxArgs) ? "exactly" : (argCount < minArgs ? "at least" : "at most"),