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.
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -354,13 +354,16 @@ mod tls {
|
||||
// thread local variable and has functions to access the variable.
|
||||
//
|
||||
// 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
|
||||
// that borrows of our TLS pointer must never live across accesses because
|
||||
// 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
|
||||
// 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 {
|
||||
use super::CallThreadState;
|
||||
use crate::Trap;
|
||||
@@ -374,9 +377,10 @@ mod tls {
|
||||
// allows the runtime to perform per-thread initialization if necessary
|
||||
// for handling traps (e.g. setting up ports on macOS and sigaltstack on
|
||||
// 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>> {
|
||||
PTR.with(|p| {
|
||||
// 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
|
||||
/// 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>> {
|
||||
PTR.with(|p| {
|
||||
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 {
|
||||
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
|
||||
// most once per-thread.
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user