1515 * limitations under the License.
1616 */
1717
18+ use std:: any:: Any ;
1819use std:: cell:: Cell ;
1920use std:: cell:: RefCell ;
2021use std:: cell:: RefMut ;
@@ -215,13 +216,17 @@ pub struct FrozenHeap {
215216 str_interner : RefCell < FrozenStringValueInterner > ,
216217}
217218
219+ pub type FrozenHeapName = Box < dyn Any + Send + Sync + ' static > ;
220+
218221/// `FrozenHeap` when it is no longer modified and can be share between threads.
219222/// Although, `arena` is not safe to share between threads, but at least `refs` is.
220- #[ derive( Default , Allocative ) ]
223+ #[ derive( Allocative ) ]
221224#[ allow( clippy:: non_send_fields_in_send_ty) ]
222225struct FrozenFrozenHeap {
223226 arena : Arena < ChunkAllocator > ,
224227 refs : Box < [ FrozenHeapRef ] > ,
228+ #[ allocative( skip) ] // We don't really expect it to be big
229+ name : Option < FrozenHeapName > ,
225230}
226231
227232// Safe because we never mutate the Arena other than with &mut
@@ -302,6 +307,22 @@ impl FrozenHeapRef {
302307 . as_ref ( )
303308 . map_or_else ( HeapSummary :: default, |a| a. arena . allocated_summary ( ) )
304309 }
310+
311+ /// Get the name of this heap.
312+ ///
313+ /// Names can be assigned when finalizing frozen heaps; in practice, this is done when freezing
314+ /// modules, see `Module::freeze_and_name`.
315+ ///
316+ /// The name is intentionally made available here and not at a higher point like the module
317+ /// level so that it can be inspected even when traversing the dependency graph of frozen heaps.
318+ pub fn name ( & self ) -> Option < & FrozenHeapName > {
319+ self . 0 . as_ref ( ) . and_then ( |a| a. name . as_ref ( ) )
320+ }
321+
322+ /// Get the frozen heaps that this frozen heap depends on.
323+ pub fn refs ( & self ) -> impl Iterator < Item = & FrozenHeapRef > {
324+ self . 0 . as_ref ( ) . map ( |h| h. refs . iter ( ) ) . into_iter ( ) . flatten ( )
325+ }
305326}
306327
307328impl FrozenHeap {
@@ -310,10 +331,21 @@ impl FrozenHeap {
310331 Self :: default ( )
311332 }
312333
334+ /// `into_ref` but also assign a name
335+ ///
336+ /// See `FrozenHeapRef::name` for more details.
337+ pub fn name_and_into_ref ( self , name : FrozenHeapName ) -> FrozenHeapRef {
338+ self . into_ref_impl ( Some ( name) )
339+ }
340+
313341 /// After all values have been allocated, convert the [`FrozenHeap`] into a
314342 /// [`FrozenHeapRef`] which can be [`clone`](Clone::clone)d, shared between threads,
315343 /// and ensures the underlying values allocated on the [`FrozenHeap`] remain valid.
316344 pub fn into_ref ( self ) -> FrozenHeapRef {
345+ self . into_ref_impl ( None )
346+ }
347+
348+ pub ( crate ) fn into_ref_impl ( self , name : Option < FrozenHeapName > ) -> FrozenHeapRef {
317349 let FrozenHeap {
318350 mut arena, refs, ..
319351 } = self ;
@@ -325,6 +357,7 @@ impl FrozenHeap {
325357 FrozenHeapRef ( Some ( Arc :: new ( FrozenFrozenHeap {
326358 arena,
327359 refs : refs. into_iter ( ) . collect ( ) ,
360+ name,
328361 } ) ) )
329362 }
330363 }
0 commit comments