-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add quickjs_common to maintain dependecy list
- Loading branch information
Showing
8 changed files
with
86 additions
and
7 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,5 +3,6 @@ resolver = "2" | |
members = [ | ||
"quickjs", | ||
"quickjs_gc", | ||
"quickjs_backtrace" | ||
"quickjs_backtrace", | ||
"quickjs_common" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "quickjs_common" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
backtrace = "0.3.67" | ||
libc = "0.2.146" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub use libc; | ||
pub use backtrace; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
#![feature(offset_of)] | ||
|
||
mod record; | ||
|
||
use std::mem::offset_of; | ||
|
||
/// Represents a node in a doubly linked list. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use std::mem::offset_of; | ||
use backtrace::Backtrace; | ||
use crate::{JSGCObjectHeader, ListHead, print_gc_objects}; | ||
|
||
// Global GC objects map | ||
lazy_static::lazy_static! { | ||
static ref GC_OBJECTS: Mutex<HashMap<*const JSGCObjectHeader, Backtrace>> = Mutex::new(HashMap::new()); | ||
} | ||
|
||
/// Records the creation of a new GC object in the global map. | ||
/// | ||
/// # Safety | ||
/// | ||
/// This function is `unsafe` because it takes a raw pointer. | ||
/// The caller must ensure that `gc_object` is a valid pointer. | ||
#[no_mangle] | ||
pub unsafe extern "C" fn record_gc_object_creation(gc_object: *mut JSGCObjectHeader) { | ||
let bt = Backtrace::new(); | ||
GC_OBJECTS.lock().unwrap().insert(gc_object, bt); | ||
} | ||
|
||
/// Prints the details of leaked GC objects, if any. | ||
#[no_mangle] | ||
pub extern "C" fn get_leaked_gc_objects() { | ||
unsafe { | ||
print_gc_objects(list_head); | ||
|
||
// Leverage the `print_gc_objects` function to access each object | ||
// in the list, and compare it with the objects in the map. | ||
let map = GC_OBJECTS.lock().unwrap(); | ||
for (&gc_object, bt) in map.iter() { | ||
if !is_in_list(list_head, gc_object) { | ||
// This object is not in the list, so it must be leaked. | ||
println!("Leaked GC object at address {:?} with backtrace:\n{:?}", gc_object, bt); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Checks if the given GC object is in the list. | ||
/// | ||
/// # Safety | ||
/// | ||
/// This function is `unsafe` because it takes a raw pointer and dereferences it. | ||
/// The caller must ensure that both `list_head` and `gc_object` are valid pointers. | ||
unsafe fn is_in_list(list_head: *mut ListHead, gc_object: *const JSGCObjectHeader) -> bool { | ||
let mut cur_node = (*list_head).next(); | ||
while cur_node as *const _ != list_head { | ||
let cur_gc_object = (cur_node as *mut ListHead as *mut u8) | ||
.offset(-(offset_of!(JSGCObjectHeader, link) as isize)) | ||
as *mut JSGCObjectHeader; | ||
if cur_gc_object == gc_object { | ||
return true; | ||
} | ||
cur_node = (*cur_node).next(); | ||
} | ||
false | ||
} |