| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | namespace factor { | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | inline static cell callstack_object_size(cell size) { | 
					
						
							|  |  |  |   return sizeof(callstack) + size; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | /* This is a little tricky. The iterator may allocate memory, so we
 | 
					
						
							| 
									
										
										
										
											2015-11-24 10:00:50 -05:00
										 |  |  |    keep the callstack in a GC root and use relative offsets */ | 
					
						
							| 
									
										
										
										
											2014-02-13 23:42:44 -05:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | template <typename Iterator, typename Fixup> | 
					
						
							|  |  |  | inline void factor_vm::iterate_callstack_object(callstack* stack_, | 
					
						
							|  |  |  |                                                 Iterator& iterator, | 
					
						
							|  |  |  |                                                 Fixup& fixup) { | 
					
						
							|  |  |  |   data_root<callstack> stack(stack_, this); | 
					
						
							| 
									
										
										
										
											2015-08-14 16:31:04 -04:00
										 |  |  |   fixnum frame_length = untag_fixnum(stack->length); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  |   fixnum frame_offset = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (frame_offset < frame_length) { | 
					
						
							| 
									
										
										
										
											2015-01-06 11:35:44 -05:00
										 |  |  |     cell frame_top = stack->frame_top_at(frame_offset); | 
					
						
							| 
									
										
										
										
											2015-01-05 08:04:12 -05:00
										 |  |  |     cell addr = *(cell*)frame_top; | 
					
						
							|  |  |  |     cell fixed_addr = Fixup::translated_code_block_map | 
					
						
							|  |  |  |                           ? (cell)fixup.translate_code((code_block*)addr) | 
					
						
							|  |  |  |                           : addr; | 
					
						
							|  |  |  |     code_block* owner = code->code_block_for_address(fixed_addr); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-05 08:04:12 -05:00
										 |  |  |     cell frame_size = owner->stack_frame_size_for_address(fixed_addr); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     iterator(frame_top, frame_size, owner, fixed_addr); | 
					
						
							|  |  |  |     frame_offset += frame_size; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  |   FACTOR_ASSERT(frame_offset == frame_length); | 
					
						
							| 
									
										
										
										
											2011-12-02 12:11:34 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-13 23:42:44 -05:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | template <typename Iterator> | 
					
						
							| 
									
										
										
										
											2013-05-12 23:20:43 -04:00
										 |  |  | inline void factor_vm::iterate_callstack_object(callstack* stack, | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  |                                                 Iterator& iterator) { | 
					
						
							|  |  |  |   no_fixup none; | 
					
						
							| 
									
										
										
										
											2013-05-12 23:20:43 -04:00
										 |  |  |   iterate_callstack_object(stack, iterator, none); | 
					
						
							| 
									
										
										
										
											2011-12-06 17:51:41 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-14 16:31:04 -04:00
										 |  |  | /* Iterates the callstack from innermost to outermost
 | 
					
						
							|  |  |  |    callframe. Allocates memory */ | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | template <typename Iterator, typename Fixup> | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  | void factor_vm::iterate_callstack(context* ctx, Iterator& iterator, | 
					
						
							|  |  |  |                                   Fixup& fixup) { | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  |   cell top = ctx->callstack_top; | 
					
						
							| 
									
										
										
										
											2015-02-18 23:43:53 -05:00
										 |  |  |   cell bottom = ctx->callstack_bottom; | 
					
						
							|  |  |  |   /* When we are translating the code block maps, all callstacks must
 | 
					
						
							|  |  |  |      be empty. */ | 
					
						
							|  |  |  |   FACTOR_ASSERT(!Fixup::translated_code_block_map || top == bottom); | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 23:43:53 -05:00
										 |  |  |   while (top < bottom) { | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  |     cell addr = *(cell*)top; | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  |     FACTOR_ASSERT(addr != 0); | 
					
						
							| 
									
										
										
										
											2011-12-06 12:14:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  |     /* Only the address is valid, if the code heap has been compacted,
 | 
					
						
							|  |  |  |        owner might not point to a real code block. */ | 
					
						
							|  |  |  |     code_block* owner = code->code_block_for_address(addr); | 
					
						
							|  |  |  |     code_block* fixed_owner = fixup.translate_code(owner); | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  |     cell delta = addr - (cell)owner - sizeof(code_block); | 
					
						
							|  |  |  |     cell natural_frame_size = fixed_owner->stack_frame_size(); | 
					
						
							|  |  |  |     cell size = LEAF_FRAME_SIZE; | 
					
						
							|  |  |  |     if (natural_frame_size > 0 && delta > 0) | 
					
						
							|  |  |  |       size = natural_frame_size; | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:56:38 -05:00
										 |  |  |     iterator(top, size, owner, addr); | 
					
						
							|  |  |  |     top += size; | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-18 23:43:53 -05:00
										 |  |  |   FACTOR_ASSERT(top == bottom); | 
					
						
							| 
									
										
										
										
											2011-12-05 17:18:42 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-13 23:42:44 -05:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2013-05-11 21:47:34 -04:00
										 |  |  | template <typename Iterator> | 
					
						
							|  |  |  | inline void factor_vm::iterate_callstack(context* ctx, Iterator& iterator) { | 
					
						
							|  |  |  |   no_fixup none; | 
					
						
							|  |  |  |   iterate_callstack(ctx, iterator, none); | 
					
						
							| 
									
										
										
										
											2011-11-30 20:56:24 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |