diff options
author | Wessam Hassanein <wessam@google.com> | 2020-11-11 16:42:52 -0800 |
---|---|---|
committer | Wessam Hassanein <wessam@google.com> | 2021-02-05 03:10:12 +0000 |
commit | b5a10be6153d9bf09e4edf4a645da4085b4436bf (patch) | |
tree | ebf5a4b90f6c3ef45bc7342405f808a71be8a38e /runtime/javaheapprof/javaheapsampler.h | |
parent | bfd622abc23c77ffc8799f376df7241f15d6550a (diff) |
ART/Perfetto Java Heap Profiler
Adding a Sampling Java Heap Profiler to ART and its interface to Perfetto.
This cl is the first cl (CL1) in a series of cls described as below to implement the full ART/Perfetto Java Heap Profiler.
CL1: ART Java Heap Profiler. This is the main ART sampling profiler code. Tested using the ART testrunner as below as well as VLOG.
CL2: Uncomment APEX code ART side. CL3: Add APEX code Perfetto side.
CL2 and CL3 will be submitted simultaneously to avoid build failures and to add APEX dependencies.
CL4: Uncomment Perfetto API code. To be reviewed by fmayer@ (Perfetto Team). Further Testing, could be full feature testing including Perfetto at this point.
CL5: Further tests and/or optimizations can be added as needed.
Test: Passing Tests
test/testrunner/testrunner.py --host --debug -b
test/testrunner/testrunner.py --host --debug -b --64 -t 004-ThreadStress
test/testrunner/testrunner.py --host --runtime-option=-XX:PerfettoJavaHeapStackProf=true --debug -b
test/testrunner/testrunner.py --host --runtime-option=-XX:PerfettoJavaHeapStackProf=true --debug -b --64 -t 004-ThreadStress
Individualized and VLOG testing.
Bug: 160214819
Change-Id: I2be4c4e715ce8c3c8ac545e3e14332198b9c2295
(cherry picked from commit 7b149d585b4627ebb389e987c14fe808f2fe698b)
Merged-In: I2be4c4e715ce8c3c8ac545e3e14332198b9c2295
Diffstat (limited to 'runtime/javaheapprof/javaheapsampler.h')
-rw-r--r-- | runtime/javaheapprof/javaheapsampler.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/runtime/javaheapprof/javaheapsampler.h b/runtime/javaheapprof/javaheapsampler.h new file mode 100644 index 0000000000..02cb7b7f9b --- /dev/null +++ b/runtime/javaheapprof/javaheapsampler.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_JAVAHEAPPROF_JAVAHEAPSAMPLER_H_ +#define ART_RUNTIME_JAVAHEAPPROF_JAVAHEAPSAMPLER_H_ + +#include <random> +#include "base/locks.h" +#include "base/mutex.h" +#include "mirror/object.h" + +namespace art { + +class HeapSampler { + public: + HeapSampler() : rng_(/*seed=*/std::minstd_rand::default_seed), + geo_dist_(1.0 / /*expected value=4KB*/ 4096), + geo_dist_rng_lock_("Heap Sampler RNG Geometric Dist lock", + art::LockLevel::kGenericBottomLock) {} + + // Set the bytes until sample. + void SetBytesUntilSample(size_t bytes) { + *GetBytesUntilSample() = bytes; + } + // Get the bytes until sample. + size_t* GetBytesUntilSample() { + // Initialization should happen only once the first time the function is called. + // However there will always be a slot allocated for it at thread creation. + thread_local size_t bytes_until_sample = 0; + return &bytes_until_sample; + } + // Report a sample to Perfetto. + void ReportSample(art::mirror::Object* obj, size_t allocation_size); + // Check whether we should take a sample or not at this allocation, and return the + // number of bytes from current pos to the next sample to use in the expand Tlab + // calculation. + // Update state of both take_sample and temp_bytes_until_sample. + // tlab_used = pos - start + // Note: we do not update bytes until sample here. It will be saved after the allocation + // happens. This function can be called before the actual allocation happens. + size_t GetSampleOffset(size_t alloc_size, + size_t tlab_used, + bool* take_sample, + size_t* temp_bytes_until_sample) REQUIRES(!geo_dist_rng_lock_); + // Adjust the sample offset value with the adjustment usually (pos - start) + // of new Tlab after Reset. + void AdjustSampleOffset(size_t adjustment); + // Is heap sampler enabled? + bool IsEnabled(); + void EnableHeapSampler(void* enable_ptr, const void* enable_info_ptr); + void DisableHeapSampler(void* disable_ptr, const void* disable_info_ptr); + // Set the sampling interval. + void SetSamplingInterval(int sampling_interval) REQUIRES(geo_dist_rng_lock_); + // Return the sampling interval. + int GetSamplingInterval(); + // Set the Perfetto Session Info. + void SetSessionInfo(void* info); + // Get the Perfetto Session Info. + void* GetSessionInfo(); + + private: + size_t NextGeoDistRandSample() REQUIRES(!geo_dist_rng_lock_); + // Choose, save, and return the number of bytes until the next sample, + // possibly decreasing sample intervals by sample_adj_bytes. + size_t PickAndAdjustNextSample(size_t sample_adj_bytes = 0) REQUIRES(!geo_dist_rng_lock_); + + std::atomic<bool> enabled_; + // Default sampling interval is 4kb. + // Writes guarded by geo_dist_rng_lock_. + std::atomic<int> p_sampling_interval_{4 * 1024}; + void* perfetto_session_info_; + uint32_t perfetto_heap_id_ = 0; + // std random number generator. + std::minstd_rand rng_ GUARDED_BY(geo_dist_rng_lock_); // Holds the state + // std geometric distribution + std::geometric_distribution</*result_type=*/size_t> geo_dist_ GUARDED_BY(geo_dist_rng_lock_); + // Multiple threads can access the geometric distribution and the random number + // generator concurrently and thus geo_dist_rng_lock_ is used for thread safety. + art::Mutex geo_dist_rng_lock_; +}; + +} // namespace art + +#endif // ART_RUNTIME_JAVAHEAPPROF_JAVAHEAPSAMPLER_H_ |