refactor: wasm memory

master
Sean McBride 4 years ago
parent 938f1a8950
commit 13a997cb80

@ -7,7 +7,7 @@
INLINE float
get_f32(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(float *)address;
@ -16,7 +16,7 @@ get_f32(int32_t offset)
INLINE double
get_f64(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(double *)address;
@ -25,7 +25,7 @@ get_f64(int32_t offset)
INLINE int8_t
get_i8(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(int8_t *)address;
@ -34,7 +34,7 @@ get_i8(int32_t offset)
INLINE int16_t
get_i16(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(int16_t *)address;
@ -43,7 +43,7 @@ get_i16(int32_t offset)
INLINE int32_t
get_i32(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(int32_t *)address;
@ -52,7 +52,7 @@ get_i32(int32_t offset)
INLINE int64_t
get_i64(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(int64_t *)address;
@ -61,7 +61,7 @@ get_i64(int32_t offset)
INLINE int32_t
get_global_i32(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(int32_t *)address;
@ -70,7 +70,7 @@ get_global_i32(int32_t offset)
INLINE int64_t
get_global_i64(int32_t offset)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
return *(int64_t *)address;
@ -80,7 +80,7 @@ get_global_i64(int32_t offset)
INLINE void
set_f32(int32_t offset, float v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(float *)address = v;
@ -89,7 +89,7 @@ set_f32(int32_t offset, float v)
INLINE void
set_f64(int32_t offset, double v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(double *)address = v;
@ -98,7 +98,7 @@ set_f64(int32_t offset, double v)
INLINE void
set_i8(int32_t offset, int8_t v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(int8_t *)address = v;
@ -107,7 +107,7 @@ set_i8(int32_t offset, int8_t v)
INLINE void
set_i16(int32_t offset, int16_t v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(int16_t *)address = v;
@ -116,7 +116,7 @@ set_i16(int32_t offset, int16_t v)
INLINE void
set_i32(int32_t offset, int32_t v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(int32_t *)address = v;
@ -125,7 +125,7 @@ set_i32(int32_t offset, int32_t v)
INLINE void
set_i64(int32_t offset, int64_t v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(int64_t *)address = v;
@ -134,7 +134,7 @@ set_i64(int32_t offset, int64_t v)
INLINE void
set_global_i32(int32_t offset, int32_t v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(int32_t *)address = v;
@ -143,7 +143,7 @@ set_global_i32(int32_t offset, int32_t v)
INLINE void
set_global_i64(int32_t offset, int64_t v)
{
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
*(int64_t *)address = v;

@ -29,15 +29,17 @@ current_sandbox_set(struct sandbox *sandbox)
/* Unpack hierarchy to avoid pointer chasing */
if (sandbox == NULL) {
local_sandbox_context_cache = (struct sandbox_context_cache){
.linear_memory_start = NULL,
.linear_memory_size = 0,
.memory = {
.start = NULL,
.size = 0,
.max = 0,
},
.module_indirect_table = NULL,
};
worker_thread_current_sandbox = NULL;
} else {
local_sandbox_context_cache = (struct sandbox_context_cache){
.linear_memory_start = sandbox->linear_memory_start,
.linear_memory_size = sandbox->linear_memory_size,
.memory = sandbox->memory,
.module_indirect_table = sandbox->module->indirect_table,
};
worker_thread_current_sandbox = sandbox;

@ -35,9 +35,9 @@ sandbox_close_http(struct sandbox *sandbox)
static inline void
sandbox_free_linear_memory(struct sandbox *sandbox)
{
int rc = munmap(sandbox->linear_memory_start, SANDBOX_MAX_MEMORY + PAGE_SIZE);
int rc = munmap(sandbox->memory.start, SANDBOX_MAX_MEMORY + PAGE_SIZE);
if (rc == -1) panic("sandbox_free_linear_memory - munmap failed\n");
sandbox->linear_memory_start = NULL;
sandbox->memory.start = NULL;
}
/**
@ -101,5 +101,5 @@ sandbox_print_perf(struct sandbox *sandbox)
sandbox->module->relative_deadline, sandbox->total_time, queued_duration,
sandbox->initializing_duration, sandbox->runnable_duration, sandbox->running_duration,
sandbox->blocked_duration, sandbox->returned_duration, runtime_processor_speed_MHz,
sandbox->linear_memory_size);
sandbox->memory.size);
}

@ -17,8 +17,8 @@ sandbox_setup_arguments(struct sandbox *sandbox)
int32_t argument_count = module_get_argument_count(sandbox->module);
/* whatever gregor has, to be able to pass arguments to a module! */
sandbox->arguments_offset = local_sandbox_context_cache.linear_memory_size;
assert(local_sandbox_context_cache.linear_memory_start == sandbox->linear_memory_start);
sandbox->arguments_offset = local_sandbox_context_cache.memory.size;
assert(local_sandbox_context_cache.memory.start == sandbox->memory.start);
expand_memory();
int32_t *array_ptr = (int32_t *)worker_thread_get_memory_ptr_void(sandbox->arguments_offset,

@ -12,6 +12,7 @@
#include "module.h"
#include "ps_list.h"
#include "sandbox_state.h"
#include "wasm_types.h"
#define SANDBOX_FILE_DESCRIPTOR_PREOPEN_MAGIC (707707707) /* upside down LOLLOLLOL 🤣😂🤣*/
#define SANDBOX_MAX_FD_COUNT 32
@ -35,9 +36,7 @@ struct sandbox {
uint32_t sandbox_size; /* The struct plus enough buffer to hold the request or response (sized off largest) */
void * linear_memory_start; /* after sandbox struct */
uint32_t linear_memory_size; /* from after sandbox struct */
uint64_t linear_memory_max_size; /* 4GB */
struct wasm_memory memory;
void * stack_start;
uint32_t stack_size;

@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdio.h>
#include "wasm_types.h"
#define PAGE_SIZE (unsigned long)(1 << 12)
@ -43,9 +45,8 @@ struct indirect_table_entry {
/* Cache of Frequently Accessed Members used to avoid pointer chasing */
struct sandbox_context_cache {
struct wasm_memory memory;
struct indirect_table_entry *module_indirect_table;
void * linear_memory_start;
uint32_t linear_memory_size;
};
extern __thread struct sandbox_context_cache local_sandbox_context_cache;

@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
struct wasm_memory {
void * start; /* after sandbox struct */
uint32_t size; /* from after sandbox struct */
uint64_t max; /* 4GB */
};

@ -11,8 +11,11 @@
__thread struct sandbox *worker_thread_current_sandbox = NULL;
__thread struct sandbox_context_cache local_sandbox_context_cache = {
.linear_memory_start = NULL,
.linear_memory_size = 0,
.memory = {
.start = NULL,
.size = 0,
.max = 0,
},
.module_indirect_table = NULL,
};

@ -215,7 +215,7 @@ wasm_mmap(int32_t addr, int32_t len, int32_t prot, int32_t flags, int32_t fd, in
assert(len % WASM_PAGE_SIZE == 0);
int32_t result = local_sandbox_context_cache.linear_memory_size;
int32_t result = local_sandbox_context_cache.memory.size;
for (int i = 0; i < len / WASM_PAGE_SIZE; i++) { expand_memory(); }
return result;
@ -319,7 +319,7 @@ wasm_mremap(int32_t offset, int32_t old_size, int32_t new_size, int32_t flags)
if (new_size <= old_size) return offset;
// If at end of linear memory, just expand and return same address
if (offset + old_size == local_sandbox_context_cache.linear_memory_size) {
if (offset + old_size == local_sandbox_context_cache.memory.size) {
int32_t amount_to_expand = new_size - old_size;
int32_t pages_to_allocate = amount_to_expand / WASM_PAGE_SIZE;
if (amount_to_expand % WASM_PAGE_SIZE > 0) pages_to_allocate++;
@ -331,11 +331,11 @@ wasm_mremap(int32_t offset, int32_t old_size, int32_t new_size, int32_t flags)
// Otherwise allocate at end of address space and copy
int32_t pages_to_allocate = new_size / WASM_PAGE_SIZE;
if (new_size % WASM_PAGE_SIZE > 0) pages_to_allocate++;
int32_t new_offset = local_sandbox_context_cache.linear_memory_size;
int32_t new_offset = local_sandbox_context_cache.memory.size;
for (int i = 0; i < pages_to_allocate; i++) expand_memory();
// Get pointer of old offset and pointer of new offset
char *linear_mem = local_sandbox_context_cache.linear_memory_start;
char *linear_mem = local_sandbox_context_cache.memory.start;
char *src = &linear_mem[offset];
char *dest = &linear_mem[new_offset];

@ -14,23 +14,22 @@ expand_memory(void)
struct sandbox *sandbox = current_sandbox_get();
// FIXME: max_pages = 0 => no limit. Issue #103.
assert((sandbox->sandbox_size + local_sandbox_context_cache.linear_memory_size) / WASM_PAGE_SIZE
< WASM_MAX_PAGES);
assert((sandbox->sandbox_size + local_sandbox_context_cache.memory.size) / WASM_PAGE_SIZE < WASM_MAX_PAGES);
assert(sandbox->state == SANDBOX_RUNNING);
// Remap the relevant wasm page to readable
char *mem_as_chars = local_sandbox_context_cache.linear_memory_start;
char *page_address = &mem_as_chars[local_sandbox_context_cache.linear_memory_size];
char *mem_as_chars = local_sandbox_context_cache.memory.start;
char *page_address = &mem_as_chars[local_sandbox_context_cache.memory.size];
void *map_result = mmap(page_address, WASM_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
// TODO: Refactor to return RC signifying out-of-mem to caller. Issue #96.
if (map_result == MAP_FAILED) panic("Mapping of new memory failed");
if (local_sandbox_context_cache.linear_memory_size > sandbox->linear_memory_max_size)
panic("expand_memory - Out of Memory!. %u out of %lu\n", local_sandbox_context_cache.linear_memory_size,
sandbox->linear_memory_max_size);
if (local_sandbox_context_cache.memory.size > local_sandbox_context_cache.memory.max)
panic("expand_memory - Out of Memory!. %u out of %lu\n", local_sandbox_context_cache.memory.size,
local_sandbox_context_cache.memory.max);
local_sandbox_context_cache.linear_memory_size += WASM_PAGE_SIZE;
local_sandbox_context_cache.memory.size += WASM_PAGE_SIZE;
#ifdef LOG_SANDBOX_MEMORY_PROFILE
// Cache the runtime of the first N page allocations
@ -41,7 +40,7 @@ expand_memory(void)
#endif
// local_sandbox_context_cache is "forked state", so update authoritative member
sandbox->linear_memory_size = local_sandbox_context_cache.linear_memory_size;
sandbox->memory.size = local_sandbox_context_cache.memory.size;
}
INLINE char *
@ -50,10 +49,10 @@ get_memory_ptr_for_runtime(uint32_t offset, uint32_t bounds_check)
// Due to how we setup memory for x86, the virtual memory mechanism will catch the error, if bounds <
// WASM_PAGE_SIZE
assert(bounds_check < WASM_PAGE_SIZE
|| (local_sandbox_context_cache.linear_memory_size > bounds_check
&& offset <= local_sandbox_context_cache.linear_memory_size - bounds_check));
|| (local_sandbox_context_cache.memory.size > bounds_check
&& offset <= local_sandbox_context_cache.memory.size - bounds_check));
char *mem_as_chars = (char *)local_sandbox_context_cache.linear_memory_start;
char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
char *address = &mem_as_chars[offset];
return address;

@ -8,8 +8,8 @@
EXPORT void
initialize_region(uint32_t offset, uint32_t data_count, char *data)
{
assert(local_sandbox_context_cache.linear_memory_size >= data_count);
assert(offset < local_sandbox_context_cache.linear_memory_size - data_count);
assert(local_sandbox_context_cache.memory.size >= data_count);
assert(offset < local_sandbox_context_cache.memory.size - data_count);
/* FIXME: Hack around segmented and unsegmented access Issue #104 */
memcpy(get_memory_ptr_for_runtime(offset, data_count), data, data_count);

@ -19,11 +19,11 @@ sandbox_allocate_memory(struct module *module)
{
assert(module != NULL);
char * error_message = NULL;
unsigned long linear_memory_size = WASM_PAGE_SIZE * WASM_START_PAGES; /* The initial pages */
uint64_t linear_memory_max_size = (uint64_t)SANDBOX_MAX_MEMORY;
struct sandbox *sandbox = NULL;
unsigned long sandbox_size = sizeof(struct sandbox) + module->max_request_or_response_size;
char * error_message = NULL;
unsigned long memory_size = WASM_PAGE_SIZE * WASM_START_PAGES; /* The initial pages */
uint64_t memory_max = (uint64_t)SANDBOX_MAX_MEMORY;
struct sandbox *sandbox = NULL;
unsigned long sandbox_size = sizeof(struct sandbox) + module->max_request_or_response_size;
/*
* Control information should be page-aligned
@ -33,7 +33,7 @@ sandbox_allocate_memory(struct module *module)
/* At an address of the system's choosing, allocate the memory, marking it as inaccessible */
errno = 0;
void *addr = mmap(NULL, sandbox_size + linear_memory_max_size + /* guard page */ PAGE_SIZE, PROT_NONE,
void *addr = mmap(NULL, sandbox_size + memory_max + /* guard page */ PAGE_SIZE, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
error_message = "sandbox_allocate_memory - memory allocation failed";
@ -44,7 +44,7 @@ sandbox_allocate_memory(struct module *module)
/* Set the struct sandbox, HTTP Req/Resp buffer, and the initial Wasm Pages as read/write */
errno = 0;
void *addr_rw = mmap(addr, sandbox_size + linear_memory_size, PROT_READ | PROT_WRITE,
void *addr_rw = mmap(addr, sandbox_size + memory_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (addr_rw == MAP_FAILED) {
error_message = "set to r/w";
@ -54,12 +54,12 @@ sandbox_allocate_memory(struct module *module)
sandbox = (struct sandbox *)addr_rw;
/* Populate Sandbox members */
sandbox->state = SANDBOX_UNINITIALIZED;
sandbox->linear_memory_start = (char *)addr + sandbox_size;
sandbox->linear_memory_size = linear_memory_size;
sandbox->linear_memory_max_size = linear_memory_max_size;
sandbox->module = module;
sandbox->sandbox_size = sandbox_size;
sandbox->state = SANDBOX_UNINITIALIZED;
sandbox->memory.start = (char *)addr + sandbox_size;
sandbox->memory.size = memory_size;
sandbox->memory.max = memory_max;
sandbox->module = module;
sandbox->sandbox_size = sandbox_size;
module_acquire(module);
done:
@ -67,7 +67,7 @@ done:
set_rw_failed:
sandbox = NULL;
errno = 0;
int rc = munmap(addr, sandbox_size + linear_memory_size + PAGE_SIZE);
int rc = munmap(addr, sandbox_size + memory_size + PAGE_SIZE);
if (rc == -1) perror("Failed to munmap after fail to set r/w");
alloc_failed:
err:
@ -194,7 +194,7 @@ sandbox_free(struct sandbox *sandbox)
*/
/* Linear Memory and Guard Page should already have been munmaped and set to NULL */
assert(sandbox->linear_memory_start == NULL);
assert(sandbox->memory.start == NULL);
errno = 0;
rc = munmap(sandbox, sandbox->sandbox_size);
if (rc == -1) {

Loading…
Cancel
Save