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::get_result_size;
pub use result::set_result_ptr; pub use result::set_result_ptr;
pub use result::set_result_size; pub use result::set_result_size;
pub use result::release_objects;
pub use result::add_object_to_release;
#[allow(unused_variables)] #[allow(unused_variables)]
pub(crate) fn log<S: AsRef<str>>(msg: S) { pub(crate) fn log<S: AsRef<str>>(msg: S) {

View File

@ -21,10 +21,13 @@
use super::log; use super::log;
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use std::cell::RefCell;
static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0); static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
static mut RESULT_SIZE: 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] #[no_mangle]
pub unsafe fn get_result_ptr() -> usize { pub unsafe fn get_result_ptr() -> usize {
log(format!( log(format!(
@ -58,3 +61,20 @@ pub unsafe fn set_result_size(size: usize) {
*RESULT_SIZE.get_mut() = size; *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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the license. * you may not use this file except in compliance with the License.
* you may obtain a copy of the license at * 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 * Unless required by applicable law or agreed to in writing, software
* distributed under the license is distributed on an "as is" basis, * distributed under the License is distributed on an "AS IS" BASIS,
* without warranties or conditions of any kind, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* see the license for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the license. * limitations under the License.
*/ */
use super::ParsedType; 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 /// If an export function returns a reference, this is probably a reference to one
/// of these function arguments. In this case they should preserve after the end /// of the function arguments. If that's the case, reference must be still valid after
/// of the function and then deleted by IT with explicitly call of deallocate. /// the end of the function. Their deletion will be handled by IT with calling `release_objects`.
fn generate_mem_forget( fn generate_mem_forget(
args: &Vec<(String, ParsedType)>, args: &Vec<(String, ParsedType)>,
converted_args: &Vec<syn::Ident>, converted_args: &Vec<syn::Ident>,
@ -144,7 +144,7 @@ fn generate_mem_forget(
let passing_style = ret_type.as_ref().map(passing_style_of); let passing_style = ret_type.as_ref().map(passing_style_of);
match passing_style { 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) => { Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => {
mem_forget_by_args(args, converted_args) 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( fn mem_forget_by_args(
args: &Vec<(String, ParsedType)>, args: &Vec<(String, ParsedType)>,
converted_args: &Vec<syn::Ident>, converted_args: &Vec<syn::Ident>,
@ -171,7 +164,10 @@ fn mem_forget_by_args(
match arg_passing_style { match arg_passing_style {
// such values will be deleted inside an export function because they are being moved // such values will be deleted inside an export function because they are being moved
PassingStyle::ByValue => {} 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::get_result_size;
pub use fluence_sdk_main::set_result_ptr; pub use fluence_sdk_main::set_result_ptr;
pub use fluence_sdk_main::set_result_size; pub use fluence_sdk_main::set_result_size;
pub use fluence_sdk_main::add_object_to_release;
} }