Skip to content

Commit 0f1dc9a

Browse files
author
Pat Hickey
authored
Merge pull request #2403 from bjorn3/simplejit_hot_swapping
SimpleJIT hot code swapping
2 parents 09662fa + 937a3fd commit 0f1dc9a

8 files changed

Lines changed: 533 additions & 33 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cranelift/codegen/src/ir/libcall.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub enum LibCall {
6363

6464
/// Elf __tls_get_addr
6565
ElfTlsGetAddr,
66+
// When adding a new variant make sure to add it to `all_libcalls` too.
6667
}
6768

6869
impl fmt::Display for LibCall {
@@ -136,6 +137,33 @@ impl LibCall {
136137
_ => return None,
137138
})
138139
}
140+
141+
/// Get a list of all known `LibCall`'s.
142+
pub fn all_libcalls() -> &'static [LibCall] {
143+
use LibCall::*;
144+
&[
145+
Probestack,
146+
UdivI64,
147+
SdivI64,
148+
UremI64,
149+
SremI64,
150+
IshlI64,
151+
UshrI64,
152+
SshrI64,
153+
CeilF32,
154+
CeilF64,
155+
FloorF32,
156+
FloorF64,
157+
TruncF32,
158+
TruncF64,
159+
NearestF32,
160+
NearestF64,
161+
Memcpy,
162+
Memset,
163+
Memmove,
164+
ElfTlsGetAddr,
165+
]
166+
}
139167
}
140168

141169
/// Get a function reference for `libcall` in `func`, following the signature

cranelift/module/src/module.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,97 @@ pub trait Module {
490490
/// Define a data object, producing the data contents from the given `DataContext`.
491491
fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()>;
492492
}
493+
494+
impl<M: Module> Module for &mut M {
495+
fn isa(&self) -> &dyn isa::TargetIsa {
496+
(**self).isa()
497+
}
498+
499+
fn declarations(&self) -> &ModuleDeclarations {
500+
(**self).declarations()
501+
}
502+
503+
fn get_name(&self, name: &str) -> Option<FuncOrDataId> {
504+
(**self).get_name(name)
505+
}
506+
507+
fn target_config(&self) -> isa::TargetFrontendConfig {
508+
(**self).target_config()
509+
}
510+
511+
fn make_context(&self) -> Context {
512+
(**self).make_context()
513+
}
514+
515+
fn clear_context(&self, ctx: &mut Context) {
516+
(**self).clear_context(ctx)
517+
}
518+
519+
fn make_signature(&self) -> ir::Signature {
520+
(**self).make_signature()
521+
}
522+
523+
fn clear_signature(&self, sig: &mut ir::Signature) {
524+
(**self).clear_signature(sig)
525+
}
526+
527+
fn declare_function(
528+
&mut self,
529+
name: &str,
530+
linkage: Linkage,
531+
signature: &ir::Signature,
532+
) -> ModuleResult<FuncId> {
533+
(**self).declare_function(name, linkage, signature)
534+
}
535+
536+
fn declare_data(
537+
&mut self,
538+
name: &str,
539+
linkage: Linkage,
540+
writable: bool,
541+
tls: bool,
542+
) -> ModuleResult<DataId> {
543+
(**self).declare_data(name, linkage, writable, tls)
544+
}
545+
546+
fn declare_func_in_func(&self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef {
547+
(**self).declare_func_in_func(func, in_func)
548+
}
549+
550+
fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue {
551+
(**self).declare_data_in_func(data, func)
552+
}
553+
554+
fn declare_func_in_data(&self, func: FuncId, ctx: &mut DataContext) -> ir::FuncRef {
555+
(**self).declare_func_in_data(func, ctx)
556+
}
557+
558+
fn declare_data_in_data(&self, data: DataId, ctx: &mut DataContext) -> ir::GlobalValue {
559+
(**self).declare_data_in_data(data, ctx)
560+
}
561+
562+
fn define_function<TS>(
563+
&mut self,
564+
func: FuncId,
565+
ctx: &mut Context,
566+
trap_sink: &mut TS,
567+
) -> ModuleResult<ModuleCompiledFunction>
568+
where
569+
TS: binemit::TrapSink,
570+
{
571+
(**self).define_function(func, ctx, trap_sink)
572+
}
573+
574+
fn define_function_bytes(
575+
&mut self,
576+
func: FuncId,
577+
bytes: &[u8],
578+
relocs: &[RelocRecord],
579+
) -> ModuleResult<ModuleCompiledFunction> {
580+
(**self).define_function_bytes(func, bytes, relocs)
581+
}
582+
583+
fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()> {
584+
(**self).define_data(data, data_ctx)
585+
}
586+
}

cranelift/simplejit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ cranelift-module = { path = "../module", version = "0.68.0" }
1414
cranelift-native = { path = "../native", version = "0.68.0" }
1515
cranelift-codegen = { path = "../codegen", version = "0.68.0", default-features = false, features = ["std"] }
1616
cranelift-entity = { path = "../entity", version = "0.68.0" }
17+
anyhow = "1.0"
1718
region = "2.2.0"
1819
libc = { version = "0.2.42" }
1920
errno = "0.2.4"

cranelift/simplejit/examples/simplejit-minimal.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
use cranelift::prelude::*;
22
use cranelift_codegen::binemit::NullTrapSink;
3+
use cranelift_codegen::settings::{self, Configurable};
34
use cranelift_module::{default_libcall_names, Linkage, Module};
45
use cranelift_simplejit::{SimpleJITBuilder, SimpleJITModule};
56
use std::mem;
67

78
fn main() {
9+
let mut flag_builder = settings::builder();
10+
flag_builder.set("use_colocated_libcalls", "false").unwrap();
11+
// FIXME set back to true once the x64 backend supports it.
12+
flag_builder.set("is_pic", "false").unwrap();
13+
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
14+
panic!("host machine is not supported: {}", msg);
15+
});
16+
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
817
let mut module: SimpleJITModule =
9-
SimpleJITModule::new(SimpleJITBuilder::new(default_libcall_names()));
18+
SimpleJITModule::new(SimpleJITBuilder::with_isa(isa, default_libcall_names()));
19+
1020
let mut ctx = module.make_context();
1121
let mut func_ctx = FunctionBuilderContext::new();
1222

0 commit comments

Comments
 (0)