Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Dec 11, 2024
1 parent 9261849 commit 6b63e1e
Show file tree
Hide file tree
Showing 18 changed files with 518 additions and 134 deletions.
88 changes: 88 additions & 0 deletions common/src/atomic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
AtomicU64, AtomicU8, AtomicUsize, Ordering,
};

pub struct AtomicF32 {
inner: AtomicU32,
}

impl AtomicF32 {
pub fn new(value: f32) -> Self {
Self {
inner: AtomicU32::new(value.to_bits()),
}
}
pub fn store(&self, value: f32, ordering: Ordering) {
self.inner.store(value.to_bits(), ordering)
}
pub fn load(&self, ordering: Ordering) -> f32 {
let as_u64 = self.inner.load(ordering);
f32::from_bits(as_u64)
}
}

pub struct AtomicF64 {
inner: AtomicU64,
}

impl AtomicF64 {
pub fn new(value: f64) -> Self {
Self {
inner: AtomicU64::new(value.to_bits()),
}
}
pub fn store(&self, value: f64, ordering: Ordering) {
self.inner.store(value.to_bits(), ordering)
}
pub fn load(&self, ordering: Ordering) -> f64 {
let as_u64 = self.inner.load(ordering);
f64::from_bits(as_u64)
}
}

pub trait Atomic {
type Output;

fn new(v: Self::Output) -> Self;
fn load(&self, order: Ordering) -> Self::Output;
fn store(&self, val: Self::Output, order: Ordering);
}

macro_rules! impl_atomic {
($(($ty:ty, $output:ty)),+ $(,)?) => {
$(
impl Atomic for $ty {
type Output = $output;

fn new(v: Self::Output) -> Self {
Self::new(v)
}

fn load(&self, order: Ordering) -> Self::Output {
self.load(order)
}

fn store(&self, val: Self::Output, order: Ordering) {
self.store(val, order);
}
}
)+
}
}

impl_atomic!(
(AtomicBool, bool),
(AtomicU8, u8),
(AtomicU16, u16),
(AtomicU32, u32),
(AtomicU64, u64),
(AtomicI8, i8),
(AtomicI16, i16),
(AtomicI32, i32),
(AtomicI64, i64),
(AtomicUsize, usize),
(AtomicIsize, isize),
(AtomicF32, f32),
(AtomicF64, f64),
);
1 change: 1 addition & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod atomic;
pub mod endian;
pub mod error;
pub mod int_types;
Expand Down
12 changes: 7 additions & 5 deletions generators/native_methods/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ impl SymbolCollector {
generated_directory,
"class_names.symbols",
&symbols_file_contents,
);
)
.unwrap();

const METHOD_NAME_SECTION_HEADER: &str = "// Methods";
const METHOD_NAME_MARKER_COMMENT: &str =
Expand All @@ -96,7 +97,8 @@ impl SymbolCollector {
generated_directory,
"method_names.symbols",
&symbols_file_contents,
);
)
.unwrap();

const METHOD_SIGNATURE_SECTION_HEADER: &str = "// Signatures";
const METHOD_SIGNATURE_MARKER_COMMENT: &str =
Expand All @@ -109,7 +111,8 @@ impl SymbolCollector {
generated_directory,
"signature_names.symbols",
&symbols_file_contents,
);
)
.unwrap();
}

/// Gets the position of a marker comment (eg. "// Classes")
Expand Down Expand Up @@ -320,8 +323,7 @@ fn create_modules_string(modules: &[Module]) -> Result<String> {
}

let mut common_root_depth = module.common_root_depth(previous_module) as usize;
let mut needs_module_definition =
common_root_depth != module.components.len() || is_new_root;
let needs_module_definition = common_root_depth != module.components.len() || is_new_root;
if common_root_depth == module.components.len() {
common_root_depth = 0;
}
Expand Down
1 change: 0 additions & 1 deletion generators/native_methods/src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::path::{Path, PathBuf};

use walkdir::WalkDir;

const MAX_MODULE_NAME_DEPTH: u8 = 5;
static METHOD_DEFINITION_DIR_NAME: &str = "def";

#[derive(Debug)]
Expand Down
6 changes: 2 additions & 4 deletions generators/native_methods/src/registernatives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ macro_rules! native_method_table_file_header {
() => {
r#"use crate::native::{{NativeMethodDef, NativeMethodPtr}};
use std::sync::atomic::{{AtomicBool, Ordering}};
static NATIVES_REGISTERED: AtomicBool = AtomicBool::new(false);
static NATIVES_REGISTERED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
#[allow(trivial_casts, unused_imports)]
pub fn registerNatives(_: std::ptr::NonNull<JniEnv>) {{
use symbols::sym;
if NATIVES_REGISTERED.compare_exchange(false, true, Ordering::SeqCst, Ordering::Acquire) != Ok(false) {{
if NATIVES_REGISTERED.compare_exchange(false, true, std::sync::atomic::Ordering::SeqCst, std::sync::atomic::Ordering::Acquire) != Ok(false) {{
return;
}}
Expand Down
7 changes: 4 additions & 3 deletions runtime/src/globals/classes.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::objects::class::Class;

use std::cell::UnsafeCell;
use std::cell::SyncUnsafeCell;

macro_rules! define_classes {
($($name:ident),+ $(,)?) => {
paste::paste! {
$(
#[allow(non_upper_case_globals)]
static mut [<$name _>]: UnsafeCell<Option<&'static Class>> = UnsafeCell::new(None);
static [<$name _>]: SyncUnsafeCell<Option<&'static Class>> = SyncUnsafeCell::new(None);

#[doc = "Set the loaded " $name " class"]
///
Expand All @@ -16,7 +16,8 @@ macro_rules! define_classes {
/// This must only be called once
#[allow(non_snake_case)]
pub unsafe fn [<set_ $name>](class: &'static Class) {
*[<$name _>].get_mut() = Some(class);
let ptr = [<$name _>].get();
unsafe { *ptr = Some(class); }
}

#[doc = "Get the loaded " $name " class"]
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/globals/threads.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::reference::Reference;

use std::cell::UnsafeCell;
use std::cell::SyncUnsafeCell;
use std::mem::MaybeUninit;

static mut THREAD_GROUP: UnsafeCell<MaybeUninit<Reference>> =
UnsafeCell::new(MaybeUninit::uninit());
static THREAD_GROUP: SyncUnsafeCell<MaybeUninit<Reference>> =
SyncUnsafeCell::new(MaybeUninit::uninit());

/// Get the main thread group
///
Expand Down
14 changes: 7 additions & 7 deletions runtime/src/native/java/io/FileDescriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::classpath::classloader::ClassLoader;
use crate::reference::Reference;

use std::cell::UnsafeCell;
use std::cell::SyncUnsafeCell;
use std::ptr::NonNull;
use std::sync::atomic::{AtomicBool, Ordering};

Expand All @@ -14,12 +14,12 @@ use symbols::sym;
include_generated!("native/java/io/def/FileDescriptor.definitions.rs");

/// `java.io.FileDescriptor#fd` field offset
static mut fd: UnsafeCell<usize> = UnsafeCell::new(0);
static fd: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);
/// `java.io.FileDescriptor#handle` field offset
#[cfg(windows)]
static mut handle: UnsafeCell<usize> = UnsafeCell::new(0);
static handle: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);
/// `java.io.FileDescriptor#append` field offset
static mut append: UnsafeCell<usize> = UnsafeCell::new(0);
static append: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);

// throws SyncFailedException
pub fn sync0(_: NonNull<JniEnv>, _this: Reference) {
Expand All @@ -46,16 +46,16 @@ pub fn initIDs(_: NonNull<JniEnv>) {
match field.name.as_str() {
"fd" => unsafe {
assert!(fields & 1 << 3 == 0, "Field can only occur once");
*fd.get_mut() = index;
*fd.get() = index;
fields |= 1 << 2;
},
#[cfg(windows)]
"handle" => unsafe {
*handle.get_mut() = index;
*handle.get() = index;
fields |= 1 << 1;
},
"append" => unsafe {
*append.get_mut() = index;
*append.get() = index;
fields |= 1;
},
_ => {},
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/native/java/io/FileInputStream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::classpath::classloader::ClassLoader;
use crate::reference::Reference;

use std::cell::UnsafeCell;
use std::cell::SyncUnsafeCell;
use std::ptr::NonNull;
use std::sync::atomic::{AtomicBool, Ordering};

Expand All @@ -14,7 +14,7 @@ use symbols::sym;
include_generated!("native/java/io/def/FileInputStream.definitions.rs");

/// `java.io.FileInputStream#fd` field offset
static mut fd: UnsafeCell<usize> = UnsafeCell::new(0);
static fd: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);

// throws FileNotFoundException
pub fn open0(_: NonNull<JniEnv>, _this: Reference, _name: Reference /* java.lang.String */) {
Expand Down Expand Up @@ -84,7 +84,7 @@ pub fn initIDs(_: NonNull<JniEnv>) {
for (index, field) in class.fields().enumerate() {
if field.name == sym!(fd) {
unsafe {
*fd.get_mut() = index;
*fd.get() = index;
}
field_set = true;
break;
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/native/java/io/FileOutputStream.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::classpath::classloader::ClassLoader;
use crate::native::Reference;

use std::cell::UnsafeCell;
use std::cell::SyncUnsafeCell;
use std::ptr::NonNull;
use std::sync::atomic::{AtomicBool, Ordering};

Expand All @@ -12,7 +12,7 @@ use symbols::sym;
include_generated!("native/java/io/def/FileOutputStream.definitions.rs");

/// `java.io.FileInputStream#fd` field offset
static mut fd: UnsafeCell<usize> = UnsafeCell::new(0);
static fd: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);

// throws FileNotFoundException
pub fn open0(_: NonNull<JniEnv>, _this: Reference, _name: Reference /* java.lang.String */) {
Expand Down Expand Up @@ -55,7 +55,7 @@ pub fn initIDs(_: NonNull<JniEnv>) {
for (index, field) in class.fields().enumerate() {
if field.name == sym!(fd) {
unsafe {
*fd.get_mut() = index;
*fd.get() = index;
}
field_set = true;
break;
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/native/java/lang/Object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn clone(_: NonNull<JniEnv>, this: Reference /* java.lang.Object */) -> Refe

let instance_ref = this.extract_class();
let instance = instance_ref.get();
if !instance.class.is_cloneable() {
if !instance.class().is_cloneable() {
// TODO
panic!("CloneNotSupportedException");
}
Expand Down
7 changes: 6 additions & 1 deletion runtime/src/native/java/lang/Thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::reference::Reference;
use crate::JavaThread;

use std::ptr::NonNull;
use std::sync::atomic::AtomicUsize;

use ::jni::env::JniEnv;
use ::jni::sys::{jboolean, jint, jlong};
Expand Down Expand Up @@ -109,5 +110,9 @@ pub fn setNativeName(
}

pub fn getNextThreadIdOffset(_env: NonNull<JniEnv>) -> jlong {
unimplemented!("java.lang.Thread#getNextThreadIdOffset");
// https://github.com/openjdk/jdk/blob/a3b58ee5cd1ec0ea78649d4128d272458b05eb13/src/java.base/share/classes/java/lang/Thread.java#L624-L627
const INITIAL_THREAD_ID: usize = 3;
static NEXT_THREAD_ID: AtomicUsize = AtomicUsize::new(INITIAL_THREAD_ID);

NEXT_THREAD_ID.as_ptr() as jlong
}
17 changes: 8 additions & 9 deletions runtime/src/native/java/lang/Throwable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@ mod stacktrace_element {
use crate::reference::Reference;
use crate::string_interner::StringInterner;

use std::sync::atomic::Ordering;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};

use common::traits::PtrType;
use instructions::Operand;
use symbols::sym;

static mut INITIALIZED: Mutex<bool> = Mutex::new(false);

static mut StackTraceElement_classLoaderName_FIELD_OFFSET: usize = 0;
static mut StackTraceElement_moduleName_FIELD_OFFSET: usize = 0;
static mut StackTraceElement_moduleVersion_FIELD_OFFSET: usize = 0;
Expand All @@ -39,8 +36,12 @@ mod stacktrace_element {
static mut StackTraceElement_lineNumber_FIELD_OFFSET: usize = 0;

unsafe fn initialize(class: &'static Class) {
let mut initialized = INITIALIZED.lock().unwrap();
if *initialized {
static ONCE: AtomicBool = AtomicBool::new(false);
if ONCE
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{
// Already initialized
return;
}

Expand Down Expand Up @@ -100,8 +101,6 @@ mod stacktrace_element {
field_set, 0b1111111,
"Not all fields were found in java/lang/StackTraceElement"
);

*initialized = true;
}

pub fn from_stack_frame(stacktrace_element_class: &'static Class, frame: &Frame) -> Reference {
Expand Down Expand Up @@ -171,7 +170,7 @@ pub fn fillInStackTrace(
let current_thread = unsafe { &*JavaThread::for_env(env.as_ptr() as _) };

let this_class_instance = this.extract_class();
let this_class = this_class_instance.get().class;
let this_class = this_class_instance.get().class();
// TODO: Make global field
let stacktrace_field = this_class.fields().find(|field| {
field.name.as_str() == "stackTrace" && matches!(&field.descriptor, FieldType::Array(value) if value.is_class(b"java/lang/StackTraceElement"))
Expand Down
Loading

0 comments on commit 6b63e1e

Please sign in to comment.