Skip to content

Commit 2ebae47

Browse files
xuhdevmeta-codesync[bot]
authored andcommitted
Promote "Use Stats for excludable_kotlin_lambda metric"
Summary: Promote {D90710396}. Reviewed By: thezhangwei Differential Revision: D91087950 fbshipit-source-id: 5f011e8891408e049a81a153ef6bfb843151ca16
1 parent 971d716 commit 2ebae47

File tree

3 files changed

+27
-33
lines changed

3 files changed

+27
-33
lines changed

opt/kotlin-lambda/KotlinInstanceRewriter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
*/
77

88
#include "KotlinInstanceRewriter.h"
9+
#include "AtomicStatCounter.h"
910
#include "CFGMutation.h"
1011
#include "PassManager.h"
1112
#include "Show.h"
13+
#include "TypeUtil.h"
1214
#include "Walkers.h"
1315

1416
namespace {
@@ -29,12 +31,14 @@ KotlinInstanceRewriter::Stats KotlinInstanceRewriter::collect_instance_usage(
2931
std::set<std::pair<IRInstruction*, DexMethod*>>>&
3032
concurrent_instance_map,
3133

32-
std::function<bool(DexClass*)> do_not_consider_type) {
34+
std::function<bool(DexClass*)> is_excludable,
35+
bool exclude_excludable) {
3336
// Collect all the types which are of Kotlin classes which sets INSTANCE
3437
// variable.
3538
// Get all the uses of the INSTANCE variables whose <init> does not have
3639
// sideeffets
3740
KotlinInstanceRewriter::Stats stats{};
41+
AtomicStatCounter<size_t> excludable_count{0};
3842
walk::parallel::classes(scope, [&](DexClass* cls) {
3943
if (!can_rename(cls) || !can_delete(cls)) {
4044
return;
@@ -43,16 +47,24 @@ KotlinInstanceRewriter::Stats KotlinInstanceRewriter::collect_instance_usage(
4347
if (instance == nullptr) {
4448
return;
4549
}
46-
if (do_not_consider_type(cls)) {
50+
if (!type::is_kotlin_non_capturing_lambda(cls)) {
4751
return;
4852
}
53+
// Count excludable classes (e.g., hot lambdas)
54+
if (is_excludable(cls)) {
55+
excludable_count++;
56+
if (exclude_excludable) {
57+
return;
58+
}
59+
}
4960
if (concurrent_instance_map.count(instance) != 0u) {
5061
return;
5162
}
5263
std::set<std::pair<IRInstruction*, DexMethod*>> insns;
5364
concurrent_instance_map.emplace(instance, insns);
5465
});
5566
stats.kotlin_new_instance = concurrent_instance_map.size();
67+
stats.excludable_kotlin_lambda = excludable_count;
5668
return stats;
5769
}
5870

@@ -219,6 +231,7 @@ void KotlinInstanceRewriter::Stats::report(PassManager& mgr) const {
219231
mgr.incr_metric("kotlin_instance_fields_removed",
220232
kotlin_instance_fields_removed);
221233
mgr.incr_metric("kotlin_new_inserted", kotlin_new_inserted);
234+
mgr.incr_metric("excludable_kotlin_lambda", excludable_kotlin_lambda);
222235

223236
TRACE(KOTLIN_INSTANCE, 1, "kotlin_new_instance = %zu", kotlin_new_instance);
224237
TRACE(KOTLIN_INSTANCE, 1, "kotlin_new_instance_which_escapes = %zu",
@@ -228,4 +241,6 @@ void KotlinInstanceRewriter::Stats::report(PassManager& mgr) const {
228241
TRACE(KOTLIN_INSTANCE, 1, "kotlin_instance_fields_removed = %zu",
229242
kotlin_instance_fields_removed);
230243
TRACE(KOTLIN_INSTANCE, 1, "kotlin_new_inserted = %zu", kotlin_new_inserted);
244+
TRACE(KOTLIN_INSTANCE, 1, "excludable_kotlin_lambda = %zu",
245+
excludable_kotlin_lambda);
231246
}

opt/kotlin-lambda/KotlinInstanceRewriter.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ class KotlinInstanceRewriter {
2020
size_t kotlin_instances_with_single_use{0};
2121
size_t kotlin_instance_fields_removed{0};
2222
size_t kotlin_new_inserted{0};
23+
size_t excludable_kotlin_lambda{0};
2324
Stats& operator+=(const Stats& that) {
2425
kotlin_new_instance += that.kotlin_new_instance;
2526
kotlin_new_instance_which_escapes +=
2627
that.kotlin_new_instance_which_escapes;
2728
kotlin_instances_with_single_use += that.kotlin_instances_with_single_use;
2829
kotlin_instance_fields_removed += that.kotlin_instance_fields_removed;
2930
kotlin_new_inserted += that.kotlin_new_inserted;
31+
excludable_kotlin_lambda += that.excludable_kotlin_lambda;
3032
return *this;
3133
}
3234
// Updates metrics tracked by \p mgr corresponding to these statistics.
@@ -43,12 +45,15 @@ class KotlinInstanceRewriter {
4345
// the same type and is initilized in <clinit>. Collect all such Lambda. Map
4446
// contains the field (that contains INSTANCE) and {insn, method} where it is
4547
// read (or used).
48+
// - is_excludable: returns true if the class is excludable (e.g., hot lambda)
49+
// - exclude_excludable: if true, excludable classes are skipped
4650
Stats collect_instance_usage(
4751
const Scope& scope,
4852
ConcurrentMap<DexFieldRef*,
4953
std::set<std::pair<IRInstruction*, DexMethod*>>>&
5054
concurrent_instance_map,
51-
std::function<bool(DexClass*)> do_not_consider_type);
55+
std::function<bool(DexClass*)> is_excludable,
56+
bool exclude_excludable);
5257

5358
// Filter out any INSTANCE that might escape and whose use we might not be
5459
// able to track

opt/kotlin-lambda/KotlinStatelessLambdaSingletonRemovalPass.cpp

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,12 @@
77

88
#include "KotlinStatelessLambdaSingletonRemovalPass.h"
99

10-
#include "AtomicStatCounter.h"
1110
#include "ConfigFiles.h"
1211
#include "DexUtil.h"
1312
#include "KotlinInstanceRewriter.h"
1413
#include "MethodProfiles.h"
1514
#include "PassManager.h"
1615
#include "TypeUtil.h"
17-
#include "Walkers.h"
18-
19-
namespace {
20-
21-
bool is_kotlin_stateless_lambda(const DexClass* cls) {
22-
return type::is_kotlin_non_capturing_lambda(cls);
23-
}
24-
25-
} // namespace
2616

2717
bool KotlinStatelessLambdaSingletonRemovalPass::is_hot_lambda(
2818
const DexClass* cls,
@@ -54,34 +44,18 @@ void KotlinStatelessLambdaSingletonRemovalPass::run_pass(
5444
const auto& method_profiles = conf.get_method_profiles();
5545
const bool has_method_profiles = method_profiles.has_stats();
5646

57-
// Count hot non-capturing lambdas for stats reporting
58-
AtomicStatCounter<size_t> excludable_stateless_kotlin_lambda{0};
59-
if (has_method_profiles) {
60-
walk::parallel::classes(scope, [&](DexClass* cls) {
61-
if (is_kotlin_stateless_lambda(cls) &&
62-
is_hot_lambda(cls, method_profiles)) {
63-
excludable_stateless_kotlin_lambda++;
64-
}
65-
});
66-
}
67-
68-
auto do_not_consider_type =
47+
auto is_excludable =
6948
[this, &method_profiles, has_method_profiles](DexClass* cls) -> bool {
70-
return !is_kotlin_stateless_lambda(cls) ||
71-
(m_exclude_hot && has_method_profiles &&
72-
is_hot_lambda(cls, method_profiles));
49+
redex_assert(type::is_kotlin_non_capturing_lambda(cls));
50+
return has_method_profiles && is_hot_lambda(cls, method_profiles);
7351
};
7452

75-
// TODO: Update the rewriter logic
7653
KotlinInstanceRewriter::Stats stats = rewriter.collect_instance_usage(
77-
scope, concurrentLambdaMap, do_not_consider_type);
54+
scope, concurrentLambdaMap, is_excludable, m_exclude_hot);
7855

7956
stats += rewriter.remove_escaping_instance(scope, concurrentLambdaMap);
8057
stats += rewriter.transform(concurrentLambdaMap);
8158
stats.report(mgr);
82-
83-
mgr.incr_metric("excludable_stateless_kotlin_lambda",
84-
excludable_stateless_kotlin_lambda);
8559
}
8660

8761
static KotlinStatelessLambdaSingletonRemovalPass s_pass;

0 commit comments

Comments
 (0)