From 02bd4f3f0012abf44538241eaf89280365601f4d Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 29 Apr 2009 19:39:43 -0500 Subject: [PATCH] PICs now pass the method table around instead of extracting it from the generic word body. This gels better with how compilation units are supposed to work --- core/generic/single/single.factor | 28 +++++++++--------- core/generic/standard/standard.factor | 4 +-- vm/inline_cache.c | 41 +++++++-------------------- 3 files changed, 26 insertions(+), 47 deletions(-) diff --git a/core/generic/single/single.factor b/core/generic/single/single.factor index 9d958b36f3..8e60b75bdc 100644 --- a/core/generic/single/single.factor +++ b/core/generic/single/single.factor @@ -230,30 +230,28 @@ M: word compile-engine ; M: f compile-engine ; : build-decision-tree ( generic -- methods ) - { - [ generic-word set ] - [ "engines" word-prop forget-all ] - [ V{ } clone "engines" set-word-prop ] - [ - "methods" word-prop clone - [ find-default default set ] - [ compile-engine ] bi - ] - } cleave ; + [ "engines" word-prop forget-all ] + [ V{ } clone "engines" set-word-prop ] + [ + "methods" word-prop clone + [ find-default default set ] + [ compile-engine ] bi + ] tri ; : make-empty-cache ( -- array ) generic-word get "methods" word-prop assoc-size 2 * next-power-of-2 f ; -HOOK: cold-call-def combination ( word -- quot/f ) +HOOK: direct-entry-def combination ( word methods -- quot/f ) -M: single-combination cold-call-def drop f ; +M: single-combination direct-entry-def 2drop f ; -: define-cold-call ( word -- ) - dup cold-call-def >>direct-entry-def drop ; +: define-direct-entry ( word methods -- ) + [ drop ] [ direct-entry-def ] 2bi >>direct-entry-def drop ; M: single-combination perform-combination [ + dup generic-word set dup build-decision-tree [ "decision-tree" set-word-prop ] [ @@ -264,5 +262,5 @@ M: single-combination perform-combination [ lookup-method (execute) ] % ] [ ] make define ] - [ drop define-cold-call ] 2tri + [ define-direct-entry ] 2tri ] with-combination ; \ No newline at end of file diff --git a/core/generic/standard/standard.factor b/core/generic/standard/standard.factor index 499495cdc0..ef3806ca3a 100644 --- a/core/generic/standard/standard.factor +++ b/core/generic/standard/standard.factor @@ -38,11 +38,11 @@ M: standard-generic effective-method [ datastack ] dip [ "combination" word-prop #>> swap nth ] keep (effective-method) ; -M: standard-combination cold-call-def +M: standard-combination direct-entry-def ( word methods -- ) #! Direct calls to the generic word (not tail calls or indirect calls) #! will jump to the inline cache entry point instead of the megamorphic #! dispatch entry point. - [ f inline-cache-miss ] curry picker prepend ; + picker first [ [ f inline-cache-miss ] 3curry ] keep prefix ; M: standard-generic definer drop \ GENERIC# f ; diff --git a/vm/inline_cache.c b/vm/inline_cache.c index 86322e026d..7230d45dc3 100644 --- a/vm/inline_cache.c +++ b/vm/inline_cache.c @@ -52,7 +52,7 @@ static void update_pic_count(CELL type) /* picker: one of dup, over, pick cache_entries: array of class/method pairs */ -static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL cache_entries) +static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL methods, CELL cache_entries) { #ifdef FACTOR_DEBUG type_check(WORD_TYPE,picker); @@ -62,6 +62,7 @@ static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL c REGISTER_ROOT(picker); REGISTER_ROOT(generic_word); + REGISTER_ROOT(methods); REGISTER_ROOT(cache_entries); CELL inline_cache_type = determine_inline_cache_type(cache_entries); @@ -96,6 +97,8 @@ static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL c object being dispatched on can be popped from the top of the stack. */ jit_emit_subprimitive(&jit,untag_object(picker)); jit_push(&jit,generic_word); + jit_push(&jit,methods); + jit_push(&jit,picker); jit_push(&jit,cache_entries); jit_word_jump(&jit,userenv[PIC_MISS_WORD]); @@ -105,6 +108,7 @@ static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL c jit_dispose(&jit); UNREGISTER_ROOT(cache_entries); + UNREGISTER_ROOT(methods); UNREGISTER_ROOT(generic_word); UNREGISTER_ROOT(picker); @@ -121,28 +125,6 @@ static F_CODE_BLOCK *megamorphic_call_stub(CELL generic_word) return untag_quotation(word->def)->code; } -/* Assumes that generic word definitions look like: - [ lookup-method (execute) ] -*/ -static void examine_generic_word(CELL generic_word, CELL *picker, CELL *all_methods) -{ - CELL def = untag_word(generic_word)->def; - F_QUOTATION *quot = untag_quotation(def); - F_ARRAY *array = untag_object(quot->array); - -#ifdef FACTOR_DEBUG - assert(array_capacity(array) == 5); - type_check(WORD_TYPE,array_nth(array,0)); - type_check(ARRAY_TYPE,array_nth(array,1)); - type_check(ARRAY_TYPE,array_nth(array,2)); - type_check(WORD_TYPE,array_nth(array,3)); - type_check(WORD_TYPE,array_nth(array,4)); -#endif - - *picker = array_nth(array,0); - *all_methods = array_nth(array,1); -} - static CELL inline_cache_size(CELL cache_entries) { return (cache_entries == F ? 0 : array_capacity(untag_array(cache_entries)) / 2); @@ -181,6 +163,8 @@ XT inline_cache_miss(CELL return_address) check_code_pointer(return_address); CELL cache_entries = dpop(); + CELL picker = dpop(); + CELL methods = dpop(); CELL generic_word = dpop(); CELL object = dpop(); @@ -194,21 +178,18 @@ XT inline_cache_miss(CELL return_address) block = megamorphic_call_stub(generic_word); else { - CELL picker, all_methods; - examine_generic_word(generic_word,&picker,&all_methods); - REGISTER_ROOT(generic_word); REGISTER_ROOT(cache_entries); REGISTER_ROOT(picker); - REGISTER_ROOT(all_methods); + REGISTER_ROOT(methods); CELL class = object_class(object); - CELL method = lookup_method(object,all_methods); + CELL method = lookup_method(object,methods); cache_entries = add_inline_cache_entry(cache_entries,class,method); - block = compile_inline_cache(picker,generic_word,cache_entries); + block = compile_inline_cache(picker,generic_word,methods,cache_entries); - UNREGISTER_ROOT(all_methods); + UNREGISTER_ROOT(methods); UNREGISTER_ROOT(picker); UNREGISTER_ROOT(cache_entries); UNREGISTER_ROOT(generic_word);