Skip to content
This repository
Browse code

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...
commit 11b723d96edec03f71c00430daf3dcb03e9e134d 1 parent acc79b2
Leopold Toetsch authored
6 build_nativecall.pl
@@ -140,16 +140,18 @@
140 140 /* This function serves a single purpose. It takes the function
141 141 signature for a C function we want to call and returns a pointer
142 142 to a function that can call it. */
143   -void *build_call_func(struct Parrot_Interp *interpreter, String *signature) {
  143 +void *build_call_func(struct Parrot_Interp *interpreter, PMC *pmc_nci,
  144 + String *signature) {
144 145 #if defined(CAN_BUILD_CALL_FRAMES)
145 146 /* This would be a good place to put the code that builds the
146 147 frames. Undoubtedly painfully platform-dependent */
147 148
148   - return Parrot_jit_build_call_func(interpreter, signature);
  149 + return Parrot_jit_build_call_func(interpreter, pmc_nci, signature);
149 150
150 151 #else
151 152 /* And in here is the platform-independent way. Which is to say
152 153 "here there be hacks" */
  154 + UNUSED(pmc_nci);
153 155 if (0 == string_length(signature)) return F2DPTR(pcf_v_v);
154 156 $icky_global_bit
155 157 PANIC("Unknown signature type");
6 build_tools/build_nativecall.pl
@@ -140,16 +140,18 @@
140 140 /* This function serves a single purpose. It takes the function
141 141 signature for a C function we want to call and returns a pointer
142 142 to a function that can call it. */
143   -void *build_call_func(struct Parrot_Interp *interpreter, String *signature) {
  143 +void *build_call_func(struct Parrot_Interp *interpreter, PMC *pmc_nci,
  144 + String *signature) {
144 145 #if defined(CAN_BUILD_CALL_FRAMES)
145 146 /* This would be a good place to put the code that builds the
146 147 frames. Undoubtedly painfully platform-dependent */
147 148
148   - return Parrot_jit_build_call_func(interpreter, signature);
  149 + return Parrot_jit_build_call_func(interpreter, pmc_nci, signature);
149 150
150 151 #else
151 152 /* And in here is the platform-independent way. Which is to say
152 153 "here there be hacks" */
  154 + UNUSED(pmc_nci);
153 155 if (0 == string_length(signature)) return F2DPTR(pcf_v_v);
154 156 $icky_global_bit
155 157 PANIC("Unknown signature type");
28 classes/nci.pmc
@@ -17,6 +17,18 @@
17 17 pmclass NCI {
18 18
19 19 void init () {
  20 + PObj_custom_mark_SET(SELF);
  21 + }
  22 +
  23 +
  24 + PMC* mark (PMC *end_of_used_list) {
  25 + PMC *f = SELF->cache.struct_val;
  26 + if (f) {
  27 + return mark_used(f, end_of_used_list);
  28 + }
  29 + else {
  30 + return end_of_used_list;
  31 + }
20 32 }
21 33
22 34 INTVAL type () {
@@ -27,8 +39,22 @@ pmclass NCI {
27 39 return whoami;
28 40 }
29 41
  42 + void destroy() {
  43 + if (SELF->data)
  44 + free(SELF->data);
  45 + }
  46 +
30 47 PMC* clone () {
31   - return Parrot_new_csub(INTERP, (Parrot_csub_t)D2FPTR(SELF->cache.struct_val));
  48 + PMC *ret = pmc_new(INTERP, enum_class_NCI);
  49 + ret->cache.struct_val = (DPOINTER *)
  50 + (Parrot_csub_t)D2FPTR(SELF->cache.struct_val);
  51 + /* FIXME if data is malloced (JIT/i386!) then we need
  52 + * the length of data here, to memcpy it
  53 + * ManagedStruct or Buffer?
  54 + */
  55 + ret->data = SELF->data;
  56 + PObj_custom_mark_SET(ret);
  57 + return ret;
32 58 }
33 59
34 60 PMC* get_pmc () {
2  include/parrot/jit.h
@@ -232,7 +232,7 @@ void Parrot_jit_emit_mov_rm_n(
232 232 void Parrot_jit_emit_mov_rm(
233 233 struct Parrot_Interp *interpreter, int reg, char *mem);
234 234
235   -void *Parrot_jit_build_call_func(struct Parrot_Interp *, String *signature);
  235 +void *Parrot_jit_build_call_func(struct Parrot_Interp *, PMC *, String *);
236 236
237 237 #endif /* JIT_H_GUARD */
238 238
2  include/parrot/nci.h
@@ -15,6 +15,6 @@
15 15
16 16 #include "parrot/parrot.h"
17 17
18   -void *build_call_func(struct Parrot_Interp *, String *);
  18 +void *build_call_func(struct Parrot_Interp *, PMC *, String *);
19 19
20 20 #endif
5 jit/i386/jit_emit.h
@@ -2040,10 +2040,8 @@ Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
2040 2040 Parrot_emit_jump_to_eax(jit_info, interpreter);
2041 2041 }
2042 2042
2043   -void * Parrot_jit_build_call_func(struct Parrot_Interp *, String *);
2044   -
2045 2043 void *
2046   -Parrot_jit_build_call_func(struct Parrot_Interp *interpreter,
  2044 +Parrot_jit_build_call_func(struct Parrot_Interp *interpreter, PMC *pmc_nci,
2047 2045 String *signature)
2048 2046 {
2049 2047 Parrot_jit_info_t jit_info;
@@ -2206,6 +2204,7 @@ Parrot_jit_build_call_func(struct Parrot_Interp *interpreter,
2206 2204 emitm_ret(pc);
2207 2205 assert(pc - jit_info.arena.start <= size);
2208 2206 /* could shrink arena.start here to used size */
  2207 + PObj_active_destroy_SET(pmc_nci);
2209 2208 return (jit_f)D2FPTR(jit_info.arena.start);
2210 2209 }
2211 2210
5 method_util.c
@@ -19,11 +19,12 @@
19 19 * Create a new native sub. (new way)
20 20 */
21 21 PMC *
22   -Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func, String *signature)
  22 +Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func,
  23 + String *signature)
23 24 {
24 25 PMC *ret = pmc_new(interp, enum_class_NCI);
25 26 ret->cache.struct_val = (DPOINTER *)F2DPTR(func);
26   - ret->data = build_call_func(interp, signature);
  27 + ret->data = build_call_func(interp, ret, signature);
27 28 return ret;
28 29 }
29 30
5 src/method_util.c
@@ -19,11 +19,12 @@
19 19 * Create a new native sub. (new way)
20 20 */
21 21 PMC *
22   -Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func, String *signature)
  22 +Parrot_new_nci(struct Parrot_Interp *interp, Parrot_csub_t func,
  23 + String *signature)
23 24 {
24 25 PMC *ret = pmc_new(interp, enum_class_NCI);
25 26 ret->cache.struct_val = (DPOINTER *)F2DPTR(func);
26   - ret->data = build_call_func(interp, signature);
  27 + ret->data = build_call_func(interp, ret, signature);
27 28 return ret;
28 29 }
29 30
78 t/pmc/nci.t
... ... @@ -1,4 +1,4 @@
1   -use Parrot::Test tests => 9;
  1 +use Parrot::Test tests => 11;
2 2 use Test::More qw/skip/;
3 3 use Parrot::Config;
4 4
@@ -304,5 +304,81 @@ OUTPUT
304 304
305 305 }
306 306
  307 +output_is(gen_test(<<'CODE'), <<'OUTPUT', "nci_d_d - stress test");
  308 + loadlib P1, "libnci.so"
  309 + print "loaded\n"
  310 + set I10, 1000000
  311 + print "dlfunced\n"
  312 +loop:
  313 + dlfunc P0, P1, "nci_dd", "dd"
  314 + set I0, 1 # prototype used - unchecked
  315 + set I1, 0 # items on stack - unchecked
  316 + set N5, 4.0
  317 + invoke
  318 + ne N5, 8.0, nok_1
  319 + dec I10
  320 + gt I10, 0, loop
  321 + print "ok 1\n"
  322 + ne I0, 0, nok_2 # test return value convention
  323 + ne I1, 0, nok_2
  324 + ne I2, 0, nok_2
  325 + ne I3, 0, nok_2
  326 + ne I4, 1, nok_2
  327 + print "ok 2\n"
  328 + end
  329 +nok_1: print "nok 1\n"
  330 + print N5
  331 + print "\n"
  332 + end
  333 +nok_2: print "nok 2\n"
  334 + end
  335 +CODE
  336 +loaded
  337 +dlfunced
  338 +ok 1
  339 +ok 2
  340 +OUTPUT
  341 +
  342 +output_is(gen_test(<<'CODE'), <<'OUTPUT', "nci_d_d - clone");
  343 + loadlib P1, "libnci.so"
  344 + print "loaded\n"
  345 + dlfunc P0, P1, "nci_dd", "dd"
  346 + print "dlfunced\n"
  347 + clone P2, P0
  348 + print "ok 1\n"
  349 + set I0, 1 # prototype used - unchecked
  350 + set I1, 0 # items on stack - unchecked
  351 + set N5, 4.0
  352 + invoke
  353 + ne N5, 8.0, nok_1
  354 + print "ok 2\n"
  355 + set I0, 1
  356 + set I1, 0
  357 + set N5, 4.0
  358 + set P0, P2
  359 + invoke
  360 + ne N5, 8.0, nok_1
  361 + print "ok 3\n"
  362 + ne I0, 0, nok_2 # test return value convention
  363 + ne I1, 0, nok_2
  364 + ne I2, 0, nok_2
  365 + ne I3, 0, nok_2
  366 + ne I4, 1, nok_2
  367 + print "ok 4\n"
  368 + end
  369 +nok_1: print "nok 1\n"
  370 + print N5
  371 + print "\n"
  372 + end
  373 +nok_2: print "nok 2\n"
  374 + end
  375 +CODE
  376 +loaded
  377 +dlfunced
  378 +ok 1
  379 +ok 2
  380 +ok 3
  381 +ok 4
  382 +OUTPUT
307 383 1;
308 384

0 comments on commit 11b723d

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