Skip to content

Commit

Permalink
Merge pull request #287 from gwsystems/spec-alignment-2
Browse files Browse the repository at this point in the history
feat: WIP restage of memory allocation features
  • Loading branch information
bushidocodes authored Dec 16, 2021
2 parents 6b037e3 + 452db10 commit af016f2
Show file tree
Hide file tree
Showing 62 changed files with 1,595 additions and 1,104 deletions.
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
"sandbox_set_as_runnable.h": "c",
"sandbox_set_as_complete.h": "c",
"deque.h": "c",
"sandbox_request.h": "c",
"sandbox_send_response.h": "c",
"sandbox_setup_arguments.h": "c",
"worker_thread.h": "c",
Expand All @@ -101,7 +100,9 @@
"scheduler.h": "c",
"sandbox_set_as_returned.h": "c",
"software_interrupt_counts.h": "c",
"sandbox_set_as_running_sys.h": "c"
"sandbox_set_as_running_sys.h": "c",
"wasm_module_instance.h": "c",
"wasm_table.h": "c"
},
"files.exclude": {
"**/.git": true,
Expand Down
9 changes: 3 additions & 6 deletions runtime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ BINARY_NAME=sledgert
# CFLAGS += -DLOG_LOCK_OVERHEAD
# CFLAGS += -DLOG_MODULE_LOADING
# CFLAGS += -DLOG_PREEMPTION
# CFLAGS += -DLOG_REQUEST_ALLOCATION
# CFLAGS += -DLOG_SANDBOX_ALLOCATION

# Stores and logs extended signal information for each worker
# CFLAGS += -DLOG_SOFTWARE_INTERRUPT_COUNTS
Expand All @@ -73,10 +73,9 @@ BINARY_NAME=sledgert
# To log, run `call http_total_log()` while in GDB
# CFLAGS += -DLOG_TOTAL_REQS_RESPS

# This flag logs the total number of sandboxes in the various states
# This flag tracks the total number of sandboxes in the various states
# It is useful to debug if sandboxes are "getting caught" in a particular state
# To log, run `call runtime_log_sandbox_states()` while in GDB
# CFLAGS += -DLOG_SANDBOX_COUNT
# CFLAGS += -DSANDBOX_STATE_TOTALS

# This flag enables an per-worker atomic count of sandbox's local runqueue count in thread local storage
# Useful to debug if sandboxes are "getting caught" or "leaking" while in a local runqueue
Expand Down Expand Up @@ -105,8 +104,6 @@ INCLUDES += -Iinclude/ -Ithirdparty/dist/include/
CFILES += src/*.c
CFILES += src/arch/${ARCH}/*.c
CFILES += src/libc/*.c
CFILES += src/memory/common.c
CFILES += src/memory/64bit_nix.c
CFILES += thirdparty/dist/lib/http_parser.o

# Configuring Jasmine
Expand Down
172 changes: 88 additions & 84 deletions runtime/compiletime/memory_instructions.c
Original file line number Diff line number Diff line change
@@ -1,78 +1,60 @@
#include <assert.h>

#include "types.h"
#include "current_wasm_module_instance.h"

uint32_t
INLINE uint32_t
instruction_memory_size()
{
return local_sandbox_context_cache.memory.size / WASM_PAGE_SIZE;
return (uint32_t)(current_wasm_module_instance.memory.size / WASM_PAGE_SIZE);
}

// All of these are pretty generic
// These functions are equivalent to those in wasm_memory.h, but they minimize pointer dereferencing
INLINE float
get_f32(uint32_t offset)
{
assert(offset + sizeof(float) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

return *(float *)address;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(float) <= current_wasm_module_instance.memory.size);
return *(float *)&current_wasm_module_instance.memory.buffer[offset];
}

INLINE double
get_f64(uint32_t offset)
{
assert(offset + sizeof(double) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

return *(double *)address;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(double) <= current_wasm_module_instance.memory.size);
return *(double *)&current_wasm_module_instance.memory.buffer[offset];
}

INLINE int8_t
get_i8(uint32_t offset)
{
assert(offset + sizeof(int8_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

return *(int8_t *)address;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int8_t) <= current_wasm_module_instance.memory.size);
return *(int8_t *)&current_wasm_module_instance.memory.buffer[offset];
}

INLINE int16_t
get_i16(uint32_t offset)
{
assert(offset + sizeof(int16_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

return *(int16_t *)address;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int16_t) <= current_wasm_module_instance.memory.size);
return *(int16_t *)&current_wasm_module_instance.memory.buffer[offset];
}

INLINE int32_t
get_i32(uint32_t offset)
{
assert(offset + sizeof(int32_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

return *(int32_t *)address;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int32_t) <= current_wasm_module_instance.memory.size);
return *(int32_t *)&current_wasm_module_instance.memory.buffer[offset];
}

INLINE int64_t
get_i64(uint32_t offset)
{
assert(offset + sizeof(int64_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

return *(int64_t *)address;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int64_t) <= current_wasm_module_instance.memory.size);
return *(int64_t *)&current_wasm_module_instance.memory.buffer[offset];
}

INLINE int32_t
Expand All @@ -89,79 +71,101 @@ get_global_i64(uint32_t offset)

// Now setting routines
INLINE void
set_f32(uint32_t offset, float v)
set_f32(uint32_t offset, float value)
{
assert(offset + sizeof(float) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

*(float *)address = v;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(float) <= current_wasm_module_instance.memory.size);
*(float *)&current_wasm_module_instance.memory.buffer[offset] = value;
}

INLINE void
set_f64(uint32_t offset, double v)
set_f64(uint32_t offset, double value)
{
assert(offset + sizeof(double) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

*(double *)address = v;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(double) <= current_wasm_module_instance.memory.size);
*(double *)&current_wasm_module_instance.memory.buffer[offset] = value;
}

INLINE void
set_i8(uint32_t offset, int8_t v)
set_i8(uint32_t offset, int8_t value)
{
assert(offset + sizeof(int8_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

*(int8_t *)address = v;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int8_t) <= current_wasm_module_instance.memory.size);
*(int8_t *)&current_wasm_module_instance.memory.buffer[offset] = value;
}

INLINE void
set_i16(uint32_t offset, int16_t v)
set_i16(uint32_t offset, int16_t value)
{
assert(offset + sizeof(int16_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
assert(current_wasm_module_instance.memory.buffer != NULL);

*(int16_t *)address = v;
assert(offset + sizeof(int16_t) <= current_wasm_module_instance.memory.size);
*(int16_t *)&current_wasm_module_instance.memory.buffer[offset] = value;
}

INLINE void
set_i32(uint32_t offset, int32_t v)
set_i32(uint32_t offset, int32_t value)
{
assert(offset + sizeof(int32_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];

*(int32_t *)address = v;
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int32_t) <= current_wasm_module_instance.memory.size);
*(int32_t *)&current_wasm_module_instance.memory.buffer[offset] = value;
}

INLINE void
set_i64(uint32_t offset, int64_t v)
set_i64(uint32_t offset, int64_t value)
{
assert(offset + sizeof(int64_t) <= local_sandbox_context_cache.memory.size);

char *mem_as_chars = (char *)local_sandbox_context_cache.memory.start;
void *address = &mem_as_chars[offset];
assert(current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int64_t) <= current_wasm_module_instance.memory.size);
*(int64_t *)&current_wasm_module_instance.memory.buffer[offset] = value;
}

*(int64_t *)address = v;
INLINE void
set_global_i32(uint32_t offset, int32_t value)
{
set_i32(offset, value);
}

INLINE void
set_global_i32(uint32_t offset, int32_t v)
set_global_i64(uint32_t offset, int64_t value)
{
set_i32(offset, v);
set_i64(offset, value);
}

/**
* @brief Stub that implements the WebAssembly memory.grow instruction
*
* @param count number of pages to grow the WebAssembly linear memory by
* @return The previous size of the linear memory in pages or -1 if enough memory cannot be allocated
*/
INLINE int32_t
instruction_memory_grow(uint32_t count)
{
int old_page_count = current_wasm_module_instance.memory.size / WASM_PAGE_SIZE;

/* Return -1 if we've hit the linear memory max */
int rc = wasm_memory_expand(&current_wasm_module_instance.memory, WASM_PAGE_SIZE * count);
if (unlikely(rc == -1)) return -1;

/* We updated "forked state" in current_wasm_module_instance.memory. We need to write this back to persist */
current_wasm_module_instance_memory_writeback();

#ifdef LOG_SANDBOX_MEMORY_PROFILE
// Cache the runtime of the first N page allocations
for (int i = 0; i < count; i++) {
if (likely(sandbox->timestamp_of.page_allocations_size < SANDBOX_PAGE_ALLOCATION_TIMESTAMP_COUNT)) {
sandbox->timestamp_of.page_allocations[sandbox->timestamp_of.page_allocations_size++] =
sandbox->duration_of_state.running
+ (uint32_t)(__getcycles() - sandbox->timestamp_of.last_state_change);
}
}
#endif
return rc;
}


INLINE void
set_global_i64(uint32_t offset, int64_t v)
initialize_region(uint32_t offset, uint32_t region_size, uint8_t region[region_size])
{
set_i64(offset, v);
wasm_memory_initialize_region(&current_wasm_module_instance.memory, offset, region_size, region);
}
33 changes: 4 additions & 29 deletions runtime/compiletime/table_instructions.c
Original file line number Diff line number Diff line change
@@ -1,42 +1,17 @@
#include <assert.h>

#include "types.h"
#include "wasm_module_instance.h"

extern thread_local struct wasm_module_instance current_wasm_module_instance;

INLINE void
add_function_to_table(uint32_t idx, uint32_t type_id, char *pointer)
{
assert(idx < INDIRECT_TABLE_SIZE);
assert(local_sandbox_context_cache.module_indirect_table != NULL);

/* TODO: atomic for multiple concurrent invocations? Issue #97 */
if (local_sandbox_context_cache.module_indirect_table[idx].type_id == type_id
&& local_sandbox_context_cache.module_indirect_table[idx].func_pointer == pointer)
return;

local_sandbox_context_cache.module_indirect_table[idx] = (struct indirect_table_entry){
.type_id = type_id, .func_pointer = pointer
};
wasm_table_set(current_wasm_module_instance.table, idx, type_id, pointer);
}

/* char * is used as a generic pointer to a function pointer */
INLINE char *
get_function_from_table(uint32_t idx, uint32_t type_id)
{
#ifdef LOG_FUNCTION_TABLE
fprintf(stderr, "get_function_from_table(idx: %u, type_id: %u)\n", idx, type_id);
fprintf(stderr, "indirect_table_size: %u\n", INDIRECT_TABLE_SIZE);
#endif
assert(idx < INDIRECT_TABLE_SIZE);

struct indirect_table_entry f = local_sandbox_context_cache.module_indirect_table[idx];
#ifdef LOG_FUNCTION_TABLE
fprintf(stderr, "assumed type: %u, type in table: %u\n", type_id, f.type_id);
#endif
// FIXME: Commented out function type check because of gocr
// assert(f.type_id == type_id);

assert(f.func_pointer != NULL);

return f.func_pointer;
return wasm_table_get(current_wasm_module_instance.table, idx, type_id);
}
Loading

0 comments on commit af016f2

Please sign in to comment.