Skip to content

Commit

Permalink
Do not scale back ifield type aggregation for Mariana Trench
Browse files Browse the repository at this point in the history
Summary: Add an option to gate the eligible ifield logic introduced in D51603486.

Reviewed By: anwesht

Differential Revision: D51869548

fbshipit-source-id: a1a37e0e72b45bc608e10709d9427d18581702a9
  • Loading branch information
Wei Zhang (Devinfra) authored and facebook-github-bot committed Dec 6, 2023
1 parent d40e2fc commit 292be93
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 22 deletions.
25 changes: 15 additions & 10 deletions service/type-analysis/GlobalTypeAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,21 +457,26 @@ std::unique_ptr<GlobalTypeAnalyzer> GlobalTypeAnalysis::analyze(
{CURRENT_PARTITION_LABEL, ArgumentTypeEnvironment()}});
auto non_true_virtuals =
mog::get_non_true_virtuals(*method_override_graph, scope);
EligibleIfields eligible_ifields =
constant_propagation::gather_safely_inferable_ifield_candidates(scope,
{});
EligibleIfields eligible_ifields;
if (m_only_aggregate_safely_inferrable_fields) {
eligible_ifields =
constant_propagation::gather_safely_inferable_ifield_candidates(scope,
{});
}
size_t iteration_cnt = 0;

for (size_t i = 0; i < m_max_global_analysis_iteration; ++i) {
// Build an approximation of all the field values and method return values.
TRACE(TYPE, 2, "[global] Collecting WholeProgramState");
auto wps = m_use_multiple_callee_callgraph
? std::make_unique<WholeProgramState>(
scope, *gta, non_true_virtuals, m_any_init_reachables,
eligible_ifields, cg)
: std::make_unique<WholeProgramState>(
scope, *gta, non_true_virtuals, m_any_init_reachables,
eligible_ifields);
auto wps =
m_use_multiple_callee_callgraph
? std::make_unique<WholeProgramState>(
scope, *gta, non_true_virtuals, m_any_init_reachables,
eligible_ifields, m_only_aggregate_safely_inferrable_fields,
cg)
: std::make_unique<WholeProgramState>(
scope, *gta, non_true_virtuals, m_any_init_reachables,
eligible_ifields, m_only_aggregate_safely_inferrable_fields);
trace_whole_program_state(*wps);
trace_stats(*wps);
trace_whole_program_state_diff(gta->get_whole_program_state(), *wps);
Expand Down
11 changes: 8 additions & 3 deletions service/type-analysis/GlobalTypeAnalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,14 @@ class GlobalTypeAnalyzer : public sparta::ParallelMonotonicFixpointIterator<
class GlobalTypeAnalysis {

public:
explicit GlobalTypeAnalysis(size_t max_global_analysis_iteration = 10,
bool use_multiple_callee_callgraph = false)
explicit GlobalTypeAnalysis(
size_t max_global_analysis_iteration = 10,
bool use_multiple_callee_callgraph = false,
bool only_aggregate_safely_inferrable_fields = true)
: m_max_global_analysis_iteration(max_global_analysis_iteration),
m_use_multiple_callee_callgraph(use_multiple_callee_callgraph) {}
m_use_multiple_callee_callgraph(use_multiple_callee_callgraph),
m_only_aggregate_safely_inferrable_fields(
only_aggregate_safely_inferrable_fields) {}

void run(Scope& scope) { analyze(scope); }

Expand All @@ -137,6 +141,7 @@ class GlobalTypeAnalysis {
private:
size_t m_max_global_analysis_iteration;
bool m_use_multiple_callee_callgraph;
bool m_only_aggregate_safely_inferrable_fields;
// Methods reachable from clinit that read static fields and reachable from
// ctors that read instance fields.
ConcurrentSet<const DexMethod*> m_any_init_reachables;
Expand Down
26 changes: 18 additions & 8 deletions service/type-analysis/WholeProgramState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,15 @@ void set_sfields_in_partition(const DexClass* cls,
* initialized in any ctor, it is nullalbe. That's why we need to join the type
* mapping across all ctors.
*/
void set_ifields_in_partition(const DexClass* cls,
const DexTypeEnvironment& env,
const EligibleIfields& eligible_ifields,
DexTypeFieldPartition* field_partition) {
void set_ifields_in_partition(
const DexClass* cls,
const DexTypeEnvironment& env,
const EligibleIfields& eligible_ifields,
const bool only_aggregate_safely_inferrable_fields,
DexTypeFieldPartition* field_partition) {
for (auto& field : cls->get_ifields()) {
if (!is_reference(field) || eligible_ifields.count(field) == 0) {
if (!is_reference(field) || (only_aggregate_safely_inferrable_fields &&
eligible_ifields.count(field) == 0)) {
continue;
}
auto domain = env.get(field);
Expand Down Expand Up @@ -155,8 +158,11 @@ WholeProgramState::WholeProgramState(
const global::GlobalTypeAnalyzer& gta,
const InsertOnlyConcurrentSet<DexMethod*>& non_true_virtuals,
const ConcurrentSet<const DexMethod*>& any_init_reachables,
const EligibleIfields& eligible_ifields)
: m_any_init_reachables(&any_init_reachables) {
const EligibleIfields& eligible_ifields,
const bool only_aggregate_safely_inferrable_fields)
: m_any_init_reachables(&any_init_reachables),
m_only_aggregate_safely_inferrable_fields(
only_aggregate_safely_inferrable_fields) {
// Exclude fields we cannot correctly analyze.
walk::fields(scope, [&](DexField* field) {
if (!type::is_object(field->get_type())) {
Expand Down Expand Up @@ -195,12 +201,14 @@ WholeProgramState::WholeProgramState(
const InsertOnlyConcurrentSet<DexMethod*>& non_true_virtuals,
const ConcurrentSet<const DexMethod*>& any_init_reachables,
const EligibleIfields& eligible_ifields,
const bool only_aggregate_safely_inferrable_fields,
std::shared_ptr<const call_graph::Graph> call_graph)
: WholeProgramState(scope,
gta,
non_true_virtuals,
any_init_reachables,
eligible_ifields) {
eligible_ifields,
only_aggregate_safely_inferrable_fields) {
m_call_graph = std::move(call_graph);
}

Expand Down Expand Up @@ -272,6 +280,7 @@ void WholeProgramState::analyze_clinits_and_ctors(
auto lta = gta.get_internal_local_analysis(ctor);
const auto& env = lta->get_exit_state_at(cfg.exit_block());
set_ifields_in_partition(cls, env, eligible_ifields,
m_only_aggregate_safely_inferrable_fields,
&cls_field_partition);
}

Expand Down Expand Up @@ -332,6 +341,7 @@ void WholeProgramState::collect_field_types(
return;
}
if (opcode::is_an_iput(insn->opcode()) &&
m_only_aggregate_safely_inferrable_fields &&
eligible_ifields.count(field) == 0) {
// Skip writes to non-eligible instance fields.
return;
Expand Down
5 changes: 4 additions & 1 deletion service/type-analysis/WholeProgramState.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ class WholeProgramState {
const global::GlobalTypeAnalyzer&,
const InsertOnlyConcurrentSet<DexMethod*>& non_true_virtuals,
const ConcurrentSet<const DexMethod*>& any_init_reachables,
const EligibleIfields& eligible_ifields);
const EligibleIfields& eligible_ifields,
const bool only_aggregate_safely_inferrable_fields);

WholeProgramState(const Scope&,
const global::GlobalTypeAnalyzer&,
const InsertOnlyConcurrentSet<DexMethod*>&,
const ConcurrentSet<const DexMethod*>&,
const EligibleIfields&,
const bool,
std::shared_ptr<const call_graph::Graph> call_graph);

void set_to_top() {
Expand Down Expand Up @@ -231,6 +233,7 @@ class WholeProgramState {
DexTypeFieldPartition m_field_partition;
DexTypeMethodPartition m_method_partition;
std::unordered_map<const DexMethodRef*, DexTypeDomain> m_known_method_returns;
bool m_only_aggregate_safely_inferrable_fields = false;
};

class WholeProgramAwareAnalyzer final
Expand Down

0 comments on commit 292be93

Please sign in to comment.