Changeset 54eb5ebd


Ignore:
Timestamp:
Jul 23, 2020, 1:33:57 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
e262b5e, f854ee32
Parents:
5751a56 (diff), f19fbbc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
3 added
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    r5751a56 r54eb5ebd  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 19 17:37:21 2020
    13 // Update Count     : 806
     12// Last Modified On : Mon Jul 20 23:00:32 2020
     13// Update Count     : 808
    1414//
    1515
     
    901901          if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    902902                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
     903                        if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    903904                        return oaddr;
    904905                } // if
     
    929930
    930931                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    931           if ( size <= odsize && odsize <= size * 2 ) { // allow up to 50% wasted storage in smaller size
    932                         // Do not know size of original allocation => cannot do 0 fill for any additional space because do not know
    933                         // where to start filling, i.e., do not overwrite existing values in space.
     932          if ( size <= odsize && odsize <= size * 2 ) {         // allow up to 50% wasted storage in smaller size
     933                        if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    934934                        return oaddr;
    935935                } // if
     
    12271227                if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    12281228                        header->kind.real.blockSize &= -2;                      // turn off 0 fill
     1229                        if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    12291230                        return oaddr;
    12301231                } // if
  • libcfa/src/heap.hfa

    r5751a56 r54eb5ebd  
    1010// Created On       : Tue May 26 11:23:55 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  1 21:19:00 2020
    13 // Update Count     : 10
     12// Last Modified On : Mon Jul 20 18:52:31 2020
     13// Update Count     : 11
    1414//
    1515
     
    3535        void * resize( void * oaddr, size_t size );
    3636        void * amemalign( size_t align, size_t dim, size_t elemSize );
    37         void * cmemalign( size_t align, size_t noOfElems, size_t elemSize );
     37        void * cmemalign( size_t align, size_t dim, size_t elemSize );
    3838        size_t malloc_alignment( void * addr );
    3939        bool malloc_zero_fill( void * addr );
  • libcfa/src/stdlib.hfa

    r5751a56 r54eb5ebd  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 20 14:29:21 2020
    13 // Update Count     : 464
     12// Last Modified On : Tue Jul 21 07:58:05 2020
     13// Update Count     : 475
    1414//
    1515
     
    3939//---------------------------------------
    4040
     41// Macro because of returns
     42#define $VAR_ALLOC( allocation, alignment ) \
     43        if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( (size_t)sizeof(T) ); /* C allocation */ \
     44        else return (T *)alignment( _Alignof(T), sizeof(T) )
     45
     46#define $ARRAY_ALLOC( allocation, alignment, dim ) \
     47        if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( dim, (size_t)sizeof(T) ); /* C allocation */ \
     48        else return (T *)alignment( _Alignof(T), dim, sizeof(T) )
     49
     50#define $RE_SPECIALS( ptr, size, allocation, alignment ) \
     51        if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { \
     52                if ( unlikely( size == 0 ) ) free( ptr ); \
     53                $VAR_ALLOC( malloc, memalign ); \
     54        } /* if */
     55
    4156static inline forall( dtype T | sized(T) ) {
    4257        // Cforall safe equivalents, i.e., implicit size specification
    4358
    4459        T * malloc( void ) {
    45                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
    46                 else return (T *)memalign( _Alignof(T), sizeof(T) );
     60                $VAR_ALLOC( malloc, memalign );
    4761        } // malloc
    4862
    4963        T * aalloc( size_t dim ) {
    50                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)aalloc( dim, (size_t)sizeof(T) ); // CFA aalloc
    51                 else return (T *)amemalign( _Alignof(T), dim, sizeof(T) );
     64                $ARRAY_ALLOC( aalloc, amemalign, dim );
    5265        } // aalloc
    5366
    5467        T * calloc( size_t dim ) {
    55                 if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc
    56                 else return (T *)cmemalign( _Alignof(T), dim, sizeof(T) );
     68                $ARRAY_ALLOC( calloc, cmemalign, dim );
    5769        } // calloc
    5870
    5971        T * resize( T * ptr, size_t size ) {                            // CFA resize, eliminate return-type cast
    60                 if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { // special cases
    61                         if ( unlikely( size == 0 ) ) free( ptr );
    62                         if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( size ); // C malloc
    63                         else return (T *)memalign( _Alignof(T), size ); // C memalign
    64                 } // if
     72                $RE_SPECIALS( ptr, size, malloc, memalign );
    6573                return (T *)(void *)resize( (void *)ptr, size ); // CFA resize
    6674        } // resize
    6775
    6876        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    69                 if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { // special cases
    70                         if ( unlikely( size == 0 ) ) free( ptr );
    71                         if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( size ); // C malloc
    72                         else return (T *)memalign( _Alignof(T), size ); // C memalign
    73                 } // if
     77                $RE_SPECIALS( ptr, size, malloc, memalign );
    7478                return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    7579        } // realloc
     
    159163        T * alloc_set( T ptr[], size_t dim, char fill ) {       // realloc array with fill
    160164                size_t osize = malloc_size( ptr );                              // current allocation
    161                 T * nptr = realloc( ptr, dim * sizeof(T) );             // CFA realloc
    162                 size_t nsize = malloc_size( nptr );                             // new allocation
     165                size_t nsize = dim * sizeof(T);                                 // new allocation
     166                T * nptr = realloc( ptr, nsize );                               // CFA realloc
    163167                if ( nsize > osize ) {                                                  // larger ?
    164168                        memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage
     
    168172
    169173        T * alloc_set( T ptr[], size_t dim, T & fill ) {        // realloc array with fill
    170                 size_t odim = malloc_size( ptr ) / sizeof(T);   // current allocation
    171                 T * nptr = realloc( ptr, dim * sizeof(T) );             // CFA realloc
    172                 size_t ndim = malloc_size( nptr ) / sizeof(T);  // new allocation
     174                size_t odim = malloc_size( ptr ) / sizeof(T);   // current dimension
     175                size_t nsize = dim * sizeof(T);                                 // new allocation
     176                size_t ndim = nsize / sizeof(T);                                // new dimension
     177                T * nptr = realloc( ptr, nsize );                               // CFA realloc
    173178                if ( ndim > odim ) {                                                    // larger ?
    174179                        for ( i; odim ~ ndim ) {
     
    226231        T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ) {
    227232                size_t osize = malloc_size( ptr );                              // current allocation
    228                 T * nptr = realloc( ptr, align, dim * sizeof(T) ); // CFA realloc
    229                 size_t nsize = malloc_size( nptr );                             // new allocation
     233                size_t nsize = dim * sizeof(T);                                 // new allocation
     234                T * nptr = realloc( ptr, align, nsize );                // CFA realloc
    230235                if ( nsize > osize ) {                                                  // larger ?
    231236                        memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage
     
    235240
    236241        T * alloc_align_set( T ptr[], size_t align, size_t dim, T & fill ) {
    237                 size_t odim = malloc_size( ptr ) / sizeof(T);   // current allocation
    238                 T * nptr = realloc( ptr, align, dim * sizeof(T) ); // CFA realloc
    239                 size_t ndim = malloc_size( nptr );                              // new allocation
     242                size_t odim = malloc_size( ptr ) / sizeof(T);   // current dimension
     243                size_t nsize = dim * sizeof(T);                                 // new allocation
     244                size_t ndim = nsize / sizeof(T);                                // new dimension
     245                T * nptr = realloc( ptr, align, nsize );                // CFA realloc
    240246                if ( ndim > odim ) {                                                    // larger ?
    241247                        for ( i; odim ~ ndim ) {
  • src/Virtual/ExpandCasts.cc

    r5751a56 r54eb5ebd  
    1010// Created On       : Mon Jul 24 13:59:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue May 26 14:37:00 2020
    13 // Update Count     : 2
     12// Last Modified On : Tue Jul 22 10:04:00 2020
     13// Update Count     : 3
    1414//
    1515
     
    2424#include "Common/PassVisitor.h"    // for PassVisitor
    2525#include "Common/SemanticError.h"  // for SemanticError
     26#include "SymTab/Mangler.h"        // for mangleType
    2627#include "SynTree/Declaration.h"   // for ObjectDecl, StructDecl, FunctionDecl
    2728#include "SynTree/Expression.h"    // for VirtualCastExpr, CastExpr, Address...
     
    3132
    3233namespace Virtual {
     34
     35        // Indented until the new ast code gets added.
     36
     37        /// Maps virtual table types the instance for that type.
     38        class VirtualTableMap final {
     39                std::unordered_map<std::string, ObjectDecl *> vtable_instances;
     40        public:
     41                ObjectDecl * insert( ObjectDecl * vtableDecl ) {
     42                        std::string const & mangledName = SymTab::Mangler::mangleType( vtableDecl->type );
     43                        ObjectDecl *& value = vtable_instances[ mangledName ];
     44                        if ( value ) {
     45                                if ( vtableDecl->storageClasses.is_extern ) {
     46                                        return nullptr;
     47                                } else if ( ! value->storageClasses.is_extern ) {
     48                                        return value;
     49                                }
     50                        }
     51                        value = vtableDecl;
     52                        return nullptr;
     53                }
     54
     55                ObjectDecl * lookup( const Type * vtableType ) {
     56                        std::string const & mangledName = SymTab::Mangler::mangleType( vtableType );
     57                        const auto it = vtable_instances.find( mangledName );
     58                        return ( vtable_instances.end() == it ) ? nullptr : it->second;
     59                }
     60        };
    3361
    3462        /* Currently virtual depends on the rather brittle name matching between
     
    3967         */
    4068
     69        namespace {
     70
    4171        std::string get_vtable_name( std::string const & name ) {
    4272                return name + "_vtable";
     
    5383        std::string get_vtable_inst_name_root( std::string const & name ) {
    5484                return get_vtable_name_root( name.substr(1, name.size() - 10 ) );
    55         }
    56 
    57         bool is_vtable_name( std::string const & name ) {
    58                 return (name.substr( name.size() - 7 ) == "_vtable" );
    5985        }
    6086
     
    6490        }
    6591
     92        } // namespace
     93
    6694        class VirtualCastCore {
    67         std::map<std::string, ObjectDecl *> vtable_instances;
    68         FunctionDecl *vcast_decl;
    69         StructDecl *pvt_decl;
     95                VirtualTableMap vtable_instances;
     96                FunctionDecl *vcast_decl;
     97                StructDecl *pvt_decl;
    7098
    7199                Type * pointer_to_pvt(int level_of_indirection) {
     
    107135        void VirtualCastCore::premutate( ObjectDecl * objectDecl ) {
    108136                if ( is_vtable_inst_name( objectDecl->get_name() ) ) {
    109                         vtable_instances[objectDecl->get_name()] = objectDecl;
    110                 }
    111         }
    112 
    113         // Better error locations for generated casts.
    114         static CodeLocation castLocation( VirtualCastExpr * castExpr ) {
     137                        if ( ObjectDecl * existing = vtable_instances.insert( objectDecl ) ) {
     138                                std::string msg = "Repeated instance of virtual table, original found at: ";
     139                                msg += existing->location.filename;
     140                                msg += ":" + toString( existing->location.first_line );
     141                                SemanticError( objectDecl->location, msg );
     142                        }
     143                }
     144        }
     145
     146        namespace {
     147
     148        /// Better error locations for generated casts.
     149        CodeLocation castLocation( const VirtualCastExpr * castExpr ) {
    115150                if ( castExpr->location.isSet() ) {
    116151                        return castExpr->location;
     
    124159        }
    125160
     161        [[noreturn]] void castError( const VirtualCastExpr * castExpr, std::string const & message ) {
     162                SemanticError( castLocation( castExpr ), message );
     163        }
     164
     165        /// Get the virtual table type used in a virtual cast.
     166        Type * getVirtualTableType( const VirtualCastExpr * castExpr ) {
     167                const Type * objectType;
     168                if ( auto target = dynamic_cast<const PointerType *>( castExpr->result ) ) {
     169                        objectType = target->base;
     170                } else if ( auto target = dynamic_cast<const ReferenceType *>( castExpr->result ) ) {
     171                        objectType = target->base;
     172                } else {
     173                        castError( castExpr, "Virtual cast type must be a pointer or reference type." );
     174                }
     175                assert( objectType );
     176
     177                const StructInstType * structType = dynamic_cast<const StructInstType *>( objectType );
     178                if ( nullptr == structType ) {
     179                        castError( castExpr, "Virtual cast type must refer to a structure type." );
     180                }
     181                const StructDecl * structDecl = structType->baseStruct;
     182                assert( structDecl );
     183
     184                const ObjectDecl * fieldDecl = nullptr;
     185                if ( 0 < structDecl->members.size() ) {
     186                        const Declaration * memberDecl = structDecl->members.front();
     187                        assert( memberDecl );
     188                        fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl );
     189                        if ( fieldDecl && fieldDecl->name != "virtual_table" ) {
     190                                fieldDecl = nullptr;
     191                        }
     192                }
     193                if ( nullptr == fieldDecl ) {
     194                        castError( castExpr, "Virtual cast type must have a leading virtual_table field." );
     195                }
     196                const PointerType * fieldType = dynamic_cast<const PointerType *>( fieldDecl->type );
     197                if ( nullptr == fieldType ) {
     198                        castError( castExpr, "Virtual cast type virtual_table field is not a pointer." );
     199                }
     200                assert( fieldType->base );
     201                auto virtualStructType = dynamic_cast<const StructInstType *>( fieldType->base );
     202                assert( virtualStructType );
     203
     204                // Here is the type, but if it is polymorphic it will have lost information.
     205                // (Always a clone so that it may always be deleted.)
     206                StructInstType * virtualType = virtualStructType->clone();
     207                if ( ! structType->parameters.empty() ) {
     208                        deleteAll( virtualType->parameters );
     209                        virtualType->parameters.clear();
     210                        cloneAll( structType->parameters, virtualType->parameters );
     211                }
     212                return virtualType;
     213        }
     214
     215        } // namespace
     216
    126217        Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
    127                 assertf( castExpr->get_result(), "Virtual Cast target not found before expansion." );
     218                assertf( castExpr->result, "Virtual Cast target not found before expansion." );
    128219
    129220                assert( vcast_decl );
    130221                assert( pvt_decl );
    131222
    132                 // Get the base type of the pointer/reference.
    133                 Type * base;
    134                 Type * result_type = castExpr->result;
    135                 if ( PointerType * target = dynamic_cast<PointerType *>( result_type ) ) {
    136                         base = target->base;
    137                 } else if ( ReferenceType * target = dynamic_cast<ReferenceType *>( result_type ) ) {
    138                         base = target->base;
    139                 } else {
     223                const Type * vtable_type = getVirtualTableType( castExpr );
     224                ObjectDecl * table = vtable_instances.lookup( vtable_type );
     225                if ( nullptr == table ) {
    140226                        SemanticError( castLocation( castExpr ),
    141                                 "Virtual cast type must be a pointer or reference type." );
    142                 }
    143 
    144                 StructInstType * target_struct = dynamic_cast<StructInstType *>( base );
    145                 if ( nullptr == target_struct ) {
    146                         SemanticError( castLocation( castExpr ),
    147                                 "Virtual cast type must refer to a structure type." );
    148                 }
    149                 StructDecl * target_decl = target_struct->get_baseStruct();
    150 
    151                 std::map<std::string, ObjectDecl *>::iterator found =
    152                         vtable_instances.find( get_vtable_inst_name( target_decl->get_name() ) );
    153                 if ( vtable_instances.end() == found ) {
    154                         SemanticError( castLocation( castExpr ),
    155                                 "Virtual cast type does not have a virtual table instance." );
    156                 }
    157                 ObjectDecl * table = found->second;
     227                                "Could not find virtual table instance." );
     228                }
    158229
    159230                Expression * result = new CastExpr(
     
    174245                castExpr->set_result( nullptr );
    175246                delete castExpr;
     247                delete vtable_type;
    176248                return result;
    177249        }
  • tests/.expect/alloc.txt

    r5751a56 r54eb5ebd  
    30300xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    3131CFA realloc array alloc, fill
    32 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     320xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
    3333CFA realloc array alloc, fill
    34340xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
Note: See TracChangeset for help on using the changeset viewer.