team icon indicating copy to clipboard operation
team copied to clipboard

Is it possible to make use of the first page(s)?

Open pepyakin opened this issue 7 years ago • 5 comments

First page(s) contains static data, bss and the stack. When allocator (e.g. wee_alloc) is asked to allocate for the first time, it mounts a new page. So the space after the stack to the end of the initial page is wasted.

This space might be useful in blockchain applications, since there user should literally pay for the each memory page.

To make use of this space, we need a some way to find out the end (or should I say the start, b/c the stack grows downward) of the stack region. I imagine that something like the linker script would come in handy.

pepyakin avatar Feb 14 '18 16:02 pepyakin

This I believe has since been solved with --stack-first option in LLD where the first pages are used for stack space now

alexcrichton avatar Jul 18 '18 17:07 alexcrichton

This is about using the first bits of heap memory after stack and data and before allocating fresh pages.

Whether stack or data comes first, right now there is an unused portion of the first page (or one of the first n pages):

|           Page 0          |          Page 1      |      Page 2      |       |
+---------------------------+----------------------+------------------+--//---+
| stack | data | unused     | heap --->                                  \\   |
+---------------------------+----------------------+------------------+--//---+

I believe that @pepyakin is requesting that we figure out how to enable this:

|           Page 0          |          Page 1      |      Page 2      |       |
+---------------------------+----------------------+------------------+--//---+
| stack | data | heap --->                                               \\   |
+---------------------------+----------------------+------------------+--//---+

fitzgen avatar Jul 18 '18 19:07 fitzgen

I think lld exposes a __heap_base variable that allocators can use to leverage the remainder of the stack/data pages. So I think there are two parts here:

  1. Expose lld's __heap_base through core::arch::wasm32

  2. Get allocators that target wasm32 to use that (presumably only if they are the global allocator)

fitzgen avatar Jul 18 '18 19:07 fitzgen

Hm I actually thought LLD aligned data differently, along the lines of:

|           Page 0          |          Page 1      |      Page 2      |       |
+---------------------------+----------------------+------------------+--//---+
|              stack | data | heap --->                                  \\   |
+---------------------------+----------------------+------------------+--//---+

but it apparently does not as this wasm file:

#![crate_type = "cdylib"]

static A: usize = 3;

#[no_mangle]
pub extern fn foo() -> usize { &A as *const usize as usize }

generates:

(module
  (type $t0 (func (result i32)))
  (func $foo (export "foo") (type $t0) (result i32)
    (i32.const 1048576))
  (table $T0 1 1 anyfunc)
  (memory $memory (export "memory") 17)
  (global $__heap_base (export "__heap_base") i32 (i32.const 1048580))
  (global $__data_end (export "__data_end") i32 (i32.const 1048580))
  (data (i32.const 1048576) "\03\00\00\00"))

alexcrichton avatar Jul 18 '18 20:07 alexcrichton

Er hit submit a little too soon, but we ask for a 1MB (1048576) stack, so LLD is definitely allocating data at the start of a page rather than the end of the page.

alexcrichton avatar Jul 18 '18 20:07 alexcrichton