pass the pointer to shared memory around, instead of using a global

This commit is contained in:
Folkert 2022-12-08 23:22:06 +01:00
parent 8307a194e1
commit 95fe9cbccd
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C
6 changed files with 68 additions and 55 deletions

View File

@ -44,8 +44,6 @@ pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
const ptr = @ptrCast([*]u8, shared_ptr);
SHARED_BUFFER = ptr[0..length];
return ptr;
} else {
unreachable;
@ -81,17 +79,11 @@ pub fn readSharedBufferEnv() callconv(.C) void {
}
}
fn get_atomic_ptr() *Atomic(u32) {
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), SHARED_BUFFER.ptr));
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
return atomic_ptr;
}
pub fn expectFailedFinalize() callconv(.C) void {
pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
const atomic_ptr = get_atomic_ptr();
atomic_ptr.storeUnchecked(1);
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), shared_buffer));
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
atomic_ptr.storeUnchecked(tag);
// wait till the parent is done before proceeding
const Ordering = std.atomic.Ordering;
@ -101,15 +93,10 @@ pub fn expectFailedFinalize() callconv(.C) void {
}
}
pub fn sendDbg() callconv(.C) void {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
const atomic_ptr = get_atomic_ptr();
atomic_ptr.storeUnchecked(2);
// wait till the parent is done before proceeding
const Ordering = std.atomic.Ordering;
while (atomic_ptr.load(Ordering.Acquire) != 0) {
std.atomic.spinLoopHint();
}
}
pub fn notifyParentExpect(shared_buffer: [*]u8) callconv(.C) void {
notifyParent(shared_buffer, 1);
}
pub fn notifyParentDbg(shared_buffer: [*]u8) callconv(.C) void {
notifyParent(shared_buffer, 2);
}

View File

@ -172,8 +172,8 @@ comptime {
if (builtin.target.cpu.arch != .wasm32) {
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
exportUtilsFn(expect.expectFailedFinalize, "expect_failed_finalize");
exportUtilsFn(expect.sendDbg, "send_dbg");
exportUtilsFn(expect.notifyParentExpect, "notify_parent_expect");
exportUtilsFn(expect.notifyParentDbg, "notify_parent_dbg");
// sets the buffer used for expect failures
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });

View File

@ -424,9 +424,9 @@ pub const UTILS_EXPECT_FAILED_START_SHARED_BUFFER: &str =
"roc_builtins.utils.expect_failed_start_shared_buffer";
pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
"roc_builtins.utils.expect_failed_start_shared_file";
pub const UTILS_EXPECT_FAILED_FINALIZE: &str = "roc_builtins.utils.expect_failed_finalize";
pub const UTILS_EXPECT_READ_ENV_SHARED_BUFFER: &str = "roc_builtins.utils.read_env_shared_buffer";
pub const UTILS_SEND_DBG: &str = "roc_builtins.utils.send_dbg";
pub const NOTIFY_PARENT_EXPECT: &str = "roc_builtins.utils.notify_parent_expect";
pub const NOTIFY_PARENT_DBG: &str = "roc_builtins.utils.notify_parent_dbg";
pub const UTILS_LONGJMP: &str = "longjmp";
pub const UTILS_SETJMP: &str = "setjmp";

View File

@ -3,7 +3,7 @@ use crate::llvm::build_list::{self, allocate_list, empty_polymorphic_list};
use crate::llvm::convert::{
argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type,
};
use crate::llvm::expect::clone_to_shared_memory;
use crate::llvm::expect::{clone_to_shared_memory, SharedMemoryPointer};
use crate::llvm::refcounting::{
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
};
@ -2611,17 +2611,20 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
match env.target_info.ptr_width() {
roc_target::PtrWidth::Bytes8 => {
let shared_memory = SharedMemoryPointer::get(env);
clone_to_shared_memory(
env,
scope,
layout_ids,
&shared_memory,
*cond_symbol,
*region,
lookups,
);
if let LlvmBackendMode::BinaryDev = env.mode {
crate::llvm::expect::finalize(env);
crate::llvm::expect::notify_parent_expect(env, &shared_memory);
}
bd.build_unconditional_branch(then_block);
@ -2677,10 +2680,13 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
match env.target_info.ptr_width() {
roc_target::PtrWidth::Bytes8 => {
let shared_memory = SharedMemoryPointer::get(env);
clone_to_shared_memory(
env,
scope,
layout_ids,
&shared_memory,
*cond_symbol,
*region,
lookups,

View File

@ -18,6 +18,32 @@ use super::build::{
Scope,
};
pub(crate) struct SharedMemoryPointer<'ctx>(PointerValue<'ctx>);
impl<'ctx> SharedMemoryPointer<'ctx> {
pub(crate) fn get<'a, 'env>(env: &Env<'a, 'ctx, 'env>) -> Self {
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
} else {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
};
let func = env.module.get_function(start_function).unwrap();
let call_result = env
.builder
.build_call(func, &[], "call_expect_start_failed");
let ptr = call_result
.try_as_basic_value()
.left()
.unwrap()
.into_pointer_value();
Self(ptr)
}
}
#[derive(Debug, Clone, Copy)]
struct Cursors<'ctx> {
offset: IntValue<'ctx>,
@ -94,48 +120,39 @@ fn write_state<'a, 'ctx, 'env>(
env.builder.build_store(offset_ptr, offset);
}
pub(crate) fn finalize(env: &Env) {
pub(crate) fn notify_parent_expect(env: &Env, shared_memory: &SharedMemoryPointer) {
let func = env
.module
.get_function(bitcode::UTILS_EXPECT_FAILED_FINALIZE)
.get_function(bitcode::NOTIFY_PARENT_EXPECT)
.unwrap();
env.builder
.build_call(func, &[], "call_expect_failed_finalize");
env.builder.build_call(
func,
&[shared_memory.0.into()],
"call_expect_failed_finalize",
);
}
pub(crate) fn send_dbg(env: &Env) {
let func = env.module.get_function(bitcode::UTILS_SEND_DBG).unwrap();
pub(crate) fn notify_parent_dbg(env: &Env, shared_memory: &SharedMemoryPointer) {
let func = env.module.get_function(bitcode::NOTIFY_PARENT_DBG).unwrap();
env.builder
.build_call(func, &[], "call_expect_failed_finalize");
env.builder.build_call(
func,
&[shared_memory.0.into()],
"call_expect_failed_finalize",
);
}
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
scope: &Scope<'a, 'ctx>,
layout_ids: &mut LayoutIds<'a>,
shared_memory: &SharedMemoryPointer<'ctx>,
condition: Symbol,
region: Region,
lookups: &[Symbol],
) {
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
} else {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
};
let func = env.module.get_function(start_function).unwrap();
let call_result = env
.builder
.build_call(func, &[], "call_expect_start_failed");
let original_ptr = call_result
.try_as_basic_value()
.left()
.unwrap()
.into_pointer_value();
let original_ptr = shared_memory.0;
let (count, mut offset) = read_state(env, original_ptr);

View File

@ -1126,16 +1126,19 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
if env.mode.runs_expects() {
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(args[0]) };
let shared_memory = crate::llvm::expect::SharedMemoryPointer::get(env);
crate::llvm::expect::clone_to_shared_memory(
env,
scope,
layout_ids,
&shared_memory,
args[0],
region,
&[args[0]],
);
crate::llvm::expect::send_dbg(env);
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);
}
condition