better isolation of ZAM instruction elements

hooks for tracking extended ZAM profiling location
This commit is contained in:
Vern Paxson 2024-03-10 17:09:34 -04:00 committed by Tim Wojtulewicz
parent dc376953fa
commit 9f9f01580f
6 changed files with 134 additions and 90 deletions

View file

@ -577,7 +577,7 @@ void ZAMCompiler::ReMapFrame() {
if ( new_slot < 0 ) { if ( new_slot < 0 ) {
ODesc d; ODesc d;
inst->stmt->GetLocationInfo()->Describe(&d); inst->loc->Loc()->Describe(&d);
reporter->Error("%s: value used but not set: %s", d.Description(), reporter->Error("%s: value used but not set: %s", d.Description(),
frame_denizens[slot]->Name()); frame_denizens[slot]->Name());
} }
@ -748,7 +748,7 @@ void ZAMCompiler::CheckSlotUse(int slot, const ZInstI* inst) {
if ( denizen_beginning.count(slot) == 0 ) { if ( denizen_beginning.count(slot) == 0 ) {
ODesc d; ODesc d;
inst->stmt->GetLocationInfo()->Describe(&d); inst->loc->Loc()->Describe(&d);
reporter->Error("%s: value used but not set: %s", d.Description(), frame_denizens[slot]->Name()); reporter->Error("%s: value used but not set: %s", d.Description(), frame_denizens[slot]->Name());
} }

View file

@ -228,6 +228,7 @@ private:
const ZAMStmt Call(const ExprStmt* e); const ZAMStmt Call(const ExprStmt* e);
const ZAMStmt AssignToCall(const ExprStmt* e); const ZAMStmt AssignToCall(const ExprStmt* e);
const ZAMStmt DoCall(const CallExpr* c, const NameExpr* n); const ZAMStmt DoCall(const CallExpr* c, const NameExpr* n);
bool CheckForBuiltIn(const ExprPtr& e, CallExprPtr c);
const ZAMStmt AssignVecElems(const Expr* e); const ZAMStmt AssignVecElems(const Expr* e);
const ZAMStmt AssignTableElem(const Expr* e); const ZAMStmt AssignTableElem(const Expr* e);

View file

@ -315,6 +315,7 @@ const ZAMStmt ZAMCompiler::CompileSchedule(const NameExpr* n, const ConstExpr* c
if ( len == 0 ) { if ( len == 0 ) {
z = n ? ZInstI(OP_SCHEDULE0_ViH, FrameSlot(n), is_interval) : ZInstI(OP_SCHEDULE0_CiH, is_interval, c); z = n ? ZInstI(OP_SCHEDULE0_ViH, FrameSlot(n), is_interval) : ZInstI(OP_SCHEDULE0_CiH, is_interval, c);
z.op_type = n ? OP_VV_I2 : OP_VC_I1; z.op_type = n ? OP_VV_I2 : OP_VC_I1;
z.aux = new ZInstAux(0);
} }
else { else {
@ -330,7 +331,7 @@ const ZAMStmt ZAMCompiler::CompileSchedule(const NameExpr* n, const ConstExpr* c
z.aux = InternalBuildVals(l); z.aux = InternalBuildVals(l);
} }
z.event_handler = h; z.aux->event_handler = h;
return AddInst(z); return AddInst(z);
} }
@ -349,12 +350,11 @@ const ZAMStmt ZAMCompiler::CompileEvent(EventHandler* h, const ListExpr* l) {
if ( n > 4 || ! all_vars ) { // do generic form if ( n > 4 || ! all_vars ) { // do generic form
ZInstI z(OP_EVENT_HL); ZInstI z(OP_EVENT_HL);
z.aux = InternalBuildVals(l); z.aux = InternalBuildVals(l);
z.event_handler = h; z.aux->event_handler = h;
return AddInst(z); return AddInst(z);
} }
ZInstI z; ZInstI z;
z.event_handler = h;
if ( n == 0 ) { if ( n == 0 ) {
z.op = OP_EVENT0_X; z.op = OP_EVENT0_X;
@ -403,6 +403,11 @@ const ZAMStmt ZAMCompiler::CompileEvent(EventHandler* h, const ListExpr* l) {
} }
} }
if ( ! z.aux )
z.aux = new ZInstAux(0);
z.aux->event_handler = h;
return AddInst(z); return AddInst(z);
} }
@ -872,11 +877,8 @@ const ZAMStmt ZAMCompiler::AssignTableElem(const Expr* e) {
const ZAMStmt ZAMCompiler::Call(const ExprStmt* e) { const ZAMStmt ZAMCompiler::Call(const ExprStmt* e) {
auto c = cast_intrusive<CallExpr>(e->StmtExprPtr()); auto c = cast_intrusive<CallExpr>(e->StmtExprPtr());
if ( IsZAM_BuiltIn(c.get()) ) { if ( CheckForBuiltIn(c, c) )
auto ret = LastInst(); return LastInst();
insts1.back()->call_expr = std::move(c);
return ret;
}
return DoCall(e->StmtExpr()->AsCallExpr(), nullptr); return DoCall(e->StmtExpr()->AsCallExpr(), nullptr);
} }
@ -885,26 +887,37 @@ const ZAMStmt ZAMCompiler::AssignToCall(const ExprStmt* e) {
auto assign = e->StmtExpr()->AsAssignExpr(); auto assign = e->StmtExpr()->AsAssignExpr();
auto call = cast_intrusive<CallExpr>(assign->GetOp2()); auto call = cast_intrusive<CallExpr>(assign->GetOp2());
if ( IsZAM_BuiltIn(e->StmtExpr()) ) { if ( CheckForBuiltIn(e->StmtExprPtr(), call) )
auto ret = LastInst(); return LastInst();
insts1.back()->call_expr = call;
return ret;
}
auto n = assign->GetOp1()->AsRefExpr()->GetOp1()->AsNameExpr(); auto n = assign->GetOp1()->AsRefExpr()->GetOp1()->AsNameExpr();
return DoCall(call.get(), n); return DoCall(call.get(), n);
} }
bool ZAMCompiler::CheckForBuiltIn(const ExprPtr& e, CallExprPtr c) {
if ( ! IsZAM_BuiltIn(e.get()) )
return false;
auto ret = LastInst();
auto& i = insts1.back();
if ( ! i->aux )
i->aux = new ZInstAux(0);
i->aux->call_expr = c;
return true;
}
const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) { const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
auto func = c->Func()->AsNameExpr(); auto func = c->Func()->AsNameExpr();
auto func_id = func->IdPtr(); auto func_id = func->IdPtr();
auto func_val = func_id->GetVal();
auto& args = c->Args()->Exprs(); auto& args = c->Args()->Exprs();
int nargs = args.length(); int nargs = args.length();
int call_case = nargs; int call_case = nargs;
bool indirect = ! func_id->IsGlobal() || ! func_id->GetVal(); bool indirect = ! func_id->IsGlobal() || ! func_val;
bool in_when = c->IsInWhen(); bool in_when = c->IsInWhen();
if ( indirect || in_when ) if ( indirect || in_when )
@ -1041,7 +1054,7 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
z.aux->can_change_non_locals = true; z.aux->can_change_non_locals = true;
} }
z.call_expr = {NewRef{}, const_cast<CallExpr*>(c)}; z.aux->call_expr = {NewRef{}, const_cast<CallExpr*>(c)};
if ( in_when ) if ( in_when )
z.SetType(n->GetType()); z.SetType(n->GetType());
@ -1049,8 +1062,11 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
if ( ! indirect || func_id->IsGlobal() ) { if ( ! indirect || func_id->IsGlobal() ) {
z.aux->id_val = func_id; z.aux->id_val = func_id;
if ( ! indirect ) if ( ! indirect ) {
z.func = func_id->GetVal()->AsFunc(); z.aux->func = func_id->GetVal()->AsFunc();
if ( z.aux->func->GetKind() == Func::BUILTIN_FUNC )
z.aux->is_BiF_call = true;
}
} }
return AddInst(z); return AddInst(z);
@ -1064,11 +1080,11 @@ const ZAMStmt ZAMCompiler::ConstructTable(const NameExpr* n, const Expr* e) {
auto z = GenInst(OP_CONSTRUCT_TABLE_VV, n, width); auto z = GenInst(OP_CONSTRUCT_TABLE_VV, n, width);
z.aux = InternalBuildVals(con, width + 1); z.aux = InternalBuildVals(con, width + 1);
z.t = tt; z.t = tt;
z.attrs = e->AsTableConstructorExpr()->GetAttrs(); z.aux->attrs = e->AsTableConstructorExpr()->GetAttrs();
auto zstmt = AddInst(z); auto zstmt = AddInst(z);
auto def_attr = z.attrs ? z.attrs->Find(ATTR_DEFAULT) : nullptr; auto def_attr = z.aux->attrs ? z.aux->attrs->Find(ATTR_DEFAULT) : nullptr;
if ( ! def_attr || def_attr->GetExpr()->Tag() != EXPR_LAMBDA ) if ( ! def_attr || def_attr->GetExpr()->Tag() != EXPR_LAMBDA )
return zstmt; return zstmt;
@ -1102,7 +1118,7 @@ const ZAMStmt ZAMCompiler::ConstructSet(const NameExpr* n, const Expr* e) {
auto z = GenInst(OP_CONSTRUCT_SET_VV, n, width); auto z = GenInst(OP_CONSTRUCT_SET_VV, n, width);
z.aux = InternalBuildVals(con, width); z.aux = InternalBuildVals(con, width);
z.t = e->GetType(); z.t = e->GetType();
z.attrs = e->AsSetConstructorExpr()->GetAttrs(); z.aux->attrs = e->AsSetConstructorExpr()->GetAttrs();
return AddInst(z); return AddInst(z);
} }

View file

@ -273,7 +273,7 @@ macro AssignV1T(v, t) {
# the instruction. # the instruction.
macro AssignV1(v) AssignV1T(v, z.t) macro AssignV1(v) AssignV1T(v, z.t)
macro BRANCH(target_slot) { pc = z.target_slot; continue; } macro BRANCH(target_slot) { DO_ZAM_PROFILE; pc = z.target_slot; continue; }
########## Unary Ops ########## ########## Unary Ops ##########
@ -1153,7 +1153,7 @@ direct-unary-op Table-Constructor ConstructTable
macro ConstructTableOrSetPre() macro ConstructTableOrSetPre()
auto tt = cast_intrusive<TableType>(z.t); auto tt = cast_intrusive<TableType>(z.t);
auto new_t = new TableVal(tt, z.attrs); auto new_t = new TableVal(tt, z.aux->attrs);
auto aux = z.aux; auto aux = z.aux;
auto n = aux->n; auto n = aux->n;
auto ind_width = z.v2; auto ind_width = z.v2;
@ -1654,7 +1654,7 @@ macro WhenCall(func)
throw ZAMDelayedCallException(); throw ZAMDelayedCallException();
auto& lhs = frame[z.v1]; auto& lhs = frame[z.v1];
auto trigger = f->GetTrigger(); auto trigger = f->GetTrigger();
Val* v = trigger ? trigger->Lookup(z.call_expr.get()) : nullptr; Val* v = trigger ? trigger->Lookup(z.aux->call_expr.get()) : nullptr;
ValPtr vp; ValPtr vp;
if ( v ) if ( v )
vp = {NewRef{}, v}; vp = {NewRef{}, v};
@ -1666,7 +1666,7 @@ macro WhenCall(func)
std::vector<ValPtr> args; std::vector<ValPtr> args;
for ( auto i = 0; i < n; ++i ) for ( auto i = 0; i < n; ++i )
args.push_back(aux->ToVal(frame, i)); args.push_back(aux->ToVal(frame, i));
f->SetCall(z.call_expr.get()); f->SetCall(z.aux->call_expr.get());
/* It's possible that this function will call another that /* It's possible that this function will call another that
* itself returns null because *it* is the actual blocker. * itself returns null because *it* is the actual blocker.
* That will set ZAM_error, which we need to ignore. * That will set ZAM_error, which we need to ignore.
@ -1685,7 +1685,7 @@ macro WhenCall(func)
internal-op WhenCallN internal-op WhenCallN
type V type V
side-effects side-effects
eval WhenCall(z.func) eval WhenCall(z.aux->func)
internal-op WhenIndCallN internal-op WhenIndCallN
type VV type VV
@ -1703,7 +1703,7 @@ macro EvalScheduleArgs(time, is_delta, build_args)
double dt = time.double_val; double dt = time.double_val;
if ( is_delta ) if ( is_delta )
dt += run_state::network_time; dt += run_state::network_time;
auto handler = EventHandlerPtr(z.event_handler); auto handler = EventHandlerPtr(z.aux->event_handler);
ValVec args; ValVec args;
build_args build_args
auto timer = new ScheduleTimer(handler, std::move(args), dt); auto timer = new ScheduleTimer(handler, std::move(args), dt);
@ -1744,19 +1744,19 @@ op1-read
custom-method return CompileEvent(h, l); custom-method return CompileEvent(h, l);
eval ValVec args; eval ValVec args;
z.aux->FillValVec(args, frame); z.aux->FillValVec(args, frame);
QueueEvent(z.event_handler, args); QueueEvent(z.aux->event_handler, args);
internal-op Event0 internal-op Event0
type X type X
eval ValVec args(0); eval ValVec args(0);
QueueEvent(z.event_handler, args); QueueEvent(z.aux->event_handler, args);
internal-op Event1 internal-op Event1
type V type V
op1-read op1-read
eval ValVec args(1); eval ValVec args(1);
args[0] = frame[z.v1].ToVal(z.t); args[0] = frame[z.v1].ToVal(z.t);
QueueEvent(z.event_handler, args); QueueEvent(z.aux->event_handler, args);
internal-op Event2 internal-op Event2
type VV type VV
@ -1764,7 +1764,7 @@ op1-read
eval ValVec args(2); eval ValVec args(2);
args[0] = frame[z.v1].ToVal(z.t); args[0] = frame[z.v1].ToVal(z.t);
args[1] = frame[z.v2].ToVal(z.t2); args[1] = frame[z.v2].ToVal(z.t2);
QueueEvent(z.event_handler, args); QueueEvent(z.aux->event_handler, args);
internal-op Event3 internal-op Event3
type VVV type VVV
@ -1774,7 +1774,7 @@ eval ValVec args(3);
args[0] = frame[z.v1].ToVal(z.t); args[0] = frame[z.v1].ToVal(z.t);
args[1] = frame[z.v2].ToVal(z.t2); args[1] = frame[z.v2].ToVal(z.t2);
args[2] = frame[z.v3].ToVal(aux->elems[2].GetType()); args[2] = frame[z.v3].ToVal(aux->elems[2].GetType());
QueueEvent(z.event_handler, args); QueueEvent(z.aux->event_handler, args);
internal-op Event4 internal-op Event4
type VVVV type VVVV
@ -1785,7 +1785,7 @@ eval ValVec args(4);
args[1] = frame[z.v2].ToVal(z.t2); args[1] = frame[z.v2].ToVal(z.t2);
args[2] = frame[z.v3].ToVal(aux->elems[2].GetType()); args[2] = frame[z.v3].ToVal(aux->elems[2].GetType());
args[3] = frame[z.v4].ToVal(aux->elems[3].GetType()); args[3] = frame[z.v4].ToVal(aux->elems[3].GetType());
QueueEvent(z.event_handler, args); QueueEvent(z.aux->event_handler, args);
op Return op Return
@ -1795,6 +1795,7 @@ eval EvalReturn(nullptr,)
macro EvalReturn(val, type) macro EvalReturn(val, type)
ret_u = val; ret_u = val;
type type
DO_ZAM_PROFILE
pc = end_pc; pc = end_pc;
continue; continue;
@ -1819,6 +1820,7 @@ macro EvalSwitchBody(cases, postscript)
else else
pc = t[v]; pc = t[v];
postscript postscript
DO_ZAM_PROFILE
continue; continue;
} }
@ -2130,7 +2132,7 @@ eval auto vt = cast_intrusive<VectorType>(z.t);
internal-op Init-Table internal-op Init-Table
type V type V
eval auto tt = cast_intrusive<TableType>(z.t); eval auto tt = cast_intrusive<TableType>(z.t);
auto t = new TableVal(tt, z.attrs); auto t = new TableVal(tt, z.aux->attrs);
Unref(frame[z.v1].table_val); Unref(frame[z.v1].table_val);
frame[z.v1].table_val = t; frame[z.v1].table_val = t;
@ -2162,7 +2164,7 @@ macro BuildWhen(timeout)
if ( v ) if ( v )
local_aggrs.push_back(v); local_aggrs.push_back(v);
} }
(void)make_intrusive<trigger::Trigger>(wi, wi->WhenExprGlobals(), local_aggrs, timeout, f, z.loc.get()); (void)make_intrusive<trigger::Trigger>(wi, wi->WhenExprGlobals(), local_aggrs, timeout, f, z.loc->Loc());
######################################## ########################################
# Internal # Internal
@ -2263,6 +2265,7 @@ internal-op Hook-Break
type X type X
eval flow = FLOW_BREAK; eval flow = FLOW_BREAK;
pc = end_pc; pc = end_pc;
DO_ZAM_PROFILE
continue; continue;
# Slot 2 gives frame size. # Slot 2 gives frame size.

View file

@ -10,75 +10,87 @@ using std::string;
namespace zeek::detail { namespace zeek::detail {
void ZInst::Dump(zeek_uint_t inst_num, const FrameReMap* mappings) const { void ZInst::Dump(FILE* f, zeek_uint_t inst_num, const FrameReMap* mappings, const string& prefix) const {
// printf("v%d ", n); // fprintf(f, "v%d ", n);
auto id1 = VName(1, inst_num, mappings); auto id1 = VName(1, inst_num, mappings);
auto id2 = VName(2, inst_num, mappings); auto id2 = VName(2, inst_num, mappings);
auto id3 = VName(3, inst_num, mappings); auto id3 = VName(3, inst_num, mappings);
auto id4 = VName(4, inst_num, mappings); auto id4 = VName(4, inst_num, mappings);
Dump(id1, id2, id3, id4); Dump(f, prefix, id1, id2, id3, id4);
} }
void ZInst::Dump(const string& id1, const string& id2, const string& id3, const string& id4) const { void ZInst::Dump(FILE* f, const string& prefix, const string& id1, const string& id2, const string& id3,
printf("%s ", ZOP_name(op)); const string& id4) const {
// printf("(%s) ", op_type_name(op_type)); fprintf(f, "%s ", ZOP_name(op));
// fprintf(f, "(%s) ", op_type_name(op_type));
if ( t && 0 ) if ( t && 0 )
printf("(%s) ", type_name(t->Tag())); fprintf(f, "(%s) ", type_name(t->Tag()));
switch ( op_type ) { switch ( op_type ) {
case OP_X: break; case OP_X: break;
case OP_V: printf("%s", id1.c_str()); break; case OP_V: fprintf(f, "%s", id1.c_str()); break;
case OP_VV: printf("%s, %s", id1.c_str(), id2.c_str()); break; case OP_VV: fprintf(f, "%s, %s", id1.c_str(), id2.c_str()); break;
case OP_VVV: printf("%s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str()); break; case OP_VVV: fprintf(f, "%s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str()); break;
case OP_VVVV: printf("%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), id4.c_str()); break; case OP_VVVV: fprintf(f, "%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), id4.c_str()); break;
case OP_VVVC: printf("%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), ConstDump().c_str()); break; case OP_VVVC: fprintf(f, "%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), ConstDump().c_str()); break;
case OP_C: printf("%s", ConstDump().c_str()); break; case OP_C: fprintf(f, "%s", ConstDump().c_str()); break;
case OP_VC: printf("%s, %s", id1.c_str(), ConstDump().c_str()); break; case OP_VC: fprintf(f, "%s, %s", id1.c_str(), ConstDump().c_str()); break;
case OP_VVC: printf("%s, %s, %s", id1.c_str(), id2.c_str(), ConstDump().c_str()); break; case OP_VVC: fprintf(f, "%s, %s, %s", id1.c_str(), id2.c_str(), ConstDump().c_str()); break;
case OP_V_I1: printf("%d", v1); break; case OP_V_I1: fprintf(f, "%d", v1); break;
case OP_VC_I1: printf("%d %s", v1, ConstDump().c_str()); break; case OP_VC_I1: fprintf(f, "%d %s", v1, ConstDump().c_str()); break;
case OP_VV_FRAME: printf("%s, interpreter frame[%d]", id1.c_str(), v2); break; case OP_VV_FRAME: fprintf(f, "%s, interpreter frame[%d]", id1.c_str(), v2); break;
case OP_VV_I2: printf("%s, %d", id1.c_str(), v2); break; case OP_VV_I2: fprintf(f, "%s, %d", id1.c_str(), v2); break;
case OP_VV_I1_I2: printf("%d, %d", v1, v2); break; case OP_VV_I1_I2: fprintf(f, "%d, %d", v1, v2); break;
case OP_VVC_I2: printf("%s, %d, %s", id1.c_str(), v2, ConstDump().c_str()); break; case OP_VVC_I2: fprintf(f, "%s, %d, %s", id1.c_str(), v2, ConstDump().c_str()); break;
case OP_VVV_I3: printf("%s, %s, %d", id1.c_str(), id2.c_str(), v3); break; case OP_VVV_I3: fprintf(f, "%s, %s, %d", id1.c_str(), id2.c_str(), v3); break;
case OP_VVV_I2_I3: printf("%s, %d, %d", id1.c_str(), v2, v3); break; case OP_VVV_I2_I3: fprintf(f, "%s, %d, %d", id1.c_str(), v2, v3); break;
case OP_VVVV_I4: printf("%s, %s, %s, %d", id1.c_str(), id2.c_str(), id3.c_str(), v4); break; case OP_VVVV_I4: fprintf(f, "%s, %s, %s, %d", id1.c_str(), id2.c_str(), id3.c_str(), v4); break;
case OP_VVVV_I3_I4: printf("%s, %s, %d, %d", id1.c_str(), id2.c_str(), v3, v4); break; case OP_VVVV_I3_I4: fprintf(f, "%s, %s, %d, %d", id1.c_str(), id2.c_str(), v3, v4); break;
case OP_VVVV_I2_I3_I4: printf("%s, %d, %d, %d", id1.c_str(), v2, v3, v4); break; case OP_VVVV_I2_I3_I4: fprintf(f, "%s, %d, %d, %d", id1.c_str(), v2, v3, v4); break;
case OP_VVVC_I3: printf("%s, %s, %d, %s", id1.c_str(), id2.c_str(), v3, ConstDump().c_str()); break; case OP_VVVC_I3: fprintf(f, "%s, %s, %d, %s", id1.c_str(), id2.c_str(), v3, ConstDump().c_str()); break;
case OP_VVVC_I2_I3: printf("%s, %d, %d, %s", id1.c_str(), v2, v3, ConstDump().c_str()); break; case OP_VVVC_I2_I3: fprintf(f, "%s, %d, %d, %s", id1.c_str(), v2, v3, ConstDump().c_str()); break;
case OP_VVVC_I1_I2_I3: printf("%d, %d, %d, %s", v1, v2, v3, ConstDump().c_str()); break; case OP_VVVC_I1_I2_I3: fprintf(f, "%d, %d, %d, %s", v1, v2, v3, ConstDump().c_str()); break;
} }
if ( func ) auto func = aux ? aux->func : nullptr;
printf(" (func %s)", func->Name());
printf("\n"); if ( func )
fprintf(f, " (func %s)", func->Name());
if ( loc ) {
auto l = loc->Describe(true);
if ( func && (func->GetBodies().empty() || func->GetBodies()[0].stmts->Tag() != STMT_ZAM) )
l = l + ";" + func->Name();
if ( ! prefix.empty() )
l = prefix + l;
fprintf(f, " // %s", l.c_str());
}
fprintf(f, "\n");
} }
int ZInst::NumFrameSlots() const { int ZInst::NumFrameSlots() const {
@ -286,16 +298,16 @@ string ZInst::ConstDump() const {
return d.Description(); return d.Description();
} }
void ZInstI::Dump(const FrameMap* frame_ids, const FrameReMap* remappings) const { void ZInstI::Dump(FILE* f, const FrameMap* frame_ids, const FrameReMap* remappings) const {
int n = NumFrameSlots(); int n = NumFrameSlots();
// printf("v%d ", n); // fprintf(f, "v%d ", n);
auto id1 = VName(1, frame_ids, remappings); auto id1 = VName(1, frame_ids, remappings);
auto id2 = VName(2, frame_ids, remappings); auto id2 = VName(2, frame_ids, remappings);
auto id3 = VName(3, frame_ids, remappings); auto id3 = VName(3, frame_ids, remappings);
auto id4 = VName(4, frame_ids, remappings); auto id4 = VName(4, frame_ids, remappings);
ZInst::Dump(id1, id2, id3, id4); ZInst::Dump(f, "", id1, id2, id3, id4);
} }
string ZInstI::VName(int n, const FrameMap* frame_ids, const FrameReMap* remappings) const { string ZInstI::VName(int n, const FrameMap* frame_ids, const FrameReMap* remappings) const {

View file

@ -60,16 +60,22 @@ public:
ZInst(ZOp _op, ZAMOpType _op_type) { ZInst(ZOp _op, ZAMOpType _op_type) {
op = _op; op = _op;
op_type = _op_type; op_type = _op_type;
ASSERT(curr_loc);
loc = curr_loc;
} }
// Create a stub instruction that will be populated later. // Create a stub instruction that will be populated later.
ZInst() = default; ZInst() {
ASSERT(curr_loc);
loc = curr_loc;
}
virtual ~ZInst() = default; virtual ~ZInst() = default;
// Methods for printing out the instruction for debugging/maintenance. // Methods for printing out the instruction for debugging/profiling.
void Dump(zeek_uint_t inst_num, const FrameReMap* mappings) const; void Dump(FILE* f, zeek_uint_t inst_num, const FrameReMap* mappings, const std::string& prefix) const;
void Dump(const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4) const; void Dump(FILE* f, const std::string& prefix, const std::string& id1, const std::string& id2,
const std::string& id3, const std::string& id4) const;
// Returns the name to use in identifying one of the slots/integer // Returns the name to use in identifying one of the slots/integer
// values (designated by "n"). "inst_num" identifies the instruction // values (designated by "n"). "inst_num" identifies the instruction
@ -121,10 +127,6 @@ public:
// Type, usually for interpreting the constant. // Type, usually for interpreting the constant.
TypePtr t = nullptr; TypePtr t = nullptr;
TypePtr t2 = nullptr; // just a few ops need two types TypePtr t2 = nullptr; // just a few ops need two types
const Expr* e = nullptr; // only needed for "when" expressions
Func* func = nullptr; // used for calls
EventHandler* event_handler = nullptr; // used for referring to events
AttributesPtr attrs = nullptr; // used for things like constructors
// Auxiliary information. We could in principle use this to // Auxiliary information. We could in principle use this to
// consolidate a bunch of the above, though at the cost of // consolidate a bunch of the above, though at the cost of
@ -132,12 +134,9 @@ public:
// which is why we bundle these separately. // which is why we bundle these separately.
ZInstAux* aux = nullptr; ZInstAux* aux = nullptr;
// Location associated with this instruction, for error reporting. // Location associated with this instruction, for error reporting
std::shared_ptr<Location> loc; // and profiling.
std::shared_ptr<ZAMLocInfo> loc;
// Interpreter call expression associated with this instruction,
// for error reporting and stack backtraces.
CallExprPtr call_expr = nullptr;
// Whether v1 represents a frame slot type for which we // Whether v1 represents a frame slot type for which we
// explicitly manage the memory. // explicitly manage the memory.
@ -201,7 +200,7 @@ public:
ZInstI() {} ZInstI() {}
// If "remappings" is non-nil, then it is used instead of frame_ids. // If "remappings" is non-nil, then it is used instead of frame_ids.
void Dump(const FrameMap* frame_ids, const FrameReMap* remappings) const; void Dump(FILE* f, const FrameMap* frame_ids, const FrameReMap* remappings) const;
// Note that this is *not* an override of the base class's VName // Note that this is *not* an override of the base class's VName
// but instead a method with similar functionality but somewhat // but instead a method with similar functionality but somewhat
@ -294,9 +293,6 @@ public:
// a branch target). // a branch target).
int num_labels = 0; int num_labels = 0;
// Used for debugging. Transformed into the ZInst "loc" field.
StmtPtr stmt = curr_stmt;
private: private:
// Initialize 'c' from the given ConstExpr. // Initialize 'c' from the given ConstExpr.
void InitConst(const ConstExpr* ce); void InitConst(const ConstExpr* ce);
@ -467,6 +463,22 @@ public:
// Used for accessing function names. // Used for accessing function names.
IDPtr id_val = nullptr; IDPtr id_val = nullptr;
// Interpreter call expression associated with this instruction,
// for error reporting and stack backtraces.
CallExprPtr call_expr = nullptr;
// Used for direct calls.
Func* func = nullptr;
// Whether we know that we're calling a BiF.
bool is_BiF_call = false;
// Used for referring to events.
EventHandler* event_handler = nullptr;
// Used for things like constructors.
AttributesPtr attrs = nullptr;
// Whether the instruction can lead to globals/captures changing. // Whether the instruction can lead to globals/captures changing.
// Currently only needed by the optimizer, but convenient to // Currently only needed by the optimizer, but convenient to
// store here. // store here.