diff --git a/src/pike_macros.h b/src/pike_macros.h index a95cc7b73c17e1102e2ee8ab99cca9f369e4998a..67250edcb369189b1d3b74b1d67d0f595fa45a05 100644 --- a/src/pike_macros.h +++ b/src/pike_macros.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: pike_macros.h,v 1.6 1998/03/28 15:05:39 grubba Exp $ + * $Id: pike_macros.h,v 1.7 1998/04/08 01:00:58 hubbe Exp $ */ #ifndef MACROS_H #define MACROS_H @@ -49,7 +49,15 @@ #define isidchar(X) is8bitalnum(X) #define ALIGN_BOUND sizeof(char *) -#define DO_ALIGN(X,Y) (((long)(X)+(Y-1)) & -(Y)) -#define MY_ALIGN(X) DO_ALIGN(X,ALIGN_BOUND) +#ifdef __GNUC__ +#define ALIGNOF(X) __alignof__(X) +#define HAVE_ALIGNOF +#else +#define ALIGNOF(X) (sizeof(X)>ALIGN_BOUND?ALIGN_BOUND:( 1<<my_log2(sizeof(X)))) +#endif + +#define DO_ALIGN(X,Y) (((long)(X)+((Y)-1)) & -(Y)) +#define MY_ALIGN(X) DO_ALIGN((X),ALIGN_BOUND) +#define SMART_ALIGN(X,Y) DO_ALIGN((X),(Y)>ALIGN_BOUND? (((Y)-1) & ~(Y)) :ALIGN_BOUND) #endif diff --git a/src/program.c b/src/program.c index 71fed04bb8c67e3f7d00782a7166bbf6c83b6264..cdd8a0c623793467bf03616479b234b08065fcc6 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.70 1998/04/06 20:38:00 hubbe Exp $"); +RCSID("$Id: program.c,v 1.71 1998/04/08 01:00:58 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -25,6 +25,7 @@ RCSID("$Id: program.c,v 1.70 1998/04/06 20:38:00 hubbe Exp $"); #include "constants.h" #include "operators.h" #include "builtin_functions.h" +#include "stuff.h" #include <errno.h> #include <fcntl.h> @@ -312,7 +313,8 @@ void optimize_program(struct program *p) if(p->flags & PROGRAM_OPTIMIZED) return; #define FOO(NUMTYPE,TYPE,NAME) \ - size+=MY_ALIGN(p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); + size=DO_ALIGN(size, ALIGNOF(TYPE)); \ + size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]); #include "program_areas.h" data=malloc(size); @@ -321,10 +323,11 @@ void optimize_program(struct program *p) size=0; #define FOO(NUMTYPE,TYPE,NAME) \ + size=DO_ALIGN(size, ALIGNOF(TYPE)); \ MEMCPY(data+size,p->NAME,p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); \ free((char *)p->NAME); \ p->NAME=(TYPE *)(data+size); \ - size+=MY_ALIGN(p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); + size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]); #include "program_areas.h" p->total_size=size + sizeof(struct program); @@ -641,6 +644,35 @@ static void toss_compilation_resources(void) } +static int sizeof_variable(int run_time_type) +{ + switch(run_time_type) + { + case T_FUNCTION: + case T_MIXED: return sizeof(struct svalue); + case T_INT: return sizeof(INT_TYPE); + case T_FLOAT: return sizeof(FLOAT_TYPE); + default: return sizeof(char *); + } +} + +static int alignof_variable(int run_time_type) +{ + switch(run_time_type) + { + case T_FUNCTION: + case T_MIXED: +#ifdef HAVE_ALIGNOF + return ALIGNOF(struct svalue); +#else + return ALIGNOF(union u); +#endif + case T_INT: return ALIGNOF(INT_TYPE); + case T_FLOAT: return ALIGNOF(FLOAT_TYPE); + default: return ALIGNOF(char *); + } +} + #ifdef DEBUG void check_program(struct program *p) { @@ -671,53 +703,6 @@ void check_program(struct program *p) if(p->num_identifier_index > p->num_identifier_references) fatal("Too many identifier index entries in program!\n"); -#if 0 - size=MY_ALIGN(sizeof(struct program)); - size+=MY_ALIGN(p->num_linenumbers); - size+=MY_ALIGN(p->program_size); - size+=MY_ALIGN(p->num_constants * sizeof(struct svalue)); - size+=MY_ALIGN(p->num_strings * sizeof(struct pike_string *)); - size+=MY_ALIGN(p->num_identifiers * sizeof(struct identifier)); - size+=MY_ALIGN(p->num_identifier_references * sizeof(struct reference)); - size+=MY_ALIGN(p->num_inherits * sizeof(struct inherit)); - - size+=MY_ALIGN(p->num_identifier_indexes * sizeof(INT16)); - - if(size > (INT32)p->total_size) - fatal("Program size is in error.\n"); - - size-=MY_ALIGN(p->num_identifier_indexes * sizeof(INT16)); - size+=MY_ALIGN(p->num_identifier_references * sizeof(INT16)); - - if(size < (INT32)p->total_size) - fatal("Program size is in error.\n"); - -#define CHECKRANGE(X,Y) \ -if((char *)(p->X) < (char *)p || (char *)(p->X)> ((char *)p)+size) fatal("Program->%s is wrong.\n",Y) - - CHECKRANGE(program,"program"); - CHECKRANGE(strings,"strings"); - CHECKRANGE(inherits,"inherits"); - CHECKRANGE(identifier_references,"identifier_references"); - CHECKRANGE(identifiers,"identifier"); - CHECKRANGE(identifier_index,"identifier_index"); - CHECKRANGE(constants,"constants"); - CHECKRANGE(linenumbers,"linenumbers"); - - checksum=hashmem(p->program, p->program_size, p->program_size) + - hashmem((unsigned char*)p->linenumbers,p->num_linenumbers,p->num_linenumbers); - - if(!checksum) checksum=1; - - if(!p->checksum) - { - p->checksum=checksum; - }else{ - if(p->checksum != checksum) - fatal("Someone changed a program!!!\n"); - } -#endif - for(e=0;e<(int)p->num_constants;e++) check_svalue(p->constants + e); @@ -737,9 +722,10 @@ if((char *)(p->X) < (char *)p || (char *)(p->X)> ((char *)p)+size) fatal("Progra if(IDENTIFIER_IS_VARIABLE(p->identifiers[e].identifier_flags)) { - if(p->identifiers[e].func.offset & (sizeof(char *)-1)) + if(p->identifiers[e].func.offset & + (alignof_variable(p->identifiers[e].run_time_type)-1)) { - fatal("Variable offset is not properly aligned (%s).\n",p->identifiers[e].name->str); + fatal("Variable %s offset is not properly aligned (%d).\n",p->identifiers[e].name->str,p->identifiers[e].func.offset); } } } @@ -764,6 +750,11 @@ if((char *)(p->X) < (char *)p || (char *)(p->X)> ((char *)p)+size) fatal("Progra { if(p->inherits[e].storage_offset < 0) fatal("Inherit->storage_offset is wrong.\n"); + + if(p->inherits[e].storage_offset & (ALIGN_BOUND-1)) + { + fatal("inherit[%d].storage_offset is not properly aligned.\n",e); + } } } #endif @@ -863,15 +854,25 @@ struct program *debug_end_program(void) * Allocate needed for this program in the object structure. * An offset to the data is returned. */ -SIZE_T add_storage(SIZE_T size) +SIZE_T low_add_storage(SIZE_T size, SIZE_T alignment) { SIZE_T offset; - offset=new_program->storage_needed; - size=MY_ALIGN(size); - new_program->storage_needed += size; + offset=DO_ALIGN(new_program->storage_needed, alignment); + new_program->storage_needed = offset + size; +#ifdef DEBUG + if(alignment <=0) fatal("Alignment must be at least 1\n"); + if(new_program->storage_needed<0) + fatal("add_storage failed horribly!\n"); +#endif return offset; } +SIZE_T add_storage(SIZE_T storage) +{ + return low_add_storage(storage, + storage>ALIGN_BOUND? ALIGN_BOUND : storage ? (1<<my_log2(storage)) : 1); +} + /* * set a callback used to initialize clones of this program * the init function is called at clone time @@ -1030,8 +1031,7 @@ void low_inherit(struct program *p, inherit_offset = new_program->num_inherits; - storage_offset=new_program->storage_needed; - add_storage(p->storage_needed); + storage_offset=add_storage(p->storage_needed); for(e=0; e<(int)p->num_inherits; e++) { @@ -1062,6 +1062,37 @@ void low_inherit(struct program *p, }else{ inherit.parent_offset+=parent_offset; } + }else{ + if(parent && parent->next != parent && inherit.parent_offset) + { + struct object *par=parent; + int e,pid=parent_identifier; + for(e=1;e<inherit.parent_offset;e++) + { + struct inherit *in; + if(!par->prog) + { + par=0; + pid=0; + break; + } + + in=INHERIT_FROM_INT(par->prog, pid); + if(in->parent_offset) + { + pid=par->parent_identifier; + par=par->parent; + e-=in->parent_offset-1; + }else{ + pid=in->parent_identifier; + par=in->parent; + } + } + + inherit.parent=par; + inherit.parent_identifier=pid; + inherit.parent_offset=0; + } } if(inherit.parent) inherit.parent->refs++; @@ -1274,7 +1305,6 @@ int low_define_variable(struct pike_string *name, return n; } - int map_variable(char *name, char *type, INT32 flags, @@ -1352,9 +1382,8 @@ int define_variable(struct pike_string *name, } n=low_define_variable(name,type,flags, - add_storage(run_time_type == T_MIXED ? - sizeof(struct svalue) : - sizeof(union anything)), + low_add_storage(sizeof_variable(run_time_type), + alignof_variable(run_time_type)), run_time_type); diff --git a/src/program.h b/src/program.h index 855e1b008ca502141eb83c19eaa68fa6ef39435a..6dffebc1178c2e7b9b0c7fcc52fb7d3a72f9d0d6 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.36 1998/04/06 04:31:32 hubbe Exp $ + * $Id: program.h,v 1.37 1998/04/08 01:00:58 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -222,6 +222,7 @@ struct program #define free_program(p) do{ struct program *_=(p); debug_malloc_touch(_); if(!--_->refs) really_free_program(_); }while(0) + extern struct object *fake_object; extern struct program *new_program; extern struct program *first_program; @@ -252,7 +253,8 @@ void dump_program_desc(struct program *p); void check_program(struct program *p); struct program *end_first_pass(int finish); struct program *debug_end_program(void); -SIZE_T add_storage(SIZE_T size); +SIZE_T low_add_storage(SIZE_T size, SIZE_T alignment); +SIZE_T add_storage(SIZE_T storage); void set_init_callback(void (*init)(struct object *)); void set_exit_callback(void (*exit)(struct object *)); void set_gc_mark_callback(void (*m)(struct object *)); diff --git a/src/program_areas.h b/src/program_areas.h index fa70f82832166370b159ac57b42e42d7d7875505..e10c5dfafc16783d8e00e76addf1aa1c17bba4da 100644 --- a/src/program_areas.h +++ b/src/program_areas.h @@ -1,14 +1,14 @@ -/* $Id: program_areas.h,v 1.3 1998/03/28 13:38:43 grubba Exp $ */ +/* $Id: program_areas.h,v 1.4 1998/04/08 01:00:58 hubbe Exp $ */ /* Who needs templates anyway? / Hubbe */ /* Program *must* be first! */ FOO(SIZE_T,unsigned char,program) FOO(SIZE_T,char,linenumbers) -FOO(unsigned INT16,struct inherit,inherits) -FOO(unsigned INT16,struct pike_string *,strings) +FOO(unsigned INT16,unsigned INT16,identifier_index) FOO(unsigned INT16,struct reference,identifier_references) +FOO(unsigned INT16,struct pike_string *,strings) +FOO(unsigned INT16,struct inherit,inherits) FOO(unsigned INT16,struct identifier,identifiers) -FOO(unsigned INT16,unsigned INT16,identifier_index) FOO(unsigned INT16,struct svalue, constants) #undef FOO