Pull some little tricks for performance

This commit is contained in:
K. Lange 2021-03-25 19:51:08 +09:00
parent 41c77de753
commit 1ec1e59c5d
6 changed files with 22 additions and 21 deletions

View File

@ -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)

View File

@ -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

View File

@ -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,{

View File

@ -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();

View File

@ -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;

View File

@ -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 : "<unnamed>",
(minArgs == maxArgs) ? "exactly" : (argCount < minArgs ? "at least" : "at most"),