Skip to content

Commit

Permalink
Optimize keys() calls
Browse files Browse the repository at this point in the history
  • Loading branch information
vtereshkov authored Nov 17, 2024
1 parent 8154266 commit 4bf2940
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 20 deletions.
2 changes: 1 addition & 1 deletion playground/umka.js

Large diffs are not rendered by default.

19 changes: 6 additions & 13 deletions src/umka_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,23 +100,17 @@ static void doTryImplicitDeref(Compiler *comp, Type **type)
}


static void doEscapeToHeap(Compiler *comp, Type *ptrType, bool useRefCnt)
static void doEscapeToHeap(Compiler *comp, Type *ptrType)
{
// Allocate heap
genPushIntConst(&comp->gen, typeSize(&comp->types, ptrType->base));
genCallTypedBuiltin(&comp->gen, ptrType->base, BUILTIN_NEW);
doCopyResultToTempVar(comp, ptrType);

// Save heap pointer
// Copy to heap and use heap pointer
genDup(&comp->gen);
genPopReg(&comp->gen, VM_REG_COMMON_0);

// Copy to heap and use heap pointer
if (useRefCnt)
genSwapChangeRefCntAssign(&comp->gen, ptrType->base);
else
genSwapAssign(&comp->gen, ptrType->base->kind, typeSize(&comp->types, ptrType->base));

genSwapChangeRefCntAssign(&comp->gen, ptrType->base);
genPushReg(&comp->gen, VM_REG_COMMON_0);
}

Expand Down Expand Up @@ -465,7 +459,7 @@ static void doValueToInterfaceConv(Compiler *comp, Type *dest, Type **src, Const
comp->error.handler(comp->error.context, "Conversion to interface is not allowed in constant expressions");

*src = typeAddPtrTo(&comp->types, &comp->blocks, *src);
doEscapeToHeap(comp, *src, true);
doEscapeToHeap(comp, *src);
doPtrToInterfaceConv(comp, dest, src, constant);
}

Expand Down Expand Up @@ -1430,13 +1424,12 @@ static void parseBuiltinKeysCall(Compiler *comp, Type **type, Const *constant)
// Result type (hidden parameter)
Type *keysType = typeAdd(&comp->types, &comp->blocks, TYPE_DYNARRAY);
keysType->base = typeMapKey(*type);
genPushGlobalPtr(&comp->gen, keysType);

// Pointer to result (hidden parameter)
int resultOffset = identAllocStack(&comp->idents, &comp->types, &comp->blocks, keysType);
genPushLocalPtr(&comp->gen, resultOffset);

genCallBuiltin(&comp->gen, (*type)->kind, BUILTIN_KEYS);
genCallTypedBuiltin(&comp->gen, keysType, BUILTIN_KEYS);
*type = keysType;
}

Expand Down Expand Up @@ -2672,7 +2665,7 @@ static void parseFactor(Compiler *comp, Type **type, Const *constant)
comp->error.handler(comp->error.context, "Cannot take address");

if (isCompLit)
doEscapeToHeap(comp, typeAddPtrTo(&comp->types, &comp->blocks, *type), true);
doEscapeToHeap(comp, typeAddPtrTo(&comp->types, &comp->blocks, *type));

// A value type is already a pointer, a structured type needs to have it added
if (typeStructured(*type))
Expand Down
7 changes: 2 additions & 5 deletions src/umka_stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,15 +922,12 @@ static void parseForInHeader(Compiler *comp)
// Call keys()
int resultOffset = identAllocStack(&comp->idents, &comp->types, &comp->blocks, keysType);
doPushVarPtr(comp, collectionIdent); // Map
genPushGlobalPtr(&comp->gen, keysType); // Result type (hidden parameter)
genPushLocalPtr(&comp->gen, resultOffset); // Pointer to result (hidden parameter)

genCallBuiltin(&comp->gen, collectionType->kind, BUILTIN_KEYS);
doCopyResultToTempVar(comp, keysType);
genCallTypedBuiltin(&comp->gen, keysType, BUILTIN_KEYS);

// Assign map keys
doPushVarPtr(comp, keysIdent);
genSwapChangeRefCntAssign(&comp->gen, keysType);
genSwapAssign(&comp->gen, keysType->kind, typeSize(&comp->types, keysType));
}

Ident *itemIdent = NULL;
Expand Down
3 changes: 2 additions & 1 deletion src/umka_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2745,9 +2745,10 @@ static FORCE_INLINE void doBuiltinValidkey(Fiber *fiber, HeapPages *pages, Error
static FORCE_INLINE void doBuiltinKeys(Fiber *fiber, HeapPages *pages, Error *error)
{
DynArray *result = (DynArray *)(fiber->top++)->ptrVal;
Type *resultType = (Type *)(fiber->top++)->ptrVal;
Map *map = (Map *)(fiber->top++)->ptrVal;

Type *resultType = fiber->code[fiber->ip].type;

if (!map)
error->runtimeHandler(error->context, VM_RUNTIME_ERROR, "Map is null");

Expand Down

0 comments on commit 4bf2940

Please sign in to comment.