Move alignment config from declare_data to define_data
This commit is contained in:
@@ -62,7 +62,6 @@ where
|
|||||||
linkage: Linkage,
|
linkage: Linkage,
|
||||||
writable: bool,
|
writable: bool,
|
||||||
tls: bool,
|
tls: bool,
|
||||||
align: Option<u8>,
|
|
||||||
) -> ModuleResult<DataId>;
|
) -> ModuleResult<DataId>;
|
||||||
|
|
||||||
/// Define a function, producing the function body from the given `Context`.
|
/// Define a function, producing the function body from the given `Context`.
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ pub struct DataDescription {
|
|||||||
pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>,
|
pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>,
|
||||||
/// Object file section
|
/// Object file section
|
||||||
pub custom_segment_section: Option<(String, String)>,
|
pub custom_segment_section: Option<(String, String)>,
|
||||||
|
/// Alignment
|
||||||
|
pub align: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is to data objects what cranelift_codegen::Context is to functions.
|
/// This is to data objects what cranelift_codegen::Context is to functions.
|
||||||
@@ -68,6 +70,7 @@ impl DataContext {
|
|||||||
function_relocs: vec![],
|
function_relocs: vec![],
|
||||||
data_relocs: vec![],
|
data_relocs: vec![],
|
||||||
custom_segment_section: None,
|
custom_segment_section: None,
|
||||||
|
align: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,6 +82,8 @@ impl DataContext {
|
|||||||
self.description.data_decls.clear();
|
self.description.data_decls.clear();
|
||||||
self.description.function_relocs.clear();
|
self.description.function_relocs.clear();
|
||||||
self.description.data_relocs.clear();
|
self.description.data_relocs.clear();
|
||||||
|
self.description.custom_segment_section = None;
|
||||||
|
self.description.align = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define a zero-initialized object with the given size.
|
/// Define a zero-initialized object with the given size.
|
||||||
@@ -100,6 +105,12 @@ impl DataContext {
|
|||||||
self.description.custom_segment_section = Some((seg.to_owned(), sec.to_owned()))
|
self.description.custom_segment_section = Some((seg.to_owned(), sec.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the alignment for data. The alignment must be a power of two.
|
||||||
|
pub fn set_align(&mut self, align: u64) {
|
||||||
|
assert!(align.is_power_of_two());
|
||||||
|
self.description.align = Some(align);
|
||||||
|
}
|
||||||
|
|
||||||
/// Declare an external function import.
|
/// Declare an external function import.
|
||||||
///
|
///
|
||||||
/// Users of the `Module` API generally should call
|
/// Users of the `Module` API generally should call
|
||||||
|
|||||||
@@ -182,14 +182,12 @@ pub struct DataDeclaration {
|
|||||||
pub linkage: Linkage,
|
pub linkage: Linkage,
|
||||||
pub writable: bool,
|
pub writable: bool,
|
||||||
pub tls: bool,
|
pub tls: bool,
|
||||||
pub align: Option<u8>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataDeclaration {
|
impl DataDeclaration {
|
||||||
fn merge(&mut self, linkage: Linkage, writable: bool, tls: bool, align: Option<u8>) {
|
fn merge(&mut self, linkage: Linkage, writable: bool, tls: bool) {
|
||||||
self.linkage = Linkage::merge(self.linkage, linkage);
|
self.linkage = Linkage::merge(self.linkage, linkage);
|
||||||
self.writable = self.writable || writable;
|
self.writable = self.writable || writable;
|
||||||
self.align = self.align.max(align);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.tls, tls,
|
self.tls, tls,
|
||||||
"Can't change TLS data object to normal or in the opposite way",
|
"Can't change TLS data object to normal or in the opposite way",
|
||||||
@@ -291,7 +289,6 @@ impl ModuleDeclarations {
|
|||||||
linkage: Linkage,
|
linkage: Linkage,
|
||||||
writable: bool,
|
writable: bool,
|
||||||
tls: bool,
|
tls: bool,
|
||||||
align: Option<u8>, // An alignment bigger than 128 is unlikely
|
|
||||||
) -> ModuleResult<(DataId, &DataDeclaration)> {
|
) -> ModuleResult<(DataId, &DataDeclaration)> {
|
||||||
// TODO: Can we avoid allocating names so often?
|
// TODO: Can we avoid allocating names so often?
|
||||||
use super::hash_map::Entry::*;
|
use super::hash_map::Entry::*;
|
||||||
@@ -299,7 +296,7 @@ impl ModuleDeclarations {
|
|||||||
Occupied(entry) => match *entry.get() {
|
Occupied(entry) => match *entry.get() {
|
||||||
FuncOrDataId::Data(id) => {
|
FuncOrDataId::Data(id) => {
|
||||||
let existing = &mut self.data_objects[id];
|
let existing = &mut self.data_objects[id];
|
||||||
existing.merge(linkage, writable, tls, align);
|
existing.merge(linkage, writable, tls);
|
||||||
Ok((id, existing))
|
Ok((id, existing))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,7 +310,6 @@ impl ModuleDeclarations {
|
|||||||
linkage,
|
linkage,
|
||||||
writable,
|
writable,
|
||||||
tls,
|
tls,
|
||||||
align,
|
|
||||||
});
|
});
|
||||||
entry.insert(FuncOrDataId::Data(id));
|
entry.insert(FuncOrDataId::Data(id));
|
||||||
Ok((id, &self.data_objects[id]))
|
Ok((id, &self.data_objects[id]))
|
||||||
@@ -410,10 +406,9 @@ where
|
|||||||
linkage: Linkage,
|
linkage: Linkage,
|
||||||
writable: bool,
|
writable: bool,
|
||||||
tls: bool,
|
tls: bool,
|
||||||
align: Option<u8>, // An alignment bigger than 128 is unlikely
|
|
||||||
) -> ModuleResult<DataId> {
|
) -> ModuleResult<DataId> {
|
||||||
self.backend
|
self.backend
|
||||||
.declare_data(name, linkage, writable, tls, align)
|
.declare_data(name, linkage, writable, tls)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this when you're building the IR of a function to reference a function.
|
/// Use this when you're building the IR of a function to reference a function.
|
||||||
|
|||||||
@@ -194,11 +194,10 @@ impl Backend for ObjectBackend {
|
|||||||
linkage: Linkage,
|
linkage: Linkage,
|
||||||
writable: bool,
|
writable: bool,
|
||||||
tls: bool,
|
tls: bool,
|
||||||
align: Option<u8>,
|
|
||||||
) -> ModuleResult<DataId> {
|
) -> ModuleResult<DataId> {
|
||||||
let (id, decl) = self
|
let (id, decl) = self
|
||||||
.declarations
|
.declarations
|
||||||
.declare_data(name, linkage, writable, tls, align)?;
|
.declare_data(name, linkage, writable, tls)?;
|
||||||
|
|
||||||
let kind = if decl.tls {
|
let kind = if decl.tls {
|
||||||
SymbolKind::Tls
|
SymbolKind::Tls
|
||||||
@@ -365,6 +364,7 @@ impl Backend for ObjectBackend {
|
|||||||
ref function_relocs,
|
ref function_relocs,
|
||||||
ref data_relocs,
|
ref data_relocs,
|
||||||
ref custom_segment_section,
|
ref custom_segment_section,
|
||||||
|
align,
|
||||||
} = data_ctx.description();
|
} = data_ctx.description();
|
||||||
|
|
||||||
let reloc_size = match self.isa.triple().pointer_width().unwrap() {
|
let reloc_size = match self.isa.triple().pointer_width().unwrap() {
|
||||||
@@ -431,7 +431,7 @@ impl Backend for ObjectBackend {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let align = u64::from(decl.align.unwrap_or(1));
|
let align = align.unwrap_or(1);
|
||||||
let offset = match *init {
|
let offset = match *init {
|
||||||
Init::Uninitialized => {
|
Init::Uninitialized => {
|
||||||
panic!("data is not initialized yet");
|
panic!("data is not initialized yet");
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ use target_lexicon::PointerWidth;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winapi;
|
use winapi;
|
||||||
|
|
||||||
const EXECUTABLE_DATA_ALIGNMENT: u8 = 0x10;
|
const EXECUTABLE_DATA_ALIGNMENT: u64 = 0x10;
|
||||||
const WRITABLE_DATA_ALIGNMENT: u8 = 0x8;
|
const WRITABLE_DATA_ALIGNMENT: u64 = 0x8;
|
||||||
const READONLY_DATA_ALIGNMENT: u8 = 0x1;
|
const READONLY_DATA_ALIGNMENT: u64 = 0x1;
|
||||||
|
|
||||||
/// A builder for `SimpleJITBackend`.
|
/// A builder for `SimpleJITBackend`.
|
||||||
pub struct SimpleJITBuilder {
|
pub struct SimpleJITBuilder {
|
||||||
@@ -415,12 +415,11 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
|||||||
linkage: Linkage,
|
linkage: Linkage,
|
||||||
writable: bool,
|
writable: bool,
|
||||||
tls: bool,
|
tls: bool,
|
||||||
align: Option<u8>,
|
|
||||||
) -> ModuleResult<DataId> {
|
) -> ModuleResult<DataId> {
|
||||||
assert!(!tls, "SimpleJIT doesn't yet support TLS");
|
assert!(!tls, "SimpleJIT doesn't yet support TLS");
|
||||||
let (id, _decl) = self
|
let (id, _decl) = self
|
||||||
.declarations
|
.declarations
|
||||||
.declare_data(name, linkage, writable, tls, align)?;
|
.declare_data(name, linkage, writable, tls)?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,18 +541,19 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
|||||||
ref function_relocs,
|
ref function_relocs,
|
||||||
ref data_relocs,
|
ref data_relocs,
|
||||||
custom_segment_section: _,
|
custom_segment_section: _,
|
||||||
|
align,
|
||||||
} = data.description();
|
} = data.description();
|
||||||
|
|
||||||
let size = init.size();
|
let size = init.size();
|
||||||
let storage = if decl.writable {
|
let storage = if decl.writable {
|
||||||
self.memory
|
self.memory
|
||||||
.writable
|
.writable
|
||||||
.allocate(size, decl.align.unwrap_or(WRITABLE_DATA_ALIGNMENT))
|
.allocate(size, align.unwrap_or(WRITABLE_DATA_ALIGNMENT))
|
||||||
.expect("TODO: handle OOM etc.")
|
.expect("TODO: handle OOM etc.")
|
||||||
} else {
|
} else {
|
||||||
self.memory
|
self.memory
|
||||||
.readonly
|
.readonly
|
||||||
.allocate(size, decl.align.unwrap_or(READONLY_DATA_ALIGNMENT))
|
.allocate(size, align.unwrap_or(READONLY_DATA_ALIGNMENT))
|
||||||
.expect("TODO: handle OOM etc.")
|
.expect("TODO: handle OOM etc.")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use libc;
|
|||||||
use memmap::MmapMut;
|
use memmap::MmapMut;
|
||||||
|
|
||||||
use region;
|
use region;
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
@@ -149,10 +150,11 @@ impl Memory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: Use a proper error type.
|
/// TODO: Use a proper error type.
|
||||||
pub fn allocate(&mut self, size: usize, align: u8) -> Result<*mut u8, String> {
|
pub fn allocate(&mut self, size: usize, align: u64) -> Result<*mut u8, String> {
|
||||||
if self.position % align as usize != 0 {
|
let align = usize::try_from(align).expect("alignment too big");
|
||||||
self.position += align as usize - self.position % align as usize;
|
if self.position % align != 0 {
|
||||||
debug_assert!(self.position % align as usize == 0);
|
self.position += align - self.position % align;
|
||||||
|
debug_assert!(self.position % align == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if size <= self.current.len - self.position {
|
if size <= self.current.len - self.position {
|
||||||
|
|||||||
Reference in New Issue
Block a user