mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
pass the pointer to shared memory around, instead of using a global
This commit is contained in:
parent
8307a194e1
commit
95fe9cbccd
6 changed files with 68 additions and 55 deletions
|
@ -44,8 +44,6 @@ pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
|
||||||
|
|
||||||
const ptr = @ptrCast([*]u8, shared_ptr);
|
const ptr = @ptrCast([*]u8, shared_ptr);
|
||||||
|
|
||||||
SHARED_BUFFER = ptr[0..length];
|
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
} else {
|
} else {
|
||||||
unreachable;
|
unreachable;
|
||||||
|
@ -81,17 +79,11 @@ pub fn readSharedBufferEnv() callconv(.C) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_atomic_ptr() *Atomic(u32) {
|
pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
|
||||||
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), SHARED_BUFFER.ptr));
|
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||||
|
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), shared_buffer));
|
||||||
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
|
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
|
||||||
|
atomic_ptr.storeUnchecked(tag);
|
||||||
return atomic_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expectFailedFinalize() callconv(.C) void {
|
|
||||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
|
||||||
const atomic_ptr = get_atomic_ptr();
|
|
||||||
atomic_ptr.storeUnchecked(1);
|
|
||||||
|
|
||||||
// wait till the parent is done before proceeding
|
// wait till the parent is done before proceeding
|
||||||
const Ordering = std.atomic.Ordering;
|
const Ordering = std.atomic.Ordering;
|
||||||
|
@ -101,15 +93,10 @@ pub fn expectFailedFinalize() callconv(.C) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sendDbg() callconv(.C) void {
|
pub fn notifyParentExpect(shared_buffer: [*]u8) callconv(.C) void {
|
||||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
notifyParent(shared_buffer, 1);
|
||||||
const atomic_ptr = get_atomic_ptr();
|
}
|
||||||
atomic_ptr.storeUnchecked(2);
|
|
||||||
|
pub fn notifyParentDbg(shared_buffer: [*]u8) callconv(.C) void {
|
||||||
// wait till the parent is done before proceeding
|
notifyParent(shared_buffer, 2);
|
||||||
const Ordering = std.atomic.Ordering;
|
|
||||||
while (atomic_ptr.load(Ordering.Acquire) != 0) {
|
|
||||||
std.atomic.spinLoopHint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,8 +172,8 @@ comptime {
|
||||||
if (builtin.target.cpu.arch != .wasm32) {
|
if (builtin.target.cpu.arch != .wasm32) {
|
||||||
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
|
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
|
||||||
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
|
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
|
||||||
exportUtilsFn(expect.expectFailedFinalize, "expect_failed_finalize");
|
exportUtilsFn(expect.notifyParentExpect, "notify_parent_expect");
|
||||||
exportUtilsFn(expect.sendDbg, "send_dbg");
|
exportUtilsFn(expect.notifyParentDbg, "notify_parent_dbg");
|
||||||
|
|
||||||
// sets the buffer used for expect failures
|
// sets the buffer used for expect failures
|
||||||
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });
|
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });
|
||||||
|
|
|
@ -424,9 +424,9 @@ pub const UTILS_EXPECT_FAILED_START_SHARED_BUFFER: &str =
|
||||||
"roc_builtins.utils.expect_failed_start_shared_buffer";
|
"roc_builtins.utils.expect_failed_start_shared_buffer";
|
||||||
pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
|
pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
|
||||||
"roc_builtins.utils.expect_failed_start_shared_file";
|
"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_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_LONGJMP: &str = "longjmp";
|
||||||
pub const UTILS_SETJMP: &str = "setjmp";
|
pub const UTILS_SETJMP: &str = "setjmp";
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::llvm::build_list::{self, allocate_list, empty_polymorphic_list};
|
||||||
use crate::llvm::convert::{
|
use crate::llvm::convert::{
|
||||||
argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type,
|
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::{
|
use crate::llvm::refcounting::{
|
||||||
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
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() {
|
match env.target_info.ptr_width() {
|
||||||
roc_target::PtrWidth::Bytes8 => {
|
roc_target::PtrWidth::Bytes8 => {
|
||||||
|
let shared_memory = SharedMemoryPointer::get(env);
|
||||||
|
|
||||||
clone_to_shared_memory(
|
clone_to_shared_memory(
|
||||||
env,
|
env,
|
||||||
scope,
|
scope,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
&shared_memory,
|
||||||
*cond_symbol,
|
*cond_symbol,
|
||||||
*region,
|
*region,
|
||||||
lookups,
|
lookups,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let LlvmBackendMode::BinaryDev = env.mode {
|
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);
|
bd.build_unconditional_branch(then_block);
|
||||||
|
@ -2677,10 +2680,13 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
match env.target_info.ptr_width() {
|
match env.target_info.ptr_width() {
|
||||||
roc_target::PtrWidth::Bytes8 => {
|
roc_target::PtrWidth::Bytes8 => {
|
||||||
|
let shared_memory = SharedMemoryPointer::get(env);
|
||||||
|
|
||||||
clone_to_shared_memory(
|
clone_to_shared_memory(
|
||||||
env,
|
env,
|
||||||
scope,
|
scope,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
&shared_memory,
|
||||||
*cond_symbol,
|
*cond_symbol,
|
||||||
*region,
|
*region,
|
||||||
lookups,
|
lookups,
|
||||||
|
|
|
@ -18,6 +18,32 @@ use super::build::{
|
||||||
Scope,
|
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)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct Cursors<'ctx> {
|
struct Cursors<'ctx> {
|
||||||
offset: IntValue<'ctx>,
|
offset: IntValue<'ctx>,
|
||||||
|
@ -94,48 +120,39 @@ fn write_state<'a, 'ctx, 'env>(
|
||||||
env.builder.build_store(offset_ptr, offset);
|
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
|
let func = env
|
||||||
.module
|
.module
|
||||||
.get_function(bitcode::UTILS_EXPECT_FAILED_FINALIZE)
|
.get_function(bitcode::NOTIFY_PARENT_EXPECT)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
env.builder
|
env.builder.build_call(
|
||||||
.build_call(func, &[], "call_expect_failed_finalize");
|
func,
|
||||||
|
&[shared_memory.0.into()],
|
||||||
|
"call_expect_failed_finalize",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn send_dbg(env: &Env) {
|
pub(crate) fn notify_parent_dbg(env: &Env, shared_memory: &SharedMemoryPointer) {
|
||||||
let func = env.module.get_function(bitcode::UTILS_SEND_DBG).unwrap();
|
let func = env.module.get_function(bitcode::NOTIFY_PARENT_DBG).unwrap();
|
||||||
|
|
||||||
env.builder
|
env.builder.build_call(
|
||||||
.build_call(func, &[], "call_expect_failed_finalize");
|
func,
|
||||||
|
&[shared_memory.0.into()],
|
||||||
|
"call_expect_failed_finalize",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
|
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
scope: &Scope<'a, 'ctx>,
|
scope: &Scope<'a, 'ctx>,
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
|
shared_memory: &SharedMemoryPointer<'ctx>,
|
||||||
condition: Symbol,
|
condition: Symbol,
|
||||||
region: Region,
|
region: Region,
|
||||||
lookups: &[Symbol],
|
lookups: &[Symbol],
|
||||||
) {
|
) {
|
||||||
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
|
let original_ptr = shared_memory.0;
|
||||||
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 (count, mut offset) = read_state(env, original_ptr);
|
let (count, mut offset) = read_state(env, original_ptr);
|
||||||
|
|
||||||
|
|
|
@ -1126,16 +1126,19 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
||||||
if env.mode.runs_expects() {
|
if env.mode.runs_expects() {
|
||||||
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(args[0]) };
|
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(
|
crate::llvm::expect::clone_to_shared_memory(
|
||||||
env,
|
env,
|
||||||
scope,
|
scope,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
&shared_memory,
|
||||||
args[0],
|
args[0],
|
||||||
region,
|
region,
|
||||||
&[args[0]],
|
&[args[0]],
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::llvm::expect::send_dbg(env);
|
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
condition
|
condition
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue