Skip to content

Commit

Permalink
Support several search scopes and scopes that must be ignored
Browse files Browse the repository at this point in the history
This implements feature proposed in Byte-Lab#69.
  • Loading branch information
AlexVanGogen committed Aug 18, 2020
1 parent 5d0e6fe commit 92f9257
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 18 deletions.
6 changes: 4 additions & 2 deletions src/native/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
enum profiler_option
{
_unknown,
_package,
_search_scopes,
_ignored_scopes,
_progress_point,
_end_to_end,
_warmup,
Expand All @@ -18,7 +19,8 @@ namespace agent_args
{
profiler_option from_string(std::string &option)
{
if (option == "pkg" || option == "package") return _package;
if (option == "pkg" || option == "package" || option == "search") return _search_scopes;
if (option == "ignore") return _ignored_scopes;
if (option == "progress-point") return _progress_point;
if (option == "end-to-end") return _end_to_end;
if (option == "warmup") return _warmup;
Expand Down
25 changes: 22 additions & 3 deletions src/native/entry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,25 @@ static void releaseCreateLock() {
std::atomic_thread_fence(std::memory_order_release);
}

bool is_prefix(const char* prefix, char* str)
{
return strstr(str, prefix) == str + sizeof(char);
}

using is_prefix_pred_t = std::function<bool(std::string&)>;

bool contains_prefix(std::vector<std::string>& elements, is_prefix_pred_t predicate)
{
return std::find_if(std::begin(elements), std::end(elements), predicate) != std::end(elements);
}

// TODO faster search (trie maybe)
bool is_in_allowed_scope(char *class_sig)
{
auto predicate = [&class_sig](std::string &scope) { return is_prefix(scope.c_str(), class_sig); };
return !contains_prefix(Profiler::get_ignored_scopes(), predicate)
&& contains_prefix(Profiler::get_search_scopes(), predicate);
}

// Calls GetClassMethods on a given class to force the creation of
// jmethodIDs of it.
Expand All @@ -153,9 +172,9 @@ void CreateJMethodIDsForClass(jvmtiEnv *jvmti, jclass klass) {
logger->info(
"Creating JMethod IDs. [Class: {class}] [Scope: {scope}]",
fmt::arg("class", ksig.Get()), fmt::arg("scope", package_str));
if( strstr(ksig.Get(), package_str.c_str()) == ksig.Get() ) {
prof->addInScopeMethods(method_count, methods.Get());

if (is_in_allowed_scope(ksig.Get()))
{
Profiler::addInScopeMethods(method_count, methods.Get());
}

//TODO: this matches a prefix. class name AA will match a progress
Expand Down
65 changes: 52 additions & 13 deletions src/native/profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <climits>
#include <string>
#include <sstream>
#include <iterator>

#include "display.h"
#include "globals.h"
Expand Down Expand Up @@ -96,6 +97,8 @@ bool Profiler::prof_ready = false;
std::string Profiler::package;
struct ProgressPoint* Profiler::progress_point = nullptr;
std::string Profiler::progress_class;
std::vector<std::string> Profiler::search_scopes;
std::vector<std::string> Profiler::ignored_scopes;

static std::atomic<int> call_index(0);
static JVMPI_CallFrame static_call_frames[NUM_CALL_FRAMES];
Expand Down Expand Up @@ -144,10 +147,27 @@ void Profiler::ParseOptions(const char *options)
agent_args::report_error(fmt::format("Unknown option: {}", option).c_str());
break;

case _package:
Profiler::package = value;
prepare_scope(Profiler::package);
case _search_scopes:
{
std::stringstream search_scopes_stream(value);
while (std::getline(search_scopes_stream, item, '|'))
{
prepare_scope(item);
add_search_scope(item);
}
break;
}

case _ignored_scopes:
{
std::stringstream ignore_scopes_stream(value);
while (std::getline(ignore_scopes_stream, item, '|'))
{
prepare_scope(item);
add_ignored_scope(item);
}
break;
}

case _progress_point:
{
Expand Down Expand Up @@ -175,16 +195,25 @@ void Profiler::ParseOptions(const char *options)
}
}

logger->info(
"Profiler arguments:\n"
"\tprogress point: {}:{}\n"
"\tscope: {}\n"
"\twarmup: {}us\n"
"\tend-to-end: {}\n"
"\texperiment duration: {}",
progress_class, progress_point->lineno, Profiler::package, warmup_time, end_to_end, fix_exp);

if (Profiler::package.empty() || (!end_to_end && (progress_class.empty() || progress_point->lineno == -1)))
const char *const delim = ", ";

std::stringstream joint_search_scopes;
std::copy(search_scopes.begin(), search_scopes.end(), std::ostream_iterator<std::string>(joint_search_scopes, delim));

std::stringstream joint_ignored_scopes;
std::copy(ignored_scopes.begin(), ignored_scopes.end(),
std::ostream_iterator<std::string>(joint_ignored_scopes, delim));

logger->info("Profiler arguments:\n"
"\tprogress point: {}:{}\n"
"\tsearch scopes: {}\n"
"\tignored scopes: {}\n"
"\twarmup: {}us\n"
"\tend-to-end: {}\n"
"\tfixed experiment duration: {}",
progress_class, progress_point->lineno, joint_search_scopes.str(), joint_ignored_scopes.str(),
warmup_time, end_to_end, fix_exp);
if (search_scopes.empty() || (!end_to_end && (progress_class.empty() || progress_point->lineno == -1)))
{
agent_args::report_error("Missing package, progress class, or progress point");
}
Expand Down Expand Up @@ -647,6 +676,16 @@ void Profiler::prepare_scope(std::string& scope) {
std::replace(scope.begin(), scope.end(), '.', '/');
}

void Profiler::add_search_scope(string &scope)
{
search_scopes.push_back(scope);
}

void Profiler::add_ignored_scope(std::string& scope)
{
ignored_scopes.push_back(scope);
}

void Profiler::Handle(int signum, siginfo_t *info, void *context) {
if( !prof_ready ) {
return;
Expand Down
9 changes: 9 additions & 0 deletions src/native/profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ class Profiler {

static std::shared_ptr<spdlog::logger> &getLogger() { return logger; };

static std::vector<std::string>& get_search_scopes() { return search_scopes; }
static std::vector<std::string>& get_ignored_scopes() { return ignored_scopes; }

static std::unordered_set<void *> &getInScopeMethods() { return in_scope_ids; }

static struct Experiment &getCurrentExperiment() { return current_experiment; }
Expand Down Expand Up @@ -167,6 +170,9 @@ class Profiler {

static void prepare_scope(std::string &scope);

static void add_search_scope(std::string &scope);
static void add_ignored_scope(std::string &scope);

static jobject mbean;

static jmethodID mbean_cache_method_id;
Expand Down Expand Up @@ -227,6 +233,9 @@ class Profiler {

static bool fix_exp;

static std::vector<std::string> search_scopes;
static std::vector<std::string> ignored_scopes;

static std::shared_ptr<spdlog::logger> logger;
};

Expand Down

0 comments on commit 92f9257

Please sign in to comment.