Skip to content

Commit

Permalink
Add various stuff to run 'examples/MillerRabin.java'
Browse files Browse the repository at this point in the history
  • Loading branch information
maekawatoshiki committed Jan 20, 2019
1 parent 2061265 commit df08b14
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 20 deletions.
Binary file added examples/MillerRabin.class
Binary file not shown.
39 changes: 39 additions & 0 deletions examples/MillerRabin.java
@@ -0,0 +1,39 @@
class MillerRabin {
public static boolean prime_miller(int n) {
if (n == 2 || n == 3) return true;
if ((n & 1) == 0) return false;

int d = n - 1;
while ((d & 1) == 0) d = d >> 1;

for (int k = 0; k < 20; k++) {
int t = d;
int q = (int)(Math.random() * (n - 2));
int x = modpow(1 + q, t, n);

while (t != n - 1 && x != 1 && x != n - 1) {
x = modpow(x, 2, n);
t = t << 1;
}

if (x != n - 1 && (t & 1) == 0) return false;
}

return true;
}

public static int modpow(int base, int power, int mod) {
int result = 1;
while (power > 0) {
if ((power & 1) == 1) result = (result * base) % mod;
base = (base * base) % mod;
power = power >> 1;
}
return result;
}

public static void main(String[] args) {
for (int i = 2; i < 30000; i++)
if (prime_miller(i)) System.out.println(i);
}
}
6 changes: 3 additions & 3 deletions src/class/class.rs
Expand Up @@ -201,7 +201,7 @@ impl JITInfoManager {
}

pub fn inc_count_of_loop_exec(&mut self, start: usize, end: usize) {
let (_, count, _) = self.loop_count.entry(start).or_insert((end, 1, None));
let (_, count, _) = self.loop_count.entry(start).or_insert((end, 0, None));
*count += 1;
}

Expand All @@ -212,12 +212,12 @@ impl JITInfoManager {

pub fn loop_executed_enough_times(&self, start: usize) -> bool {
let (_, count, _) = self.loop_count.get(&start).unwrap();
*count > 5
*count > 7
}

pub fn func_executed_enough_times(&self) -> bool {
let (count, _) = &self.whole_method;
*count > 3
*count > 4
}

pub fn get_jit_loop(&mut self, start: usize) -> &mut Option<LoopJITExecInfo> {
Expand Down
12 changes: 11 additions & 1 deletion src/class/classfile/constant.rs
@@ -1,4 +1,5 @@
use super::super::super::exec::frame::Variable;
use super::super::super::exec::frame::{ObjectBody, Variable};
use super::super::super::gc::gc::GcType;

#[derive(Debug, Clone)]
pub enum ConstantType {
Expand Down Expand Up @@ -121,6 +122,15 @@ impl Constant {
}
}

pub fn get_java_string_utf8(&self) -> Option<GcType<ObjectBody>> {
match self {
Constant::Utf8 { java_string, .. } => {
Some(java_string.unwrap().get_pointer::<ObjectBody>())
}
_ => None,
}
}

pub fn get_class_name_index(&self) -> Option<usize> {
match self {
Constant::ClassInfo { name_index } => Some(*name_index as usize),
Expand Down
1 change: 1 addition & 0 deletions src/exec/cfg.rs
Expand Up @@ -61,6 +61,7 @@ impl CFGMaker {
Inst::if_icmpne
| Inst::if_icmpge
| Inst::if_icmpgt
| Inst::if_icmpeq
| Inst::ifne
| Inst::ifeq
| Inst::ifle
Expand Down
87 changes: 73 additions & 14 deletions src/exec/jit.rs
Expand Up @@ -382,6 +382,7 @@ impl JIT {

if let Err(e) = compiling_error {
LLVMDeleteFunction(func);
dprintln!("JIT: compiling error");
return Err(e);
}

Expand Down Expand Up @@ -535,6 +536,7 @@ impl JIT {

if let Err(e) = compiling_error {
LLVMDeleteFunction(func);
dprintln!("JIT: compiling error");
return Err(e);
}

Expand Down Expand Up @@ -773,12 +775,13 @@ impl JIT {
CString::new("").unwrap().as_ptr(),
))
}
Inst::if_icmpne | Inst::if_icmpge | Inst::if_icmpgt => {
Inst::if_icmpne | Inst::if_icmpge | Inst::if_icmpgt | Inst::if_icmpeq => {
let val2 = stack.pop().unwrap();
let val1 = stack.pop().unwrap();
let cond_val = LLVMBuildICmp(
self.builder,
match cur_code {
Inst::if_icmpeq => llvm::LLVMIntPredicate::LLVMIntEQ,
Inst::if_icmpne => llvm::LLVMIntPredicate::LLVMIntNE,
Inst::if_icmpge => llvm::LLVMIntPredicate::LLVMIntSGE,
Inst::if_icmpgt => llvm::LLVMIntPredicate::LLVMIntSGT,
Expand Down Expand Up @@ -905,6 +908,46 @@ impl JIT {
CString::new("dmul").unwrap().as_ptr(),
));
}
Inst::iand => {
let val2 = stack.pop().unwrap();
let val1 = stack.pop().unwrap();
stack.push(LLVMBuildAnd(
self.builder,
val1,
val2,
CString::new("iand").unwrap().as_ptr(),
));
}
Inst::ixor => {
let val2 = stack.pop().unwrap();
let val1 = stack.pop().unwrap();
stack.push(LLVMBuildXor(
self.builder,
val1,
val2,
CString::new("ixor").unwrap().as_ptr(),
));
}
Inst::ishl => {
let val2 = stack.pop().unwrap();
let val1 = stack.pop().unwrap();
stack.push(LLVMBuildShl(
self.builder,
val1,
val2,
CString::new("ishl").unwrap().as_ptr(),
));
}
Inst::ishr => {
let val2 = stack.pop().unwrap();
let val1 = stack.pop().unwrap();
stack.push(LLVMBuildAShr(
self.builder,
val1,
val2,
CString::new("ishr").unwrap().as_ptr(),
));
}
Inst::dcmpl | Inst::dcmpg => self.gen_dcmp(&mut stack)?,
Inst::bipush => {
stack.push(llvm_const_int32(self.context, code[pc + 1] as i8 as u64));
Expand All @@ -924,20 +967,15 @@ impl JIT {
LLVMFloatTypeInContext(self.context),
f as f64,
)),
Constant::String { string_index } => {
let string = cur_class
.get_utf8_from_const_pool(string_index as usize)
Constant::String { string_index } => stack.push(
(&mut *self.cur_class.unwrap())
.get_java_string_utf8_from_const_pool(
(&mut *self.runtime_env).objectheap,
string_index as usize,
)
.unwrap()
.to_owned();
// TODO: Constant string refers to constant pool,
// so should not create a new string object.
// "aaa" == "aaa" // => true
stack.push(
(&mut *(&mut *self.runtime_env).objectheap)
.create_string_object(string, cur_class.classheap.unwrap())
.to_llvm_val(self.context),
)
}
.to_llvm_val(self.context),
),
_ => return Err(Error::CouldntCompile),
};
}
Expand Down Expand Up @@ -1019,10 +1057,31 @@ impl JIT {
);
stack.push(ret);
}
Inst::pop => {
stack.pop().unwrap();
}
Inst::dup => {
let val = stack.last().clone().unwrap();
stack.push(*val);
}
Inst::i2d => {
let val = stack.pop().unwrap();
stack.push(LLVMBuildSIToFP(
self.builder,
val,
VariableType::Double.to_llvmty(self.context),
CString::new("i2d").unwrap().as_ptr(),
));
}
Inst::d2i => {
let val = stack.pop().unwrap();
stack.push(LLVMBuildFPToSI(
self.builder,
val,
VariableType::Int.to_llvmty(self.context),
CString::new("d2i").unwrap().as_ptr(),
));
}
Inst::invokespecial => {}
Inst::invokestatic | Inst::invokevirtual => {
// TODO: The following code should be a method.
Expand Down
13 changes: 12 additions & 1 deletion src/exec/native_functions.rs
Expand Up @@ -16,7 +16,7 @@ pub unsafe fn native_functions(
macro_rules! parse_ty {
(void ) => { VariableType::Void. to_llvmty(context) };
(int ) => { VariableType::Int. to_llvmty(context) };
(double ) => { VariableType::Double. to_llvmty(context) };
(dbl) => { VariableType::Double. to_llvmty(context) };
(ptr) => { VariableType::Pointer.to_llvmty(context) };
}
macro_rules! define_native_function {
Expand All @@ -40,6 +40,7 @@ pub unsafe fn native_functions(
define_native_function!(ptr, [ptr, ptr, int ],"java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;");
define_native_function!(ptr, [ptr, ptr, ptr], "java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;");
define_native_function!(ptr, [ptr, ptr], "java/lang/StringBuilder.toString:()Ljava/lang/String;");
define_native_function!(dbl, [ptr], "java/lang/Math.random:()D");
define_native_function!(ptr, [ptr, ptr], "ferrugo_internal_new");

map
Expand Down Expand Up @@ -74,6 +75,10 @@ pub unsafe fn add_native_functions(
"java/lang/StringBuilder.toString:()Ljava/lang/String;",
java_lang_stringbuilder_tostring_string as *mut libc::c_void,
),
(
"java/lang/Math.random:()D",
java_lang_math_random_d as *mut libc::c_void,
),
(
"ferrugo_internal_new",
ferrugo_internal_new as *mut libc::c_void,
Expand Down Expand Up @@ -176,3 +181,9 @@ pub extern "C" fn ferrugo_internal_new(
let object = unsafe { &mut *renv.objectheap }.create_object(class);
object.get_pointer::<ObjectBody>()
}

#[no_mangle]
pub extern "C" fn java_lang_math_random_d(_renv: *mut RuntimeEnvironment) -> f64 {
use rand::random;
random::<f64>()
}
13 changes: 12 additions & 1 deletion src/exec/vm.rs
Expand Up @@ -431,6 +431,12 @@ impl VM {
frame.sp += 1;
frame.pc += 1;
}
Inst::d2i => {
self.stack[self.bp + frame.sp - 2] =
Variable::Int(self.stack[self.bp + frame.sp - 2].get_double() as i32);
frame.sp -= 1;
frame.pc += 1;
}
Inst::i2s => {
self.stack[self.bp + frame.sp - 1] =
Variable::Short(self.stack[self.bp + frame.sp - 1].get_int() as i16);
Expand Down Expand Up @@ -748,6 +754,10 @@ impl VM {
);
self.stack[self.bp + 0] = Variable::Pointer(s as *mut u64);
}
"java/lang/Math.random:()D" => {
self.stack[self.bp + 0] =
Variable::Double(native_functions::java_lang_math_random_d(self.runtime_env));
}
e => panic!("{:?}", e),
}
}
Expand Down Expand Up @@ -1303,6 +1313,7 @@ pub mod Inst {
pub const ixor: u8 = 130;
pub const iinc: u8 = 132;
pub const i2d: u8 = 135;
pub const d2i: u8 = 142;
pub const i2s: u8 = 147;
pub const dcmpl: u8 = 151;
pub const dcmpg: u8 = 152;
Expand Down Expand Up @@ -1343,7 +1354,7 @@ pub mod Inst {
| astore_3 | iaload | aaload | iastore | aastore | iadd | isub | imul | irem | iand
| dadd | dsub | dmul | ddiv | dneg | i2d | i2s | pop | pop2 | dcmpl | dcmpg | dup
| ireturn | dreturn | areturn | return_ | monitorenter | aconst_null | arraylength
| ishl | ishr | ixor | dup_x1 => 1,
| ishl | ishr | ixor | dup_x1 | d2i => 1,
dstore | astore | istore | ldc | aload | dload | iload | bipush | newarray => 2,
sipush | ldc2_w | iinc | invokestatic | invokespecial | invokevirtual | new | anewarray
| goto | ifeq | ifne | ifle | ifge | if_icmpne | if_icmpge | if_icmpgt | if_icmpeq | if_acmpne |
Expand Down

0 comments on commit df08b14

Please sign in to comment.