From bdc038b5780746d3659b8935bacd5ff89b1e4ffe Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sun, 3 Feb 2019 17:37:46 -0700 Subject: [PATCH] [OCaml] Cache the result of caml_named_value() in some cases The result of caml_named_value() can be cached for (slightly) improved performance. This is mentioned in the OCaml reference manual. https://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#sec453 In addition, fix incorrect use of CAMLreturn() in caml_ptr_val_internal(). --- Lib/ocaml/ocaml.swg | 21 +++++++++++---------- Source/Modules/ocaml.cxx | 6 ++++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg index 8d9877143..92a3637ce 100644 --- a/Lib/ocaml/ocaml.swg +++ b/Lib/ocaml/ocaml.swg @@ -451,27 +451,28 @@ extern "C" { CAMLparam1(v); void *outptr = NULL; swig_type_info *outdescr = NULL; + static CAML_VALUE *func_val = NULL; if( v == Val_unit ) { *out = 0; - CAMLreturn(0); + CAMLreturn_type(0); } if( !Is_block(v) ) return -1; switch( SWIG_Tag_val(v) ) { case C_int: if( !caml_long_val( v ) ) { *out = 0; - CAMLreturn(0); + CAMLreturn_type(0); } else { *out = 0; - CAMLreturn(1); + CAMLreturn_type(1); } break; case C_obj: - CAMLreturn - (caml_ptr_val_internal - (caml_callback(*caml_named_value("caml_obj_ptr"),v), - out,descriptor)); + if (!func_val) { + func_val = caml_named_value("caml_obj_ptr"); + } + CAMLreturn_type(caml_ptr_val_internal(caml_callback(*func_val, v), out, descriptor)); case C_string: outptr = (void *)String_val(SWIG_Field(v,0)); break; @@ -481,11 +482,11 @@ extern "C" { break; default: *out = 0; - CAMLreturn(1); + CAMLreturn_type(1); break; } - - CAMLreturn(SWIG_GetPtr(outptr,out,outdescr,descriptor)); + + CAMLreturn_type(SWIG_GetPtr(outptr, out, outdescr, descriptor)); } SWIGINTERN void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ) { diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 99f2a98d7..2f5e038bb 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -1595,10 +1595,12 @@ public: /* wrap complex arguments to values */ Printv(w->code, wrap_args, NIL); - /* pass the method call on to the Python object */ + /* pass the method call on to the OCaml object */ Printv(w->code, "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0); - Printf(w->code, "swig_result = " "caml_callback3(*caml_named_value(\"swig_runmethod\")," "swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name")); + Printf(w->code, "static CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n"); + Printf(w->code, " swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n }\n"); + Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name")); /* exception handling */ tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); if (!tm) {