Use const-initialized thread locals (#3923)
This was a relatively recent feature added to the Rust standard library which should help accelerate calls into WebAssembly slightly.
This commit is contained in:
@@ -176,7 +176,7 @@ mod details {
|
|||||||
|
|
||||||
// Information about passes in a single thread.
|
// Information about passes in a single thread.
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static CURRENT_PASS: Cell<Pass> = Cell::new(Pass::None);
|
static CURRENT_PASS: Cell<Pass> = const { Cell::new(Pass::None) };
|
||||||
static PASS_TIME: RefCell<PassTimes> = RefCell::new(Default::default());
|
static PASS_TIME: RefCell<PassTimes> = RefCell::new(Default::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -354,13 +354,16 @@ mod tls {
|
|||||||
// thread local variable and has functions to access the variable.
|
// thread local variable and has functions to access the variable.
|
||||||
//
|
//
|
||||||
// Note that this is specially done to fully encapsulate that the accessors
|
// Note that this is specially done to fully encapsulate that the accessors
|
||||||
// for tls must not be inlined. Wasmtime's async support employs stack
|
// for tls may or may not be inlined. Wasmtime's async support employs stack
|
||||||
// switching which can resume execution on different OS threads. This means
|
// switching which can resume execution on different OS threads. This means
|
||||||
// that borrows of our TLS pointer must never live across accesses because
|
// that borrows of our TLS pointer must never live across accesses because
|
||||||
// otherwise the access may be split across two threads and cause unsafety.
|
// otherwise the access may be split across two threads and cause unsafety.
|
||||||
//
|
//
|
||||||
// This also means that extra care is taken by the runtime to save/restore
|
// This also means that extra care is taken by the runtime to save/restore
|
||||||
// these TLS values when the runtime may have crossed threads.
|
// these TLS values when the runtime may have crossed threads.
|
||||||
|
//
|
||||||
|
// Note, though, that if async support is disabled at compile time then
|
||||||
|
// these functions are free to be inlined.
|
||||||
mod raw {
|
mod raw {
|
||||||
use super::CallThreadState;
|
use super::CallThreadState;
|
||||||
use crate::Trap;
|
use crate::Trap;
|
||||||
@@ -374,9 +377,10 @@ mod tls {
|
|||||||
// allows the runtime to perform per-thread initialization if necessary
|
// allows the runtime to perform per-thread initialization if necessary
|
||||||
// for handling traps (e.g. setting up ports on macOS and sigaltstack on
|
// for handling traps (e.g. setting up ports on macOS and sigaltstack on
|
||||||
// Unix).
|
// Unix).
|
||||||
thread_local!(static PTR: Cell<(Ptr, bool)> = Cell::new((ptr::null(), false)));
|
thread_local!(static PTR: Cell<(Ptr, bool)> = const { Cell::new((ptr::null(), false)) });
|
||||||
|
|
||||||
#[inline(never)] // see module docs for why this is here
|
#[cfg_attr(feature = "async", inline(never))] // see module docs
|
||||||
|
#[cfg_attr(not(feature = "async"), inline)]
|
||||||
pub fn replace(val: Ptr) -> Result<Ptr, Box<Trap>> {
|
pub fn replace(val: Ptr) -> Result<Ptr, Box<Trap>> {
|
||||||
PTR.with(|p| {
|
PTR.with(|p| {
|
||||||
// When a new value is configured that means that we may be
|
// When a new value is configured that means that we may be
|
||||||
@@ -391,9 +395,10 @@ mod tls {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
|
||||||
/// Eagerly initialize thread-local runtime functionality. This will be performed
|
/// Eagerly initialize thread-local runtime functionality. This will be performed
|
||||||
/// lazily by the runtime if users do not perform it eagerly.
|
/// lazily by the runtime if users do not perform it eagerly.
|
||||||
|
#[cfg_attr(feature = "async", inline(never))] // see module docs
|
||||||
|
#[cfg_attr(not(feature = "async"), inline)]
|
||||||
pub fn initialize() -> Result<(), Box<Trap>> {
|
pub fn initialize() -> Result<(), Box<Trap>> {
|
||||||
PTR.with(|p| {
|
PTR.with(|p| {
|
||||||
let (state, initialized) = p.get();
|
let (state, initialized) = p.get();
|
||||||
@@ -406,7 +411,8 @@ mod tls {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)] // see module docs for why this is here
|
#[cfg_attr(feature = "async", inline(never))] // see module docs
|
||||||
|
#[cfg_attr(not(feature = "async"), inline)]
|
||||||
pub fn get() -> Ptr {
|
pub fn get() -> Ptr {
|
||||||
PTR.with(|p| p.get().0)
|
PTR.with(|p| p.get().0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ pub fn lazy_per_thread_init() -> Result<(), Box<Trap>> {
|
|||||||
// when the thread exists. Otherwise this function is only ever called at
|
// when the thread exists. Otherwise this function is only ever called at
|
||||||
// most once per-thread.
|
// most once per-thread.
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static STACK: RefCell<Option<Stack>> = RefCell::new(None);
|
static STACK: RefCell<Option<Stack>> = const { RefCell::new(None) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The size of the sigaltstack (not including the guard, which will be
|
/// The size of the sigaltstack (not including the guard, which will be
|
||||||
|
|||||||
Reference in New Issue
Block a user