Branch: Tag:

2014-05-21

2014-05-21 22:15:31 by Per Hedbor <ph@opera.com>

Some more RAM + binary size optimizations.

o type_stack_mark is no longer inline, saves ~10Kb code size

o The type_stack and pike_type_mark_stack are now allocated on demand
when possible (using mmap, the pages are allocated when accessed at
least on macosx and linux)

This saves about 1Mb of RSS in a freshly started pike.

687:      #endif /* PIKE_DEBUG */    - struct pike_type *type_stack[PIKE_TYPE_STACK_SIZE]; - struct pike_type **pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4]; + struct pike_type **type_stack; + struct pike_type ***pike_type_mark_stack;      ptrdiff_t pop_stack_mark(void)   {
721: Inside #if SIZEOF_INT_TYPE > 4
  #if SIZEOF_INT_TYPE > 4   /* a bit kludgy: should maybe really allow 64 bit INT_TYPE */   /* see also extract_type_int */ -  +     if (min<MIN_INT32) min=MIN_INT32;    else if (min>MAX_INT32) min=MAX_INT32;    if (max<MIN_INT32) max=MIN_INT32;    else if (max>MAX_INT32) max=MAX_INT32; -  - #if 0 -  if (min!=(INT32)min || -  max!=(INT32)max) -  Pike_fatal("push_int_type(): int outside INT32 range (sorry)" -  " (%"PRINTPIKEINT"d..%"PRINTPIKEINT"d)\n", -  min,max); +    #endif - #endif +       #ifdef PIKE_DEBUG    if (min > max)
8454:    }   }    + void type_stack_mark() + { +  if(UNLIKELY(Pike_compiler->pike_type_mark_stackp >= pike_type_mark_stack + (PIKE_TYPE_STACK_SIZE>>4))) +  Pike_fatal("Type mark stack overflow.\n"); +  *Pike_compiler->pike_type_mark_stackp=Pike_compiler->type_stackp; +  Pike_compiler->pike_type_mark_stackp++; +  TYPE_STACK_DEBUG("type_stack_mark"); + } +    /* Make a pike-type from a serialized (old-style) type. */   struct pike_type *debug_make_pike_type(const char *serialized_type)   {
8682:   static struct callback *pike_type_gc_callback = NULL;   #endif /* PIKE_DEBUG */    + #ifdef HAVE_SYS_MMAN_H + #include <sys/mman.h> + #endif +  + #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) + #define MAP_ANONYMOUS MAP_ANON + static int type_stack_mmap, type_mark_stack_mmap; + #endif /* !MAP_ANONYMOUS && MAP_ANON */ +    void init_types(void)   {    /* Initialize hashtable here. */
8689:    (PIKE_TYPE_HASH_SIZE+1));    pike_type_hash_size = PIKE_TYPE_HASH_SIZE;    +  /* if possible, use mmap with on-demand allocation */ + #if defined(MAP_ANONYMOUS) +  type_stack = mmap( NULL, sizeof(struct pike_type *)*PIKE_TYPE_STACK_SIZE, +  PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE,0,0); +  if( type_stack ) +  type_stack_mmap = 1; +  pike_type_mark_stack = mmap( NULL, sizeof(struct pike_type **)*PIKE_TYPE_STACK_SIZE>>2, +  PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); +  if( pike_type_mark_stack ) +  type_mark_stack_mmap = 1; + #endif +  if( !type_stack ) +  type_stack = xalloc(sizeof(struct pike_type *)*PIKE_TYPE_STACK_SIZE); +  if( !pike_type_mark_stack ) +  pike_type_mark_stack = xalloc(sizeof(struct pike_type *)*PIKE_TYPE_STACK_SIZE); +  +  Pike_compiler->type_stackp = type_stack; +  Pike_compiler->pike_type_mark_stackp = pike_type_mark_stack; +     int_type_string = CONSTTYPE(tInt); /* MUST come before string! */    string0_type_string = CONSTTYPE(tStr0);    string_type_string = CONSTTYPE(tStr32);
8732: Inside #if defined(DO_PIKE_CLEANUP)
   free_type(all_pike_type_locations->t);    all_pike_type_locations = all_pike_type_locations->next;    } + #ifdef MAP_ANONYMOUS +  if( type_stack_mmap ) +  { +  munmap( type_stack, sizeof(struct pike_type *)*PIKE_TYPE_STACK_SIZE); +  type_stack = NULL; +  } +  if( pike_type_mark_stack_mmap ) +  { +  munmap( pike_type_mark_stack, sizeof(struct pike_type *)*PIKE_TYPE_STACK_SIZE>>2); +  pike_type_mark_stack = NULL; +  } + #endif +  free( type_stack ); +  free( pike_type_mark_stack );   #endif /* DO_PIKE_CLEANUP */       clear_markers();