add explicit deletion of forgetting objects

This commit is contained in:
vms 2021-03-09 01:01:04 +03:00
parent e577d6b0c8
commit 37cfd15543
5 changed files with 41 additions and 22 deletions

View File

@ -57,6 +57,8 @@ pub use result::get_result_ptr;
pub use result::get_result_size;
pub use result::set_result_ptr;
pub use result::set_result_size;
pub use result::release_objects;
pub use result::add_object_to_release;
#[allow(unused_variables)]
pub(crate) fn log<S: AsRef<str>>(msg: S) {

View File

@ -21,10 +21,13 @@
use super::log;
use std::sync::atomic::AtomicUsize;
use std::cell::RefCell;
static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0);
thread_local!(static OBJECTS_TO_RELEASE: RefCell<Vec<Box<dyn Drop>>> = RefCell::new(Vec::new()));
#[no_mangle]
pub unsafe fn get_result_ptr() -> usize {
log(format!(
@ -58,3 +61,20 @@ pub unsafe fn set_result_size(size: usize) {
*RESULT_SIZE.get_mut() = size;
}
#[no_mangle]
pub unsafe fn release_objects() {
OBJECTS_TO_RELEASE.with(|objects| {
let mut objects = objects.borrow_mut();
while let Some(object) = objects.pop() {
drop(object);
}
})
}
pub fn add_object_to_release(object: Box<dyn Drop>) {
OBJECTS_TO_RELEASE.with(|objects| {
let mut objects = objects.borrow_mut();
objects.push(object);
});
}

View File

@ -1,17 +1,17 @@
/*
* copyright 2020 fluence labs limited
* Copyright 2020 Fluence Labs Limited
*
* licensed under the apache license, version 2.0 (the "license");
* you may not use this file except in compliance with the license.
* you may obtain a copy of the license at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* unless required by applicable law or agreed to in writing, software
* distributed under the license is distributed on an "as is" basis,
* without warranties or conditions of any kind, either express or implied.
* see the license for the specific language governing permissions and
* limitations under the license.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use super::ParsedType;

View File

@ -133,9 +133,9 @@ fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
}
}
/// If an export function returns a reference, probably this reference is to one
/// of these function arguments. In this case they should preserve after the end
/// of the function and then deleted by IT with explicitly call of deallocate.
/// If an export function returns a reference, this is probably a reference to one
/// of the function arguments. If that's the case, reference must be still valid after
/// the end of the function. Their deletion will be handled by IT with calling `release_objects`.
fn generate_mem_forget(
args: &Vec<(String, ParsedType)>,
converted_args: &Vec<syn::Ident>,
@ -144,7 +144,7 @@ fn generate_mem_forget(
let passing_style = ret_type.as_ref().map(passing_style_of);
match passing_style {
Some(PassingStyle::ByValue) => mem_forget_by_ret_type(ret_type),
Some(PassingStyle::ByValue) => quote! { std::mem::forget(result); },
Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => {
mem_forget_by_args(args, converted_args)
}
@ -152,13 +152,6 @@ fn generate_mem_forget(
}
}
fn mem_forget_by_ret_type(ret_type: &Option<ParsedType>) -> proc_macro2::TokenStream {
match ret_type {
Some(_) => quote! { std::mem::forget(result); },
None => quote! {},
}
}
fn mem_forget_by_args(
args: &Vec<(String, ParsedType)>,
converted_args: &Vec<syn::Ident>,
@ -171,7 +164,10 @@ fn mem_forget_by_args(
match arg_passing_style {
// such values will be deleted inside an export function because they are being moved
PassingStyle::ByValue => {}
_ => res.extend(quote! { std::mem::forget(#converted_arg); }),
_ => res.extend(quote! {
fluence::internal::add_object_to_release(Box::new(#converted_arg));
std::mem::forget(#converted_arg);
}),
}
}

View File

@ -90,4 +90,5 @@ pub mod internal {
pub use fluence_sdk_main::get_result_size;
pub use fluence_sdk_main::set_result_ptr;
pub use fluence_sdk_main::set_result_size;
pub use fluence_sdk_main::add_object_to_release;
}