Changeset 54eb5ebd
- Timestamp:
- Jul 23, 2020, 1:33:57 PM (4 years ago)
- 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. - Files:
-
- 3 added
- 5 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
r5751a56 r54eb5ebd 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 19 17:37:21202013 // Update Count : 80 612 // Last Modified On : Mon Jul 20 23:00:32 2020 13 // Update Count : 808 14 14 // 15 15 … … 901 901 if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 902 902 header->kind.real.blockSize &= -2; // no alignment and turn off 0 fill 903 if ( size != odsize ) header->kind.real.size = size; // reset allocation size 903 904 return oaddr; 904 905 } // if … … 929 930 930 931 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 934 934 return oaddr; 935 935 } // if … … 1227 1227 if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 1228 1228 header->kind.real.blockSize &= -2; // turn off 0 fill 1229 if ( size != odsize ) header->kind.real.size = size; // reset allocation size 1229 1230 return oaddr; 1230 1231 } // if -
libcfa/src/heap.hfa
r5751a56 r54eb5ebd 10 10 // Created On : Tue May 26 11:23:55 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Ju n 1 21:19:00202013 // Update Count : 1 012 // Last Modified On : Mon Jul 20 18:52:31 2020 13 // Update Count : 11 14 14 // 15 15 … … 35 35 void * resize( void * oaddr, size_t size ); 36 36 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 ); 38 38 size_t malloc_alignment( void * addr ); 39 39 bool malloc_zero_fill( void * addr ); -
libcfa/src/stdlib.hfa
r5751a56 r54eb5ebd 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jul 20 14:29:21202013 // Update Count : 4 6412 // Last Modified On : Tue Jul 21 07:58:05 2020 13 // Update Count : 475 14 14 // 15 15 … … 39 39 //--------------------------------------- 40 40 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 41 56 static inline forall( dtype T | sized(T) ) { 42 57 // Cforall safe equivalents, i.e., implicit size specification 43 58 44 59 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 ); 47 61 } // malloc 48 62 49 63 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 ); 52 65 } // aalloc 53 66 54 67 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 ); 57 69 } // calloc 58 70 59 71 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 ); 65 73 return (T *)(void *)resize( (void *)ptr, size ); // CFA resize 66 74 } // resize 67 75 68 76 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 ); 74 78 return (T *)(void *)realloc( (void *)ptr, size ); // C realloc 75 79 } // realloc … … 159 163 T * alloc_set( T ptr[], size_t dim, char fill ) { // realloc array with fill 160 164 size_t osize = malloc_size( ptr ); // current allocation 161 T * nptr = realloc( ptr, dim * sizeof(T) ); // CFA realloc162 size_t nsize = malloc_size( nptr ); // new allocation165 size_t nsize = dim * sizeof(T); // new allocation 166 T * nptr = realloc( ptr, nsize ); // CFA realloc 163 167 if ( nsize > osize ) { // larger ? 164 168 memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage … … 168 172 169 173 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 173 178 if ( ndim > odim ) { // larger ? 174 179 for ( i; odim ~ ndim ) { … … 226 231 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ) { 227 232 size_t osize = malloc_size( ptr ); // current allocation 228 T * nptr = realloc( ptr, align, dim * sizeof(T) ); // CFA realloc229 size_t nsize = malloc_size( nptr ); // new allocation233 size_t nsize = dim * sizeof(T); // new allocation 234 T * nptr = realloc( ptr, align, nsize ); // CFA realloc 230 235 if ( nsize > osize ) { // larger ? 231 236 memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage … … 235 240 236 241 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 240 246 if ( ndim > odim ) { // larger ? 241 247 for ( i; odim ~ ndim ) { -
src/Virtual/ExpandCasts.cc
r5751a56 r54eb5ebd 10 10 // Created On : Mon Jul 24 13:59:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 26 14:37:00 202013 // Update Count : 212 // Last Modified On : Tue Jul 22 10:04:00 2020 13 // Update Count : 3 14 14 // 15 15 … … 24 24 #include "Common/PassVisitor.h" // for PassVisitor 25 25 #include "Common/SemanticError.h" // for SemanticError 26 #include "SymTab/Mangler.h" // for mangleType 26 27 #include "SynTree/Declaration.h" // for ObjectDecl, StructDecl, FunctionDecl 27 28 #include "SynTree/Expression.h" // for VirtualCastExpr, CastExpr, Address... … … 31 32 32 33 namespace 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 }; 33 61 34 62 /* Currently virtual depends on the rather brittle name matching between … … 39 67 */ 40 68 69 namespace { 70 41 71 std::string get_vtable_name( std::string const & name ) { 42 72 return name + "_vtable"; … … 53 83 std::string get_vtable_inst_name_root( std::string const & name ) { 54 84 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" );59 85 } 60 86 … … 64 90 } 65 91 92 } // namespace 93 66 94 class VirtualCastCore { 67 std::map<std::string, ObjectDecl *>vtable_instances;68 69 95 VirtualTableMap vtable_instances; 96 FunctionDecl *vcast_decl; 97 StructDecl *pvt_decl; 70 98 71 99 Type * pointer_to_pvt(int level_of_indirection) { … … 107 135 void VirtualCastCore::premutate( ObjectDecl * objectDecl ) { 108 136 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 ) { 115 150 if ( castExpr->location.isSet() ) { 116 151 return castExpr->location; … … 124 159 } 125 160 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 126 217 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." ); 128 219 129 220 assert( vcast_decl ); 130 221 assert( pvt_decl ); 131 222 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 ) { 140 226 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 } 158 229 159 230 Expression * result = new CastExpr( … … 174 245 castExpr->set_result( nullptr ); 175 246 delete castExpr; 247 delete vtable_type; 176 248 return result; 177 249 } -
tests/.expect/alloc.txt
r5751a56 r54eb5ebd 30 30 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 31 31 CFA realloc array alloc, fill 32 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x 1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x10101010xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede32 0xdeadbeef 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 33 33 CFA realloc array alloc, fill 34 34 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
Note: See TracChangeset
for help on using the changeset viewer.