<s> import sys <EOL> from pypy . rpython . memory . gc . semispace import SemiSpaceGC <EOL> from pypy . rpython . memory . gc . semispace import GCFLAG_EXTERNAL , GCFLAG_FORWARDED <EOL> from pypy . rpython . memory . gc . semispace import GCFLAG_HASHTAKEN <EOL> from pypy . rpython . lltypesystem . llmemory import NULL , raw_malloc_usage <EOL> from pypy . rpython . lltypesystem import lltype , llmemory , llarena <EOL> from pypy . rpython . memory . support import DEFAULT_CHUNK_SIZE <EOL> from pypy . rlib . objectmodel import free_non_gc_object <EOL> from pypy . rlib . debug import ll_assert <EOL> from pypy . rpython . lltypesystem . lloperation import llop <EOL> GCFLAG_NO_YOUNG_PTRS = SemiSpaceGC . first_unused_gcflag << <NUM_LIT:0> <EOL> GCFLAG_NO_HEAP_PTRS = SemiSpaceGC . first_unused_gcflag << <NUM_LIT:1> <EOL> class GenerationGC ( SemiSpaceGC ) : <EOL> """<STR_LIT>""" <EOL> inline_simple_malloc = True <EOL> inline_simple_malloc_varsize = True <EOL> needs_write_barrier = True <EOL> prebuilt_gc_objects_are_static_roots = False <EOL> first_unused_gcflag = SemiSpaceGC . first_unused_gcflag << <NUM_LIT:2> <EOL> TRANSLATION_PARAMS = { '<STR_LIT>' : <NUM_LIT:8> * <NUM_LIT> * <NUM_LIT> , <EOL> '<STR_LIT>' : <NUM_LIT> * <NUM_LIT> , <EOL> '<STR_LIT>' : <NUM_LIT> * <NUM_LIT> , <EOL> '<STR_LIT>' : True } <EOL> def __init__ ( self , config , chunk_size = DEFAULT_CHUNK_SIZE , <EOL> nursery_size = <NUM_LIT> , <EOL> min_nursery_size = <NUM_LIT> , <EOL> auto_nursery_size = False , <EOL> space_size = <NUM_LIT> , <EOL> max_space_size = sys . maxint // <NUM_LIT:2> + <NUM_LIT:1> ) : <EOL> SemiSpaceGC . __init__ ( self , config , chunk_size = chunk_size , <EOL> space_size = space_size , <EOL> max_space_size = max_space_size ) <EOL> assert min_nursery_size <= nursery_size <= space_size // <NUM_LIT:2> <EOL> self . initial_nursery_size = nursery_size <EOL> self . auto_nursery_size = auto_nursery_size <EOL> self . min_nursery_size = min_nursery_size <EOL> self . reset_nursery ( ) <EOL> self . _setup_wb ( ) <EOL> sz = self . get_young_fixedsize ( self . min_nursery_size ) <EOL> self . lb_young_fixedsize = sz <EOL> sz = self . get_young_var_basesize ( self . min_nursery_size ) <EOL> self . lb_young_var_basesize = sz <EOL> def setup ( self ) : <EOL> self . old_objects_pointing_to_young = self . AddressStack ( ) <EOL> self . young_objects_with_weakrefs = self . AddressStack ( ) <EOL> self . last_generation_root_objects = self . AddressStack ( ) <EOL> self . young_objects_with_id = self . AddressDict ( ) <EOL> SemiSpaceGC . setup ( self ) <EOL> self . set_nursery_size ( self . initial_nursery_size ) <EOL> if self . auto_nursery_size : <EOL> newsize = nursery_size_from_env ( ) <EOL> if newsize <= <NUM_LIT:0> : <EOL> newsize = estimate_best_nursery_size ( <EOL> self . config . gcconfig . debugprint ) <EOL> if newsize > <NUM_LIT:0> : <EOL> self . set_nursery_size ( newsize ) <EOL> self . reset_nursery ( ) <EOL> def _teardown ( self ) : <EOL> self . collect ( ) <EOL> SemiSpaceGC . _teardown ( self ) <EOL> def reset_nursery ( self ) : <EOL> self . nursery = NULL <EOL> self . nursery_top = NULL <EOL> self . nursery_free = NULL <EOL> def set_nursery_size ( self , newsize ) : <EOL> if newsize < self . min_nursery_size : <EOL> newsize = self . min_nursery_size <EOL> if newsize > self . space_size // <NUM_LIT:2> : <EOL> newsize = self . space_size // <NUM_LIT:2> <EOL> self . nursery_size = newsize <EOL> self . largest_young_fixedsize = self . get_young_fixedsize ( newsize ) <EOL> self . largest_young_var_basesize = self . get_young_var_basesize ( newsize ) <EOL> scale = <NUM_LIT:0> <EOL> while ( self . min_nursery_size << ( scale + <NUM_LIT:1> ) ) <= newsize : <EOL> scale += <NUM_LIT:1> <EOL> self . nursery_scale = scale <EOL> if self . config . gcconfig . debugprint : <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , newsize ) <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , <EOL> self . largest_young_fixedsize ) <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , <EOL> self . largest_young_var_basesize ) <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , scale ) <EOL> assert self . nursery_size >= ( self . min_nursery_size << scale ) <EOL> self . semispace_collect ( ) <EOL> @ staticmethod <EOL> def get_young_fixedsize ( nursery_size ) : <EOL> return nursery_size // <NUM_LIT:2> - <NUM_LIT:1> <EOL> @ staticmethod <EOL> def get_young_var_basesize ( nursery_size ) : <EOL> return nursery_size // <NUM_LIT:4> - <NUM_LIT:1> <EOL> def is_in_nursery ( self , addr ) : <EOL> ll_assert ( llmemory . cast_adr_to_int ( addr ) & <NUM_LIT:1> == <NUM_LIT:0> , <EOL> "<STR_LIT>" ) <EOL> return self . nursery <= addr < self . nursery_top <EOL> def malloc_fixedsize_clear ( self , typeid , size , can_collect , <EOL> has_finalizer = False , contains_weakptr = False ) : <EOL> if ( has_finalizer or not can_collect or <EOL> ( raw_malloc_usage ( size ) > self . lb_young_fixedsize and <EOL> raw_malloc_usage ( size ) > self . largest_young_fixedsize ) ) : <EOL> ll_assert ( not contains_weakptr , "<STR_LIT>" ) <EOL> return SemiSpaceGC . malloc_fixedsize_clear ( self , typeid , size , <EOL> can_collect , <EOL> has_finalizer , <EOL> contains_weakptr ) <EOL> size_gc_header = self . gcheaderbuilder . size_gc_header <EOL> totalsize = size_gc_header + size <EOL> result = self . nursery_free <EOL> if raw_malloc_usage ( totalsize ) > self . nursery_top - result : <EOL> result = self . collect_nursery ( ) <EOL> llarena . arena_reserve ( result , totalsize ) <EOL> self . init_gc_object ( result , typeid , flags = <NUM_LIT:0> ) <EOL> self . nursery_free = result + totalsize <EOL> if contains_weakptr : <EOL> self . young_objects_with_weakrefs . append ( result + size_gc_header ) <EOL> return llmemory . cast_adr_to_ptr ( result + size_gc_header , llmemory . GCREF ) <EOL> def malloc_varsize_clear ( self , typeid , length , size , itemsize , <EOL> offset_to_length , can_collect ) : <EOL> if not raw_malloc_usage ( itemsize ) : <EOL> too_many_items = False <EOL> else : <EOL> maxlength_for_minimal_nursery = ( self . min_nursery_size // <NUM_LIT:4> // <EOL> raw_malloc_usage ( itemsize ) ) <EOL> maxlength = maxlength_for_minimal_nursery << self . nursery_scale <EOL> too_many_items = length > maxlength <EOL> if ( not can_collect or <EOL> too_many_items or <EOL> ( raw_malloc_usage ( size ) > self . lb_young_var_basesize and <EOL> raw_malloc_usage ( size ) > self . largest_young_var_basesize ) ) : <EOL> return SemiSpaceGC . malloc_varsize_clear ( self , typeid , length , size , <EOL> itemsize , offset_to_length , <EOL> can_collect ) <EOL> size_gc_header = self . gcheaderbuilder . size_gc_header <EOL> totalsize = size_gc_header + size + itemsize * length <EOL> result = self . nursery_free <EOL> if raw_malloc_usage ( totalsize ) > self . nursery_top - result : <EOL> result = self . collect_nursery ( ) <EOL> llarena . arena_reserve ( result , totalsize ) <EOL> self . init_gc_object ( result , typeid , flags = <NUM_LIT:0> ) <EOL> ( result + size_gc_header + offset_to_length ) . signed [ <NUM_LIT:0> ] = length <EOL> self . nursery_free = result + llarena . round_up_for_allocation ( totalsize ) <EOL> return llmemory . cast_adr_to_ptr ( result + size_gc_header , llmemory . GCREF ) <EOL> def init_gc_object ( self , addr , typeid , flags = GCFLAG_NO_YOUNG_PTRS ) : <EOL> SemiSpaceGC . init_gc_object ( self , addr , typeid , flags ) <EOL> def init_gc_object_immortal ( self , addr , typeid , <EOL> flags = GCFLAG_NO_YOUNG_PTRS | GCFLAG_NO_HEAP_PTRS ) : <EOL> SemiSpaceGC . init_gc_object_immortal ( self , addr , typeid , flags ) <EOL> GCFLAGS_FOR_NEW_YOUNG_OBJECTS = <NUM_LIT:0> <EOL> GCFLAGS_FOR_NEW_EXTERNAL_OBJECTS = ( GCFLAG_EXTERNAL | GCFLAG_FORWARDED | <EOL> GCFLAG_NO_YOUNG_PTRS | <EOL> GCFLAG_HASHTAKEN ) <EOL> def collect ( self , gen = <NUM_LIT:1> ) : <EOL> if gen == <NUM_LIT:0> : <EOL> self . collect_nursery ( ) <EOL> else : <EOL> SemiSpaceGC . collect ( self ) <EOL> def semispace_collect ( self , size_changing = False ) : <EOL> self . reset_young_gcflags ( ) <EOL> self . weakrefs_grow_older ( ) <EOL> self . ids_grow_older ( ) <EOL> self . reset_nursery ( ) <EOL> if self . config . gcconfig . debugprint : <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , size_changing ) <EOL> SemiSpaceGC . semispace_collect ( self , size_changing ) <EOL> if self . config . gcconfig . debugprint and not size_changing : <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , float ( self . free - self . tospace ) / self . space_size ) <EOL> def make_a_copy ( self , obj , objsize ) : <EOL> tid = self . header ( obj ) . tid <EOL> tid |= GCFLAG_NO_YOUNG_PTRS <EOL> return self . _make_a_copy_with_tid ( obj , objsize , tid ) <EOL> def reset_young_gcflags ( self ) : <EOL> oldlist = self . old_objects_pointing_to_young <EOL> while oldlist . non_empty ( ) : <EOL> obj = oldlist . pop ( ) <EOL> hdr = self . header ( obj ) <EOL> hdr . tid |= GCFLAG_NO_YOUNG_PTRS <EOL> def weakrefs_grow_older ( self ) : <EOL> while self . young_objects_with_weakrefs . non_empty ( ) : <EOL> obj = self . young_objects_with_weakrefs . pop ( ) <EOL> self . objects_with_weakrefs . append ( obj ) <EOL> def collect_roots ( self ) : <EOL> """<STR_LIT>""" <EOL> self . collect_last_generation_roots ( ) <EOL> self . root_walker . walk_roots ( <EOL> SemiSpaceGC . _collect_root , <EOL> SemiSpaceGC . _collect_root , <EOL> None ) <EOL> def collect_last_generation_roots ( self ) : <EOL> stack = self . last_generation_root_objects <EOL> self . last_generation_root_objects = self . AddressStack ( ) <EOL> while stack . non_empty ( ) : <EOL> obj = stack . pop ( ) <EOL> self . header ( obj ) . tid |= GCFLAG_NO_HEAP_PTRS <EOL> self . trace ( obj , self . _trace_external_obj , obj ) <EOL> stack . delete ( ) <EOL> def _trace_external_obj ( self , pointer , obj ) : <EOL> addr = pointer . address [ <NUM_LIT:0> ] <EOL> newaddr = self . copy ( addr ) <EOL> pointer . address [ <NUM_LIT:0> ] = newaddr <EOL> self . write_into_last_generation_obj ( obj , newaddr ) <EOL> def collect_nursery ( self ) : <EOL> if self . nursery_size > self . top_of_space - self . free : <EOL> self . obtain_free_space ( self . nursery_size ) <EOL> ll_assert ( self . nursery_size <= self . top_of_space - self . free , <EOL> "<STR_LIT>" ) <EOL> if self . nursery : <EOL> if self . config . gcconfig . debugprint : <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" ) <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , <EOL> self . nursery , "<STR_LIT:to>" , self . nursery_top ) <EOL> scan = beginning = self . free <EOL> self . collect_oldrefs_to_nursery ( ) <EOL> self . collect_roots_in_nursery ( ) <EOL> scan = self . scan_objects_just_copied_out_of_nursery ( scan ) <EOL> if self . young_objects_with_weakrefs . non_empty ( ) : <EOL> self . invalidate_young_weakrefs ( ) <EOL> if self . young_objects_with_id . length ( ) > <NUM_LIT:0> : <EOL> self . update_young_objects_with_id ( ) <EOL> llarena . arena_reset ( self . nursery , self . nursery_size , <NUM_LIT:2> ) <EOL> if self . config . gcconfig . debugprint : <EOL> llop . debug_print ( lltype . Void , <EOL> "<STR_LIT>" , <EOL> float ( scan - beginning ) / self . nursery_size ) <EOL> else : <EOL> self . nursery = self . free <EOL> self . nursery_top = self . nursery + self . nursery_size <EOL> self . free = self . nursery_top <EOL> self . nursery_free = self . nursery <EOL> return self . nursery_free <EOL> def collect_oldrefs_to_nursery ( self ) : <EOL> count = <NUM_LIT:0> <EOL> oldlist = self . old_objects_pointing_to_young <EOL> while oldlist . non_empty ( ) : <EOL> count += <NUM_LIT:1> <EOL> obj = oldlist . pop ( ) <EOL> hdr = self . header ( obj ) <EOL> hdr . tid |= GCFLAG_NO_YOUNG_PTRS <EOL> self . trace_and_drag_out_of_nursery ( obj ) <EOL> if self . config . gcconfig . debugprint : <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , count ) <EOL> def collect_roots_in_nursery ( self ) : <EOL> self . root_walker . walk_roots ( <EOL> GenerationGC . _collect_root_in_nursery , <EOL> GenerationGC . _collect_root_in_nursery , <EOL> None ) <EOL> def _collect_root_in_nursery ( self , root ) : <EOL> obj = root . address [ <NUM_LIT:0> ] <EOL> if self . is_in_nursery ( obj ) : <EOL> root . address [ <NUM_LIT:0> ] = self . copy ( obj ) <EOL> def scan_objects_just_copied_out_of_nursery ( self , scan ) : <EOL> while scan < self . free : <EOL> curr = scan + self . size_gc_header ( ) <EOL> self . trace_and_drag_out_of_nursery ( curr ) <EOL> scan += self . size_gc_header ( ) + self . get_size_incl_hash ( curr ) <EOL> return scan <EOL> def trace_and_drag_out_of_nursery ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> self . trace ( obj , self . _trace_drag_out , None ) <EOL> def _trace_drag_out ( self , pointer , ignored ) : <EOL> if self . is_in_nursery ( pointer . address [ <NUM_LIT:0> ] ) : <EOL> pointer . address [ <NUM_LIT:0> ] = self . copy ( pointer . address [ <NUM_LIT:0> ] ) <EOL> def invalidate_young_weakrefs ( self ) : <EOL> while self . young_objects_with_weakrefs . non_empty ( ) : <EOL> obj = self . young_objects_with_weakrefs . pop ( ) <EOL> if not self . surviving ( obj ) : <EOL> continue <EOL> obj = self . get_forwarding_address ( obj ) <EOL> offset = self . weakpointer_offset ( self . get_type_id ( obj ) ) <EOL> pointing_to = ( obj + offset ) . address [ <NUM_LIT:0> ] <EOL> if self . is_in_nursery ( pointing_to ) : <EOL> if self . surviving ( pointing_to ) : <EOL> ( obj + offset ) . address [ <NUM_LIT:0> ] = self . get_forwarding_address ( <EOL> pointing_to ) <EOL> else : <EOL> ( obj + offset ) . address [ <NUM_LIT:0> ] = NULL <EOL> continue <EOL> self . objects_with_weakrefs . append ( obj ) <EOL> JIT_WB_IF_FLAG = GCFLAG_NO_YOUNG_PTRS <EOL> def write_barrier ( self , newvalue , addr_struct ) : <EOL> if self . header ( addr_struct ) . tid & GCFLAG_NO_YOUNG_PTRS : <EOL> self . remember_young_pointer ( addr_struct , newvalue ) <EOL> def _setup_wb ( self ) : <EOL> def remember_young_pointer ( addr_struct , addr ) : <EOL> ll_assert ( not self . is_in_nursery ( addr_struct ) , <EOL> "<STR_LIT>" ) <EOL> if ( self . config . taggedpointers and <EOL> not self . is_valid_gc_object ( addr ) ) : <EOL> return <EOL> if self . is_in_nursery ( addr ) : <EOL> self . old_objects_pointing_to_young . append ( addr_struct ) <EOL> self . header ( addr_struct ) . tid &= ~ GCFLAG_NO_YOUNG_PTRS <EOL> elif ( not self . config . taggedpointers and <EOL> not self . is_valid_gc_object ( addr ) ) : <EOL> return <EOL> self . write_into_last_generation_obj ( addr_struct , addr ) <EOL> remember_young_pointer . _dont_inline_ = True <EOL> self . remember_young_pointer = remember_young_pointer <EOL> def assume_young_pointers ( self , addr_struct ) : <EOL> objhdr = self . header ( addr_struct ) <EOL> if objhdr . tid & GCFLAG_NO_YOUNG_PTRS : <EOL> self . old_objects_pointing_to_young . append ( addr_struct ) <EOL> objhdr . tid &= ~ GCFLAG_NO_YOUNG_PTRS <EOL> if objhdr . tid & GCFLAG_NO_HEAP_PTRS : <EOL> objhdr . tid &= ~ GCFLAG_NO_HEAP_PTRS <EOL> self . last_generation_root_objects . append ( addr_struct ) <EOL> def write_into_last_generation_obj ( self , addr_struct , addr ) : <EOL> objhdr = self . header ( addr_struct ) <EOL> if objhdr . tid & GCFLAG_NO_HEAP_PTRS : <EOL> if not self . is_last_generation ( addr ) : <EOL> objhdr . tid &= ~ GCFLAG_NO_HEAP_PTRS <EOL> self . last_generation_root_objects . append ( addr_struct ) <EOL> def is_last_generation ( self , obj ) : <EOL> return ( self . header ( obj ) . tid & GCFLAG_EXTERNAL ) != <NUM_LIT:0> <EOL> def _compute_id ( self , obj ) : <EOL> if self . is_in_nursery ( obj ) : <EOL> result = self . young_objects_with_id . get ( obj ) <EOL> if not result : <EOL> result = self . _next_id ( ) <EOL> self . young_objects_with_id . setitem ( obj , result ) <EOL> return result <EOL> else : <EOL> return SemiSpaceGC . _compute_id ( self , obj ) <EOL> def update_young_objects_with_id ( self ) : <EOL> self . young_objects_with_id . foreach ( self . _update_object_id , <EOL> self . objects_with_id ) <EOL> self . young_objects_with_id . clear ( ) <EOL> def ids_grow_older ( self ) : <EOL> self . young_objects_with_id . foreach ( self . _id_grow_older , None ) <EOL> self . young_objects_with_id . clear ( ) <EOL> def _id_grow_older ( self , obj , id , ignored ) : <EOL> self . objects_with_id . setitem ( obj , id ) <EOL> def debug_check_object ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> SemiSpaceGC . debug_check_object ( self , obj ) <EOL> tid = self . header ( obj ) . tid <EOL> if tid & GCFLAG_NO_YOUNG_PTRS : <EOL> ll_assert ( not self . is_in_nursery ( obj ) , <EOL> "<STR_LIT>" ) <EOL> self . trace ( obj , self . _debug_no_nursery_pointer , None ) <EOL> elif not self . is_in_nursery ( obj ) : <EOL> ll_assert ( self . _d_oopty . contains ( obj ) , <EOL> "<STR_LIT>" ) <EOL> if tid & GCFLAG_NO_HEAP_PTRS : <EOL> ll_assert ( self . is_last_generation ( obj ) , <EOL> "<STR_LIT>" ) <EOL> self . trace ( obj , self . _debug_no_gen1or2_pointer , None ) <EOL> elif self . is_last_generation ( obj ) : <EOL> ll_assert ( self . _d_lgro . contains ( obj ) , <EOL> "<STR_LIT>" ) <EOL> def _debug_no_nursery_pointer ( self , root , ignored ) : <EOL> ll_assert ( not self . is_in_nursery ( root . address [ <NUM_LIT:0> ] ) , <EOL> "<STR_LIT>" ) <EOL> def _debug_no_gen1or2_pointer ( self , root , ignored ) : <EOL> target = root . address [ <NUM_LIT:0> ] <EOL> ll_assert ( not target or self . is_last_generation ( target ) , <EOL> "<STR_LIT>" ) <EOL> def debug_check_consistency ( self ) : <EOL> if self . DEBUG : <EOL> self . _d_oopty = self . old_objects_pointing_to_young . stack2dict ( ) <EOL> self . _d_lgro = self . last_generation_root_objects . stack2dict ( ) <EOL> SemiSpaceGC . debug_check_consistency ( self ) <EOL> self . _d_oopty . delete ( ) <EOL> self . _d_lgro . delete ( ) <EOL> self . old_objects_pointing_to_young . foreach ( <EOL> self . _debug_check_flag_1 , None ) <EOL> self . last_generation_root_objects . foreach ( <EOL> self . _debug_check_flag_2 , None ) <EOL> def _debug_check_flag_1 ( self , obj , ignored ) : <EOL> ll_assert ( not ( self . header ( obj ) . tid & GCFLAG_NO_YOUNG_PTRS ) , <EOL> "<STR_LIT>" ) <EOL> def _debug_check_flag_2 ( self , obj , ignored ) : <EOL> ll_assert ( not ( self . header ( obj ) . tid & GCFLAG_NO_HEAP_PTRS ) , <EOL> "<STR_LIT>" ) <EOL> def debug_check_can_copy ( self , obj ) : <EOL> if self . is_in_nursery ( obj ) : <EOL> pass <EOL> else : <EOL> SemiSpaceGC . debug_check_can_copy ( self , obj ) <EOL> import os <EOL> def nursery_size_from_env ( ) : <EOL> value = os . environ . get ( '<STR_LIT>' ) <EOL> if value : <EOL> if value [ - <NUM_LIT:1> ] in '<STR_LIT>' : <EOL> factor = <NUM_LIT> <EOL> value = value [ : - <NUM_LIT:1> ] <EOL> else : <EOL> factor = <NUM_LIT:1> <EOL> try : <EOL> return int ( value ) * factor <EOL> except ValueError : <EOL> pass <EOL> return - <NUM_LIT:1> <EOL> def best_nursery_size_for_L2cache ( L2cache , debugprint = False ) : <EOL> if debugprint : <EOL> llop . debug_print ( lltype . Void , "<STR_LIT>" , L2cache ) <EOL> return L2cache // <NUM_LIT:2> <EOL> if sys . platform == '<STR_LIT>' : <EOL> def estimate_best_nursery_size ( debugprint = False ) : <EOL> """<STR_LIT>""" <EOL> L2cache = sys . maxint <EOL> try : <EOL> fd = os . open ( '<STR_LIT>' , os . O_RDONLY , <NUM_LIT:0> <NUM_LIT> ) <EOL> try : <EOL> data = [ ] <EOL> while True : <EOL> buf = os . read ( fd , <NUM_LIT> ) <EOL> if not buf : <EOL> break <EOL> data . append ( buf ) <EOL> finally : <EOL> os . close ( fd ) <EOL> except OSError : <EOL> pass <EOL> else : <EOL> data = '<STR_LIT>' . join ( data ) <EOL> linepos = <NUM_LIT:0> <EOL> while True : <EOL> start = findend ( data , '<STR_LIT>' , linepos ) <EOL> if start < <NUM_LIT:0> : <EOL> break <EOL> linepos = findend ( data , '<STR_LIT:\n>' , start ) <EOL> if linepos < <NUM_LIT:0> : <EOL> break <EOL> start = skipspace ( data , start ) <EOL> if data [ start ] != '<STR_LIT::>' : <EOL> continue <EOL> start = skipspace ( data , start + <NUM_LIT:1> ) <EOL> end = start <EOL> while '<STR_LIT:0>' <= data [ end ] <= '<STR_LIT>' : <EOL> end += <NUM_LIT:1> <EOL> if start == end : <EOL> continue <EOL> number = int ( data [ start : end ] ) <EOL> end = skipspace ( data , end ) <EOL> if data [ end ] not in ( '<STR_LIT>' , '<STR_LIT:k>' ) : <EOL> continue <EOL> number = number * <NUM_LIT> <EOL> if number < L2cache : <EOL> L2cache = number <EOL> if L2cache < sys . maxint : <EOL> return best_nursery_size_for_L2cache ( L2cache , debugprint ) <EOL> else : <EOL> llop . debug_print ( lltype . Void , <EOL> "<STR_LIT>" ) <EOL> return - <NUM_LIT:1> <EOL> def findend ( data , pattern , pos ) : <EOL> pos = data . find ( pattern , pos ) <EOL> if pos < <NUM_LIT:0> : <EOL> return - <NUM_LIT:1> <EOL> return pos + len ( pattern ) <EOL> def skipspace ( data , pos ) : <EOL> while data [ pos ] in ( '<STR_LIT:U+0020>' , '<STR_LIT:\t>' ) : <EOL> pos += <NUM_LIT:1> <EOL> return pos <EOL> elif sys . platform == '<STR_LIT>' : <EOL> from pypy . rpython . lltypesystem import lltype , rffi <EOL> sysctlbyname = rffi . llexternal ( '<STR_LIT>' , <EOL> [ rffi . CCHARP , rffi . VOIDP , rffi . SIZE_TP , <EOL> rffi . VOIDP , rffi . SIZE_T ] , <EOL> rffi . INT , <EOL> sandboxsafe = True ) <EOL> def estimate_best_nursery_size ( debugprint = False ) : <EOL> """<STR_LIT>""" <EOL> L2cache = <NUM_LIT:0> <EOL> l2cache_p = lltype . malloc ( rffi . LONGLONGP . TO , <NUM_LIT:1> , flavor = '<STR_LIT>' ) <EOL> try : <EOL> len_p = lltype . malloc ( rffi . SIZE_TP . TO , <NUM_LIT:1> , flavor = '<STR_LIT>' ) <EOL> try : <EOL> size = rffi . sizeof ( rffi . LONGLONG ) <EOL> l2cache_p [ <NUM_LIT:0> ] = rffi . cast ( rffi . LONGLONG , <NUM_LIT:0> ) <EOL> len_p [ <NUM_LIT:0> ] = rffi . cast ( rffi . SIZE_T , size ) <EOL> result = sysctlbyname ( "<STR_LIT>" , <EOL> rffi . cast ( rffi . VOIDP , l2cache_p ) , <EOL> len_p , <EOL> lltype . nullptr ( rffi . VOIDP . TO ) , <EOL> rffi . cast ( rffi . SIZE_T , <NUM_LIT:0> ) ) <EOL> if ( rffi . cast ( lltype . Signed , result ) == <NUM_LIT:0> and <EOL> rffi . cast ( lltype . Signed , len_p [ <NUM_LIT:0> ] ) == size ) : <EOL> L2cache = rffi . cast ( lltype . Signed , l2cache_p [ <NUM_LIT:0> ] ) <EOL> if rffi . cast ( rffi . LONGLONG , L2cache ) != l2cache_p [ <NUM_LIT:0> ] : <EOL> L2cache = <NUM_LIT:0> <EOL> finally : <EOL> lltype . free ( len_p , flavor = '<STR_LIT>' ) <EOL> finally : <EOL> lltype . free ( l2cache_p , flavor = '<STR_LIT>' ) <EOL> if L2cache > <NUM_LIT:0> : <EOL> return best_nursery_size_for_L2cache ( L2cache , debugprint ) <EOL> else : <EOL> llop . debug_print ( lltype . Void , <EOL> "<STR_LIT>" ) <EOL> return - <NUM_LIT:1> <EOL> else : <EOL> def estimate_best_nursery_size ( debugprint = False ) : <EOL> return - <NUM_LIT:1> </s>
