Skip to main content

ic_memory/slot/
mod.rs

1mod descriptor;
2mod memory_manager;
3mod range_authority;
4
5pub use descriptor::{AllocationSlot, AllocationSlotDescriptor};
6pub use memory_manager::{
7    IC_MEMORY_AUTHORITY_OWNER, IC_MEMORY_AUTHORITY_PURPOSE, IC_MEMORY_LEDGER_LABEL,
8    IC_MEMORY_LEDGER_STABLE_KEY, IC_MEMORY_STABLE_KEY_PREFIX, MEMORY_MANAGER_GOVERNANCE_MAX_ID,
9    MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_LEDGER_ID, MEMORY_MANAGER_MAX_ID,
10    MEMORY_MANAGER_MIN_ID, MemoryManagerSlotError, is_ic_memory_stable_key,
11    memory_manager_governance_range, validate_memory_manager_id,
12};
13pub use range_authority::{
14    MemoryManagerAuthorityRecord, MemoryManagerIdRange, MemoryManagerRangeAuthority,
15    MemoryManagerRangeAuthorityError, MemoryManagerRangeError, MemoryManagerRangeMode,
16};
17
18#[cfg(test)]
19mod tests {
20    use super::*;
21
22    #[test]
23    fn memory_manager_default_constructor_rejects_sentinel() {
24        let err = AllocationSlotDescriptor::memory_manager(MEMORY_MANAGER_INVALID_ID)
25            .expect_err("sentinel must fail");
26
27        assert_eq!(
28            err,
29            MemoryManagerSlotError::InvalidMemoryManagerId {
30                id: MEMORY_MANAGER_INVALID_ID
31            }
32        );
33    }
34
35    #[test]
36    fn memory_manager_usable_domain_is_u8_with_255_sentinel() {
37        assert_eq!(MEMORY_MANAGER_MIN_ID, 0);
38        assert_eq!(MEMORY_MANAGER_MAX_ID, 254);
39        assert_eq!(MEMORY_MANAGER_INVALID_ID, 255);
40        assert_eq!(MEMORY_MANAGER_INVALID_ID, u8::MAX);
41
42        AllocationSlotDescriptor::memory_manager(MEMORY_MANAGER_MAX_ID)
43            .expect("254 is the last usable MemoryManager ID");
44        AllocationSlotDescriptor::memory_manager(MEMORY_MANAGER_INVALID_ID)
45            .expect_err("255 is always the unallocated sentinel");
46    }
47
48    #[test]
49    fn memory_manager_id_validates_sentinel() {
50        let slot = AllocationSlotDescriptor::memory_manager(42).expect("usable slot");
51        assert_eq!(slot.memory_manager_id().expect("usable ID"), 42);
52
53        let err = AllocationSlotDescriptor {
54            slot: AllocationSlot::MemoryManagerId(MEMORY_MANAGER_INVALID_ID),
55        }
56        .memory_manager_id()
57        .expect_err("sentinel should fail");
58        assert_eq!(
59            err,
60            MemoryManagerSlotError::InvalidMemoryManagerId {
61                id: MEMORY_MANAGER_INVALID_ID
62            }
63        );
64    }
65
66    #[test]
67    fn memory_manager_range_accepts_usable_ranges() {
68        let range = MemoryManagerIdRange::new(MEMORY_MANAGER_MIN_ID, MEMORY_MANAGER_MAX_ID)
69            .expect("usable full range");
70
71        assert!(range.contains(MEMORY_MANAGER_MIN_ID));
72        assert!(range.contains(MEMORY_MANAGER_MAX_ID));
73        assert!(!range.contains(MEMORY_MANAGER_INVALID_ID));
74    }
75
76    #[test]
77    fn memory_manager_range_all_usable_matches_usable_bounds() {
78        assert_eq!(
79            MemoryManagerIdRange::all_usable(),
80            MemoryManagerIdRange::new(MEMORY_MANAGER_MIN_ID, MEMORY_MANAGER_MAX_ID)
81                .expect("usable full range")
82        );
83    }
84
85    #[test]
86    fn memory_manager_governance_range_is_owned_by_ic_memory() {
87        let range = memory_manager_governance_range();
88
89        assert_eq!(range.start(), MEMORY_MANAGER_MIN_ID);
90        assert_eq!(MEMORY_MANAGER_LEDGER_ID, range.start());
91        assert!(range.contains(MEMORY_MANAGER_LEDGER_ID));
92        assert!(is_ic_memory_stable_key(IC_MEMORY_LEDGER_STABLE_KEY));
93        assert_eq!(IC_MEMORY_AUTHORITY_OWNER, "ic-memory");
94    }
95
96    #[test]
97    fn memory_manager_range_rejects_reversed_bounds() {
98        let err = MemoryManagerIdRange::new(10, 9).expect_err("reversed range");
99
100        assert_eq!(
101            err,
102            MemoryManagerRangeError::InvalidRange { start: 10, end: 9 }
103        );
104    }
105
106    #[test]
107    fn memory_manager_range_rejects_sentinel_bounds() {
108        let err =
109            MemoryManagerIdRange::new(240, MEMORY_MANAGER_INVALID_ID).expect_err("sentinel range");
110
111        assert_eq!(
112            err,
113            MemoryManagerRangeError::InvalidMemoryManagerId {
114                id: MEMORY_MANAGER_INVALID_ID
115            }
116        );
117    }
118
119    #[test]
120    fn memory_manager_range_authority_accepts_non_overlapping_construction() {
121        let authority = MemoryManagerRangeAuthority::new()
122            .reserve(memory_manager_governance_range(), IC_MEMORY_AUTHORITY_OWNER)
123            .expect("ic-memory range")
124            .reserve_ids(10, 99, "framework")
125            .expect("framework range")
126            .allow_ids(100, MEMORY_MANAGER_MAX_ID, "applications")
127            .expect("app range");
128
129        assert_eq!(authority.authorities().len(), 3);
130        assert_eq!(
131            authority.authorities()[0].range,
132            memory_manager_governance_range()
133        );
134        assert_eq!(
135            authority.authorities()[0].mode,
136            MemoryManagerRangeMode::Reserved
137        );
138        assert_eq!(authority.authorities()[1].range.start(), 10);
139        assert_eq!(authority.authorities()[2].range.start(), 100);
140    }
141
142    #[test]
143    fn memory_manager_range_authority_id_bound_builders_reject_invalid_ranges() {
144        let err = MemoryManagerRangeAuthority::new()
145            .allow_ids(100, MEMORY_MANAGER_INVALID_ID, "applications")
146            .expect_err("sentinel must fail");
147
148        assert_eq!(
149            err,
150            MemoryManagerRangeAuthorityError::Range(
151                MemoryManagerRangeError::InvalidMemoryManagerId {
152                    id: MEMORY_MANAGER_INVALID_ID
153                }
154            )
155        );
156    }
157
158    #[test]
159    fn memory_manager_range_authority_from_records_rejects_decoded_reversed_range() {
160        let err = MemoryManagerRangeAuthority::from_records(vec![MemoryManagerAuthorityRecord {
161            range: MemoryManagerIdRange {
162                start: 100,
163                end: 99,
164            },
165            authority: "applications".to_string(),
166            mode: MemoryManagerRangeMode::Allowed,
167            purpose: None,
168        }])
169        .expect_err("decoded reversed range must fail");
170
171        assert_eq!(
172            err,
173            MemoryManagerRangeAuthorityError::Range(MemoryManagerRangeError::InvalidRange {
174                start: 100,
175                end: 99,
176            })
177        );
178    }
179
180    #[test]
181    fn memory_manager_range_authority_from_records_rejects_decoded_sentinel_range() {
182        let err = MemoryManagerRangeAuthority::from_records(vec![MemoryManagerAuthorityRecord {
183            range: MemoryManagerIdRange {
184                start: 100,
185                end: MEMORY_MANAGER_INVALID_ID,
186            },
187            authority: "applications".to_string(),
188            mode: MemoryManagerRangeMode::Allowed,
189            purpose: None,
190        }])
191        .expect_err("decoded sentinel range must fail");
192
193        assert_eq!(
194            err,
195            MemoryManagerRangeAuthorityError::Range(
196                MemoryManagerRangeError::InvalidMemoryManagerId {
197                    id: MEMORY_MANAGER_INVALID_ID,
198                }
199            )
200        );
201    }
202
203    #[test]
204    fn memory_manager_range_authority_rejects_overlap() {
205        let err = MemoryManagerRangeAuthority::new()
206            .reserve(
207                MemoryManagerIdRange::new(10, 99).expect("framework range"),
208                "framework",
209            )
210            .expect("framework range")
211            .allow(
212                MemoryManagerIdRange::new(99, 120).expect("overlapping app range"),
213                "applications",
214            )
215            .expect_err("overlap must fail");
216
217        assert_eq!(
218            err,
219            MemoryManagerRangeAuthorityError::OverlappingRanges {
220                existing_start: 10,
221                existing_end: 99,
222                candidate_start: 99,
223                candidate_end: 120,
224            }
225        );
226    }
227
228    #[test]
229    fn memory_manager_range_authority_rejects_invalid_diagnostic_strings() {
230        let err = MemoryManagerRangeAuthority::new()
231            .reserve(
232                MemoryManagerIdRange::new(10, 99).expect("framework range"),
233                "",
234            )
235            .expect_err("empty authority must fail");
236        assert_eq!(
237            err,
238            MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
239                field: "authority",
240                reason: "must not be empty",
241            }
242        );
243
244        let err = MemoryManagerRangeAuthority::new()
245            .allow_with_purpose(
246                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
247                "applications",
248                Some("bad\npurpose".to_string()),
249            )
250            .expect_err("control character purpose must fail");
251        assert_eq!(
252            err,
253            MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
254                field: "purpose",
255                reason: "must not contain ASCII control characters",
256            }
257        );
258    }
259
260    #[test]
261    fn memory_manager_range_authority_rejects_sentinel_lookup() {
262        let err = MemoryManagerRangeAuthority::new()
263            .authority_for_id(MEMORY_MANAGER_INVALID_ID)
264            .expect_err("sentinel lookup must fail");
265
266        assert_eq!(
267            err,
268            MemoryManagerRangeAuthorityError::Slot(
269                MemoryManagerSlotError::InvalidMemoryManagerId {
270                    id: MEMORY_MANAGER_INVALID_ID
271                }
272            )
273        );
274    }
275
276    #[test]
277    fn memory_manager_range_authority_finds_authority_for_id() {
278        let authority = MemoryManagerRangeAuthority::new()
279            .allow(
280                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
281                "applications",
282            )
283            .expect("app range")
284            .reserve(memory_manager_governance_range(), IC_MEMORY_AUTHORITY_OWNER)
285            .expect("ic-memory range");
286
287        let record = authority
288            .authority_for_id(100)
289            .expect("valid ID")
290            .expect("authority record");
291        assert_eq!(record.authority, "applications");
292        assert_eq!(record.mode, MemoryManagerRangeMode::Allowed);
293
294        assert!(
295            authority
296                .authority_for_id(99)
297                .expect("valid unclaimed ID")
298                .is_none()
299        );
300    }
301
302    #[test]
303    fn memory_manager_range_authority_validates_slot_authority() {
304        let authority = MemoryManagerRangeAuthority::new()
305            .reserve(
306                MemoryManagerIdRange::new(10, 99).expect("framework range"),
307                "framework",
308            )
309            .expect("framework range")
310            .allow(
311                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
312                "applications",
313            )
314            .expect("app range");
315
316        let record = authority
317            .validate_slot_authority(
318                &AllocationSlotDescriptor::memory_manager(42).expect("framework slot"),
319                "framework",
320            )
321            .expect("framework authority");
322        assert_eq!(record.mode, MemoryManagerRangeMode::Reserved);
323
324        let err = authority
325            .validate_slot_authority(
326                &AllocationSlotDescriptor::memory_manager(42).expect("framework slot"),
327                "applications",
328            )
329            .expect_err("wrong authority must fail");
330        assert_eq!(
331            err,
332            MemoryManagerRangeAuthorityError::AuthorityMismatch {
333                id: 42,
334                expected_authority: "applications".to_string(),
335                actual_authority: "framework".to_string(),
336            }
337        );
338    }
339
340    #[test]
341    fn memory_manager_range_authority_validates_slot_authority_mode() {
342        let authority = MemoryManagerRangeAuthority::new()
343            .reserve(
344                MemoryManagerIdRange::new(10, 99).expect("framework range"),
345                "framework",
346            )
347            .expect("framework range")
348            .allow(
349                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
350                "applications",
351            )
352            .expect("app range");
353
354        let record = authority
355            .validate_slot_authority_mode(
356                &AllocationSlotDescriptor::memory_manager(42).expect("framework slot"),
357                "framework",
358                MemoryManagerRangeMode::Reserved,
359            )
360            .expect("framework reserved authority");
361        assert_eq!(record.authority, "framework");
362
363        let err = authority
364            .validate_slot_authority_mode(
365                &AllocationSlotDescriptor::memory_manager(42).expect("framework slot"),
366                "framework",
367                MemoryManagerRangeMode::Allowed,
368            )
369            .expect_err("wrong mode must fail");
370        assert_eq!(
371            err,
372            MemoryManagerRangeAuthorityError::ModeMismatch {
373                id: 42,
374                authority: "framework".to_string(),
375                expected_mode: MemoryManagerRangeMode::Allowed,
376                actual_mode: MemoryManagerRangeMode::Reserved,
377            }
378        );
379    }
380
381    #[test]
382    fn memory_manager_range_authority_validates_id_authority() {
383        let authority = MemoryManagerRangeAuthority::new()
384            .reserve(
385                MemoryManagerIdRange::new(10, 99).expect("framework range"),
386                "framework",
387            )
388            .expect("framework range")
389            .allow(
390                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
391                "applications",
392            )
393            .expect("app range");
394
395        assert_eq!(
396            authority
397                .validate_id_authority(100, "applications")
398                .expect("application authority")
399                .mode,
400            MemoryManagerRangeMode::Allowed
401        );
402        assert_eq!(
403            authority
404                .validate_id_authority_mode(42, "framework", MemoryManagerRangeMode::Reserved)
405                .expect("framework reserved authority")
406                .range,
407            MemoryManagerIdRange::new(10, 99).expect("framework range")
408        );
409
410        let err = authority
411            .validate_id_authority_mode(100, "applications", MemoryManagerRangeMode::Reserved)
412            .expect_err("wrong mode must fail");
413        assert_eq!(
414            err,
415            MemoryManagerRangeAuthorityError::ModeMismatch {
416                id: 100,
417                authority: "applications".to_string(),
418                expected_mode: MemoryManagerRangeMode::Reserved,
419                actual_mode: MemoryManagerRangeMode::Allowed,
420            }
421        );
422    }
423
424    #[test]
425    fn memory_manager_range_authority_reports_authority_mismatch_before_mode_mismatch() {
426        let authority = MemoryManagerRangeAuthority::new()
427            .allow(
428                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
429                "applications",
430            )
431            .expect("app range");
432
433        let err = authority
434            .validate_id_authority_mode(100, "framework", MemoryManagerRangeMode::Reserved)
435            .expect_err("authority mismatch must be distinct");
436        assert_eq!(
437            err,
438            MemoryManagerRangeAuthorityError::AuthorityMismatch {
439                id: 100,
440                expected_authority: "framework".to_string(),
441                actual_authority: "applications".to_string(),
442            }
443        );
444    }
445
446    #[test]
447    fn memory_manager_range_authority_preserves_reserve_and_allow_modes() {
448        let authority = MemoryManagerRangeAuthority::new()
449            .reserve(
450                MemoryManagerIdRange::new(10, 99).expect("framework range"),
451                "framework",
452            )
453            .expect("framework range")
454            .allow(
455                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
456                "applications",
457            )
458            .expect("app range");
459
460        assert_eq!(
461            authority.authorities()[0].mode,
462            MemoryManagerRangeMode::Reserved
463        );
464        assert_eq!(
465            authority.authorities()[1].mode,
466            MemoryManagerRangeMode::Allowed
467        );
468    }
469
470    #[test]
471    fn memory_manager_range_authority_validates_complete_coverage() {
472        let authority = MemoryManagerRangeAuthority::new()
473            .reserve(memory_manager_governance_range(), IC_MEMORY_AUTHORITY_OWNER)
474            .expect("ic-memory range")
475            .reserve(
476                MemoryManagerIdRange::new(10, 99).expect("framework range"),
477                "framework",
478            )
479            .expect("framework range")
480            .allow(
481                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
482                "applications",
483            )
484            .expect("app range");
485
486        authority
487            .validate_complete_coverage(
488                MemoryManagerIdRange::new(MEMORY_MANAGER_MIN_ID, MEMORY_MANAGER_MAX_ID)
489                    .expect("full range"),
490            )
491            .expect("complete coverage");
492    }
493
494    #[test]
495    fn memory_manager_range_authority_rejects_complete_coverage_gaps() {
496        let authority = MemoryManagerRangeAuthority::new()
497            .reserve(memory_manager_governance_range(), IC_MEMORY_AUTHORITY_OWNER)
498            .expect("ic-memory range")
499            .allow(
500                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
501                "applications",
502            )
503            .expect("app range");
504
505        let err = authority
506            .validate_complete_coverage(
507                MemoryManagerIdRange::new(MEMORY_MANAGER_MIN_ID, MEMORY_MANAGER_MAX_ID)
508                    .expect("full range"),
509            )
510            .expect_err("coverage gap must fail");
511        assert_eq!(
512            err,
513            MemoryManagerRangeAuthorityError::MissingCoverage { start: 10, end: 99 }
514        );
515
516        let err = MemoryManagerRangeAuthority::new()
517            .validate_complete_coverage(
518                MemoryManagerIdRange::new(MEMORY_MANAGER_MIN_ID, MEMORY_MANAGER_MAX_ID)
519                    .expect("full range"),
520            )
521            .expect_err("empty coverage must fail");
522        assert_eq!(
523            err,
524            MemoryManagerRangeAuthorityError::MissingCoverage {
525                start: MEMORY_MANAGER_MIN_ID,
526                end: MEMORY_MANAGER_MAX_ID,
527            }
528        );
529    }
530
531    #[test]
532    fn memory_manager_range_authority_rejects_complete_coverage_outside_target() {
533        let authority = MemoryManagerRangeAuthority::new()
534            .reserve(memory_manager_governance_range(), IC_MEMORY_AUTHORITY_OWNER)
535            .expect("ic-memory range")
536            .reserve(
537                MemoryManagerIdRange::new(10, 99).expect("framework range"),
538                "framework",
539            )
540            .expect("framework range");
541
542        let err = authority
543            .validate_complete_coverage(MemoryManagerIdRange::new(10, 99).expect("target range"))
544            .expect_err("outside range must fail");
545        assert_eq!(
546            err,
547            MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
548                start: MEMORY_MANAGER_MIN_ID,
549                end: MEMORY_MANAGER_GOVERNANCE_MAX_ID,
550                target_start: 10,
551                target_end: 99,
552            }
553        );
554    }
555
556    #[test]
557    fn memory_manager_range_authority_from_records_sorts_and_validates() {
558        let err = MemoryManagerRangeAuthority::from_records(vec![MemoryManagerAuthorityRecord {
559            range: MemoryManagerIdRange::new(10, 99).expect("framework range"),
560            authority: String::new(),
561            mode: MemoryManagerRangeMode::Reserved,
562            purpose: None,
563        }])
564        .expect_err("empty authority must fail");
565        assert_eq!(
566            err,
567            MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
568                field: "authority",
569                reason: "must not be empty",
570            }
571        );
572
573        let authority = MemoryManagerRangeAuthority::from_records(vec![
574            MemoryManagerAuthorityRecord {
575                range: MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
576                authority: "applications".to_string(),
577                mode: MemoryManagerRangeMode::Allowed,
578                purpose: Some("application stable stores".to_string()),
579            },
580            MemoryManagerAuthorityRecord {
581                range: memory_manager_governance_range(),
582                authority: IC_MEMORY_AUTHORITY_OWNER.to_string(),
583                mode: MemoryManagerRangeMode::Reserved,
584                purpose: Some(IC_MEMORY_AUTHORITY_PURPOSE.to_string()),
585            },
586        ])
587        .expect("records");
588
589        assert_eq!(
590            authority.authorities()[0].authority,
591            IC_MEMORY_AUTHORITY_OWNER
592        );
593        assert_eq!(authority.authorities()[1].authority, "applications");
594    }
595
596    #[test]
597    fn memory_manager_authority_record_constructor_validates_metadata() {
598        let record = MemoryManagerAuthorityRecord::new(
599            MemoryManagerIdRange::new(10, 99).expect("framework range"),
600            "framework",
601            MemoryManagerRangeMode::Reserved,
602            Some("framework-owned stores".to_string()),
603        )
604        .expect("authority record");
605
606        assert_eq!(record.authority, "framework");
607        assert_eq!(record.purpose.as_deref(), Some("framework-owned stores"));
608
609        let err = MemoryManagerAuthorityRecord::new(
610            MemoryManagerIdRange::new(10, 99).expect("framework range"),
611            "",
612            MemoryManagerRangeMode::Reserved,
613            None,
614        )
615        .expect_err("empty authority must fail");
616
617        assert_eq!(
618            err,
619            MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
620                field: "authority",
621                reason: "must not be empty",
622            }
623        );
624    }
625
626    #[test]
627    fn memory_manager_range_authority_from_records_rejects_overlap() {
628        let err = MemoryManagerRangeAuthority::from_records(vec![
629            MemoryManagerAuthorityRecord {
630                range: MemoryManagerIdRange::new(10, 99).expect("framework range"),
631                authority: "framework".to_string(),
632                mode: MemoryManagerRangeMode::Reserved,
633                purpose: None,
634            },
635            MemoryManagerAuthorityRecord {
636                range: MemoryManagerIdRange::new(90, 120).expect("overlap range"),
637                authority: "applications".to_string(),
638                mode: MemoryManagerRangeMode::Allowed,
639                purpose: None,
640            },
641        ])
642        .expect_err("overlap must fail");
643
644        assert_eq!(
645            err,
646            MemoryManagerRangeAuthorityError::OverlappingRanges {
647                existing_start: 10,
648                existing_end: 99,
649                candidate_start: 90,
650                candidate_end: 120,
651            }
652        );
653    }
654
655    #[test]
656    fn memory_manager_range_authority_diagnostic_export_is_stable() {
657        let authority = MemoryManagerRangeAuthority::new()
658            .allow_with_purpose(
659                MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID).expect("app range"),
660                "applications",
661                Some("application stable stores".to_string()),
662            )
663            .expect("app range")
664            .reserve_with_purpose(
665                memory_manager_governance_range(),
666                IC_MEMORY_AUTHORITY_OWNER,
667                Some(IC_MEMORY_AUTHORITY_PURPOSE.to_string()),
668            )
669            .expect("ic-memory range");
670
671        assert_eq!(
672            authority.authorities(),
673            vec![
674                MemoryManagerAuthorityRecord {
675                    range: memory_manager_governance_range(),
676                    authority: IC_MEMORY_AUTHORITY_OWNER.to_string(),
677                    mode: MemoryManagerRangeMode::Reserved,
678                    purpose: Some(IC_MEMORY_AUTHORITY_PURPOSE.to_string()),
679                },
680                MemoryManagerAuthorityRecord {
681                    range: MemoryManagerIdRange::new(100, MEMORY_MANAGER_MAX_ID)
682                        .expect("app range"),
683                    authority: "applications".to_string(),
684                    mode: MemoryManagerRangeMode::Allowed,
685                    purpose: Some("application stable stores".to_string()),
686                },
687            ]
688            .as_slice()
689        );
690    }
691}