=== src/pmc/jitcode.pmc ================================================================== --- src/pmc/jitcode.pmc (revision 82) +++ src/pmc/jitcode.pmc (revision 83) @@ -0,0 +1,73 @@ +/* +Copyright (C) 2009-, Parrot Foundation. + +=head1 DESCRIPTION + +src/pmc/jitcode.pmc - JIT code memory management + +=head1 DESCRIPTION + +C provides a class to hold memory areas used for JIT code. + +JIT-specific structure instead of C is used +because underlying method of allocating and freeing executable memory +varies from platform to another (though those are really hidden behind +mem_free_executable and its relatives.) + +=head2 Methods + +=over 4 + +=cut + +*/ + +#include "parrot/parrot.h" + +pmclass JitCode need_ext no_ro { + ATTR void *code; + ATTR INTVAL size; + + VTABLE void init() { + Parrot_JitCode_attributes *attr = + mem_allocate_typed(Parrot_JitCode_attributes); + + PMC_data(SELF) = attr; + PObj_active_destroy_SET(SELF); + SET_ATTR_code(INTERP, SELF, NULL); + SET_ATTR_size(INTERP, SELF, 0); + } + + VTABLE void destroy() { + Parrot_JitCode_attributes * attr = PARROT_JITCODE(SELF); + if (attr->code) + mem_free_executable(attr->code, attr->size); + } + + VTABLE PMC *clone() { + Parrot_JitCode_attributes * const attr = PARROT_JITCODE(SELF); + PMC *dest = pmc_new(interp, SELF->vtable->base_type); + Parrot_JitCode_attributes * dattr = PARROT_JITCODE(dest); + + if (attr->code) { + dattr->size = attr->size; + dattr->code = mem_alloc_executable(attr->size); + memcpy(dattr->code, attr->code, attr->size); + } + + return dest; + } + + VTABLE STRING *get_string() { + Parrot_JitCode_attributes * const attr = PARROT_JITCODE(SELF); + + return Parrot_sprintf_c(INTERP, "code[%p/%d]", attr->code, attr->size); + } +} + +/* + * Local variables: + * c-file-style: "parrot" + * End: + * vim: expandtab shiftwidth=4: + */ === src/jit/i386/jit_defs.c ================================================================== --- src/jit/i386/jit_defs.c (revision 82) +++ src/jit/i386/jit_defs.c (revision 83) @@ -2118,7 +2118,8 @@ */ void * -Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature) +Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, + size_t *size_ret) { Parrot_jit_info_t jit_info; char *pc; @@ -2450,6 +2451,8 @@ PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE); /* could shrink arena.start here to used size */ PObj_active_destroy_SET(pmc_nci); + if (size_ret) + *size_ret = JIT_ALLOC_SIZE; return (void *)D2FPTR(jit_info.arena.start); } === src/jit/i386/jit_emit.h ================================================================== --- src/jit/i386/jit_emit.h (revision 82) +++ src/jit/i386/jit_emit.h (revision 83) @@ -1879,7 +1879,7 @@ size_t calc_signature_needs(const char *sig, int *strings); void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, - STRING *signature); + STRING *signature, size_t *size_ret); /* * register usage === src/jit.h ================================================================== --- src/jit.h (revision 82) +++ src/jit.h (revision 83) @@ -321,7 +321,7 @@ /* * NCI interface */ -void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *); +void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, size_t *); #endif /* PARROT_JIT_H_GUARD */ === tools/build/nativecall.pl ================================================================== --- tools/build/nativecall.pl (revision 82) +++ tools/build/nativecall.pl (revision 83) @@ -197,6 +197,7 @@ #include "parrot/oplib/ops.h" #include "pmc/pmc_nci.h" #include "nci.str" +#include "pmc/pmc_jitcode.h" /* HEADERIZER HFILE: none */ /* HEADERIZER STOP */ @@ -549,16 +550,20 @@ jit_key_name = Parrot_str_concat(interp, jit_key_name, signature, 0); b = VTABLE_get_pmc_keyed_str(interp, HashPointer, jit_key_name); - if (b && b->vtable->base_type == enum_class_ManagedStruct) { + if (b && b->vtable->base_type == enum_class_JitCode) { + void *code; + GETATTR_JitCode_code(interp, b, code); *jitted = 1; - return F2DPTR(VTABLE_get_pointer(interp, b)); + return F2DPTR(code); } else { - void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature); + size_t result_size; + void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &result_size); if (result) { *jitted = 1; - temp_pmc = pmc_new(interp, enum_class_ManagedStruct); - VTABLE_set_pointer(interp, temp_pmc, (void *)result); + temp_pmc = pmc_new(interp, enum_class_JitCode); + SETATTR_JitCode_code(interp, temp_pmc, result); + SETATTR_JitCode_size(interp, temp_pmc, result_size); VTABLE_set_pmc_keyed_str(interp, HashPointer, jit_key_name, temp_pmc); return result; } === t/pmc/jitcode.t ================================================================== --- t/pmc/jitcode.t (revision 82) +++ t/pmc/jitcode.t (revision 83) @@ -0,0 +1,42 @@ +#! parrot + +# Err. Someone with knowledge of PIR and PMC should really take a look +# at JitCode PMC and figure what kind of tests are really relevant. + +=head1 NAME + +t/pmc/jitcode.t - JIT code memory block + +=head1 SYNOPSIS + + % prove t/pmc/jitcode.t + +=head1 DESCRIPTION + +Tests the JitCode PMC. Checks element access and memory allocation. + +=cut + + +.sub main :main + .include 'test_more.pir' + plan(2) + + interface_check() +.end + +.sub interface_check + .local pmc pmc1 + pmc1 = new ['JitCode'] + .local int bool1 + does bool1, pmc1, "scalar" + is(bool1, 1, "JitCode does scalar") + does bool1, pmc1, "no_interface" + is(bool1, 0, "JitCode doesn't do no_interface") +.end + +# Local Variables: +# mode: pir +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4 ft=pir: