| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::search_lookup_alist(cell table, cell klass) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-09 21:24:32 -04:00
										 |  |  | 	array *elements = untag<array>(table); | 
					
						
							|  |  |  | 	fixnum index = array_capacity(elements) - 2; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	while(index >= 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-09 21:24:32 -04:00
										 |  |  | 		if(array_nth(elements,index) == klass) | 
					
						
							|  |  |  | 			return array_nth(elements,index + 1); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-05-09 21:24:32 -04:00
										 |  |  | 			index -= 2; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-18 21:26:21 -04:00
										 |  |  | 	return false_object; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::search_lookup_hash(cell table, cell klass, cell hashcode) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	array *buckets = untag<array>(table); | 
					
						
							|  |  |  | 	cell bucket = array_nth(buckets,hashcode & (array_capacity(buckets) - 1)); | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 	if(TAG(bucket) == ARRAY_TYPE) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		return search_lookup_alist(bucket,klass); | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		return bucket; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::nth_superclass(tuple_layout *layout, fixnum echelon) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell *ptr = (cell *)(layout + 1); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	return ptr[echelon * 2]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::nth_hashcode(tuple_layout *layout, fixnum echelon) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell *ptr = (cell *)(layout + 1); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	return ptr[echelon * 2 + 1]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::lookup_tuple_method(cell obj, cell methods) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	tuple_layout *layout = untag<tuple_layout>(untag<tuple>(obj)->layout); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	array *echelons = untag<array>(methods); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 	fixnum echelon = std::min(untag_fixnum(layout->echelon),(fixnum)array_capacity(echelons) - 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	while(echelon >= 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		cell echelon_methods = array_nth(echelons,echelon); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		if(tagged<object>(echelon_methods).type_p(WORD_TYPE)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			return echelon_methods; | 
					
						
							| 
									
										
										
										
											2009-10-18 21:26:21 -04:00
										 |  |  | 		else if(to_boolean(echelon_methods)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			cell klass = nth_superclass(layout,echelon); | 
					
						
							|  |  |  | 			cell hashcode = untag_fixnum(nth_hashcode(layout,echelon)); | 
					
						
							|  |  |  | 			cell result = search_lookup_hash(echelon_methods,klass,hashcode); | 
					
						
							| 
									
										
										
										
											2009-10-18 21:26:21 -04:00
										 |  |  | 			if(to_boolean(result)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				return result; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		echelon--; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	critical_error("Cannot find tuple method",methods); | 
					
						
							| 
									
										
										
										
											2009-10-18 21:26:21 -04:00
										 |  |  | 	return false_object; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | cell factor_vm::lookup_method(cell obj, cell methods) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 	cell tag = TAG(obj); | 
					
						
							|  |  |  | 	cell method = array_nth(untag<array>(methods),tag); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(tag == TUPLE_TYPE) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 		if(TAG(method) == ARRAY_TYPE) | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			return lookup_tuple_method(obj,method); | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			return method; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 		return method; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_lookup_method() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	cell methods = ctx->pop(); | 
					
						
							|  |  |  | 	cell obj = ctx->pop(); | 
					
						
							|  |  |  | 	ctx->push(lookup_method(obj,methods)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::object_class(cell obj) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-02 04:25:39 -05:00
										 |  |  | 	cell tag = TAG(obj); | 
					
						
							|  |  |  | 	if(tag == TUPLE_TYPE) | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		return untag<tuple>(obj)->layout; | 
					
						
							| 
									
										
										
										
											2009-11-02 04:25:39 -05:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		return tag_fixnum(tag); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | cell factor_vm::method_cache_hashcode(cell klass, array *array) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell capacity = (array_capacity(array) >> 1) - 1; | 
					
						
							| 
									
										
										
										
											2009-11-02 04:25:39 -05:00
										 |  |  | 	return ((klass >> TAG_BITS) & capacity) << 1; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | void factor_vm::update_method_cache(cell cache, cell klass, cell method) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	array *cache_elements = untag<array>(cache); | 
					
						
							|  |  |  | 	cell hashcode = method_cache_hashcode(klass,cache_elements); | 
					
						
							|  |  |  | 	set_array_nth(cache_elements,hashcode,klass); | 
					
						
							|  |  |  | 	set_array_nth(cache_elements,hashcode + 1,method); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_mega_cache_miss() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-05 02:07:59 -05:00
										 |  |  | 	dispatch_stats.megamorphic_cache_misses++; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	cell cache = ctx->pop(); | 
					
						
							|  |  |  | 	fixnum index = untag_fixnum(ctx->pop()); | 
					
						
							|  |  |  | 	cell methods = ctx->pop(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	cell object = ((cell *)ctx->datastack)[-index]; | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell klass = object_class(object); | 
					
						
							|  |  |  | 	cell method = lookup_method(object,methods); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	update_method_cache(cache,klass,method); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	ctx->push(method); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_reset_dispatch_stats() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-05 02:07:59 -05:00
										 |  |  | 	memset(&dispatch_stats,0,sizeof(dispatch_statistics)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_dispatch_stats() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	ctx->push(tag<byte_array>(byte_array_from_value(&dispatch_stats))); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cache_) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-02 19:10:34 -05:00
										 |  |  | 	data_root<array> methods(methods_,parent); | 
					
						
							|  |  |  | 	data_root<array> cache(cache_,parent); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 17:38:01 -05:00
										 |  |  | 	/* The object must be on the top of the datastack at this point. */ | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Do a cache lookup. */ | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | 	emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* If we end up here, the cache missed. */ | 
					
						
							| 
									
										
										
										
											2009-10-23 01:33:53 -04:00
										 |  |  | 	emit(parent->special_objects[JIT_PROLOG]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Push index, method table and cache on the stack. */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	push(methods.value()); | 
					
						
							|  |  |  | 	push(tag_fixnum(index)); | 
					
						
							|  |  |  | 	push(cache.value()); | 
					
						
							| 
									
										
										
										
											2009-10-23 01:33:53 -04:00
										 |  |  | 	word_call(parent->special_objects[MEGA_MISS_WORD]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Now the new method has been stored into the cache, and its on
 | 
					
						
							|  |  |  | 	   the stack. */ | 
					
						
							| 
									
										
										
										
											2009-10-23 01:33:53 -04:00
										 |  |  | 	emit(parent->special_objects[JIT_EPILOG]); | 
					
						
							| 
									
										
										
										
											2009-12-15 07:20:09 -05:00
										 |  |  | 	emit(parent->special_objects[JIT_EXECUTE]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |