@@ -481,7 +481,7 @@ impl Profile {
481
481
let handle = ThreadHandle ( self . threads . len ( ) ) ;
482
482
self . threads
483
483
. push ( Thread :: new ( process, tid, start_time, is_main) ) ;
484
- self . processes [ process. 0 ] . add_thread ( handle) ;
484
+ self . processes [ process. 0 ] . add_thread ( handle, is_main ) ;
485
485
handle
486
486
}
487
487
@@ -926,8 +926,12 @@ impl Profile {
926
926
self . threads [ thread. 0 ] . add_sample_same_stack_zero_cpu ( timestamp, weight) ;
927
927
}
928
928
929
- /// Add an allocation or deallocation sample to the given thread. This is used
930
- /// to collect stacks showing where allocations and deallocations happened.
929
+ /// Add an allocation or deallocation sample to the *main* thread of the given
930
+ /// process. This is used to collect stacks showing where allocations and
931
+ /// deallocations happened.
932
+ ///
933
+ /// CANNOT BE CALLED BEFORE THE MAIN THREAD FOR `process` HAS BEEN CREATED.
934
+ /// `stack` MUST BE A STACK HANDLE WHICH IS VALID FOR THAT MAIN THREAD.
931
935
///
932
936
/// When loading profiles with allocation samples in the Firefox Profiler, the
933
937
/// UI will display a dropdown above the call tree to switch between regular
@@ -951,40 +955,40 @@ impl Profile {
951
955
///
952
956
/// To get the stack handle, you can use [`Profile::handle_for_stack`] or
953
957
/// [`Profile::handle_for_stack_frames`].
958
+ ///
959
+ /// ## Main thread requirement
960
+ ///
961
+ /// Allocations are per-process, because you can allocate something one one thread
962
+ /// and then free it on a different thread, and you'll still want those two operations
963
+ /// to be matched up in a view that shows the retained memory.
964
+ ///
965
+ /// Unfortunately, `StackHandle` is currently per-thread. This method will become more
966
+ /// ergonomic once the profile format has changed so that `StackHandle`s can be used
967
+ /// across all threads of a profile. In the meantime, unfortunately you must manually
968
+ /// ensure that you create the stack handle for the main thread of the given process.
954
969
pub fn add_allocation_sample (
955
970
& mut self ,
956
- thread : ThreadHandle ,
971
+ process : ProcessHandle ,
957
972
timestamp : Timestamp ,
958
973
stack : Option < StackHandle > ,
959
974
allocation_address : u64 ,
960
975
allocation_size : i64 ,
961
976
) {
962
- // The profile format strictly separates sample data from different threads.
963
- // For allocation samples, this separation is a bit unfortunate, especially
964
- // when it comes to the "Retained Memory" panel which shows allocation stacks
965
- // for just objects that haven't been deallocated yet. This panel is per-thread,
966
- // and it needs to know about deallocations even if they happened on a different
967
- // thread from the allocation.
968
- // To resolve this conundrum, for now, we will put all allocation and deallocation
969
- // samples on a single thread per process, regardless of what thread they actually
970
- // happened on.
971
- // The Gecko profiler puts all allocation samples on the main thread, for example.
972
- // Here in fxprof-processed-profile, we just deem the first thread of each process
973
- // as the processes "allocation thread".
974
- let process_handle = self . threads [ thread. 0 ] . process ( ) ;
975
- let process = & self . processes [ process_handle. 0 ] ;
976
- let allocation_thread_handle = process. thread_handle_for_allocations ( ) . unwrap ( ) ;
977
+ let process = & self . processes [ process. 0 ] ;
978
+ let Some ( allocation_thread) = process. thread_handle_for_allocations ( ) else {
979
+ panic ! ( "Profile::add_allocation_sample called for a thread whose process does not have a main thread" ) ;
980
+ } ;
977
981
let stack_index = match stack {
978
- Some ( StackHandle ( stack_thread_handle , stack_index) ) => {
982
+ Some ( StackHandle ( stack_thread , stack_index) ) => {
979
983
assert_eq ! (
980
- stack_thread_handle , thread ,
981
- "StackHandle from different thread passed to Profile::add_sample "
984
+ stack_thread , allocation_thread ,
985
+ "StackHandle from different thread passed to Profile::add_allocation_sample "
982
986
) ;
983
987
Some ( stack_index)
984
988
}
985
989
None => None ,
986
990
} ;
987
- self . threads [ allocation_thread_handle . 0 ] . add_allocation_sample (
991
+ self . threads [ allocation_thread . 0 ] . add_allocation_sample (
988
992
timestamp,
989
993
stack_index,
990
994
allocation_address,
0 commit comments