1212#include " safe_force.h"
1313#include " utils/Pool.h"
1414#include " utils/measuring.h"
15-
15+ # include < chrono >
1616#include < assert.h>
1717#include < deque>
1818#include < libintl.h>
@@ -524,16 +524,29 @@ void recordDeoptReason(SEXP val, const DeoptReason& reason) {
524524 auto pos = reason.pc ();
525525
526526 switch (reason.reason ) {
527- case DeoptReason::Unknown:
527+ case DeoptReason::Unknown: {
528+ #if LOGG > 2
529+ std::ofstream & logg = Measuring::getLogStream ();
530+ logg << " Deopt: Unknown" << std::endl;
531+ #endif
528532 break ;
533+ }
529534 case DeoptReason::DeadBranchReached: {
530535 assert (*pos == Opcode::record_test_);
536+ #if LOGG > 2
537+ std::ofstream & logg = Measuring::getLogStream ();
538+ logg << " Deopt: DeadBranchReached" << std::endl;
539+ #endif
531540 ObservedTest* feedback = (ObservedTest*)(pos + 1 );
532541 feedback->seen = ObservedTest::Both;
533542 break ;
534543 }
535544 case DeoptReason::Typecheck: {
536545 assert (*pos == Opcode::record_type_);
546+ #if LOGG > 2
547+ std::ofstream & logg = Measuring::getLogStream ();
548+ logg << " Deopt: Typecheck" << std::endl;
549+ #endif
537550 if (val == symbol::UnknownDeoptTrigger)
538551 break ;
539552 ObservedValues* feedback = (ObservedValues*)(pos + 1 );
@@ -549,12 +562,21 @@ void recordDeoptReason(SEXP val, const DeoptReason& reason) {
549562 }
550563 break ;
551564 }
552- case DeoptReason::DeadCall:
565+ case DeoptReason::DeadCall: {
566+ #if LOGG > 2
567+ std::ofstream & logg = Measuring::getLogStream ();
568+ logg << " Deopt: DeadCall" << std::endl;
569+ #endif
553570 reason.srcCode ()->deadCallReached ++;
554571 // fall through
555572 [[clang::fallthrough]];
573+ }
556574 case DeoptReason::Calltarget: {
557575 assert (*pos == Opcode::record_call_);
576+ #if LOGG > 2
577+ std::ofstream & logg = Measuring::getLogStream ();
578+ logg << " Deopt: CallTarget" << std::endl;
579+ #endif
558580 if (val == symbol::UnknownDeoptTrigger)
559581 break ;
560582 ObservedCallees* feedback = (ObservedCallees*)(pos + 1 );
@@ -564,6 +586,10 @@ void recordDeoptReason(SEXP val, const DeoptReason& reason) {
564586 }
565587 case DeoptReason::EnvStubMaterialized: {
566588 reason.srcCode ()->flags .set (Code::NeedsFullEnv);
589+ #if LOGG > 2
590+ std::ofstream & logg = Measuring::getLogStream ();
591+ logg << " Deopt: EnvStubMaterialized" << std::endl;
592+ #endif
567593 break ;
568594 }
569595 }
@@ -888,6 +914,53 @@ class SlowcaseCounter {
888914};
889915#endif
890916
917+ #if LOGG > 0
918+ class Timer {
919+ private:
920+ std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::_V2::steady_clock::duration> tick, tock;
921+ std::chrono::duration<double , std::milli> runtime;
922+ size_t fun_id;
923+ public:
924+ void start (const CallContext& call, int hast) {
925+ tick = std::chrono::steady_clock::now ();
926+ std::ofstream & logg = Measuring::getLogStream ();
927+ SEXP const lhs = CAR (call.ast );
928+ static const SEXP double_colons = Rf_install (" ::" );
929+ static const SEXP triple_colons = Rf_install (" :::" );
930+ fun_id = reinterpret_cast <size_t >(BODY (call.callee ));
931+ logg << " =,\" " << fun_id << " \" ," << hast << " ," ;
932+ // Function Header
933+ if (TYPEOF (lhs) == SYMSXP) {
934+ // case 1: function call of the form f(x,y,z)
935+ logg << " \" " << CHAR (PRINTNAME (lhs)) << " \" " ;
936+ } else if (TYPEOF (lhs) == LANGSXP && ((CAR (lhs) == double_colons) || (CAR (lhs) == triple_colons))) {
937+ // case 2: function call of the form pkg::f(x,y,z) or pkg:::f(x,y,z)
938+ SEXP const fun1 = CAR (lhs);
939+ SEXP const pkg = CADR (lhs);
940+ SEXP const fun2 = CADDR (lhs);
941+ assert (TYPEOF (pkg) == SYMSXP && TYPEOF (fun2) == SYMSXP);
942+ logg << " \" " << CHAR (PRINTNAME (pkg)) << CHAR (PRINTNAME (fun1)) << CHAR (PRINTNAME (fun2)) << " \" " ;
943+ } else {
944+ logg << " \" AN_" << fun_id << " \" " ;
945+ }
946+ logg << " \n " ;
947+ }
948+
949+ void end (const Context & context) {
950+ std::ofstream & logg = Measuring::getLogStream ();
951+ tock = std::chrono::steady_clock::now ();
952+ runtime = tock - tick;
953+ logg << " !," << " \" " << context << " \" ," << context.toI () << " ," << runtime.count () << " ," << fun_id << " \n " ;
954+ }
955+ private:
956+ void * operator new (size_t );
957+ void * operator new [](size_t );
958+ void operator delete (void *);
959+ void operator delete[] (void *);
960+ };
961+ #endif
962+
963+
891964SEXP doCall (CallContext& call, InterpreterInstance* ctx, bool popArgs) {
892965 assert (call.callee );
893966
@@ -952,6 +1025,11 @@ SEXP doCall(CallContext& call, InterpreterInstance* ctx, bool popArgs) {
9521025
9531026 auto table = DispatchTable::unpack (body);
9541027
1028+ #if LOGG > 0
1029+ Timer t;
1030+ t.start (call,table->hast );
1031+ #endif
1032+
9551033 inferCurrentContext (call, table->baseline ()->signature ().formalNargs (),
9561034 ctx);
9571035 Function* fun = dispatch (call, table);
@@ -1093,6 +1171,11 @@ SEXP doCall(CallContext& call, InterpreterInstance* ctx, bool popArgs) {
10931171 assert (!fun->flags .contains (Function::Deopt));
10941172 if (popArgs)
10951173 ostack_popn (ctx, call.passedArgs - call.suppliedArgs );
1174+
1175+ #if LOGG > 0
1176+ t.end (fun->context ());
1177+ #endif
1178+
10961179 return result;
10971180 }
10981181 default :
0 commit comments