mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2026-08-18 12:08:22 +00:00
only reset string arena when it is used
This commit is contained in:
@@ -218,6 +218,7 @@ impl<'types, 'names> CompileFnBuilder<'types, 'names> {
|
||||
let mut lowering_context = LoweringContext {
|
||||
args_ptr,
|
||||
string_arena_ptr,
|
||||
string_arena_was_reset: false,
|
||||
pointer_type,
|
||||
native_functions: &native_functions,
|
||||
};
|
||||
|
||||
@@ -64,7 +64,6 @@ impl CompiledFn {
|
||||
{
|
||||
debug_assert_eq!(args.len(), self.inputs.len());
|
||||
let args: &[VariableValue<'output>] = args;
|
||||
self.string_arena.clear();
|
||||
let string_arena = &raw mut self.string_arena;
|
||||
// SAFETY: Guaranteed by the caller. Both the input and compiled-function
|
||||
// lifetimes outlive the lifetime selected for the returned value.
|
||||
|
||||
@@ -45,6 +45,7 @@ pub fn compile_to_assembly(
|
||||
pub(crate) struct LoweringContext<'a> {
|
||||
args_ptr: CraneliftValue,
|
||||
string_arena_ptr: CraneliftValue,
|
||||
string_arena_was_reset: bool,
|
||||
pointer_type: Type,
|
||||
native_functions: &'a NativeFunctions,
|
||||
}
|
||||
@@ -122,7 +123,17 @@ impl LoweringContext<'_> {
|
||||
self.pointer_type
|
||||
}
|
||||
|
||||
pub(crate) fn string_arena_ptr(&self) -> CraneliftValue {
|
||||
pub(crate) fn string_arena_ptr(&mut self, builder: &mut FunctionBuilder<'_>) -> CraneliftValue {
|
||||
if !self.string_arena_was_reset {
|
||||
let zero = builder.ins().iconst(cranelift_types::I64, 0);
|
||||
builder.ins().store(
|
||||
MemFlagsData::trusted(),
|
||||
zero,
|
||||
self.string_arena_ptr,
|
||||
StringArena::CURSOR_OFFSET,
|
||||
);
|
||||
self.string_arena_was_reset = true;
|
||||
}
|
||||
self.string_arena_ptr
|
||||
}
|
||||
|
||||
@@ -217,10 +228,12 @@ mod tests {
|
||||
let untyped_expr = UntypedExpr::variable("flag");
|
||||
let variable_types = HashMap::from([("flag", VarType::Bool)]);
|
||||
let mut compiled_fn = compile(&untyped_expr, &variable_types).unwrap();
|
||||
assert!(compiled_fn.string_arena.allocate(1).is_some());
|
||||
let input = [VariableValue::some(true)];
|
||||
let output = unsafe { compiled_fn.call(&input) };
|
||||
|
||||
assert_eq!(unsafe { output.as_bool() }, Some(true));
|
||||
assert_eq!(compiled_fn.string_arena.used_bytes(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -7,6 +7,8 @@ pub(crate) struct StringArena {
|
||||
}
|
||||
|
||||
impl StringArena {
|
||||
pub(crate) const CURSOR_OFFSET: i32 = std::mem::offset_of!(StringArena, cursor) as i32;
|
||||
|
||||
pub(crate) fn new() -> Self {
|
||||
let buffer = vec![0; STRING_ARENA_CAPACITY].into_boxed_slice();
|
||||
let buffer = buffer
|
||||
@@ -15,10 +17,6 @@ impl StringArena {
|
||||
Self { buffer, cursor: 0 }
|
||||
}
|
||||
|
||||
pub(crate) fn clear(&mut self) {
|
||||
self.cursor = 0;
|
||||
}
|
||||
|
||||
/// Reserves `len` contiguous bytes without growing the backing allocation.
|
||||
pub(crate) fn allocate(&mut self, len: usize) -> Option<*mut u8> {
|
||||
let end = self.cursor.checked_add(len)?;
|
||||
|
||||
@@ -78,9 +78,11 @@ impl FnCall for LowerFnCall {
|
||||
let arg = context.compile_expr(&self.arg, builder)?;
|
||||
let null = builder.ins().iconst(context.pointer_type(), 0);
|
||||
let input_ptr = builder.ins().select(arg.is_present, arg.value, null);
|
||||
let string_lowercase = context.native_functions().string_lowercase();
|
||||
let string_arena_ptr = context.string_arena_ptr(builder);
|
||||
let call = builder.ins().call(
|
||||
context.native_functions().string_lowercase(),
|
||||
&[input_ptr, arg.string_len, context.string_arena_ptr()],
|
||||
string_lowercase,
|
||||
&[input_ptr, arg.string_len, string_arena_ptr],
|
||||
);
|
||||
let value = builder.inst_results(call)[0];
|
||||
let string_len = builder.inst_results(call)[1];
|
||||
@@ -265,9 +267,7 @@ mod tests {
|
||||
let mut compiled = compile(&expression, &variable_types).unwrap();
|
||||
let input = [VariableValue::some("HeLLo")];
|
||||
|
||||
let output = unsafe { compiled.call(&input) };
|
||||
|
||||
assert_eq!(unsafe { output.as_str() }, Some("hello"));
|
||||
assert_eq!(unsafe { compiled.call(&input).as_str() }, Some("hello"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -275,11 +275,12 @@ mod tests {
|
||||
let expression = deserialize("(EQ (LOWER left) (LOWER right))").unwrap();
|
||||
let variable_types = HashMap::from([("left", VarType::Str), ("right", VarType::Str)]);
|
||||
let mut compiled = compile(&expression, &variable_types).unwrap();
|
||||
let input = [VariableValue::some("FiRsT"), VariableValue::some("fIrSt")];
|
||||
let input = [VariableValue::some("FiRsT"), VariableValue::some("SeCoNd")];
|
||||
|
||||
let output = unsafe { compiled.call(&input) };
|
||||
|
||||
assert_eq!(unsafe { output.as_bool() }, Some(true));
|
||||
assert_eq!(unsafe { output.as_bool() }, Some(false));
|
||||
assert_eq!(compiled.string_arena.used_bytes(), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user