mirror of
https://github.com/pezkuwichain/pezkuwi-fellows.git
synced 2026-04-29 02:08:02 +00:00
344 lines
26 KiB
HTML
344 lines
26 KiB
HTML
|
||
<!DOCTYPE HTML>
|
||
<html lang="en" class="polkadot" dir="ltr">
|
||
<head>
|
||
<!-- Book generated using mdBook -->
|
||
<meta charset="UTF-8">
|
||
<title>RFC-0061: Support allocator inside of runtime - Polkadot Fellowship RFCs</title>
|
||
|
||
|
||
<!-- Custom HTML head -->
|
||
|
||
<meta name="description" content="An online book of RFCs approved or proposed within the Polkadot Fellowship.">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="theme-color" content="#ffffff">
|
||
|
||
<link rel="icon" href="../favicon.svg">
|
||
<link rel="shortcut icon" href="../favicon.png">
|
||
<link rel="stylesheet" href="../css/variables.css">
|
||
<link rel="stylesheet" href="../css/general.css">
|
||
<link rel="stylesheet" href="../css/chrome.css">
|
||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||
|
||
<!-- Fonts -->
|
||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||
|
||
<!-- Highlight.js Stylesheets -->
|
||
<link rel="stylesheet" href="../highlight.css">
|
||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||
|
||
<!-- Custom theme stylesheets -->
|
||
<link rel="stylesheet" href="../theme/polkadot.css">
|
||
|
||
</head>
|
||
<body class="sidebar-visible no-js">
|
||
<div id="body-container">
|
||
<!-- Provide site root to javascript -->
|
||
<script>
|
||
var path_to_root = "../";
|
||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "polkadot" : "polkadot";
|
||
</script>
|
||
|
||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
<script>
|
||
try {
|
||
var theme = localStorage.getItem('mdbook-theme');
|
||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
}
|
||
|
||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
}
|
||
} catch (e) { }
|
||
</script>
|
||
|
||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
<script>
|
||
var theme;
|
||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
var html = document.querySelector('html');
|
||
html.classList.remove('polkadot')
|
||
html.classList.add(theme);
|
||
var body = document.querySelector('body');
|
||
body.classList.remove('no-js')
|
||
body.classList.add('js');
|
||
</script>
|
||
|
||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||
|
||
<!-- Hide / unhide sidebar before it is displayed -->
|
||
<script>
|
||
var body = document.querySelector('body');
|
||
var sidebar = null;
|
||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||
if (document.body.clientWidth >= 1080) {
|
||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
sidebar = sidebar || 'visible';
|
||
} else {
|
||
sidebar = 'hidden';
|
||
}
|
||
sidebar_toggle.checked = sidebar === 'visible';
|
||
body.classList.remove('sidebar-visible');
|
||
body.classList.add("sidebar-" + sidebar);
|
||
</script>
|
||
|
||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
<div class="sidebar-scrollbox">
|
||
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Approved</li><li class="chapter-item expanded "><a href="../approved/0001-agile-coretime.html">RFC-1: Agile Coretime</a></li><li class="chapter-item expanded "><a href="../approved/0005-coretime-interface.html">RFC-5: Coretime Interface</a></li><li class="chapter-item expanded "><a href="../approved/0007-system-collator-selection.html">RFC-0007: System Collator Selection</a></li><li class="chapter-item expanded "><a href="../approved/0008-parachain-bootnodes-dht.html">RFC-0008: Store parachain bootnodes in relay chain DHT</a></li><li class="chapter-item expanded "><a href="../approved/0012-process-for-adding-new-collectives.html">RFC-0012: Process for Adding New System Collectives</a></li><li class="chapter-item expanded "><a href="../approved/0014-improve-locking-mechanism-for-parachains.html">RFC-0014: Improve locking mechanism for parachains</a></li><li class="chapter-item expanded "><a href="../approved/0022-adopt-encointer-runtime.html">RFC-0022: Adopt Encointer Runtime</a></li><li class="chapter-item expanded "><a href="../approved/0032-minimal-relay.html">RFC-0032: Minimal Relay</a></li><li class="chapter-item expanded "><a href="../approved/0050-fellowship-salaries.html">RFC-0050: Fellowship Salaries</a></li><li class="chapter-item expanded "><a href="../approved/0056-one-transaction-per-notification.html">RFC-0056: Enforce only one transaction per notification</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Newly Proposed</li><li class="chapter-item expanded "><a href="../new/0066-add-smartcontracts-to-assethub.html">RFC-0066: Add EVM+ink! Contracts Pallets to Asset Hub for Polkadot</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Proposed</li><li class="chapter-item expanded "><a href="../proposed/000x-lowering-deposits-assethub.html">RFC-0000: Lowering NFT Deposits on Polkadot and Kusama Asset Hubs</a></li><li class="chapter-item expanded "><a href="../proposed/0026-sassafras-consensus.html">RFC-0026: Sassafras Consensus Protocol</a></li><li class="chapter-item expanded "><a href="../proposed/0034-xcm-absolute-location-account-derivation.html">RFC-34: XCM Absolute Location Account Derivation</a></li><li class="chapter-item expanded "><a href="../proposed/0042-extrinsics-state-version.html">RFC-0042: Add System version that replaces StateVersion on RuntimeVersion</a></li><li class="chapter-item expanded "><a href="../proposed/0044-rent-based-registration.html">RFC-0044: Rent based registration model</a></li><li class="chapter-item expanded "><a href="../proposed/0046-metadata-for-offline-signers.html">RFC-0000: Metadata for offline signers</a></li><li class="chapter-item expanded "><a href="../proposed/0047-assignment-of-availability-chunks.html">RFC-0047: Assignment of availability chunks to validators</a></li><li class="chapter-item expanded "><a href="../proposed/0061-allocator-inside-of-runtime.html" class="active">RFC-0061: Support allocator inside of runtime</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Stale</li><li class="chapter-item expanded "><a href="../stale/0004-remove-unnecessary-allocator-usage.html">RFC-0004: Remove the host-side runtime memory allocator</a></li><li class="chapter-item expanded "><a href="../stale/0006-dynamic-pricing-for-bulk-coretime-sales.html">RFC-0006: Dynamic Pricing for Bulk Coretime Sales</a></li><li class="chapter-item expanded "><a href="../stale/0009-improved-net-light-client-requests.html">RFC-0009: Improved light client requests networking protocol</a></li><li class="chapter-item expanded "><a href="../stale/0010-burn-coretime-revenue.html">RFC-0010: Burn Coretime Revenue</a></li><li class="chapter-item expanded "><a href="../stale/0013-prepare-blockbuilder-and-core-runtime-apis-for-mbms.html">RFC-0013: Prepare BlockBuilder and Core runtime APIs for MBMs</a></li><li class="chapter-item expanded "><a href="../stale/0015-market-design-revisit.html">RFC-0015: Market Design Revisit</a></li><li class="chapter-item expanded "><a href="../stale/0020-treasurer-track-confirmation-period-duration-modification.html">RFC-0020: Treasurer Track Confirmation Period Duration Modification</a></li><li class="chapter-item expanded "><a href="../stale/0035-conviction-voting-delegation-modifications.html"> RFC-0035: Conviction Voting Delegation Modifications</a></li><li class="chapter-item expanded "><a href="../stale/0043-storage-proof-size-hostfunction.html">RFC-0043: Introduce storage_proof_size Host Function for Improved Parachain Block Utilization</a></li><li class="chapter-item expanded "><a href="../stale/0048-session-keys-runtime-api.html">RFC-0048: Generate ownership proof for SessionKeys</a></li><li class="chapter-item expanded "><a href="../stale/0054-remove-heap-pages.html">RFC-0054: Remove the concept of "heap pages" from the client</a></li><li class="chapter-item expanded "><a href="../stale/0059-nodes-capabilities-discovery.html">RFC-0059: Add a discovery mechanism for nodes based on their capabilities</a></li></ol>
|
||
</div>
|
||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||
</nav>
|
||
|
||
<!-- Track and set sidebar scroll position -->
|
||
<script>
|
||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||
sidebarScrollbox.addEventListener('click', function(e) {
|
||
if (e.target.tagName === 'A') {
|
||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||
}
|
||
}, { passive: true });
|
||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||
sessionStorage.removeItem('sidebar-scroll');
|
||
if (sidebarScrollTop) {
|
||
// preserve sidebar scroll position when navigating via links within sidebar
|
||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||
} else {
|
||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||
var activeSection = document.querySelector('#sidebar .active');
|
||
if (activeSection) {
|
||
activeSection.scrollIntoView({ block: 'center' });
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<div id="page-wrapper" class="page-wrapper">
|
||
|
||
<div class="page">
|
||
<div id="menu-bar-hover-placeholder"></div>
|
||
<div id="menu-bar" class="menu-bar sticky">
|
||
<div class="left-buttons">
|
||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||
<i class="fa fa-bars"></i>
|
||
</label>
|
||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||
<i class="fa fa-paint-brush"></i>
|
||
</button>
|
||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
<li role="none"><button role="menuitem" class="theme" id="polkadot">Polkadot</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||
</ul>
|
||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||
<i class="fa fa-search"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<h1 class="menu-title">Polkadot Fellowship RFCs</h1>
|
||
|
||
<div class="right-buttons">
|
||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||
<i id="print-button" class="fa fa-print"></i>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div id="search-wrapper" class="hidden">
|
||
<form id="searchbar-outer" class="searchbar-outer">
|
||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||
</form>
|
||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||
<div id="searchresults-header" class="searchresults-header"></div>
|
||
<ul id="searchresults">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
<script>
|
||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
});
|
||
</script>
|
||
|
||
<div id="content" class="content">
|
||
<main>
|
||
<p><a href="https://github.com/polkadot-fellows/RFCs/pull/61">(source)</a></p>
|
||
<p><strong>Table of Contents</strong></p>
|
||
<ul>
|
||
<li><a href="#rfc-0061-support-allocator-inside-of-runtime">RFC-0061: Support allocator inside of runtime</a>
|
||
<ul>
|
||
<li><a href="#summary">Summary</a></li>
|
||
<li><a href="#motivation">Motivation</a></li>
|
||
<li><a href="#stakeholders">Stakeholders</a></li>
|
||
<li><a href="#explanation">Explanation</a>
|
||
<ul>
|
||
<li><a href="#runtime-side-spec">Runtime side spec</a></li>
|
||
<li><a href="#client-side-spec">Client side spec</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#drawbacks">Drawbacks</a></li>
|
||
<li><a href="#testing-security-and-privacy">Testing, Security, and Privacy</a></li>
|
||
<li><a href="#performance-ergonomics-and-compatibility">Performance, Ergonomics, and Compatibility</a>
|
||
<ul>
|
||
<li><a href="#performance">Performance</a></li>
|
||
<li><a href="#ergonomics">Ergonomics</a></li>
|
||
<li><a href="#compatibility">Compatibility</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#prior-art-and-references">Prior Art and References</a></li>
|
||
<li><a href="#unresolved-questions">Unresolved Questions</a></li>
|
||
<li><a href="#future-directions-and-related-material">Future Directions and Related Material</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h1 id="rfc-0061-support-allocator-inside-of-runtime"><a class="header" href="#rfc-0061-support-allocator-inside-of-runtime">RFC-0061: Support allocator inside of runtime</a></h1>
|
||
<div class="table-wrapper"><table><thead><tr><th></th><th></th></tr></thead><tbody>
|
||
<tr><td><strong>Start Date</strong></td><td>27 December 2023</td></tr>
|
||
<tr><td><strong>Description</strong></td><td>Supporting runtime built-in allocator makes the substrate runtime more versatile</td></tr>
|
||
<tr><td><strong>Authors</strong></td><td>Jiahao Ye</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
|
||
<p>Currently, substrate runtime use an simple allocator defined by host side. Every runtime MUST
|
||
import these allocator functions for normal execution. This situation make runtime code not versatile enough.</p>
|
||
<p>So this RFC proposes to define a new spec for allocator part to make substrate runtime more generic.</p>
|
||
<h2 id="motivation"><a class="header" href="#motivation">Motivation</a></h2>
|
||
<p>Since this RFC define a new way for allocator, we now regard the old one as <code>legacy</code> allocator.
|
||
As we all know, since the allocator implementation details are defined by the substrate client, parachain/parathread cannot customize memory allocator algorithm, so the new specification allows the runtime to customize memory allocation, and then export the allocator function according to the specification for the client side to use.
|
||
Another benefit is that some new host functions can be designed without allocating memory on the client, which may have potential performance improvements. Also it will help provide a unified and clean specification if substrate runtime support multi-targets(e.g. RISC-V).
|
||
There is also a potential benefit. Many programming languages that support compilation to wasm may not be friendly to supporting external allocator. This is beneficial for other programming languages to enter the substrate runtime ecosystem.
|
||
The last and most important benefit is that for offchain context execution, the runtime can fully support pure wasm. What this means here is that all imported host functions could not actually be called (as stub functions), then the various verification logic of the runtime can be converted into pure wasm, which provides the possibility for the substrate runtime to run block verification in other environments (such as in browsers and other non-substrate environments).</p>
|
||
<h2 id="stakeholders"><a class="header" href="#stakeholders">Stakeholders</a></h2>
|
||
<p>No attempt was made at convincing stakeholders.</p>
|
||
<h2 id="explanation"><a class="header" href="#explanation">Explanation</a></h2>
|
||
<h3 id="runtime-side-spec"><a class="header" href="#runtime-side-spec">Runtime side spec</a></h3>
|
||
<p>This section contains a list of functions should be exported by substrate runtime.</p>
|
||
<p>We define the spec as version 1, so the following <code>dummy</code> function <code>v1</code> MUST be exported to hint
|
||
client that runtime is using version 1 spec, otherwise rollback to <code>legacy</code> allocator.
|
||
The function should never be used, and its name is only for version checking.</p>
|
||
<pre><code class="language-wat"> (export "v1" (func $v1))
|
||
</code></pre>
|
||
<p>Choose this way is more generic than custom section since many other tools do not support custom section very well. But if an environment want to run it, it should always be possible to parse
|
||
the export section.</p>
|
||
<p>The allocator functions are:</p>
|
||
<pre><code class="language-wat">(export "alloc" (func $alloc))
|
||
(export "dealloc" (func $dealloc))
|
||
(export "realloc" (func $realloc))
|
||
</code></pre>
|
||
<p>Their signatures are:</p>
|
||
<pre><code class="language-wat">(func $alloc (param $size i32) (result i32))
|
||
(func $dealloc (param $addr i32) (param $size i32))
|
||
(func $realloc (param $addr i32) (param $size i32) (param $new_size i32) (result i32))
|
||
</code></pre>
|
||
<p>Note: <code>dealloc</code>/<code>realloc</code> is not used in substrate side currently, but for the functional integrity.</p>
|
||
<p>The following imports are disabled.</p>
|
||
<p>The two kind of allocators(<code>leagcy</code> and <code>v1</code>) cannot know each other, and importing them will cause abnormal memory allocation.</p>
|
||
<pre><code class="language-wat">(import "env" "ext_allocator_free_version_1" (func $ext_allocator_free_version_1 (type 0)))
|
||
(import "env" "ext_allocator_malloc_version_1" (func $ext_allocator_malloc_version_1 (type 1)))
|
||
</code></pre>
|
||
<p>The following export could be removed. The client side no need to know heap base.</p>
|
||
<pre><code class="language-wat">(export "__heap_base" (global 2))
|
||
</code></pre>
|
||
<h3 id="client-side-spec"><a class="header" href="#client-side-spec">Client side spec</a></h3>
|
||
<p>During instantiating time, add a version checking stage for wasm executor before any other wasm module checking.
|
||
Check if parsed wasm module contains a exported <code>v1</code> function:</p>
|
||
<ul>
|
||
<li>If not exist, we predicate it using legacy allocator, just do normal checking like before. Set legacy allocator be <code>Some</code> while set <code>v1</code> allocator be <code>None</code>.</li>
|
||
<li>If exist, we predicate it using <code>v1</code> allocator. And then we lookup and hold the exported <code>alloc</code> function for the total lifestyle of instance, return error if not exist. Set legacy allocator be <code>None</code> while set <code>v1</code> allocator be <code>Some</code>.</li>
|
||
<li>When wasm host functions or other entrypoint call(e.g. <code>runtime_apis</code>/<code>validate_block</code>) need to allocate memory, check if instance hold the <code>alloc</code>, if hold just call it otherwise call the legacy
|
||
allocator.</li>
|
||
</ul>
|
||
<p>Detail-heavy explanation of the RFC, suitable for explanation to an implementer of the changeset. This should address corner cases in detail and provide justification behind decisions, and provide rationale for how the design meets the solution requirements.</p>
|
||
<h2 id="drawbacks"><a class="header" href="#drawbacks">Drawbacks</a></h2>
|
||
<p>The allocator inside of the runtime will make code size bigger, but it's not obvious.
|
||
The allocator inside of the runtime maybe slow down(or speed up) the runtime, still not obvious.</p>
|
||
<p>We could ignore these drawbacks since they are not prominent. And the execution efficiency is highly decided by runtime developer. We could not prevent a poor efficiency if developer want to do it.</p>
|
||
<h2 id="testing-security-and-privacy"><a class="header" href="#testing-security-and-privacy">Testing, Security, and Privacy</a></h2>
|
||
<p>Keep the legacy allocator runtime test cases, and add new feature to compile test cases for <code>v1</code> allocator spec. And then update the test asserts.</p>
|
||
<p>Update template runtime to enable <code>v1</code> spec. Once the dev network runs well, it seems that the spec is implmented correctly.</p>
|
||
<h2 id="performance-ergonomics-and-compatibility"><a class="header" href="#performance-ergonomics-and-compatibility">Performance, Ergonomics, and Compatibility</a></h2>
|
||
<h3 id="performance"><a class="header" href="#performance">Performance</a></h3>
|
||
<p>As the above says, not obvious impact about performance. And <code>polkadot-sdk</code> could offer the best practice allocator for all chains.
|
||
Third party also could customized by theirself. So the performance could be improved over time.</p>
|
||
<h3 id="ergonomics"><a class="header" href="#ergonomics">Ergonomics</a></h3>
|
||
<p>Only for runtime developer, Just need to import a new crate and enable a new feature. Maybe it's convienient for other wasm-target language to implment.</p>
|
||
<h3 id="compatibility"><a class="header" href="#compatibility">Compatibility</a></h3>
|
||
<p>It's 100% compatible. Only Some runtime configs and executor configs need to be depreacted.</p>
|
||
<p>For support new runtime spec, we MUST upgrade the client binary to support new spec of client part firstly.</p>
|
||
<p>We SHALL add an optional primtive crate to enable the version 1 spec and disable the legacy allocator by cargo feature.
|
||
For the first year, we SHALL disable the v1 by default, and enable it by default start in the next year.</p>
|
||
<h2 id="prior-art-and-references"><a class="header" href="#prior-art-and-references">Prior Art and References</a></h2>
|
||
<ul>
|
||
<li><a href="https://github.com/paritytech/substrate/issues/11883">Move the allocator inside of the runtime</a></li>
|
||
<li><a href="https://github.com/paritytech/polkadot-sdk/pull/1658">Add new allocator design</a></li>
|
||
</ul>
|
||
<h2 id="unresolved-questions"><a class="header" href="#unresolved-questions">Unresolved Questions</a></h2>
|
||
<p>None at this time.</p>
|
||
<h2 id="future-directions-and-related-material"><a class="header" href="#future-directions-and-related-material">Future Directions and Related Material</a></h2>
|
||
<p>The content discussed with <a href="https://github.com/polkadot-fellows/RFCs/pull/4">RFC-0004</a> is basically orthogonal, but it could still be considered together, and it is preferred that this rfc be implmentented first.</p>
|
||
<p>This feature could make substrate runtime be easier supported by other languages and integreted into other ecosystem.</p>
|
||
|
||
</main>
|
||
|
||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||
<!-- Mobile navigation buttons -->
|
||
<a rel="prev" href="../proposed/0047-assignment-of-availability-chunks.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
<a rel="next prefetch" href="../stale/0004-remove-unnecessary-allocator-usage.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
|
||
<div style="clear: both"></div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||
<a rel="prev" href="../proposed/0047-assignment-of-availability-chunks.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
<a rel="next prefetch" href="../stale/0004-remove-unnecessary-allocator-usage.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
</nav>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<script>
|
||
window.playground_copyable = true;
|
||
</script>
|
||
|
||
|
||
<script src="../elasticlunr.min.js"></script>
|
||
<script src="../mark.min.js"></script>
|
||
<script src="../searcher.js"></script>
|
||
|
||
<script src="../clipboard.min.js"></script>
|
||
<script src="../highlight.js"></script>
|
||
<script src="../book.js"></script>
|
||
|
||
<!-- Custom JS scripts -->
|
||
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|