Bug 1520678 - Simplify naming of interner and data_store instances. r=kamidphish
authorBobby Holley <bobbyholley@gmail.com>
Fri, 18 Jan 2019 00:45:13 +0000
changeset 511494 32476b4042f7fbcd6c201e03affd8284db01caad
parent 511493 b79c6b00e3c0e2e8160096c7066e5471019705c7
child 511495 29dcf30c1cada54e646566966065131f81d0d863
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish
bugs1520678
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1520678 - Simplify naming of interner and data_store instances. r=kamidphish Depends on D16780 Differential Revision: https://phabricator.services.mozilla.com/D16781
gfx/thebes/gfxPlatform.cpp
gfx/webrender_bindings/webrender_ffi.h
gfx/wr/webrender/src/batch.rs
gfx/wr/webrender/src/display_list_flattener.rs
gfx/wr/webrender/src/picture.rs
gfx/wr/webrender/src/prim_store/mod.rs
gfx/wr/webrender/src/profiler.rs
gfx/wr/webrender/src/render_backend.rs
gfx/wr/webrender/src/scene_builder.rs
gfx/wr/webrender/src/tiling.rs
gfx/wr/webrender_api/src/api.rs
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -680,22 +680,22 @@ static void FinishAsyncMemoryReport() {
   if (imgr) {
     imgr->EndReport();
   }
 }
 
 // clang-format off
 // (For some reason, clang-format gets the second macro right, but totally mangles the first).
 #define REPORT_INTERNER(id)                      \
-  helper.Report(aReport.interning.id##_interner, \
+  helper.Report(aReport.interning.interners.id, \
                 "interning/" #id "/interners");
 // clang-format on
 
 #define REPORT_DATA_STORE(id)                      \
-  helper.Report(aReport.interning.id##_data_store, \
+  helper.Report(aReport.interning.data_stores.id, \
                 "interning/" #id "/data-stores");
 
 NS_IMPL_ISUPPORTS(WebRenderMemoryReporter, nsIMemoryReporter)
 
 NS_IMETHODIMP
 WebRenderMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
                                         nsISupports* aData, bool aAnonymize) {
   MOZ_ASSERT(XRE_IsParentProcess());
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -49,25 +49,23 @@ void gecko_profiler_end_marker(const cha
   macro(picture);                          \
   macro(text_run);
 
 // Prelude of types necessary before including webrender_ffi_generated.h
 namespace mozilla {
 namespace wr {
 
 // Because this struct is macro-generated on the Rust side, cbindgen can't see
-// it for some reason. Work around that by re-declaring it here.
-#define DECLARE_MEMBERS(id) \
-  uintptr_t id##_interner;  \
-  uintptr_t id##_data_store;
-struct InterningMemoryReport {
-  WEBRENDER_FOR_EACH_INTERNER(DECLARE_MEMBERS)
+// it. Work around that by re-declaring it here.
+#define DECLARE_MEMBER(id) uintptr_t id;
+struct InternerSubReport {
+  WEBRENDER_FOR_EACH_INTERNER(DECLARE_MEMBER)
 };
 
-#undef DECLARE_MEMBERS
+#undef DECLARE_MEMBER
 
 struct FontInstanceFlags {
   uint32_t bits;
 
   bool operator==(const FontInstanceFlags& aOther) const {
     return bits == aOther.bits;
   }
 
--- a/gfx/wr/webrender/src/batch.rs
+++ b/gfx/wr/webrender/src/batch.rs
@@ -617,17 +617,17 @@ impl AlphaBatchBuilder {
         let prim_common_data = &ctx.resources.as_common_data(&prim_instance);
         let prim_rect = LayoutRect::new(
             prim_instance.prim_origin,
             prim_common_data.prim_size,
         );
 
         match prim_instance.kind {
             PrimitiveInstanceKind::Clear { data_handle } => {
-                let prim_data = &ctx.resources.prim_data_store[data_handle];
+                let prim_data = &ctx.resources.prim[data_handle];
                 let prim_cache_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);
 
                 // TODO(gw): We can abstract some of the common code below into
                 //           helper methods, as we port more primitives to make
                 //           use of interning.
 
                 let prim_header = PrimitiveHeader {
                     local_rect: prim_rect,
@@ -662,17 +662,17 @@ impl AlphaBatchBuilder {
                 self.current_batch_list().push_single_instance(
                     batch_key,
                     bounding_rect,
                     z_id,
                     PrimitiveInstanceData::from(instance),
                 );
             }
             PrimitiveInstanceKind::NormalBorder { data_handle, ref cache_handles, .. } => {
-                let prim_data = &ctx.resources.normal_border_data_store[data_handle];
+                let prim_data = &ctx.resources.normal_border[data_handle];
                 let common_data = &prim_data.common;
                 let prim_cache_address = gpu_cache.get_address(&common_data.gpu_cache_handle);
                 let cache_handles = &ctx.scratch.border_cache_handles[*cache_handles];
                 let specified_blend_mode = BlendMode::PremultipliedAlpha;
                 let mut segment_data: SmallVec<[SegmentInstanceData; 8]> = SmallVec::new();
 
                 // Collect the segment instance data from each render
                 // task for each valid edge / corner of the border.
@@ -742,17 +742,17 @@ impl AlphaBatchBuilder {
                 );
             }
             PrimitiveInstanceKind::TextRun { data_handle, run_index, .. } => {
                 let run = &ctx.prim_store.text_runs[run_index];
                 let subpx_dir = run.used_font.get_subpx_dir();
 
                 // The GPU cache data is stored in the template and reused across
                 // frames and display lists.
-                let prim_data = &ctx.resources.text_run_data_store[data_handle];
+                let prim_data = &ctx.resources.text_run[data_handle];
                 let glyph_fetch_buffer = &mut self.glyph_fetch_buffer;
                 let alpha_batch_list = &mut self.batch_lists.last_mut().unwrap().alpha_batch_list;
                 let prim_cache_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);
 
                 let prim_header = PrimitiveHeader {
                     local_rect: prim_rect,
                     local_clip_rect: prim_info.combined_local_clip_rect,
                     task_address,
@@ -849,17 +849,17 @@ impl AlphaBatchBuilder {
                             ));
                         }
                     },
                 );
             }
             PrimitiveInstanceKind::LineDecoration { data_handle, ref cache_handle, .. } => {
                 // The GPU cache data is stored in the template and reused across
                 // frames and display lists.
-                let common_data = &ctx.resources.line_decoration_data_store[data_handle].common;
+                let common_data = &ctx.resources.line_decoration[data_handle].common;
                 let prim_cache_address = gpu_cache.get_address(&common_data.gpu_cache_handle);
 
                 let (batch_kind, textures, prim_user_data, segment_user_data) = match cache_handle {
                     Some(cache_handle) => {
                         let rt_cache_entry = ctx
                             .resource_cache
                             .get_cached_render_task(cache_handle);
                         let cache_item = ctx
@@ -1483,17 +1483,17 @@ impl AlphaBatchBuilder {
                             transforms,
                             root_spatial_node_index,
                             z_generator,
                         );
                     }
                 }
             }
             PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
-                let prim_data = &ctx.resources.image_border_data_store[data_handle];
+                let prim_data = &ctx.resources.image_border[data_handle];
                 let common_data = &prim_data.common;
                 let border_data = &prim_data.kind;
 
                 let cache_item = resolve_image(
                     border_data.request,
                     ctx.resource_cache,
                     gpu_cache,
                     deferred_resolves,
@@ -1552,17 +1552,17 @@ impl AlphaBatchBuilder {
                     transform_kind,
                     render_tasks,
                     z_id,
                     prim_info.clip_task_index,
                     ctx,
                 );
             }
             PrimitiveInstanceKind::Rectangle { data_handle, segment_instance_index, opacity_binding_index, .. } => {
-                let prim_data = &ctx.resources.prim_data_store[data_handle];
+                let prim_data = &ctx.resources.prim[data_handle];
                 let specified_blend_mode = BlendMode::PremultipliedAlpha;
                 let opacity_binding = ctx.prim_store.get_opacity_binding(opacity_binding_index);
 
                 let opacity = PrimitiveOpacity::from_alpha(opacity_binding);
                 let opacity = opacity.combine(prim_data.opacity);
 
                 let non_segmented_blend_mode = if !opacity.is_opaque ||
                     prim_info.clip_task_index != ClipTaskIndex::INVALID ||
@@ -1615,17 +1615,17 @@ impl AlphaBatchBuilder {
                     transform_kind,
                     render_tasks,
                     z_id,
                     prim_info.clip_task_index,
                     ctx,
                 );
             }
             PrimitiveInstanceKind::YuvImage { data_handle, segment_instance_index, .. } => {
-                let yuv_image_data = &ctx.resources.yuv_image_data_store[data_handle].kind;
+                let yuv_image_data = &ctx.resources.yuv_image[data_handle].kind;
                 let mut textures = BatchTextures::no_texture();
                 let mut uv_rect_addresses = [0; 3];
 
                 //yuv channel
                 let channel_count = yuv_image_data.format.get_plane_num();
                 debug_assert!(channel_count <= 3);
                 for channel in 0 .. channel_count {
                     let image_key = yuv_image_data.yuv_key[channel];
@@ -1723,18 +1723,18 @@ impl AlphaBatchBuilder {
                     transform_kind,
                     render_tasks,
                     z_id,
                     prim_info.clip_task_index,
                     ctx,
                 );
             }
             PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
-                let image_data = &ctx.resources.image_data_store[data_handle].kind;
-                let common_data = &ctx.resources.image_data_store[data_handle].common;
+                let image_data = &ctx.resources.image[data_handle].kind;
+                let common_data = &ctx.resources.image[data_handle].common;
                 let image_instance = &ctx.prim_store.images[image_instance_index];
                 let opacity_binding = ctx.prim_store.get_opacity_binding(image_instance.opacity_binding_index);
                 let specified_blend_mode = match image_data.alpha_type {
                     AlphaType::PremultipliedAlpha => BlendMode::PremultipliedAlpha,
                     AlphaType::Alpha => BlendMode::Alpha,
                 };
                 let request = ImageRequest {
                     key: image_data.key,
@@ -1862,17 +1862,17 @@ impl AlphaBatchBuilder {
                                 uv_rect_address,
                                 z_id,
                             );
                         }
                     }
                 }
             }
             PrimitiveInstanceKind::LinearGradient { data_handle, ref visible_tiles_range, .. } => {
-                let prim_data = &ctx.resources.linear_grad_data_store[data_handle];
+                let prim_data = &ctx.resources.linear_grad[data_handle];
                 let specified_blend_mode = BlendMode::PremultipliedAlpha;
 
                 let mut prim_header = PrimitiveHeader {
                     local_rect: prim_rect,
                     local_clip_rect: prim_info.combined_local_clip_rect,
                     task_address,
                     specific_prim_address: GpuCacheAddress::invalid(),
                     clip_task_address,
@@ -1943,17 +1943,17 @@ impl AlphaBatchBuilder {
                         self.current_batch_list(),
                         &prim_header,
                         prim_headers,
                         z_id,
                     );
                 }
             }
             PrimitiveInstanceKind::RadialGradient { data_handle, ref visible_tiles_range, .. } => {
-                let prim_data = &ctx.resources.radial_grad_data_store[data_handle];
+                let prim_data = &ctx.resources.radial_grad[data_handle];
                 let specified_blend_mode = BlendMode::PremultipliedAlpha;
 
                 let mut prim_header = PrimitiveHeader {
                     local_rect: prim_rect,
                     local_clip_rect: prim_info.combined_local_clip_rect,
                     task_address,
                     specific_prim_address: GpuCacheAddress::invalid(),
                     clip_task_address,
@@ -2359,22 +2359,22 @@ impl BrushBatchParameters {
 impl PrimitiveInstance {
     pub fn is_cacheable(
         &self,
         resources: &FrameResources,
         resource_cache: &ResourceCache,
     ) -> bool {
         let image_key = match self.kind {
             PrimitiveInstanceKind::Image { data_handle, .. } => {
-                let image_data = &resources.image_data_store[data_handle].kind;
+                let image_data = &resources.image[data_handle].kind;
                 image_data.key
             }
             PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
                 let yuv_image_data =
-                    &resources.yuv_image_data_store[data_handle].kind;
+                    &resources.yuv_image[data_handle].kind;
                 yuv_image_data.yuv_key[0]
             }
             PrimitiveInstanceKind::Picture { .. } |
             PrimitiveInstanceKind::TextRun { .. } |
             PrimitiveInstanceKind::LineDecoration { .. } |
             PrimitiveInstanceKind::NormalBorder { .. } |
             PrimitiveInstanceKind::ImageBorder { .. } |
             PrimitiveInstanceKind::Rectangle { .. } |
--- a/gfx/wr/webrender/src/display_list_flattener.rs
+++ b/gfx/wr/webrender/src/display_list_flattener.rs
@@ -335,17 +335,17 @@ impl<'a> DisplayListFlattener<'a> {
             true,
             LayoutSize::zero(),
             Picture {
                 composite_mode_key: PictureCompositeKey::Identity,
             },
         );
 
         let pic_data_handle = self.resources
-            .picture_interner
+            .picture
             .intern(&pic_key, || {
                 PrimitiveSceneData {
                     prim_size: LayoutSize::zero(),
                     is_backface_visible: true,
                 }
             }
         );
 
@@ -1024,17 +1024,17 @@ impl<'a> DisplayListFlattener<'a> {
             parent_clip_chain_id
         } else {
             let mut clip_chain_id = parent_clip_chain_id;
 
             for (local_pos, item) in clip_items {
                 // Intern this clip item, and store the handle
                 // in the clip chain node.
                 let handle = self.resources
-                    .clip_interner
+                    .clip
                     .intern(&item, || ());
 
                 clip_chain_id = self.clip_store.add_clip_chain_node(
                     handle,
                     local_pos,
                     spatial_node_index,
                     clip_chain_id,
                 );
@@ -1658,50 +1658,50 @@ impl<'a> DisplayListFlattener<'a> {
         // Intern each clip item in this clip node, and add the interned
         // handle to a clip chain node, parented to form a chain.
         // TODO(gw): We could re-structure this to share some of the
         //           interning and chaining code.
 
         // Build the clip sources from the supplied region.
         let handle = self
             .resources
-            .clip_interner
+            .clip
             .intern(&ClipItemKey::rectangle(clip_region.main.size, ClipMode::Clip), || ());
 
         parent_clip_chain_index = self
             .clip_store
             .add_clip_chain_node(
                 handle,
                 clip_region.main.origin,
                 spatial_node,
                 parent_clip_chain_index,
             );
         clip_count += 1;
 
         if let Some(ref image_mask) = clip_region.image_mask {
             let handle = self
                 .resources
-                .clip_interner
+                .clip
                 .intern(&ClipItemKey::image_mask(image_mask), || ());
 
             parent_clip_chain_index = self
                 .clip_store
                 .add_clip_chain_node(
                     handle,
                     image_mask.rect.origin,
                     spatial_node,
                     parent_clip_chain_index,
                 );
             clip_count += 1;
         }
 
         for region in clip_region.complex_clips {
             let handle = self
                 .resources
-                .clip_interner
+                .clip
                 .intern(&ClipItemKey::rounded_rect(region.rect.size, region.radii, region.mode), || ());
 
             parent_clip_chain_index = self
                 .clip_store
                 .add_clip_chain_node(
                     handle,
                     region.rect.origin,
                     spatial_node,
@@ -1858,17 +1858,17 @@ impl<'a> DisplayListFlattener<'a> {
 
                         let shadow_pic_key = PictureKey::new(
                             true,
                             LayoutSize::zero(),
                             Picture { composite_mode_key },
                         );
 
                         let shadow_prim_data_handle = self.resources
-                            .picture_interner
+                            .picture
                             .intern(&shadow_pic_key, || {
                                 PrimitiveSceneData {
                                     prim_size: LayoutSize::zero(),
                                     is_backface_visible: true,
                                 }
                             }
                         );
 
@@ -2706,17 +2706,17 @@ fn create_prim_instance(
 ) -> PrimitiveInstance {
     let pic_key = PictureKey::new(
         is_backface_visible,
         LayoutSize::zero(),
         Picture { composite_mode_key },
     );
 
     let data_handle = resources
-        .picture_interner
+        .picture
         .intern(&pic_key, || {
             PrimitiveSceneData {
                 prim_size: LayoutSize::zero(),
                 is_backface_visible,
             }
         }
     );
 
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -758,17 +758,17 @@ impl TileCache {
         // at the root of its clip chain (this is enforced by the per-pipeline-root
         // clip node added implicitly during display list flattening). Doing it once
         // here saves doing it for every primitive during update_prim_dependencies.
         let root_clip_chain_node = &frame_state
             .clip_store
             .clip_chain_nodes[self.root_clip_chain_id.0 as usize];
         let root_clip_node = &frame_state
             .resources
-            .clip_data_store[root_clip_chain_node.handle];
+            .clip[root_clip_chain_node.handle];
         if let Some(clip_rect) = root_clip_node.item.get_local_clip_rect(root_clip_chain_node.local_pos) {
             self.map_local_to_world.set_target_spatial_node(
                 root_clip_chain_node.spatial_node_index,
                 frame_context.clip_scroll_tree,
             );
 
             if let Some(world_clip_rect) = self.map_local_to_world.map(&clip_rect) {
                 self.root_clip_rect = world_clip_rect;
@@ -908,32 +908,32 @@ impl TileCache {
                     for binding in &opacity_binding.bindings {
                         opacity_bindings.push(OpacityBinding::from(*binding));
                     }
                 }
 
                 true
             }
             PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
-                let image_data = &resources.image_data_store[data_handle].kind;
+                let image_data = &resources.image[data_handle].kind;
                 let image_instance = &image_instances[image_instance_index];
                 let opacity_binding_index = image_instance.opacity_binding_index;
 
                 if opacity_binding_index != OpacityBindingIndex::INVALID {
                     let opacity_binding = &opacity_binding_store[opacity_binding_index];
                     for binding in &opacity_binding.bindings {
                         opacity_bindings.push(OpacityBinding::from(*binding));
                     }
                 }
 
                 image_keys.push(image_data.key);
                 true
             }
             PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
-                let yuv_image_data = &resources.yuv_image_data_store[data_handle].kind;
+                let yuv_image_data = &resources.yuv_image[data_handle].kind;
                 image_keys.extend_from_slice(&yuv_image_data.yuv_key);
                 true
             }
             PrimitiveInstanceKind::TextRun { .. } |
             PrimitiveInstanceKind::LineDecoration { .. } |
             PrimitiveInstanceKind::Clear { .. } |
             PrimitiveInstanceKind::NormalBorder { .. } |
             PrimitiveInstanceKind::LinearGradient { .. } |
@@ -949,17 +949,17 @@ impl TileCache {
         let mut world_clip_rect = world_rect;
         let mut culling_rect = prim_rect
             .intersection(&prim_instance.local_clip_rect)
             .unwrap_or(LayoutRect::zero());
 
         let mut current_clip_chain_id = prim_instance.clip_chain_id;
         while current_clip_chain_id != ClipChainId::NONE {
             let clip_chain_node = &clip_chain_nodes[current_clip_chain_id.0 as usize];
-            let clip_node = &resources.clip_data_store[clip_chain_node.handle];
+            let clip_node = &resources.clip[clip_chain_node.handle];
 
             // We can skip the root clip node - it will be taken care of by the
             // world bounding rect calculated for the cache.
             if current_clip_chain_id == self.root_clip_chain_id {
                 current_clip_chain_id = clip_chain_node.parent_clip_chain_id;
                 continue;
             }
 
@@ -1653,44 +1653,44 @@ impl PrimitiveList {
                 _ => {
                     false
                 }
             };
 
             let prim_data = match prim_instance.kind {
                 PrimitiveInstanceKind::Rectangle { data_handle, .. } |
                 PrimitiveInstanceKind::Clear { data_handle, .. } => {
-                    &resources.prim_interner[data_handle]
+                    &resources.prim[data_handle]
                 }
                 PrimitiveInstanceKind::Image { data_handle, .. } => {
-                    &resources.image_interner[data_handle]
+                    &resources.image[data_handle]
                 }
                 PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
-                    &resources.image_border_interner[data_handle]
+                    &resources.image_border[data_handle]
                 }
                 PrimitiveInstanceKind::LineDecoration { data_handle, .. } => {
-                    &resources.line_decoration_interner[data_handle]
+                    &resources.line_decoration[data_handle]
                 }
                 PrimitiveInstanceKind::LinearGradient { data_handle, .. } => {
-                    &resources.linear_grad_interner[data_handle]
+                    &resources.linear_grad[data_handle]
                 }
                 PrimitiveInstanceKind::NormalBorder { data_handle, .. } => {
-                    &resources.normal_border_interner[data_handle]
+                    &resources.normal_border[data_handle]
                 }
                 PrimitiveInstanceKind::Picture { data_handle, .. } => {
-                    &resources.picture_interner[data_handle]
+                    &resources.picture[data_handle]
                 }
                 PrimitiveInstanceKind::RadialGradient { data_handle, ..} => {
-                    &resources.radial_grad_interner[data_handle]
+                    &resources.radial_grad[data_handle]
                 }
                 PrimitiveInstanceKind::TextRun { data_handle, .. } => {
-                    &resources.text_run_interner[data_handle]
+                    &resources.text_run[data_handle]
                 }
                 PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
-                    &resources.yuv_image_interner[data_handle]
+                    &resources.yuv_image[data_handle]
                 }
             };
 
             // Get the key for the cluster that this primitive should
             // belong to.
             let key = PrimitiveClusterKey {
                 spatial_node_index: prim_instance.spatial_node_index,
                 is_backface_visible: prim_data.is_backface_visible,
--- a/gfx/wr/webrender/src/prim_store/mod.rs
+++ b/gfx/wr/webrender/src/prim_store/mod.rs
@@ -1929,17 +1929,17 @@ impl PrimitiveStore {
                         &map_local_to_surface,
                         &map_surface_to_world,
                         &frame_context.clip_scroll_tree,
                         frame_state.gpu_cache,
                         frame_state.resource_cache,
                         frame_context.device_pixel_scale,
                         &frame_context.screen_world_rect,
                         clip_node_collector.as_ref(),
-                        &mut frame_state.resources.clip_data_store,
+                        &mut frame_state.resources.clip,
                     );
 
                 if let Some(ref mut tile_cache) = frame_state.tile_cache {
                     tile_cache.update_prim_dependencies(
                         prim_instance,
                         frame_context.clip_scroll_tree,
                         frame_state.resources,
                         &frame_state.clip_store.clip_chain_nodes,
@@ -2434,17 +2434,17 @@ impl PrimitiveStore {
         frame_state: &mut FrameBuildingState,
         resources: &mut FrameResources,
         scratch: &mut PrimitiveScratchBuffer,
     ) {
         let is_chased = prim_instance.is_chased();
 
         match &mut prim_instance.kind {
             PrimitiveInstanceKind::LineDecoration { data_handle, ref mut cache_handle, .. } => {
-                let prim_data = &mut resources.line_decoration_data_store[*data_handle];
+                let prim_data = &mut resources.line_decoration[*data_handle];
                 let common_data = &mut prim_data.common;
                 let line_dec_data = &mut prim_data.kind;
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 line_dec_data.update(common_data, frame_state);
 
                 // Work out the device pixel size to be used to cache this line decoration.
@@ -2483,17 +2483,17 @@ impl PrimitiveStore {
                                 LayoutSize::from_au(cache_key.size),
                             );
                             render_tasks.add(task)
                         }
                     ));
                 }
             }
             PrimitiveInstanceKind::TextRun { data_handle, run_index, .. } => {
-                let prim_data = &mut resources.text_run_data_store[*data_handle];
+                let prim_data = &mut resources.text_run[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 prim_data.update(frame_state);
 
                 // The transform only makes sense for screen space rasterization
                 let transform = prim_context.spatial_node.world_content_transform.to_transform();
                 let prim_offset = prim_instance.prim_origin.to_vector() - prim_data.offset;
@@ -2512,24 +2512,24 @@ impl PrimitiveStore {
                     pic_context,
                     frame_state.resource_cache,
                     frame_state.gpu_cache,
                     frame_state.render_tasks,
                     scratch,
                 );
             }
             PrimitiveInstanceKind::Clear { data_handle, .. } => {
-                let prim_data = &mut resources.prim_data_store[*data_handle];
+                let prim_data = &mut resources.prim[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 prim_data.update(frame_state);
             }
             PrimitiveInstanceKind::NormalBorder { data_handle, ref mut cache_handles, .. } => {
-                let prim_data = &mut resources.normal_border_data_store[*data_handle];
+                let prim_data = &mut resources.normal_border[*data_handle];
                 let common_data = &mut prim_data.common;
                 let border_data = &mut prim_data.kind;
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 border_data.update(common_data, frame_state);
 
                 // TODO(gw): When drawing in screen raster mode, we should also incorporate a
@@ -2576,24 +2576,24 @@ impl PrimitiveStore {
                     ));
                 }
 
                 *cache_handles = scratch
                     .border_cache_handles
                     .extend(handles);
             }
             PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
-                let prim_data = &mut resources.image_border_data_store[*data_handle];
+                let prim_data = &mut resources.image_border[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 prim_data.kind.update(&mut prim_data.common, frame_state);
             }
             PrimitiveInstanceKind::Rectangle { data_handle, segment_instance_index, opacity_binding_index, .. } => {
-                let prim_data = &mut resources.prim_data_store[*data_handle];
+                let prim_data = &mut resources.prim[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 prim_data.update(frame_state);
 
                 update_opacity_binding(
                     &mut self.opacity_bindings,
                     *opacity_binding_index,
@@ -2602,28 +2602,28 @@ impl PrimitiveStore {
 
                 write_segment(*segment_instance_index, frame_state, scratch, |request| {
                     prim_data.kind.write_prim_gpu_blocks(
                         request,
                     );
                 });
             }
             PrimitiveInstanceKind::YuvImage { data_handle, segment_instance_index, .. } => {
-                let yuv_image_data = &mut resources.yuv_image_data_store[*data_handle];
+                let yuv_image_data = &mut resources.yuv_image[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 yuv_image_data.kind.update(&mut yuv_image_data.common, frame_state);
 
                 write_segment(*segment_instance_index, frame_state, scratch, |request| {
                     yuv_image_data.kind.write_prim_gpu_blocks(request);
                 });
             }
             PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
-                let prim_data = &mut resources.image_data_store[*data_handle];
+                let prim_data = &mut resources.image[*data_handle];
                 let common_data = &mut prim_data.common;
                 let image_data = &mut prim_data.kind;
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 image_data.update(common_data, frame_state);
 
                 let image_instance = &mut self.images[*image_instance_index];
@@ -2727,17 +2727,17 @@ impl PrimitiveStore {
                     }
                 }
 
                 write_segment(image_instance.segment_instance_index, frame_state, scratch, |request| {
                     image_data.write_prim_gpu_blocks(request);
                 });
             }
             PrimitiveInstanceKind::LinearGradient { data_handle, ref mut visible_tiles_range, .. } => {
-                let prim_data = &mut resources.linear_grad_data_store[*data_handle];
+                let prim_data = &mut resources.linear_grad[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 prim_data.update(frame_state);
 
                 if prim_data.tile_spacing != LayoutSize::zero() {
                     let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
                     let prim_rect = LayoutRect::new(
@@ -2774,17 +2774,17 @@ impl PrimitiveStore {
                         prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
                     }
                 }
 
                 // TODO(gw): Consider whether it's worth doing segment building
                 //           for gradient primitives.
             }
             PrimitiveInstanceKind::RadialGradient { data_handle, ref mut visible_tiles_range, .. } => {
-                let prim_data = &mut resources.radial_grad_data_store[*data_handle];
+                let prim_data = &mut resources.radial_grad[*data_handle];
 
                 // Update the template this instane references, which may refresh the GPU
                 // cache with any shared template data.
                 prim_data.update(frame_state);
 
                 if prim_data.tile_spacing != LayoutSize::zero() {
                     let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
                     let prim_rect = LayoutRect::new(
@@ -2982,17 +2982,17 @@ impl<'a> GpuDataRequest<'a> {
             prim_local_clip_rect
         );
 
         // Segment the primitive on all the local-space clip sources that we can.
         let mut local_clip_count = 0;
         for i in 0 .. clip_chain.clips_range.count {
             let clip_instance = clip_store
                 .get_instance_from_range(&clip_chain.clips_range, i);
-            let clip_node = &resources.clip_data_store[clip_instance.handle];
+            let clip_node = &resources.clip[clip_instance.handle];
 
             // If this clip item is positioned by another positioning node, its relative position
             // could change during scrolling. This means that we would need to resegment. Instead
             // of doing that, only segment with clips that have the same positioning node.
             // TODO(mrobinson, #2858): It may make sense to include these nodes, resegmenting only
             // when necessary while scrolling.
             if !clip_instance.flags.contains(ClipNodeFlags::SAME_SPATIAL_NODE) {
                 continue;
@@ -3103,17 +3103,17 @@ impl PrimitiveInstance {
         );
 
         let segment_instance_index = match self.kind {
             PrimitiveInstanceKind::Rectangle { ref mut segment_instance_index, .. } |
             PrimitiveInstanceKind::YuvImage { ref mut segment_instance_index, .. } => {
                 segment_instance_index
             }
             PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
-                let image_data = &resources.image_data_store[data_handle].kind;
+                let image_data = &resources.image[data_handle].kind;
                 let image_instance = &mut prim_store.images[image_instance_index];
                 // tiled images don't support segmentation
                 if frame_state
                     .resource_cache
                     .get_image_properties(image_data.key)
                     .and_then(|properties| properties.tiling)
                     .is_some() {
                         image_instance.segment_instance_index = SegmentInstanceIndex::UNUSED;
@@ -3216,42 +3216,42 @@ impl PrimitiveInstance {
                     return false;
                 }
 
                 let segment_instance = &segment_instances_store[segment_instance_index];
 
                 &segments_store[segment_instance.segments_range]
             }
             PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
-                let border_data = &resources.image_border_data_store[data_handle].kind;
+                let border_data = &resources.image_border[data_handle].kind;
 
                 // TODO: This is quite messy - once we remove legacy primitives we
                 //       can change this to be a tuple match on (instance, template)
                 border_data.brush_segments.as_slice()
             }
             PrimitiveInstanceKind::NormalBorder { data_handle, .. } => {
-                let border_data = &resources.normal_border_data_store[data_handle].kind;
+                let border_data = &resources.normal_border[data_handle].kind;
 
                 // TODO: This is quite messy - once we remove legacy primitives we
                 //       can change this to be a tuple match on (instance, template)
                 border_data.brush_segments.as_slice()
             }
             PrimitiveInstanceKind::LinearGradient { data_handle, .. } => {
-                let prim_data = &resources.linear_grad_data_store[data_handle];
+                let prim_data = &resources.linear_grad[data_handle];
 
                 // TODO: This is quite messy - once we remove legacy primitives we
                 //       can change this to be a tuple match on (instance, template)
                 if prim_data.brush_segments.is_empty() {
                     return false;
                 }
 
                 prim_data.brush_segments.as_slice()
             }
             PrimitiveInstanceKind::RadialGradient { data_handle, .. } => {
-                let prim_data = &resources.radial_grad_data_store[data_handle];
+                let prim_data = &resources.radial_grad[data_handle];
 
                 // TODO: This is quite messy - once we remove legacy primitives we
                 //       can change this to be a tuple match on (instance, template)
                 if prim_data.brush_segments.is_empty() {
                     return false;
                 }
 
                 prim_data.brush_segments.as_slice()
@@ -3277,17 +3277,17 @@ impl PrimitiveInstance {
             let clip_mask_kind = segments[0].update_clip_task(
                 Some(&prim_info.clip_chain),
                 prim_info.clipped_world_rect,
                 root_spatial_node_index,
                 pic_context.surface_index,
                 pic_state,
                 frame_context,
                 frame_state,
-                &mut resources.clip_data_store,
+                &mut resources.clip,
             );
             clip_mask_instances.push(clip_mask_kind);
         } else {
             for segment in segments {
                 // Build a clip chain for the smaller segment rect. This will
                 // often manage to eliminate most/all clips, and sometimes
                 // clip the segment completely.
                 let segment_clip_chain = frame_state
@@ -3303,28 +3303,28 @@ impl PrimitiveInstance {
                         &pic_state.map_local_to_pic,
                         &pic_state.map_pic_to_world,
                         &frame_context.clip_scroll_tree,
                         frame_state.gpu_cache,
                         frame_state.resource_cache,
                         frame_context.device_pixel_scale,
                         &pic_context.dirty_world_rect,
                         None,
-                        &mut resources.clip_data_store,
+                        &mut resources.clip,
                     );
 
                 let clip_mask_kind = segment.update_clip_task(
                     segment_clip_chain.as_ref(),
                     prim_info.clipped_world_rect,
                     root_spatial_node_index,
                     pic_context.surface_index,
                     pic_state,
                     frame_context,
                     frame_state,
-                    &mut resources.clip_data_store,
+                    &mut resources.clip,
                 );
                 clip_mask_instances.push(clip_mask_kind);
             }
         }
 
         true
     }
 
@@ -3387,17 +3387,17 @@ impl PrimitiveInstance {
                 let clip_task = RenderTask::new_mask(
                     device_rect,
                     prim_info.clip_chain.clips_range,
                     root_spatial_node_index,
                     frame_state.clip_store,
                     frame_state.gpu_cache,
                     frame_state.resource_cache,
                     frame_state.render_tasks,
-                    &mut resources.clip_data_store,
+                    &mut resources.clip,
                 );
 
                 let clip_task_id = frame_state.render_tasks.add(clip_task);
                 if self.is_chased() {
                     println!("\tcreated task {:?} with device rect {:?}",
                         clip_task_id, device_rect);
                 }
                 // Set the global clip mask instance for this primitive.
--- a/gfx/wr/webrender/src/profiler.rs
+++ b/gfx/wr/webrender/src/profiler.rs
@@ -397,25 +397,26 @@ pub struct IpcProfileCounters {
     pub build_time: TimeProfileCounter,
     pub consume_time: TimeProfileCounter,
     pub send_time: TimeProfileCounter,
     pub total_time: TimeProfileCounter,
     pub display_lists: ResourceProfileCounter,
 }
 
 macro_rules! declare_intern_profile_counters {
-    ( $( { $name: ident, $x: ident, $y: ident } )+ ) => {
+    ( $( $name: ident, )+ ) => {
         #[derive(Clone)]
         pub struct InternProfileCounters {
             $(
                 pub $name: ResourceProfileCounter,
             )+
         }
 
         impl InternProfileCounters {
+            #[cfg(feature = "debug_renderer")]
             fn draw(
                 &self,
                 debug_renderer: &mut DebugRenderer,
                 draw_state: &mut DrawState,
             ) {
                 Profiler::draw_counters(
                     &[
                         $(
--- a/gfx/wr/webrender/src/render_backend.rs
+++ b/gfx/wr/webrender/src/render_backend.rs
@@ -204,43 +204,43 @@ impl FrameStamp {
     pub const INVALID: FrameStamp = FrameStamp {
         id: FrameId(0),
         time: UNIX_EPOCH,
         document_id: DocumentId::INVALID,
     };
 }
 
 macro_rules! declare_frame_resources {
-    ( $( { $name: ident, $x: ident, $datastore_ident: ident } )+ ) => {
+    ( $( $name: ident, )+ ) => {
         /// A collection of resources that are shared by clips, primitives
         /// between display lists.
         #[cfg_attr(feature = "capture", derive(Serialize))]
         #[cfg_attr(feature = "replay", derive(Deserialize))]
         #[derive(Default)]
         pub struct FrameResources {
             $(
-                pub $datastore_ident: intern_types::$name::Store,
+                pub $name: intern_types::$name::Store,
             )+
         }
 
         impl FrameResources {
             /// Reports CPU heap usage.
             fn report_memory(&self, ops: &mut MallocSizeOfOps, r: &mut MemoryReport) {
                 $(
-                    r.interning.$datastore_ident += self.$datastore_ident.size_of(ops);
+                    r.interning.data_stores.$name += self.$name.size_of(ops);
                 )+
             }
 
             fn apply_updates(
                 &mut self,
                 updates: DocumentResourceUpdates,
                 profile_counters: &mut BackendProfileCounters,
             ) {
                 $(
-                    self.$datastore_ident.apply_updates(
+                    self.$name.apply_updates(
                         updates.$name,
                         &mut profile_counters.intern.$name,
                     );
                 )+
             }
         }
     }
 }
@@ -250,53 +250,53 @@ enumerate_interners!(declare_frame_resou
 impl FrameResources {
     pub fn as_common_data(
         &self,
         prim_inst: &PrimitiveInstance
     ) -> &PrimTemplateCommonData {
         match prim_inst.kind {
             PrimitiveInstanceKind::Rectangle { data_handle, .. } |
             PrimitiveInstanceKind::Clear { data_handle, .. } => {
-                let prim_data = &self.prim_data_store[data_handle];
+                let prim_data = &self.prim[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::Image { data_handle, .. } => {
-                let prim_data = &self.image_data_store[data_handle];
+                let prim_data = &self.image[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
-                let prim_data = &self.image_border_data_store[data_handle];
+                let prim_data = &self.image_border[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::LineDecoration { data_handle, .. } => {
-                let prim_data = &self.line_decoration_data_store[data_handle];
+                let prim_data = &self.line_decoration[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::LinearGradient { data_handle, .. } => {
-                let prim_data = &self.linear_grad_data_store[data_handle];
+                let prim_data = &self.linear_grad[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::NormalBorder { data_handle, .. } => {
-                let prim_data = &self.normal_border_data_store[data_handle];
+                let prim_data = &self.normal_border[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::Picture { data_handle, .. } => {
-                let prim_data = &self.picture_data_store[data_handle];
+                let prim_data = &self.picture[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::RadialGradient { data_handle, .. } => {
-                let prim_data = &self.radial_grad_data_store[data_handle];
+                let prim_data = &self.radial_grad[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::TextRun { data_handle, .. }  => {
-                let prim_data = &self.text_run_data_store[data_handle];
+                let prim_data = &self.text_run[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
-                let prim_data = &self.yuv_image_data_store[data_handle];
+                let prim_data = &self.yuv_image[data_handle];
                 &prim_data.common
             }
         }
     }
 }
 
 struct Document {
     // The latest built scene, usable to build frames.
@@ -520,17 +520,17 @@ impl Document {
                 &mut resource_profile.gpu_cache,
                 &self.dynamic_properties,
                 &mut self.resources,
                 &mut self.scratch,
                 debug_flags,
             );
             self.hit_tester = Some(frame_builder.create_hit_tester(
                 &self.clip_scroll_tree,
-                &self.resources.clip_data_store,
+                &self.resources.clip,
             ));
             frame
         };
 
         self.frame_is_valid = true;
         self.hit_tester_is_valid = true;
 
         let is_new_scene = self.has_built_scene;
@@ -550,17 +550,17 @@ impl Document {
             self.clip_scroll_tree.update_tree(
                 pan,
                 &self.dynamic_properties,
                 None,
             );
 
             self.hit_tester = Some(frame_builder.create_hit_tester(
                 &self.clip_scroll_tree,
-                &self.resources.clip_data_store,
+                &self.resources.clip,
             ));
             self.hit_tester_is_valid = true;
         }
     }
 
     pub fn updated_pipeline_info(&mut self) -> PipelineInfo {
         let removed_pipelines = replace(&mut self.removed_pipelines, Vec::new());
         PipelineInfo {
--- a/gfx/wr/webrender/src/scene_builder.rs
+++ b/gfx/wr/webrender/src/scene_builder.rs
@@ -165,29 +165,29 @@ pub enum SceneBuilderResult {
 // scene swap was completed. We need a separate channel for this
 // so that they don't get mixed with SceneBuilderRequest messages.
 pub enum SceneSwapResult {
     Complete(Sender<()>),
     Aborted,
 }
 
 macro_rules! declare_document_resources {
-    ( $( { $name: ident, $interner_ident: ident, $y: ident } )+ ) => {
+    ( $( $name: ident, )+ ) => {
         /// This struct contains all items that can be shared between
         /// display lists. We want to intern and share the same clips,
         /// primitives and other things between display lists so that:
         /// - GPU cache handles remain valid, reducing GPU cache updates.
         /// - Comparison of primitives and pictures between two
         ///   display lists is (a) fast (b) done during scene building.
         #[cfg_attr(feature = "capture", derive(Serialize))]
         #[cfg_attr(feature = "replay", derive(Deserialize))]
         #[derive(Default)]
         pub struct DocumentResources {
             $(
-                pub $interner_ident: intern_types::$name::Interner,
+                pub $name: intern_types::$name::Interner,
             )+
         }
 
         pub struct DocumentResourceUpdates {
             $(
                 pub $name: intern_types::$name::UpdateList,
             )+
         }
@@ -195,24 +195,24 @@ macro_rules! declare_document_resources 
         impl DocumentResources {
             /// Reports CPU heap memory used by the interners.
             fn report_memory(
                 &self,
                 ops: &mut MallocSizeOfOps,
                 r: &mut MemoryReport,
             ) {
                 $(
-                    r.interning.$interner_ident += self.$interner_ident.size_of(ops);
+                    r.interning.interners.$name += self.$name.size_of(ops);
                 )+
             }
 
             fn end_frame_and_get_pending_updates(&mut self) -> DocumentResourceUpdates {
                 DocumentResourceUpdates {
                     $(
-                        $name: self.$interner_ident.end_frame_and_get_pending_updates(),
+                        $name: self.$name.end_frame_and_get_pending_updates(),
                     )+
                 }
             }
         }
     }
 }
 
 enumerate_interners!(declare_document_resources);
@@ -233,26 +233,26 @@ macro_rules! impl_interner_mut {
             > {
                 &mut self.$mem
             }
         })*
     }
 }
 
 impl_interner_mut! {
-    Image: image_interner,
-    ImageBorder: image_border_interner,
-    LineDecoration: line_decoration_interner,
-    LinearGradient: linear_grad_interner,
-    NormalBorderPrim: normal_border_interner,
-    Picture: picture_interner,
-    PrimitiveKeyKind: prim_interner,
-    RadialGradient: radial_grad_interner,
-    TextRun: text_run_interner,
-    YuvImage: yuv_image_interner,
+    Image: image,
+    ImageBorder: image_border,
+    LineDecoration: line_decoration,
+    LinearGradient: linear_grad,
+    NormalBorderPrim: normal_border,
+    Picture: picture,
+    PrimitiveKeyKind: prim,
+    RadialGradient: radial_grad,
+    TextRun: text_run,
+    YuvImage: yuv_image,
 }
 
 // A document in the scene builder contains the current scene,
 // as well as a persistent clip interner. This allows clips
 // to be de-duplicated, and persisted in the GPU cache between
 // display lists.
 struct Document {
     scene: Scene,
--- a/gfx/wr/webrender/src/tiling.rs
+++ b/gfx/wr/webrender/src/tiling.rs
@@ -653,17 +653,17 @@ impl RenderTarget for AlphaRenderTarget 
                     task_address,
                     task_info.clip_node_range,
                     task_info.root_spatial_node_index,
                     ctx.resource_cache,
                     gpu_cache,
                     clip_store,
                     ctx.clip_scroll_tree,
                     transforms,
-                    &ctx.resources.clip_data_store,
+                    &ctx.resources.clip,
                 );
             }
             RenderTaskKind::ClipRegion(ref task) => {
                 let task_address = render_tasks.get_task_address(task_id);
                 self.clip_batcher.add_clip_region(
                     task_address,
                     task.clip_data_address,
                     task.local_pos,
--- a/gfx/wr/webrender_api/src/api.rs
+++ b/gfx/wr/webrender_api/src/api.rs
@@ -820,55 +820,69 @@ impl PipelineId {
 /// IMPORTANT: Keep this synchronized with the list in mozilla-central located at
 /// gfx/webrender_bindings/webrender_ffi.h
 ///
 /// Note that this could be a lot less verbose if concat_idents! were stable. :-(
 #[macro_export]
 macro_rules! enumerate_interners {
     ($macro_name: ident) => {
         $macro_name! {
-            { clip, clip_interner, clip_data_store }
-            { prim, prim_interner, prim_data_store }
-            { normal_border, normal_border_interner, normal_border_data_store }
-            { image_border, image_border_interner, image_border_data_store }
-            { image, image_interner, image_data_store }
-            { yuv_image, yuv_image_interner, yuv_image_data_store }
-            { line_decoration, line_decoration_interner, line_decoration_data_store }
-            { linear_grad, linear_grad_interner, linear_grad_data_store }
-            { radial_grad, radial_grad_interner, radial_grad_data_store }
-            { picture, picture_interner, picture_data_store }
-            { text_run, text_run_interner, text_run_data_store }
+            clip,
+            prim,
+            normal_border,
+            image_border,
+            image,
+            yuv_image,
+            line_decoration,
+            linear_grad,
+            radial_grad,
+            picture,
+            text_run,
         }
     }
 }
 
 macro_rules! declare_interning_memory_report {
-    ( $( { $x: ident, $interner_ident: ident, $datastore_ident: ident } )+ ) => {
+    ( $( $name: ident, )+ ) => {
         #[repr(C)]
         #[derive(Clone, Debug, Default, Deserialize, Serialize)]
-        pub struct InterningMemoryReport {
+        pub struct InternerSubReport {
             $(
-                pub $interner_ident: usize,
-                pub $datastore_ident: usize,
+                pub $name: usize,
             )+
         }
 
-        impl ::std::ops::AddAssign for InterningMemoryReport {
-            fn add_assign(&mut self, other: InterningMemoryReport) {
+        impl ::std::ops::AddAssign for InternerSubReport {
+            fn add_assign(&mut self, other: InternerSubReport) {
                 $(
-                    self.$interner_ident += other.$interner_ident;
-                    self.$datastore_ident += other.$datastore_ident;
+                    self.$name += other.$name;
                 )+
             }
         }
     }
 }
 
 enumerate_interners!(declare_interning_memory_report);
 
+/// Memory report for interning-related data structures.
+/// cbindgen:derive-eq=false
+#[repr(C)]
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
+pub struct InterningMemoryReport {
+    pub interners: InternerSubReport,
+    pub data_stores: InternerSubReport,
+}
+
+impl ::std::ops::AddAssign for InterningMemoryReport {
+    fn add_assign(&mut self, other: InterningMemoryReport) {
+        self.interners += other.interners;
+        self.data_stores += other.data_stores;
+    }
+}
+
 /// Collection of heap sizes, in bytes.
 /// cbindgen:derive-eq=false
 #[repr(C)]
 #[derive(Clone, Debug, Default, Deserialize, Serialize)]
 pub struct MemoryReport {
     //
     // CPU Memory.
     //