Skip to content

Commit cca321e

Browse files
committed
Refactor string allocation
Strings should be allocated only in the beginning of scripts. They are deallocated when the thread is destroyed.
1 parent b58df7d commit cca321e

File tree

5 files changed

+24
-34
lines changed

5 files changed

+24
-34
lines changed

src/engine/internal/llvm/instructions/functions.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins)
3636
llvm::Value *stringRet = nullptr;
3737

3838
if (ins->functionReturnReg && ins->functionReturnReg->type() == Compiler::StaticType::String) {
39-
stringRet = m_builder.CreateCall(m_utils.functions().resolve_string_pool_new(), { m_builder.getInt1(true) });
39+
stringRet = m_utils.addStringAlloca();
4040
types.push_back(m_utils.getType(Compiler::StaticType::String, false));
4141
args.push_back(stringRet);
4242
}
@@ -63,10 +63,9 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins)
6363
llvm::Value *ret = m_builder.CreateCall(m_utils.functions().resolveFunction(ins->functionName, llvm::FunctionType::get(retType, types, false)), args);
6464

6565
if (ins->functionReturnReg) {
66-
if (ins->functionReturnReg->type() == Compiler::StaticType::String) {
66+
if (ins->functionReturnReg->type() == Compiler::StaticType::String)
6767
ins->functionReturnReg->value = stringRet;
68-
m_utils.freeStringLater(stringRet);
69-
} else if (m_utils.isSingleType(ins->functionReturnReg->type()))
68+
else if (m_utils.isSingleType(ins->functionReturnReg->type()))
7069
ins->functionReturnReg->value = ret;
7170
else {
7271
ins->functionReturnReg->value = m_utils.addAlloca(retType);

src/engine/internal/llvm/instructions/lists.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,8 @@ LLVMInstruction *Lists::buildGetListContents(LLVMInstruction *ins)
270270
{
271271
assert(ins->args.size() == 0);
272272
const LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList);
273-
llvm::Value *ptr = m_builder.CreateCall(m_utils.functions().resolve_string_pool_new(), { m_builder.getInt1(true) });
273+
llvm::Value *ptr = m_utils.addStringAlloca();
274274
m_builder.CreateCall(m_utils.functions().resolve_list_to_string(), { listPtr.ptr, ptr });
275-
m_utils.freeStringLater(ptr);
276275
ins->functionReturnReg->value = ptr;
277276

278277
return ins->next;

src/engine/internal/llvm/instructions/string.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ LLVMInstruction *String::buildStringConcat(LLVMInstruction *ins)
4444
llvm::StructType *stringPtrType = m_utils.compilerCtx()->stringPtrType();
4545
llvm::Function *memcpyFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::memcpy_inline, { charPointerType, charPointerType, m_builder.getInt64Ty() });
4646

47-
// StringPtr *result = string_pool_new(true)
48-
llvm::Value *result = m_builder.CreateCall(m_utils.functions().resolve_string_pool_new(), m_builder.getInt1(true));
49-
m_utils.freeStringLater(result);
47+
// StringPtr *result = (allocated string)
48+
llvm::Value *result = m_utils.addStringAlloca();
5049

5150
// result->size = string1->size + string2->size
5251
llvm::Value *sizeField1 = m_builder.CreateStructGEP(stringPtrType, str1, 1);
@@ -100,8 +99,7 @@ LLVMInstruction *String::buildStringChar(LLVMInstruction *ins)
10099
llvm::Value *charPtr = m_builder.CreateGEP(m_builder.getInt16Ty(), data, index);
101100

102101
// Allocate string
103-
llvm::Value *result = m_builder.CreateCall(m_utils.functions().resolve_string_pool_new(), m_builder.getInt1(true));
104-
m_utils.freeStringLater(result);
102+
llvm::Value *result = m_utils.addStringAlloca();
105103
m_builder.CreateCall(m_utils.functions().resolve_string_alloc(), { result, m_builder.getInt64(1) }); // size 1 to avoid branching
106104

107105
// Get result data ptr

src/engine/internal/llvm/llvmbuildutils.cpp

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -395,16 +395,6 @@ void LLVMBuildUtils::popScopeLevel()
395395
m_stringHeap.pop_back();
396396
}
397397

398-
void LLVMBuildUtils::freeStringLater(llvm::Value *value)
399-
{
400-
assert(!m_stringHeap.empty());
401-
402-
if (m_stringHeap.empty())
403-
return;
404-
405-
m_stringHeap.back().push_back(value);
406-
}
407-
408398
void LLVMBuildUtils::freeScopeHeap()
409399
{
410400
if (m_stringHeap.empty())
@@ -468,6 +458,16 @@ llvm::Value *LLVMBuildUtils::addAlloca(llvm::Type *type)
468458
return ret;
469459
}
470460

461+
llvm::Value *LLVMBuildUtils::addStringAlloca()
462+
{
463+
// NOTE: The string will be deallocated when the thread is destroyed
464+
llvm::BasicBlock *block = m_builder.GetInsertBlock();
465+
m_builder.SetInsertPointPastAllocas(m_function);
466+
llvm::Value *ret = m_builder.CreateCall(m_functions.resolve_string_pool_new(), { m_builder.getInt1(true) }, "localString");
467+
m_builder.SetInsertPoint(block);
468+
return ret;
469+
}
470+
471471
llvm::Value *LLVMBuildUtils::castValue(LLVMRegister *reg, Compiler::StaticType targetType, NumberType targetNumType)
472472
{
473473
if (reg->isConst()) {
@@ -629,7 +629,7 @@ llvm::Value *LLVMBuildUtils::castValue(LLVMRegister *reg, Compiler::StaticType t
629629
llvm::Value *intCast = m_builder.CreateSIToFP(reg->intValue, m_builder.getDoubleTy());
630630
llvm::Value *value = m_builder.CreateSelect(reg->isInt, intCast, doubleValue);
631631

632-
llvm::Value *numberResult = m_builder.CreateCall(m_functions.resolve_string_pool_new(), { m_builder.getInt1(true) });
632+
llvm::Value *numberResult = addStringAlloca();
633633
m_builder.CreateCall(m_functions.resolve_value_doubleToStringPtr(), { value, numberResult });
634634
m_builder.CreateBr(mergeBlock);
635635
results.push_back({ numberBlock, numberResult });
@@ -640,13 +640,10 @@ llvm::Value *LLVMBuildUtils::castValue(LLVMRegister *reg, Compiler::StaticType t
640640
llvm::BasicBlock *boolBlock = llvm::BasicBlock::Create(m_llvmCtx, "bool", m_function);
641641
sw->addCase(m_builder.getInt32(static_cast<uint32_t>(ValueType::Bool)), boolBlock);
642642

643-
// Since the value is deallocated later, we need to create a copy
644643
m_builder.SetInsertPoint(boolBlock);
645644
llvm::Value *ptr = m_builder.CreateStructGEP(m_valueDataType, reg->value, 0);
646645
llvm::Value *value = m_builder.CreateLoad(m_builder.getInt1Ty(), ptr);
647-
llvm::Value *stringPtr = m_builder.CreateCall(m_functions.resolve_value_boolToStringPtr(), value);
648-
llvm::Value *boolResult = m_builder.CreateCall(m_functions.resolve_string_pool_new(), m_builder.getInt1(true));
649-
m_builder.CreateCall(m_functions.resolve_string_assign(), { boolResult, stringPtr });
646+
llvm::Value *boolResult = m_builder.CreateCall(m_functions.resolve_value_boolToStringPtr(), value);
650647
m_builder.CreateBr(mergeBlock);
651648
results.push_back({ boolBlock, boolResult });
652649
}
@@ -658,9 +655,7 @@ llvm::Value *LLVMBuildUtils::castValue(LLVMRegister *reg, Compiler::StaticType t
658655

659656
m_builder.SetInsertPoint(stringBlock);
660657
llvm::Value *ptr = m_builder.CreateStructGEP(m_valueDataType, reg->value, 0);
661-
llvm::Value *stringPtr = m_builder.CreateLoad(m_stringPtrType->getPointerTo(), ptr);
662-
llvm::Value *stringResult = m_builder.CreateCall(m_functions.resolve_string_pool_new(), m_builder.getInt1(true));
663-
m_builder.CreateCall(m_functions.resolve_string_assign(), { stringResult, stringPtr });
658+
llvm::Value *stringResult = m_builder.CreateLoad(m_stringPtrType->getPointerTo(), ptr);
664659
m_builder.CreateBr(mergeBlock);
665660
results.push_back({ stringBlock, stringResult });
666661
}
@@ -1504,9 +1499,8 @@ llvm::Value *LLVMBuildUtils::castRawValue(LLVMRegister *reg, Compiler::StaticTyp
15041499
// Convert double/int to string
15051500
llvm::Value *intCast = m_builder.CreateSIToFP(reg->intValue, m_builder.getDoubleTy());
15061501
llvm::Value *doubleValue = m_builder.CreateSelect(reg->isInt, intCast, reg->value);
1507-
llvm::Value *ptr = m_builder.CreateCall(m_functions.resolve_string_pool_new(), { m_builder.getInt1(true) });
1502+
llvm::Value *ptr = addStringAlloca();
15081503
m_builder.CreateCall(m_functions.resolve_value_doubleToStringPtr(), { doubleValue, ptr });
1509-
freeStringLater(ptr);
15101504
return ptr;
15111505
}
15121506

@@ -1800,10 +1794,9 @@ llvm::Value *LLVMBuildUtils::createNumberAndStringComparison(LLVMRegister *arg1,
18001794

18011795
// String comparison
18021796
m_builder.SetInsertPoint(stringBlock);
1803-
llvm::Value *stringValue = m_builder.CreateCall(m_functions.resolve_string_pool_new(), { m_builder.getInt1(true) });
1797+
llvm::Value *stringValue = addStringAlloca();
18041798
m_builder.CreateCall(m_functions.resolve_value_doubleToStringPtr(), { value1, stringValue });
18051799
llvm::Value *cmp = m_builder.CreateCall(m_functions.resolve_string_compare_case_insensitive(), { stringValue, value2 });
1806-
m_builder.CreateCall(m_functions.resolve_string_pool_free(), { stringValue }); // free the string immediately
18071800

18081801
llvm::Value *zero = llvm::ConstantInt::get(m_builder.getInt32Ty(), 0, true);
18091802
llvm::Value *stringCmp;

src/engine/internal/llvm/llvmbuildutils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ class LLVMBuildUtils
7777
void pushScopeLevel();
7878
void popScopeLevel();
7979

80-
void freeStringLater(llvm::Value *value);
8180
void freeScopeHeap();
8281

8382
std::vector<LLVMIfStatement> &ifStatements();
@@ -89,6 +88,8 @@ class LLVMBuildUtils
8988
static bool isSingleType(Compiler::StaticType type);
9089

9190
llvm::Value *addAlloca(llvm::Type *type);
91+
llvm::Value *addStringAlloca();
92+
9293
llvm::Value *castValue(LLVMRegister *reg, Compiler::StaticType targetType, NumberType targetNumType = NumberType::Double);
9394
llvm::Type *getType(Compiler::StaticType type, bool isReturnType);
9495
llvm::Value *isNaN(llvm::Value *num);

0 commit comments

Comments
 (0)