simplify function call instrumentation
src/ldo.c now has a minimal diff with Lua 5.1. It might be a bit slower than it was before, but not noticeably so.. This approach doesn't support indirect calls.
This commit is contained in:
parent
182408ec54
commit
ef5195dee9
33
src/ldo.c
33
src/ldo.c
|
@ -29,7 +29,6 @@
|
||||||
#include "lundump.h"
|
#include "lundump.h"
|
||||||
#include "lvm.h"
|
#include "lvm.h"
|
||||||
#include "lzio.h"
|
#include "lzio.h"
|
||||||
#include "teliva.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,37 +255,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* based on getfuncname */
|
extern void record_metadata_about_function_call (lua_State *L, CallInfo *ci);
|
||||||
extern Instruction symbexec (const Proto *pt, int lastpc, int reg);
|
|
||||||
extern int luaL_newmetatable (lua_State *L, const char *tname);
|
|
||||||
void record_metadata_about_function_call (lua_State *L, CallInfo *ci) {
|
|
||||||
if (!isLua(ci))
|
|
||||||
return;
|
|
||||||
if (ci->tailcalls > 0)
|
|
||||||
return;
|
|
||||||
if (!isLua(ci - 1))
|
|
||||||
return;
|
|
||||||
ci--; /* calling function */
|
|
||||||
if (ci == L->ci)
|
|
||||||
ci->savedpc = L->savedpc;
|
|
||||||
int pc = cast(int, ci->savedpc - ci_func(ci)->l.p->code) - 1;
|
|
||||||
lua_assert(pc != -1); // TODO: lua_assert not triggering
|
|
||||||
Instruction i = ci_func(ci)->l.p->code[pc];
|
|
||||||
if (GET_OPCODE(i) != OP_CALL && GET_OPCODE(i) != OP_TAILCALL &&
|
|
||||||
GET_OPCODE(i) != OP_TFORLOOP)
|
|
||||||
return;
|
|
||||||
Proto *p = ci_func(ci)->l.p;
|
|
||||||
i = symbexec(p, pc, GETARG_A(i)); /* previous instruction that writes to call's RA */
|
|
||||||
if (GET_OPCODE(i) != OP_GETGLOBAL)
|
|
||||||
return;
|
|
||||||
int g = GETARG_Bx(i); /* global index */
|
|
||||||
lua_assert(ttisstring(&p->k[g]));
|
|
||||||
int call_graph_depth = ci - L->base_ci;
|
|
||||||
const char* function_name = svalue(&p->k[g]);
|
|
||||||
assign_call_graph_depth_to_name(L, call_graph_depth, function_name);
|
|
||||||
save_caller(L, function_name, call_graph_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define inc_ci(L) \
|
#define inc_ci(L) \
|
||||||
((L->ci == L->end_ci) ? growCI(L) : \
|
((L->ci == L->end_ci) ? growCI(L) : \
|
||||||
|
|
25
src/teliva.c
25
src/teliva.c
|
@ -13,6 +13,9 @@
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
|
|
||||||
|
#undef getstr
|
||||||
|
#include "lstate.h"
|
||||||
#include "teliva.h"
|
#include "teliva.h"
|
||||||
#include "tlv.h"
|
#include "tlv.h"
|
||||||
|
|
||||||
|
@ -341,11 +344,21 @@ static void save_caller_as(lua_State* L, const char* name, const char* caller_na
|
||||||
lua_pop(L, 1); // table of caller tables
|
lua_pop(L, 1); // table of caller tables
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_caller(lua_State* L, const char* name, int call_graph_depth) {
|
void record_metadata_about_function_call (lua_State *L, CallInfo *ci) {
|
||||||
lua_Debug ar;
|
lua_Debug f;
|
||||||
lua_getstack(L, 1, &ar);
|
lua_getstack(L, 0, &f);
|
||||||
lua_getinfo(L, "n", &ar);
|
lua_getinfo(L, "n", &f);
|
||||||
if (ar.name) save_caller_as(L, name, ar.name);
|
long int call_depth = ci - L->base_ci;
|
||||||
|
/* note to self: the function pointer is at ci_func(ci) */
|
||||||
|
if (f.name) {
|
||||||
|
assign_call_graph_depth_to_name(L, call_depth, f.name);
|
||||||
|
if (call_depth <= 1) return;
|
||||||
|
lua_Debug caller_f;
|
||||||
|
lua_getstack(L, 1, &caller_f);
|
||||||
|
lua_getinfo(L, "n", &caller_f);
|
||||||
|
if (caller_f.name)
|
||||||
|
save_caller_as(L, f.name, caller_f.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_caller(lua_State* L) {
|
static void clear_caller(lua_State* L) {
|
||||||
|
@ -496,7 +509,7 @@ restart:
|
||||||
y += 2;
|
y += 2;
|
||||||
mvprintw(y, 0, "functions: ");
|
mvprintw(y, 0, "functions: ");
|
||||||
y++;
|
y++;
|
||||||
for (int depth = /*ignore call_main*/2; ; ++depth) {
|
for (int depth = /*ignore callers of main*/3; ; ++depth) {
|
||||||
mvaddstr(y, 0, " ");
|
mvaddstr(y, 0, " ");
|
||||||
bool drew_anything = false;
|
bool drew_anything = false;
|
||||||
index_within_level = 0;
|
index_within_level = 0;
|
||||||
|
|
|
@ -165,10 +165,7 @@ extern void save_editor_state(int rowoff, int coloff, int cy, int cx);
|
||||||
int editor_view_in_progress(lua_State* L);
|
int editor_view_in_progress(lua_State* L);
|
||||||
|
|
||||||
extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name);
|
extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name);
|
||||||
extern char* get_caller(lua_State* L);
|
|
||||||
extern void save_caller(lua_State* L, const char* name, int call_graph_depth);
|
|
||||||
extern void draw_callers_of_current_definition(lua_State* L);
|
extern void draw_callers_of_current_definition(lua_State* L);
|
||||||
extern char* get_caller_of_caller(lua_State* L);
|
|
||||||
|
|
||||||
extern void append_to_audit_log(lua_State* L, const char* buffer);
|
extern void append_to_audit_log(lua_State* L, const char* buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue