Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions daslib/debug.das
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,17 @@ class private DAStackWalker : DapiStackWalker {
}
}

def override onCallJIT(pp : Prologue; fileName : string#) : void {
//! Handles a JIT function call event, updating the current stack frame with JIT call info.
let n = length(ctx.stack)
if (n > 0) {
ctx.stack[n - 1].name = pp.info != null ? "def {pp.info.name} [JIT]" : "def [JIT]"
ctx.stack[n - 1].path = "{fileName}"

self->collectGlobals()
}
}

def override onCallAt(pp : Prologue; info : FuncInfo; at : LineInfo) : void {
//! Handles a function call event with source location, updating the stack frame name, path, and line.
// print("def {info.name} at {at}\n")
Expand Down
3 changes: 3 additions & 0 deletions examples/test/misc/context_state_example.das
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class SampleStackWalker : DapiStackWalker {
def override onCallAOT(pp : Prologue; fileName : string#) : void {
print("AOT {fileName}\n")
}
def override onCallJIT(pp : Prologue; fileName : string#) : void {
print("JIT {fileName}\n")
}
def override onCallAt(pp : Prologue; info : FuncInfo; at : LineInfo) : void {
print("{info.name} at {at}\n")
}
Expand Down
3 changes: 3 additions & 0 deletions examples/test/misc/eval_in_context.das
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class EvalDataWalker : DapiStackWalker {
def override onCallAOT(pp : Prologue; fileName : string#) : void {
*W |> write("// AOT {fileName}\n")
}
def override onCallJIT(pp : Prologue; fileName : string#) : void {
*W |> write("// JIT {fileName}\n")
}
def override onCallAt(pp : Prologue; info : FuncInfo; at : LineInfo) : void {
*W |> write("// {info.name} at {describe(at)}\n")
}
Expand Down
3 changes: 3 additions & 0 deletions examples/test/misc/stackwalk.das
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class SampleStackWalker : DapiStackWalker {
def override onCallAOT(pp : Prologue; fileName : string#) : void {
print("AOT {fileName}\n")
}
def override onCallJIT(pp : Prologue; fileName : string#) : void {
print("JIT {fileName}\n")
}
def override onCallAt(pp : Prologue; info : FuncInfo; at : LineInfo) : void {
print("{info.name} at {at}\n")
}
Expand Down
1 change: 1 addition & 0 deletions include/daScript/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,7 @@ namespace das
bool jit_jit_all_functions = true; // JIT all functions by default
bool jit_debug_info = false; // Add debug info to generate binary code
bool jit_use_dll_mode = true; // Create if missing and reuse DLL or JIT compile
bool jit_emit_prologue = false; // Emit prologue for all functions and blocks
string jit_output_folder; // Folder to store compiled dll's. By default it'll be _das_root_/jitted_scripts
int32_t jit_opt_level = 3u; // Opt level for LLVM to codegen and IR optimizations
int32_t jit_size_level = 3u; // Opt level for LLVM for binary size
Expand Down
45 changes: 28 additions & 17 deletions include/daScript/builtin/debugapi_gen.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1227,32 +1227,34 @@ protected:
__fn_canWalkOutOfScopeVariables = 2,
__fn_onBeforeCall = 3,
__fn_onCallAOT = 4,
__fn_onCallAt = 5,
__fn_onCall = 6,
__fn_onAfterPrologue = 7,
__fn_onArgument = 8,
__fn_onBeforeVariables = 9,
__fn_onVariable = 10,
__fn_onAfterCall = 11,
__fn_onCorruptStack = 12,
__fn_onCallJIT = 5,
__fn_onCallAt = 6,
__fn_onCall = 7,
__fn_onAfterPrologue = 8,
__fn_onArgument = 9,
__fn_onBeforeVariables = 10,
__fn_onVariable = 11,
__fn_onAfterCall = 12,
__fn_onCorruptStack = 13,
};
protected:
int _das_class_method_offset[13];
int _das_class_method_offset[14];
public:
DapiStackWalker_Adapter ( const StructInfo * info ) {
_das_class_method_offset[__fn_canWalkArguments] = info->fields[2]->offset;
_das_class_method_offset[__fn_canWalkVariables] = info->fields[3]->offset;
_das_class_method_offset[__fn_canWalkOutOfScopeVariables] = info->fields[4]->offset;
_das_class_method_offset[__fn_onBeforeCall] = info->fields[5]->offset;
_das_class_method_offset[__fn_onCallAOT] = info->fields[6]->offset;
_das_class_method_offset[__fn_onCallAt] = info->fields[7]->offset;
_das_class_method_offset[__fn_onCall] = info->fields[8]->offset;
_das_class_method_offset[__fn_onAfterPrologue] = info->fields[9]->offset;
_das_class_method_offset[__fn_onArgument] = info->fields[10]->offset;
_das_class_method_offset[__fn_onBeforeVariables] = info->fields[11]->offset;
_das_class_method_offset[__fn_onVariable] = info->fields[12]->offset;
_das_class_method_offset[__fn_onAfterCall] = info->fields[13]->offset;
_das_class_method_offset[__fn_onCorruptStack] = info->fields[14]->offset;
_das_class_method_offset[__fn_onCallJIT] = info->fields[7]->offset;
_das_class_method_offset[__fn_onCallAt] = info->fields[8]->offset;
_das_class_method_offset[__fn_onCall] = info->fields[9]->offset;
_das_class_method_offset[__fn_onAfterPrologue] = info->fields[10]->offset;
_das_class_method_offset[__fn_onArgument] = info->fields[11]->offset;
_das_class_method_offset[__fn_onBeforeVariables] = info->fields[12]->offset;
_das_class_method_offset[__fn_onVariable] = info->fields[13]->offset;
_das_class_method_offset[__fn_onAfterCall] = info->fields[14]->offset;
_das_class_method_offset[__fn_onCorruptStack] = info->fields[15]->offset;
}
__forceinline Func get_canWalkArguments ( void * self ) const {
return getDasClassMethod(self,_das_class_method_offset[__fn_canWalkArguments]);
Expand Down Expand Up @@ -1299,6 +1301,15 @@ public:
(__context__,nullptr,__funcCall__,
self,pp,fileName);
}
__forceinline Func get_onCallJIT ( void * self ) const {
return getDasClassMethod(self,_das_class_method_offset[__fn_onCallJIT]);
}
__forceinline void invoke_onCallJIT ( Context * __context__, Func __funcCall__, void * self, Prologue const & pp, char * const fileName ) const {
das_invoke_function<void>::invoke
<void *,Prologue const &,char * const >
(__context__,nullptr,__funcCall__,
self,pp,fileName);
}
__forceinline Func get_onCallAt ( void * self ) const {
return getDasClassMethod(self,_das_class_method_offset[__fn_onCallAt]);
}
Expand Down
8 changes: 8 additions & 0 deletions include/daScript/simulate/simulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ namespace das
const char * fileName;
LineInfo * functionLine;
int32_t stackSize;
union {
uint32_t flags;
// By default it's AOT Prologue.
struct {
bool is_jit : 1;
};
};
};
struct {
vec4f * arguments;
Expand Down Expand Up @@ -280,6 +287,7 @@ namespace das
virtual bool canWalkOutOfScopeVariables() { return true; }
virtual void onBeforeCall ( Prologue *, char * ) { }
virtual void onCallAOT ( Prologue *, const char * ) { }
virtual void onCallJIT ( Prologue *, const char * ) { }
virtual void onCallAt ( Prologue *, FuncInfo *, LineInfo * ) { }
virtual void onCall ( Prologue *, FuncInfo * ) { }
virtual void onAfterPrologue ( Prologue *, char * ) { }
Expand Down
34 changes: 24 additions & 10 deletions modules/dasLLVM/daslib/llvm_jit.das
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,18 @@ class LlvmJitVisitor : AstVisitor {
option_no_range_check : bool = false
option_no_alias : bool = false
option_no_capture : bool = false
// If debug_build enabled we'll emit prologue for every function.
emit_prologue : bool = false
own_di : bool = false
ldu_hint : bool
attributes : Attributes?

def LlvmJitVisitor(ctx : Context?; var types_ : PrimitiveTypes?; uids : UidNodes?; need_di : bool; dib : LLVMOpaqueDIBuilder?; attrs : Attributes?) {
def LlvmJitVisitor(ctx : Context?; var types_ : PrimitiveTypes?; uids : UidNodes?; need_di : bool; emit_prologue_ : bool; dib : LLVMOpaqueDIBuilder?; attrs : Attributes?) {
jit_context = ctx
types = types_
g_builder = LLVMCreateBuilderInContext(g_ctx)
g_di_builder = dib
emit_prologue = emit_prologue_
attributes = attrs
uid = uids
if (need_di) {
Expand Down Expand Up @@ -647,17 +650,21 @@ class LlvmJitVisitor : AstVisitor {
return loaded_ptr
}

def build_function_entry(funAt : LineInfo; bodyId : uint64; hasMakeBlock : bool; var totalStackSize : uint; var arguments : dasvector`smart_ptr`Variable) {
def build_function_entry(funAt : LineInfo;
bodyId : uint64; need_prologue : bool;
var totalStackSize : uint;
var arguments : dasvector`smart_ptr`Variable) {
// now write to regular function
function_entry = append_basic_block("entry")
LLVMPositionBuilderAtEnd(g_builder, function_entry)
// enter
build_enter(funAt)
// allocate prologue if need be
if (hasMakeBlock) {
if (need_prologue) {
prologue = LLVMBuildAlloca(g_builder, g_t_stack_state, "prologue")
prologue = LLVMBuildPointerCast(g_builder, prologue, LLVMPointerType(g_t_stack_state, 0u), "")
var params = fixed_array(
get_string_constant_ptr(g_builder, "{thisFunc.name}"),
get_line_info_ptr(funAt),
types.ConstI32(uint64(totalStackSize)),
prologue,
Expand Down Expand Up @@ -704,7 +711,9 @@ class LlvmJitVisitor : AstVisitor {
wfunc = LLVMGetNamedFunction(g_mod, fnmna.publ())
// build wrapper function
build_wrapper_function(fnmna, fun.arguments, fun.result, isCMRES(fun), null, fun.at)
build_function_entry(fun.at, hash(get_mangled_name(fun)), fun.flags.hasMakeBlock, fun.totalStackSize, fun.arguments)
build_function_entry(fun.at, hash(get_mangled_name(fun)),
fun.flags.hasMakeBlock || emit_prologue,
fun.totalStackSize, fun.arguments)
process_function_hints(fun.annotations, fun.arguments)
process_labels(fun.body)
process_finally(fun.body)
Expand Down Expand Up @@ -4893,7 +4902,9 @@ class LlvmJitVisitor : AstVisitor {
wfunc = LLVMGetNamedFunction(g_mod, fnmna.publ())
// build wrapper function
build_wrapper_function(fnmna, thisBlock.arguments, thisBlock.returnType, isCmres, captureType, thisBlock.at)
build_function_entry(expr.at, hash(fnmna), thisBlock.blockFlags.hasMakeBlock, thisFunc.totalStackSize, thisBlock.arguments)
build_function_entry(expr.at, hash(fnmna),
thisBlock.blockFlags.hasMakeBlock || emit_prologue,
thisFunc.totalStackSize, thisBlock.arguments)
process_function_hints(thisBlock.annotations, thisBlock.arguments)
process_labels(expr)
process_finally(expr)
Expand All @@ -4909,7 +4920,7 @@ class LlvmJitVisitor : AstVisitor {
}

def make_block_function(expr : smart_ptr<ExprMakeBlock>; captured : array<CapturedVariable>; first_field_index : int; captureType : LLVMOpaqueType?) : tuple<func : LLVMOpaqueValue?; impl : LLVMOpaqueValue?> {
var astVisitor = new LlvmJitVisitor(jit_context, types, uid, false, g_di_builder, attributes)
var astVisitor = new LlvmJitVisitor(jit_context, types, uid, false, emit_prologue, g_di_builder, attributes)
unsafe {
astVisitor.adapter <- make_visitor(*astVisitor)
}
Expand Down Expand Up @@ -6001,7 +6012,9 @@ def get_dll_missing(fns : array<FunctionPtr>; disabled : array<FunctionPtr>; var


[macro_function]
def private generate_llvm(ctx : Context?; var types : PrimitiveTypes?; uids : UidNodes?; attrs : Attributes?; fn : FunctionPtr; enable_debug_info : bool) {
def private generate_llvm(ctx : Context?; var types : PrimitiveTypes?; uids : UidNodes?;
attrs : Attributes?; fn : FunctionPtr;
enable_debug_info : bool; emit_prologue : bool) {
verify(!(is_in_completion() || is_compiling_macros() || is_folding()))

let dll_name = uids.get_dll_fn_name(fn)
Expand All @@ -6010,7 +6023,7 @@ def private generate_llvm(ctx : Context?; var types : PrimitiveTypes?; uids : Ui
let aot_hash : uint64 = get_function_aot_hash(fn |> get_ptr)
// debug("initializer hash for {dll_name.publ()}: {aot_hash}")
globalVar |> LLVMSetInitializer(types.ConstI64(aot_hash))
var astVisitor = new LlvmJitVisitor(ctx, types, uids, enable_debug_info, null, attrs)
var astVisitor = new LlvmJitVisitor(ctx, types, uids, enable_debug_info, emit_prologue, null, attrs)
unsafe {
astVisitor.adapter <- make_visitor(*astVisitor)
}
Expand Down Expand Up @@ -6231,6 +6244,7 @@ class JIT_LLVM : AstSimulateMacro {
let use_dll = prog.policies.jit_use_dll_mode && das_is_dll_build()
let opt_level = prog.policies.jit_opt_level
let size_level = prog.policies.jit_size_level
let emit_prologue = true // prog.policies.emit_prologue
assume config_out_folder = string(prog.policies.jit_output_folder)
let output_folder = config_out_folder |> empty() ? "{get_das_root()}/jitted_scripts/" : config_out_folder
assume path_to_shared_lib = string(prog.policies.jit_path_to_shared_lib)
Expand Down Expand Up @@ -6267,7 +6281,7 @@ class JIT_LLVM : AstSimulateMacro {
init_jit(opt_level |> uint)
let attrs = new Attributes(g_ctx)
var uids = create_uid_nodes(prog, funcs)
var fake_visitor = new LlvmJitVisitor(ctx, g_prim_t, uids, false, null, attrs)
var fake_visitor = new LlvmJitVisitor(ctx, g_prim_t, uids, false, emit_prologue, null, attrs)
for (fun in funcs) {
fake_visitor->add_llvm_functions(fun)
}
Expand All @@ -6288,7 +6302,7 @@ class JIT_LLVM : AstSimulateMacro {
}
if (recompile_prog) {
for (fun in funcs) {
generate_llvm(ctx, g_prim_t, uids, attrs, fun, debug_info)
generate_llvm(ctx, g_prim_t, uids, attrs, fun, debug_info, emit_prologue)
let fnmna = uids.get_dll_fn_name(fun)
var fn_impl = LLVMGetNamedFunction(g_mod, fnmna.impl())
var fn = LLVMGetNamedFunction(g_mod, fnmna.publ())
Expand Down
12 changes: 10 additions & 2 deletions modules/dasLLVM/daslib/llvm_jit_common.das
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,18 @@ def public init_jit(cg_opt_level : uint) {
// void jit_prologue ( void * line_info, int32_t stackSize, JitStackState * stackState, Context * context )
var jit_prologue = LLVMAddFunctionWithType(g_mod, FN_JIT_PROLOGUE,
LLVMFunctionType(g_prim_t.t_void,
fixed_array<LLVMTypeRef>(g_prim_t.LLVMVoidPtrType(), g_prim_t.t_int32, LLVMPointerType(g_t_stack_state, 0u), g_prim_t.LLVMVoidPtrType())))
fixed_array<LLVMTypeRef>(
g_prim_t.get_type_string(),
g_prim_t.LLVMVoidPtrType(),
g_prim_t.t_int32,
LLVMPointerType(g_t_stack_state, 0u),
g_prim_t.LLVMVoidPtrType()
)
)
)
LLVMAddGlobalMapping(g_engine, jit_prologue, get_jit_prologue())
LLVMAddAttributesToFunction(jit_prologue, fixed_array(nounwind, willreturn))
LLVMAddAttributeToFunctionArgumentRange(jit_prologue, urange(2, 4), nocapture)
LLVMAddAttributeToFunctionArgumentRange(jit_prologue, urange(3, 5), nocapture)
// void jit_epilogue ( JitStackState * stackState, Context * context )
var jit_epilogue = LLVMAddFunctionWithType(g_mod, FN_JIT_EPILOGUE,
LLVMFunctionType(g_prim_t.t_void,
Expand Down
1 change: 1 addition & 0 deletions src/builtin/debugger.das
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class DapiStackWalker {
def abstract canWalkOutOfScopeVariables : bool
def abstract onBeforeCall(pp : Prologue; sp : void?) : void
def abstract onCallAOT(pp : Prologue; fileName : string#) : void
def abstract onCallJIT(pp : Prologue; fileName : string#) : void
def abstract onCallAt(pp : Prologue; info : FuncInfo; at : LineInfo) : void
def abstract onCall(pp : Prologue; info : FuncInfo) : void
def abstract onAfterPrologue(pp : Prologue; sp : void?) : void
Expand Down
9 changes: 9 additions & 0 deletions src/builtin/debugger.das.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,15 @@ static unsigned char debugger_das[] = {
0x76,0x6f,0x69,0x64,0x0a,
0x20,0x20,0x20,0x20,0x64,0x65,0x66,0x20,
0x61,0x62,0x73,0x74,0x72,0x61,0x63,0x74,
0x20,0x6f,0x6e,0x43,0x61,0x6c,0x6c,0x4a,
0x49,0x54,0x28,0x70,0x70,0x20,0x3a,0x20,
0x50,0x72,0x6f,0x6c,0x6f,0x67,0x75,0x65,
0x3b,0x20,0x66,0x69,0x6c,0x65,0x4e,0x61,
0x6d,0x65,0x20,0x3a,0x20,0x73,0x74,0x72,
0x69,0x6e,0x67,0x23,0x29,0x20,0x3a,0x20,
0x76,0x6f,0x69,0x64,0x0a,
0x20,0x20,0x20,0x20,0x64,0x65,0x66,0x20,
0x61,0x62,0x73,0x74,0x72,0x61,0x63,0x74,
0x20,0x6f,0x6e,0x43,0x61,0x6c,0x6c,0x41,
0x74,0x28,0x70,0x70,0x20,0x3a,0x20,0x50,
0x72,0x6f,0x6c,0x6f,0x67,0x75,0x65,0x3b,
Expand Down
6 changes: 5 additions & 1 deletion src/builtin/module_builtin_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,11 @@ namespace debugapi {
}
walker->onBeforeCall(pp,SP);
if ( !info ) {
walker->onCallAOT(pp,pp->fileName);
if (pp->is_jit) {
walker->onCallJIT(pp,pp->fileName);
} else {
walker->onCallAOT(pp,pp->fileName);
}
} else if ( pp->line ) {
walker->onCallAt(pp,info,pp->line);
} else {
Expand Down
1 change: 1 addition & 0 deletions src/builtin/module_builtin_rtti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ namespace das {
addField<DAS_BIND_MANAGED_FIELD(jit_opt_level)>("jit_opt_level");
addField<DAS_BIND_MANAGED_FIELD(jit_size_level)>("jit_size_level");
addField<DAS_BIND_MANAGED_FIELD(jit_use_dll_mode)>("jit_use_dll_mode");
addField<DAS_BIND_MANAGED_FIELD(jit_emit_prologue)>("emit_prologue");
addField<DAS_BIND_MANAGED_FIELD(jit_output_folder)>("jit_output_folder");
addField<DAS_BIND_MANAGED_FIELD(jit_path_to_shared_lib)>("jit_path_to_shared_lib");
addField<DAS_BIND_MANAGED_FIELD(jit_path_to_linker)>("jit_path_to_linker");
Expand Down
7 changes: 5 additions & 2 deletions src/builtin/module_jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,19 @@ extern "C" {
char * SP;
};

DAS_API void jit_prologue ( void * funcLineInfo, int32_t stackSize, JitStackState * stackState, Context * context, LineInfoArg * at ) {
DAS_API void jit_prologue ( const char *funcName, void * funcLineInfo,
int32_t stackSize, JitStackState * stackState,
Context * context, LineInfoArg * at ) {
if (!context->stack.push(stackSize, stackState->EP, stackState->SP)) {
context->throw_error_at(at, "stack overflow");
}
#if DAS_ENABLE_STACK_WALK
Prologue * pp = (Prologue *)context->stack.sp();
pp->info = nullptr;
pp->fileName = "`jit`";
pp->fileName = funcName;
pp->functionLine = (LineInfo *) funcLineInfo;
pp->stackSize = stackSize;
pp->is_jit = true;
#endif
}

Expand Down
3 changes: 3 additions & 0 deletions src/simulate/simulate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,9 @@ namespace das
virtual void onCallAOT ( Prologue *, const char * fileName ) override {
ssw << fileName << ", AOT";
}
virtual void onCallJIT ( Prologue *, const char * fileName ) override {
ssw << fileName << ", JIT";
}
virtual void onCallAt ( Prologue *, FuncInfo * info, LineInfo * at ) override {
ssw << info->name << " from " << at->describe();
}
Expand Down
Loading