From d5f66d95614a2912bd6cfe59094dac8c7c2eef20 Mon Sep 17 00:00:00 2001 From: Erik Charlebois Date: Sat, 11 May 2013 21:57:45 -0400 Subject: [PATCH] VM: Refactor dispatch to Factor style --- vm/dispatch.cpp | 242 ++++++++++++++++++++++-------------------------- vm/dispatch.hpp | 17 ++-- 2 files changed, 120 insertions(+), 139 deletions(-) diff --git a/vm/dispatch.cpp b/vm/dispatch.cpp index 8b2859bd70..3aab4f9ffe 100644 --- a/vm/dispatch.cpp +++ b/vm/dispatch.cpp @@ -1,172 +1,154 @@ #include "master.hpp" -namespace factor -{ - -cell factor_vm::search_lookup_alist(cell table, cell klass) -{ - array *elements = untag(table); - fixnum index = array_capacity(elements) - 2; - while(index >= 0) - { - if(array_nth(elements,index) == klass) - return array_nth(elements,index + 1); - else - index -= 2; - } - - return false_object; +namespace factor { + +cell factor_vm::search_lookup_alist(cell table, cell klass) { + array* elements = untag(table); + fixnum index = array_capacity(elements) - 2; + while (index >= 0) { + if (array_nth(elements, index) == klass) + return array_nth(elements, index + 1); + else + index -= 2; + } + + return false_object; } -cell factor_vm::search_lookup_hash(cell table, cell klass, cell hashcode) -{ - array *buckets = untag(table); - cell bucket = array_nth(buckets,hashcode & (array_capacity(buckets) - 1)); - if(TAG(bucket) == ARRAY_TYPE) - return search_lookup_alist(bucket,klass); - else - return bucket; +cell factor_vm::search_lookup_hash(cell table, cell klass, cell hashcode) { + array* buckets = untag(table); + cell bucket = array_nth(buckets, hashcode & (array_capacity(buckets) - 1)); + if (TAG(bucket) == ARRAY_TYPE) + return search_lookup_alist(bucket, klass); + else + return bucket; } -cell factor_vm::nth_superclass(tuple_layout *layout, fixnum echelon) -{ - cell *ptr = (cell *)(layout + 1); - return ptr[echelon * 2]; +cell factor_vm::nth_superclass(tuple_layout* layout, fixnum echelon) { + cell* ptr = (cell*)(layout + 1); + return ptr[echelon * 2]; } -cell factor_vm::nth_hashcode(tuple_layout *layout, fixnum echelon) -{ - cell *ptr = (cell *)(layout + 1); - return ptr[echelon * 2 + 1]; +cell factor_vm::nth_hashcode(tuple_layout* layout, fixnum echelon) { + cell* ptr = (cell*)(layout + 1); + return ptr[echelon * 2 + 1]; } -cell factor_vm::lookup_tuple_method(cell obj, cell methods) -{ - tuple_layout *layout = untag(untag(obj)->layout); +cell factor_vm::lookup_tuple_method(cell obj, cell methods) { + tuple_layout* layout = untag(untag(obj)->layout); - array *echelons = untag(methods); + array* echelons = untag(methods); - fixnum echelon = std::min(untag_fixnum(layout->echelon),(fixnum)array_capacity(echelons) - 1); + fixnum echelon = std::min(untag_fixnum(layout->echelon), + (fixnum) array_capacity(echelons) - 1); - while(echelon >= 0) - { - cell echelon_methods = array_nth(echelons,echelon); + while (echelon >= 0) { + cell echelon_methods = array_nth(echelons, echelon); - if(tagged(echelon_methods).type_p(WORD_TYPE)) - return echelon_methods; - else if(to_boolean(echelon_methods)) - { - cell klass = nth_superclass(layout,echelon); - cell hashcode = untag_fixnum(nth_hashcode(layout,echelon)); - cell result = search_lookup_hash(echelon_methods,klass,hashcode); - if(to_boolean(result)) - return result; - } + if (tagged(echelon_methods).type_p(WORD_TYPE)) + return echelon_methods; + else if (to_boolean(echelon_methods)) { + cell klass = nth_superclass(layout, echelon); + cell hashcode = untag_fixnum(nth_hashcode(layout, echelon)); + cell result = search_lookup_hash(echelon_methods, klass, hashcode); + if (to_boolean(result)) + return result; + } - echelon--; - } + echelon--; + } - critical_error("Cannot find tuple method",methods); - return false_object; + critical_error("Cannot find tuple method", methods); + return false_object; } -cell factor_vm::lookup_method(cell obj, cell methods) -{ - cell tag = TAG(obj); - cell method = array_nth(untag(methods),tag); - - if(tag == TUPLE_TYPE) - { - if(TAG(method) == ARRAY_TYPE) - return lookup_tuple_method(obj,method); - else - return method; - } - else - return method; +cell factor_vm::lookup_method(cell obj, cell methods) { + cell tag = TAG(obj); + cell method = array_nth(untag(methods), tag); + + if (tag == TUPLE_TYPE) { + if (TAG(method) == ARRAY_TYPE) + return lookup_tuple_method(obj, method); + else + return method; + } else + return method; } -void factor_vm::primitive_lookup_method() -{ - cell methods = ctx->pop(); - cell obj = ctx->pop(); - ctx->push(lookup_method(obj,methods)); +void factor_vm::primitive_lookup_method() { + cell methods = ctx->pop(); + cell obj = ctx->pop(); + ctx->push(lookup_method(obj, methods)); } -cell factor_vm::object_class(cell obj) -{ - cell tag = TAG(obj); - if(tag == TUPLE_TYPE) - return untag(obj)->layout; - else - return tag_fixnum(tag); +cell factor_vm::object_class(cell obj) { + cell tag = TAG(obj); + if (tag == TUPLE_TYPE) + return untag(obj)->layout; + else + return tag_fixnum(tag); } -cell factor_vm::method_cache_hashcode(cell klass, array *array) -{ - cell capacity = (array_capacity(array) >> 1) - 1; - return ((klass >> TAG_BITS) & capacity) << 1; +cell factor_vm::method_cache_hashcode(cell klass, array* array) { + cell capacity = (array_capacity(array) >> 1) - 1; + return ((klass >> TAG_BITS) & capacity) << 1; } -void factor_vm::update_method_cache(cell cache, cell klass, cell method) -{ - array *cache_elements = untag(cache); - cell hashcode = method_cache_hashcode(klass,cache_elements); - set_array_nth(cache_elements,hashcode,klass); - set_array_nth(cache_elements,hashcode + 1,method); +void factor_vm::update_method_cache(cell cache, cell klass, cell method) { + array* cache_elements = untag(cache); + cell hashcode = method_cache_hashcode(klass, cache_elements); + set_array_nth(cache_elements, hashcode, klass); + set_array_nth(cache_elements, hashcode + 1, method); } -void factor_vm::primitive_mega_cache_miss() -{ - dispatch_stats.megamorphic_cache_misses++; +void factor_vm::primitive_mega_cache_miss() { + dispatch_stats.megamorphic_cache_misses++; - cell cache = ctx->pop(); - fixnum index = untag_fixnum(ctx->pop()); - cell methods = ctx->pop(); + cell cache = ctx->pop(); + fixnum index = untag_fixnum(ctx->pop()); + cell methods = ctx->pop(); - cell object = ((cell *)ctx->datastack)[-index]; - cell klass = object_class(object); - cell method = lookup_method(object,methods); + cell object = ((cell*)ctx->datastack)[-index]; + cell klass = object_class(object); + cell method = lookup_method(object, methods); - update_method_cache(cache,klass,method); + update_method_cache(cache, klass, method); - ctx->push(method); + ctx->push(method); } -void factor_vm::primitive_reset_dispatch_stats() -{ - memset(&dispatch_stats,0,sizeof(dispatch_statistics)); +void factor_vm::primitive_reset_dispatch_stats() { + memset(&dispatch_stats, 0, sizeof(dispatch_statistics)); } /* Allocates memory */ -void factor_vm::primitive_dispatch_stats() -{ - ctx->push(tag(byte_array_from_value(&dispatch_stats))); +void factor_vm::primitive_dispatch_stats() { + ctx->push(tag(byte_array_from_value(&dispatch_stats))); } -void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cache_) -{ - data_root methods(methods_,parent); - data_root cache(cache_,parent); - - /* The object must be on the top of the datastack at this point. */ - - /* Do a cache lookup. */ - emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value()); - - /* If we end up here, the cache missed. */ - emit(parent->special_objects[JIT_PROLOG]); - - /* Push index, method table and cache on the stack. */ - push(methods.value()); - push(tag_fixnum(index)); - push(cache.value()); - word_call(parent->special_objects[MEGA_MISS_WORD]); - - /* Now the new method has been stored into the cache, and its on - the stack. */ - emit(parent->special_objects[JIT_EPILOG]); - emit(parent->special_objects[JIT_EXECUTE]); +void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, + cell cache_) { + data_root methods(methods_, parent); + data_root cache(cache_, parent); + + /* The object must be on the top of the datastack at this point. */ + + /* Do a cache lookup. */ + emit_with_literal(parent->special_objects[MEGA_LOOKUP], cache.value()); + + /* If we end up here, the cache missed. */ + emit(parent->special_objects[JIT_PROLOG]); + + /* Push index, method table and cache on the stack. */ + push(methods.value()); + push(tag_fixnum(index)); + push(cache.value()); + word_call(parent->special_objects[MEGA_MISS_WORD]); + + /* Now the new method has been stored into the cache, and its on + the stack. */ + emit(parent->special_objects[JIT_EPILOG]); + emit(parent->special_objects[JIT_EXECUTE]); } } diff --git a/vm/dispatch.hpp b/vm/dispatch.hpp index 87d08e2760..7f676212cb 100644 --- a/vm/dispatch.hpp +++ b/vm/dispatch.hpp @@ -1,16 +1,15 @@ -namespace factor -{ +namespace factor { struct dispatch_statistics { - cell megamorphic_cache_hits; - cell megamorphic_cache_misses; + cell megamorphic_cache_hits; + cell megamorphic_cache_misses; - cell cold_call_to_ic_transitions; - cell ic_to_pic_transitions; - cell pic_to_mega_transitions; + cell cold_call_to_ic_transitions; + cell ic_to_pic_transitions; + cell pic_to_mega_transitions; - cell pic_tag_count; - cell pic_tuple_count; + cell pic_tag_count; + cell pic_tuple_count; }; } -- 2.34.1