libredex/Trace.h (223 lines of code) (raw):
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <memory>
#include <mutex>
#include <string>
#include "Macros.h"
#include "Util.h"
class DexMethodRef;
class DexType;
#define TMS \
TM(ACCESS) \
TM(ANNO) \
TM(API_UTILS) \
TM(APP_MOD_USE) \
TM(ARGS) \
TM(ASSESSOR) \
TM(BBPROFILE) \
TM(BBREORDERING) \
TM(BIND) \
TM(BLD_PATTERN) \
TM(BPH) \
TM(BRCR) \
TM(BRIDGE) \
TM(BUILDERS) \
TM(CALLGRAPH) \
TM(CDDP) \
TM(CFG) \
TM(CFP) \
TM(CHECKRECURSION) \
TM(CIC) \
TM(CLA) \
TM(CLMG) \
TM(CLP_LITHO) \
TM(CONSTP) \
TM(CPG) \
TM(CS) \
TM(CSE) \
TM(CU) \
TM(CUSTOMSORT) \
TM(DBGSTRIP) \
TM(DC) \
TM(DCE) \
TM(DEDUP_BLOCKS) \
TM(DEDUP_RES) \
TM(DELINIT) \
TM(DELMET) \
TM(DS) \
TM(EMPTY) \
TM(ENUM) \
TM(EVALTC) \
TM(FINALINLINE) \
TM(FREG) \
TM(GETTER) \
TM(GQL) \
TM(HASHER) \
TM(ICL) \
TM(ICONSTP) \
TM(IDEX) \
TM(IFCS_ANALYSIS) \
TM(INL) \
TM(INLINE) \
TM(INLRES) \
TM(INSTRUMENT) \
TM(INTF) \
TM(INTRO_SWITCH) \
TM(IODI) \
TM(ISO) \
TM(LCR_PASS) \
TM(LIB) \
TM(LOC) \
TM(LOCKS) \
TM(LOOP) \
TM(MAGIC_FIELDS) \
TM(MAIN) \
TM(MARIANA_TRENCH) \
TM(MEINT) \
TM(METH_DEDUP) \
TM(METH_MERGER) \
TM(METH_PROF) \
TM(MFLOW) \
TM(MMINL) \
TM(MODULARITY) \
TM(MONITOR) \
TM(MORTIROLO) \
TM(MTRANS) \
TM(NATIVE) \
TM(NULLCHECK) \
TM(OBFUSCATE) \
TM(OEA) \
TM(OPTRES) \
TM(OPT_STORES) \
TM(OPUT) \
TM(ORIGINALNAME) \
TM(OSDCE) \
TM(OUTLINE) \
TM(PA) \
TM(PEEPHOLE) \
TM(PGR) \
TM(PM) \
TM(POST_LOWERING) \
TM(PTA) \
TM(PURITY) \
TM(QUICK) \
TM(RABBIT) \
TM(RAL) \
TM(RBB) \
TM(REACH) \
TM(REFL) \
TM(REFU) \
TM(REG) \
TM(RENAME) \
TM(RES) \
TM(RESO) \
TM(RG) \
TM(RME) \
TM(RMGOTO) \
TM(RM_INTF) \
TM(RMU) \
TM(RMUF) \
TM(RMUNINST) \
TM(ROR) \
TM(RP) \
TM(SBCC) \
TM(SDIS) \
TM(SHORTEN) \
TM(SPLIT_RES) \
TM(STATIC_RELO) \
TM(STATS) \
TM(STRBUILD) \
TM(STR_CAT) \
TM(SUPER) \
TM(SW) \
TM(SWIN) \
TM(SWITCH_EQUIV) \
TM(SYNT) \
TM(TIME) \
TM(TP) \
TM(TRACKRESOURCES) \
TM(TRMU) \
TM(TYPE) \
TM(TYPE_TRANSFORM) \
TM(UCM) \
TM(UNREF_INTF) \
TM(USES_NAMES) \
TM(VERIFY) \
TM(VIRT) \
TM(VM) \
TM(VMERGE) \
TM(KOTLIN_INSTANCE) \
TM(KOTLIN_STATS) \
TM(KOTLIN_OBJ_INLINE) \
/* End of list */
enum TraceModule : int {
#define TM(x) x,
TMS
#undef TM
N_TRACE_MODULES,
};
// To avoid "-Wunused" warnings, keep the TRACE macros in common so that the
// compiler sees a "use." However, ensure that it is optimized away through
// a constexpr condition in NDEBUG mode.
#ifdef NDEBUG
constexpr bool traceEnabled(TraceModule, int) { return false; }
#else
bool traceEnabled(TraceModule module, int level);
#endif // NDEBUG
void trace(TraceModule module,
int level,
bool suppress_newline,
const char* fmt,
...) ATTR_FORMAT(4, 5);
#define TRACE(module, level, fmt, ...) \
do { \
if (traceEnabled(module, level)) { \
trace(module, level, /* suppress_newline */ false, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define TRACE_NO_LINE(module, level, fmt, ...) \
do { \
if (traceEnabled(module, level)) { \
trace(module, level, /* suppress_newline */ true, fmt, ##__VA_ARGS__); \
} \
} while (0)
class TraceContext {
public:
explicit TraceContext(const DexMethodRef* current_method) {
#if !IS_WINDOWS
last_context = s_context;
s_context = this;
method = current_method;
string_value = &string_value_cache;
#endif
}
explicit TraceContext(const DexType* current_type) {
#if !IS_WINDOWS
last_context = s_context;
s_context = this;
type = current_type;
string_value = &string_value_cache;
#endif
}
explicit TraceContext(const std::string* string_value) {
#if !IS_WINDOWS
last_context = s_context;
s_context = this;
this->string_value = string_value;
#endif
}
~TraceContext() {
#if !IS_WINDOWS
s_context = last_context;
#endif
}
#if !IS_WINDOWS
const std::string& get_string_value() const;
const DexMethodRef* get_dex_method_ref() const { return this->method; }
#endif
private:
#if !IS_WINDOWS
thread_local static const TraceContext* s_context;
const TraceContext* last_context{nullptr};
const DexMethodRef* method{nullptr};
const DexType* type{nullptr};
const std::string* string_value{nullptr};
mutable std::string string_value_cache;
#endif
friend struct TraceContextAccess;
};