Ticket #18: 04_jitcode-pmc.diff

File 04_jitcode-pmc.diff, 5.9 KB (added by santtu, 13 years ago)

Another approach to calling mem_free_executable with correct values (see Inifinoid's 02 patch): use custom and only-for-JIT PMC (JitCode) instead of generic ManagedStruct

  • src/pmc/jitcode.pmc

    === src/pmc/jitcode.pmc
    ==================================================================
     
     1/* 
     2Copyright (C) 2009-, Parrot Foundation. 
     3 
     4=head1 DESCRIPTION 
     5 
     6src/pmc/jitcode.pmc - JIT code memory management 
     7 
     8=head1 DESCRIPTION 
     9 
     10C<JitCode> provides a class to hold memory areas used for JIT code. 
     11 
     12JIT-specific structure instead of C<MemoryManagedStruct> is used 
     13because underlying method of allocating and freeing executable memory 
     14varies from platform to another (though those are really hidden behind 
     15mem_free_executable and its relatives.) 
     16 
     17=head2 Methods 
     18 
     19=over 4 
     20 
     21=cut 
     22 
     23*/ 
     24 
     25#include "parrot/parrot.h" 
     26 
     27pmclass JitCode need_ext no_ro { 
     28  ATTR void *code; 
     29  ATTR INTVAL size; 
     30 
     31  VTABLE void init() { 
     32    Parrot_JitCode_attributes *attr = 
     33      mem_allocate_typed(Parrot_JitCode_attributes); 
     34 
     35    PMC_data(SELF) = attr; 
     36    PObj_active_destroy_SET(SELF); 
     37    SET_ATTR_code(INTERP, SELF, NULL); 
     38    SET_ATTR_size(INTERP, SELF, 0); 
     39  } 
     40 
     41  VTABLE void destroy() { 
     42    Parrot_JitCode_attributes * attr = PARROT_JITCODE(SELF); 
     43    if (attr->code) 
     44      mem_free_executable(attr->code, attr->size); 
     45  } 
     46 
     47  VTABLE PMC *clone() { 
     48    Parrot_JitCode_attributes * const attr = PARROT_JITCODE(SELF); 
     49    PMC *dest = pmc_new(interp, SELF->vtable->base_type); 
     50    Parrot_JitCode_attributes * dattr = PARROT_JITCODE(dest); 
     51 
     52    if (attr->code) { 
     53      dattr->size = attr->size; 
     54      dattr->code = mem_alloc_executable(attr->size); 
     55      memcpy(dattr->code, attr->code, attr->size); 
     56    } 
     57 
     58    return dest; 
     59  } 
     60 
     61  VTABLE STRING *get_string() { 
     62    Parrot_JitCode_attributes * const attr = PARROT_JITCODE(SELF); 
     63 
     64    return Parrot_sprintf_c(INTERP, "code[%p/%d]", attr->code, attr->size); 
     65  } 
     66} 
     67 
     68/* 
     69 * Local variables: 
     70 *   c-file-style: "parrot" 
     71 * End: 
     72 * vim: expandtab shiftwidth=4: 
     73 */ 
  • src/jit/i386/jit_defs.c

    === src/jit/i386/jit_defs.c
    ==================================================================
     
    21182118 */ 
    21192119 
    21202120void * 
    2121 Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature) 
     2121Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, 
     2122                           size_t *size_ret) 
    21222123{ 
    21232124    Parrot_jit_info_t jit_info; 
    21242125    char     *pc; 
     
    24502451    PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE); 
    24512452    /* could shrink arena.start here to used size */ 
    24522453    PObj_active_destroy_SET(pmc_nci); 
     2454    if (size_ret) 
     2455        *size_ret = JIT_ALLOC_SIZE; 
    24532456    return (void *)D2FPTR(jit_info.arena.start); 
    24542457} 
    24552458 
  • src/jit/i386/jit_emit.h

    === src/jit/i386/jit_emit.h
    ==================================================================
     
    18791879size_t calc_signature_needs(const char *sig, int *strings); 
    18801880 
    18811881void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, 
    1882     STRING *signature); 
     1882                                  STRING *signature, size_t *size_ret); 
    18831883 
    18841884/* 
    18851885 * register usage 
  • src/jit.h

    === src/jit.h
    ==================================================================
     
    321321/* 
    322322 * NCI interface 
    323323 */ 
    324 void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *); 
     324void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, size_t *); 
    325325 
    326326#endif /* PARROT_JIT_H_GUARD */ 
    327327 
  • tools/build/nativecall.pl

    === tools/build/nativecall.pl
    ==================================================================
     
    197197#include "parrot/oplib/ops.h" 
    198198#include "pmc/pmc_nci.h" 
    199199#include "nci.str" 
     200#include "pmc/pmc_jitcode.h" 
    200201 
    201202/* HEADERIZER HFILE: none */ 
    202203/* HEADERIZER STOP */ 
     
    549550    jit_key_name = Parrot_str_concat(interp, jit_key_name, signature, 0); 
    550551    b            = VTABLE_get_pmc_keyed_str(interp, HashPointer, jit_key_name); 
    551552 
    552     if (b && b->vtable->base_type == enum_class_ManagedStruct) { 
     553    if (b && b->vtable->base_type == enum_class_JitCode) { 
     554        void *code; 
     555        GETATTR_JitCode_code(interp, b, code); 
    553556        *jitted = 1; 
    554         return F2DPTR(VTABLE_get_pointer(interp, b)); 
     557        return F2DPTR(code); 
    555558    } 
    556559    else { 
    557         void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature); 
     560        size_t result_size; 
     561        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &result_size); 
    558562        if (result) { 
    559563            *jitted = 1; 
    560             temp_pmc = pmc_new(interp, enum_class_ManagedStruct); 
    561             VTABLE_set_pointer(interp, temp_pmc, (void *)result); 
     564            temp_pmc = pmc_new(interp, enum_class_JitCode); 
     565            SETATTR_JitCode_code(interp, temp_pmc, result); 
     566            SETATTR_JitCode_size(interp, temp_pmc, result_size); 
    562567            VTABLE_set_pmc_keyed_str(interp, HashPointer, jit_key_name, temp_pmc); 
    563568            return result; 
    564569        } 
  • t/pmc/jitcode.t

    === t/pmc/jitcode.t
    ==================================================================
     
     1#! parrot 
     2 
     3# Err. Someone with knowledge of PIR and PMC should really take a look 
     4# at JitCode PMC and figure what kind of tests are really relevant. 
     5 
     6=head1 NAME 
     7 
     8t/pmc/jitcode.t - JIT code memory block 
     9 
     10=head1 SYNOPSIS 
     11 
     12    % prove t/pmc/jitcode.t 
     13 
     14=head1 DESCRIPTION 
     15 
     16Tests the JitCode PMC. Checks element access and memory allocation. 
     17 
     18=cut 
     19 
     20 
     21.sub main :main 
     22    .include 'test_more.pir' 
     23    plan(2) 
     24 
     25    interface_check() 
     26.end 
     27 
     28.sub interface_check 
     29    .local pmc pmc1 
     30    pmc1 = new ['JitCode'] 
     31    .local int bool1 
     32    does bool1, pmc1, "scalar" 
     33    is(bool1, 1, "JitCode does scalar") 
     34    does bool1, pmc1, "no_interface" 
     35    is(bool1, 0, "JitCode doesn't do no_interface") 
     36.end 
     37 
     38# Local Variables: 
     39#   mode: pir 
     40#   fill-column: 100 
     41# End: 
     42# vim: expandtab shiftwidth=4 ft=pir: