Skip to content
Browse files

fixed memory leak in jitted i386 nci code; clone nci

git-svn-id: https://svn.parrot.org/parrot/trunk@2798 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
1 parent acc79b2 commit 11b723d96edec03f71c00430daf3dcb03e9e134d Leopold Toetsch committed Dec 14, 2002
Showing with 122 additions and 15 deletions.
  1. +4 −2 build_nativecall.pl
  2. +4 −2 build_tools/build_nativecall.pl
  3. +27 −1 classes/nci.pmc
  4. +1 −1 include/parrot/jit.h
  5. +1 −1 include/parrot/nci.h
  6. +2 −3 jit/i386/jit_emit.h
  7. +3 −2 method_util.c
  8. +3 −2 src/method_util.c
  9. +77 −1 t/pmc/nci.t
View
6 build_nativecall.pl
@@ -140,16 +140,18 @@
/* This function serves a single purpose. It takes the function
signature for a C function we want to call and returns a pointer
to a function that can call it. */
-void *build_call_func(struct Parrot_Interp *interpreter, String *signature) {
+void *build_call_func(struct Parrot_Interp *interpreter, PMC *pmc_nci,
+ String *signature) {
#if defined(CAN_BUILD_CALL_FRAMES)
/* This would be a good place to put the code that builds the
frames. Undoubtedly painfully platform-dependent */
- return Parrot_jit_build_call_func(interpreter, signature);
+ return Parrot_jit_build_call_func(interpreter, pmc_nci, signature);
#else
/* And in here is the platform-independent way. Which is to say
"here there be hacks" */
+ UNUSED(pmc_nci);
if (0 == string_length(signature)) return F2DPTR(pcf_v_v);
$icky_global_bit
PANIC("Unknown signature type");
View
6 build_tools/build_nativecall.pl
@@ -140,16 +140,18 @@
/* This function serves a single purpose. It takes the function
signature for a C function we want to call and returns a pointer
to a function that can call it. */
-void *build_call_func(struct Parrot_Interp *interpreter, String *signature) {
+void *build_call_func(struct Parrot_Interp *interpreter, PMC *pmc_nci,
+ String *signature) {
#if defined(CAN_BUILD_CALL_FRAMES)
/* This would be a good place to put the code that builds the
frames. Undoubtedly painfully platform-dependent */
- return Parrot_jit_build_call_func(interpreter, signature);
+ return Parrot_jit_build_call_func(interpreter, pmc_nci, signature);
#else
/* And in here is the platform-independent way. Which is to say
"here there be hacks" */
+ UNUSED(pmc_nci);
if (0 == string_length(signature)) return F2DPTR(pcf_v_v);
$icky_global_bit
PANIC("Unknown signature type");
View
28 classes/nci.pmc
@@ -17,6 +17,18 @@
pmclass NCI {
void init () {
+ PObj_custom_mark_SET(SELF);
+ }
+
+
+ PMC* mark (PMC *end_of_used_list) {
+ PMC *f = SELF->cache.struct_val;
+ if (f) {
+ return mark_used(f, end_of_used_list);
+ }
+ else {
+ return end_of_used_list;
+ }
}
INTVAL type () {
@@ -27,8 +39,22 @@ pmclass NCI {
return whoami;
}
+ void destroy() {
+ if (SELF->data)
+ free(SELF->data);
+ }
+
PMC* clone () {
- return Parrot_new_csub(INTERP, (Parrot_csub_t)D2FPTR(SELF->cache.struct_val));
+ PMC *ret = pmc_new(INTERP, enum_class_NCI);
+ ret->cache.struct_val = (DPOINTER *)
+ (Parrot_csub_t)D2FPTR(SELF->cache.struct_val);
+ /* FIXME if data is malloced (JIT/i386!) then we need
+ * the length of data here, to memcpy it
+ * ManagedStruct or Buffer?
+ */
+ ret->data = SELF->data;
+ PObj_custom_mark_SET(ret);
+ return ret;
}
PMC* get_pmc () {
View
2 include/parrot/jit.h
@@ -232,7 +232,7 @@ void Parrot_jit_emit_mov_rm_n(
void Parrot_jit_emit_mov_rm(
struct Parrot_Interp *interpreter, int reg, char *mem);
-void *Parrot_jit_build_call_func(struct Parrot_Interp *, String *signature);
+void *Parrot_jit_build_call_func(struct Parrot_Interp *, PMC *, String *);
#endif /* JIT_H_GUARD */
View
2 include/parrot/nci.h
@@ -15,6 +15,6 @@
#include "parrot/parrot.h"
-void *build_call_func(struct Parrot_Interp *, String *);
+void *build_call_func(struct Parrot_Interp *, PMC *, String *);
#endif
View
5 jit/i386/jit_emit.h
@@ -2040,10 +2040,8 @@ Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
Parrot_emit_jump_to_eax(jit_info, interpreter);
}
-void * Parrot_jit_build_call_func(struct Parrot_Interp *, String *);
-
void *
-Parrot_jit_build_call_func(struct Parrot_Interp *interpreter,
+Parrot_jit_build_call_func(struct Parrot_Interp *interpreter, PMC *pmc_nci,
String *signature)
{
Parrot_jit_info_t jit_info;
@@ -2206,6 +2204,7 @@ Parrot_jit_build_call_func(struct Parrot_Interp *interpreter,
emitm_ret(pc);
assert(pc - jit_info.arena.start <= size);
/* could shrink arena.start here to used size */
+ PObj_active_destroy_SET(pmc_nci);
return (jit_f)D2FPTR(jit_info.arena.start);
}
View
5 method_util.c
@@ -19,11 +19,12 @@
* Create a new native sub. (new way)
*/
PMC *
-Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func, String *signature)
+Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func,
+ String *signature)
{
PMC *ret = pmc_new(interp, enum_class_NCI);
ret->cache.struct_val = (DPOINTER *)F2DPTR(func);
- ret->data = build_call_func(interp, signature);
+ ret->data = build_call_func(interp, ret, signature);
return ret;
}
View
5 src/method_util.c
@@ -19,11 +19,12 @@
* Create a new native sub. (new way)
*/
PMC *
-Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func, String *signature)
+Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func,
+ String *signature)
{
PMC *ret = pmc_new(interp, enum_class_NCI);
ret->cache.struct_val = (DPOINTER *)F2DPTR(func);
- ret->data = build_call_func(interp, signature);
+ ret->data = build_call_func(interp, ret, signature);
return ret;
}
View
78 t/pmc/nci.t
@@ -1,4 +1,4 @@
-use Parrot::Test tests => 9;
+use Parrot::Test tests => 11;
use Test::More qw/skip/;
use Parrot::Config;
@@ -304,5 +304,81 @@ OUTPUT
}
+output_is(gen_test(<<'CODE'), <<'OUTPUT', "nci_d_d - stress test");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ set I10, 1000000
+ print "dlfunced\n"
+loop:
+ dlfunc P0, P1, "nci_dd", "dd"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set N5, 4.0
+ invoke
+ ne N5, 8.0, nok_1
+ dec I10
+ gt I10, 0, loop
+ print "ok 1\n"
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 0, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 1, nok_2
+ print "ok 2\n"
+ end
+nok_1: print "nok 1\n"
+ print N5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok 1
+ok 2
+OUTPUT
+
+output_is(gen_test(<<'CODE'), <<'OUTPUT', "nci_d_d - clone");
+ loadlib P1, "libnci.so"
+ print "loaded\n"
+ dlfunc P0, P1, "nci_dd", "dd"
+ print "dlfunced\n"
+ clone P2, P0
+ print "ok 1\n"
+ set I0, 1 # prototype used - unchecked
+ set I1, 0 # items on stack - unchecked
+ set N5, 4.0
+ invoke
+ ne N5, 8.0, nok_1
+ print "ok 2\n"
+ set I0, 1
+ set I1, 0
+ set N5, 4.0
+ set P0, P2
+ invoke
+ ne N5, 8.0, nok_1
+ print "ok 3\n"
+ ne I0, 0, nok_2 # test return value convention
+ ne I1, 0, nok_2
+ ne I2, 0, nok_2
+ ne I3, 0, nok_2
+ ne I4, 1, nok_2
+ print "ok 4\n"
+ end
+nok_1: print "nok 1\n"
+ print N5
+ print "\n"
+ end
+nok_2: print "nok 2\n"
+ end
+CODE
+loaded
+dlfunced
+ok 1
+ok 2
+ok 3
+ok 4
+OUTPUT
1;

0 comments on commit 11b723d

Please sign in to comment.
Something went wrong with that request. Please try again.