Commits

camlspotter  committed 14bd792 Draft

added test code and possible bug fix

  • Participants
  • Parent commits f53c8c4
  • Branches gc_debug

Comments (0)

Files changed (7)

-.*\.(cm*|o|a|sp.t|annot)
+.*\.(cm*|o|a|sp.t|annot|so|log)
 \#.*#
 .*~
-camljava-0\.3/lib/jni\.ml
-ojacare/src/ojacare
-ojacare/src/parser/lexer\.ml
-ojacare/src/parser/parser\.ml
-ojacare/src/parser/parser\.mli
+camljava-0\.3/lib/jni\.ml$
+ojacare/src/ojacare$
+ojacare/src/parser/lexer\.ml$
+ojacare/src/parser/parser\.ml$
+ojacare/src/parser/parser\.mli$
 
+camljava-0.3/test_simple_call_from_java/Test.h$
+camljava-0.3/test_simple_call_from_java_to_ocaml/Test.h$
+
+callback/.*
+ojacare/examples/awt/awt
+ojacare/examples/awt/callback/java/awt/event/ActionListener.java
+ojacare/examples/observer/observer
+ojacare/examples/ojdvi/mldvi-1.0.tar.gz
+ojacare/examples/point/point
+ojacare/examples/rectangle/rectangle
+ojacare/examples/visitorML/visitorML

File camljava-0.3/lib/fr/inria/caml/camljava/Callback.java

 package fr.inria.caml.camljava;
 
 public class Callback {
-    public Callback(long obj) { objref = obj; }
+    public Callback(long obj) { 
+	System.out.println("Callback construct " + obj);
+	System.gc();
+	objref = obj; 
+    }
 
-    protected void finalize() { freeWrapper(objref); }
+    protected void finalize() { 
+	System.out.println("Callback finalize " + objref);
+	freeWrapper(objref); 
+    }
 
     public native static long getCamlMethodID(String method_name);
 

File camljava-0.3/lib/jnistubs.c

 static void finalize_jobject(value v)
 {
   jobject obj = JObject(v);
+  fprintf(stderr, "finalize_jobject(value)!!!\n");
   if (obj != NULL) (*jenv)->DeleteGlobalRef(jenv, obj);
 }
 
   custom_deserialize_default    /* TODO? use Java serialization intf */
 };
 
+// Create an OCaml value from Java object.
+// It creates a new Global Reference to the object.
+// This new global ref is deleted when the OCaml value is GCed.
+// See finalize_jobject().
 static value alloc_jobject(jobject obj)
 {
   value v = alloc_custom(&jobject_ops, sizeof(jobject), 0, 1);
 {
   jobject res = (*jenv)->AllocObject(jenv, JObject(vclass));
   if (res == NULL) check_java_exception();
-  return alloc_jobject(res);
+  value v = alloc_jobject(res);
+  (*jenv)->DeleteGlobalRef(jenv, res);
+  return v;
 }
 
 value camljava_GetObjectClass(value vobj)
 
 /****************** Auxiliary functions for callbacks *****************/
 
+// Copy the value pointer and register it to the root, 
+// and returns it as an int64
 value camljava_WrapCamlObject(value vobj)
 {
   value * wrapper = stat_alloc(sizeof(value));
   *wrapper = vobj;
   register_global_root(wrapper);
+  fprintf(stderr, "> CAMLOBJECT %d\n", (int)wrapper); 
   return copy_int64((int64) (value) wrapper);
 }
 
 void camljava_FreeWrapper(JNIEnv * env, jclass cls, jlong wrapper)
 {
   value * w = (value *) (value) wrapper;
+  fprintf(stderr, "< CAMLOBJECT %d\n", (int)w); 
   remove_global_root(w);
   stat_free(w);
 }

File camljava-0.3/test_gc/Makefile

+include ../Makefile.config
+
+CAMLJAVA=$(shell ocamlfind printconf destdir)/camljava/camljava.jar
+
+all: jnitest Test.class Testcb.class
+	CLASSPATH=. ./jnitest
+
+jnitest: jnitest.ml
+	ocamlfind ocamlc -package camljava -g -o jnitest jni.cma jnitest.ml
+
+clean::
+	rm -f jnitest
+
+.SUFFIXES: .java .class
+
+.java.class:
+	$(JAVAC) -classpath $(CAMLJAVA):. $*.java
+
+clean::
+	rm -f *.cm?
+	rm -f *.class

File camljava-0.3/test_gc/Test.java

+class Test {
+  static void f()
+  {
+    System.out.println("f"); 
+  }
+  static int g(int x, int y)
+  {
+    System.out.println("g " + x + " " + y); 
+    return x + y;
+  }
+  static int a;
+  int b;
+  int h() {
+    System.out.println("h");
+    return b;
+  }
+  static int k(Testcb cb, int x)
+  {
+    System.out.println("k " + x);
+    cb.f();
+    System.gc();
+    return cb.g(x); 
+  }
+}

File camljava-0.3/test_gc/Testcb.java

+import fr.inria.caml.camljava.Callback;
+
+class Testcb {
+    private Callback cb;
+    private static long _f = Callback.getCamlMethodID("f");
+    private static long _g = Callback.getCamlMethodID("g");
+    public Testcb(Callback c) { 
+	System.out.println("Testcb construct");
+	cb = c; 
+    }
+    protected void finalize() { 
+	System.out.println("Testcb finalize");
+    }
+    public void f()
+    { Object[] args = { }; cb.callVoid(_f, args); }
+    public int g(int x)
+    { Object[] args = { new fr.inria.caml.camljava.Camlint(x) };
+      return cb.callCamlint(_g, args); }
+}

File camljava-0.3/test_gc/jnitest.ml

+open Jni
+
+class cls n = object
+  method f = print_string "cls.f called"; print_newline()
+  method g x =
+    print_string "cls.g called with "; print_int x; print_newline();
+    x+n
+end
+
+let wrap_caml_object n =
+  Gc.full_major ();
+  (* The OCaml object [camlobj], and its Java object [co] *)
+  let camlobj = new cls n in
+  let co = wrap_object camlobj in
+
+  (* Allocate  the result Java object *)
+  let cls = find_class "Testcb" in
+  let o = alloc_object cls in
+
+  (* Initialize [o] using the constructor [i] of [c] *)
+  let init = get_methodID cls 
+    "<init>"                               (* the constructor *)
+    "(Lfr/inria/caml/camljava/Callback;)V" (* the type *)
+  in
+  call_nonvirtual_void_method o cls init [|Obj co|];
+  o
+
+let test() =
+  (* Static method invocation *)
+  let c = find_class "Test" in
+  let f = get_static_methodID c "f" "()V" in
+  print_string "Calling Test.f()"; print_newline();
+  call_static_void_method c f [||];
+  let g = get_static_methodID c "g" "(II)I" in
+  print_string "Calling Test.g(12,45)"; print_newline();
+  let r = call_static_int_method c g [|Camlint 12; Camlint 45|] in
+  print_string "Result is: "; print_string (Int32.to_string r); 
+  print_newline();
+  (* Static field access *)
+  let a = get_static_fieldID c "a" "I" in
+  print_string "Current value of Test.a is: ";
+  print_string (Int32.to_string (get_static_int_field c a));
+  print_newline();
+  print_string "Setting Test.a to 12"; print_newline();
+  set_static_int_field c a (Int32.of_int 12);
+  print_string "Current value of Test.a is: ";
+  print_string (Int32.to_string (get_static_int_field c a));
+  print_newline();
+  (* Object creation *)
+  print_string "Creating an instance of Test..."; print_newline();
+  let o = alloc_object c in
+  let init = get_methodID c "<init>" "()V" in
+  call_nonvirtual_void_method o c init [||];
+  (* Virtual method invocation *)
+  let h = get_methodID c "h" "()I" in
+  print_string "Calling testinstance.h()"; print_newline();
+  let r = call_int_method o h [||] in
+  print_string "Result is: "; print_string (Int32.to_string r); 
+  print_newline();
+  (* Instance field access *)
+  let b = get_fieldID c "b" "I" in
+  print_string "Setting testinstance.b to 45"; print_newline();
+  set_int_field o b (Int32.of_int 45);
+  print_string "Calling testinstance.h()"; print_newline();
+  let r = call_int_method o h [||] in
+  print_string "Result is: "; print_string (Int32.to_string r); 
+  print_newline();
+  print_string "Current value of testinstance.b is: ";
+  print_string (Int32.to_string (get_int_field o b));
+  print_newline();
+  print_string "Wrapping Caml object into Java object..."; print_newline();
+  let k = get_static_methodID c "k" "(LTestcb;I)I" in
+  for i = 0 to 30000 do 
+    let cb = wrap_caml_object i in
+    print_string "Calling Test.k(<caml object>, 2)"; print_newline();
+    let r = call_static_int_method c k [|Obj cb; Camlint 2|] in
+    print_string "Result is: "; print_string (Int32.to_string r); 
+    print_newline()
+  done
+
+let _ =
+  test()