Пример #1
0
	void operator()(instruction_operand op)
	{
		code_block *compiled = op.parent_code_block();
		cell old_offset = op.rel_offset() + (cell)compiled->entry_point() - code_offset;

		switch(op.rel_type())
		{
		case RT_LITERAL:
			op.store_value(data_visitor.visit_pointer(op.load_value(old_offset)));
			break;
		case RT_ENTRY_POINT:
		case RT_ENTRY_POINT_PIC:
		case RT_ENTRY_POINT_PIC_TAIL:
			op.store_code_block(code_visitor(op.load_code_block(old_offset)));
			break;
		case RT_HERE:
			op.store_value(op.load_value(old_offset) + code_offset);
			break;
		case RT_UNTAGGED:
			break;
		default:
			parent->store_external_address(op);
			break;
		}
	}
Пример #2
0
	void operator()(code_block *old_address, code_block *new_address, cell size)
	{
		data_forwarder.visit_code_block_objects(new_address);

		code_block_compaction_relocation_visitor<Fixup> visitor(parent,old_address,fixup);
		new_address->each_instruction_operand(visitor);
	}
Пример #3
0
	/*
	next  -> [entry_point]
	         [size]
	         [return address] -- x86 only, backend adds 1 to each spill location
	         [spill area]
	         ...
	frame -> [entry_point]
	         [size]
	*/
	void operator()(stack_frame *frame)
	{
		cell return_address = parent->frame_offset(frame);
		if(return_address == (cell)-1)
			return;

		code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame));
		gc_info *info = compiled->block_gc_info();

		assert(return_address < compiled->size());
		cell callsite = info->return_address_index(return_address);
		if(callsite == (cell)-1)
			return;

#ifdef DEBUG_GC_MAPS
		std::cout << "call frame code block " << compiled << " with offset " << return_address << std::endl;
#endif
		cell *stack_pointer = (cell *)(parent->frame_successor(frame) + 1);
		u8 *bitmap = info->gc_info_bitmap();

		/* Subtract old value of base pointer from every derived pointer. */
		for(cell spill_slot = 0; spill_slot < info->derived_root_count; spill_slot++)
		{
			u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot);
			if(base_pointer != (u32)-1)
			{
#ifdef DEBUG_GC_MAPS
				std::cout << "visiting derived root " << spill_slot
					<< " with base pointer " << base_pointer
					<< std::endl;
#endif
				stack_pointer[spill_slot] -= stack_pointer[base_pointer];
			}
		}

		/* Update all GC roots, including base pointers. */
		cell callsite_gc_roots = info->callsite_gc_roots(callsite);

		for(cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++)
		{
			if(bitmap_p(bitmap,callsite_gc_roots + spill_slot))
			{
#ifdef DEBUG_GC_MAPS
				std::cout << "visiting GC root " << spill_slot << std::endl;
#endif
				visitor->visit_handle(stack_pointer + spill_slot);
			}
		}

		/* Add the base pointers to obtain new derived pointer values. */
		for(cell spill_slot = 0; spill_slot < info->derived_root_count; spill_slot++)
		{
			u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot);
			if(base_pointer != (u32)-1)
				stack_pointer[spill_slot] += stack_pointer[base_pointer];
		}
	}
Пример #4
0
	void operator()(object *obj, cell size)
	{
		parent->data->tenured->starts.record_object_start_offset(obj);

		switch(obj->type())
		{
		case ALIEN_TYPE:
			{
				cell payload_start = obj->binary_payload_start();
				data_visitor.visit_slots(obj,payload_start);

				alien *ptr = (alien *)obj;

				if(to_boolean(ptr->base))
					ptr->update_address();
				else
					ptr->expired = parent->true_object;
				break;
			}
		case DLL_TYPE:
			{
				cell payload_start = obj->binary_payload_start();
				data_visitor.visit_slots(obj,payload_start);

				parent->ffi_dlopen((dll *)obj);
				break;
			}
		case TUPLE_TYPE:
			{
				cell payload_start = tuple_size_with_fixup(data_offset,obj);
				data_visitor.visit_slots(obj,payload_start);
				break;
			}
		default:
			{
				cell payload_start = obj->binary_payload_start();
				data_visitor.visit_slots(obj,payload_start);
				code_visitor.visit_object_code_block(obj);
				break;
			}
		}
	}
Пример #5
0
  /*
	frame top -> [return address]
	             [spill area]
	             ...
	             [entry_point]
	             [size]
	*/
  void operator()(void* frame_top, cell frame_size, code_block* owner,
                  void* addr) {
    cell return_address = owner->offset(addr);

    code_block* compiled =
        Fixup::translated_code_block_map ? owner
                                         : visitor->fixup.translate_code(owner);
    gc_info* info = compiled->block_gc_info();

    FACTOR_ASSERT(return_address < compiled->size());
    cell callsite = info->return_address_index(return_address);
    if (callsite == (cell)-1)
      return;

#ifdef DEBUG_GC_MAPS
    std::cout << "call frame code block " << compiled << " with offset "
              << return_address << std::endl;
#endif
    cell* stack_pointer = (cell*)frame_top;
    uint8_t* bitmap = info->gc_info_bitmap();

    /* Subtract old value of base pointer from every derived pointer. */
    for (cell spill_slot = 0; spill_slot < info->derived_root_count;
         spill_slot++) {
      uint32_t base_pointer = info->lookup_base_pointer(callsite, spill_slot);
      if (base_pointer != (uint32_t)-1) {
#ifdef DEBUG_GC_MAPS
        std::cout << "visiting derived root " << spill_slot
                  << " with base pointer " << base_pointer << std::endl;
#endif
        stack_pointer[spill_slot] -= stack_pointer[base_pointer];
      }
    }

    /* Update all GC roots, including base pointers. */
    cell callsite_gc_roots = info->callsite_gc_roots(callsite);

    for (cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++) {
      if (bitmap_p(bitmap, callsite_gc_roots + spill_slot)) {
#ifdef DEBUG_GC_MAPS
        std::cout << "visiting GC root " << spill_slot << std::endl;
#endif
        visitor->visit_handle(stack_pointer + spill_slot);
      }
    }

    /* Add the base pointers to obtain new derived pointer values. */
    for (cell spill_slot = 0; spill_slot < info->derived_root_count;
         spill_slot++) {
      uint32_t base_pointer = info->lookup_base_pointer(callsite, spill_slot);
      if (base_pointer != (uint32_t)-1)
        stack_pointer[spill_slot] += stack_pointer[base_pointer];
    }
  }
Пример #6
0
	void trace_partial_objects(cell start, cell end, cell card_start, cell card_end)
	{
		if(card_start < end)
		{
			start += sizeof(cell);

			if(start < card_start) start = card_start;
			if(end > card_end) end = card_end;

			cell *slot_ptr = (cell *)start;
			cell *end_ptr = (cell *)end;

			for(; slot_ptr < end_ptr; slot_ptr++)
				data_visitor.visit_handle(slot_ptr);
		}
	}
Пример #7
0
	/*
	next  -> [entry_point]
	         [size]
	         [return address] -- x86 only, backend adds 1 to each spill location
	         [spill area]
	         ...
	frame -> [entry_point]
	         [size]
	*/
	void operator()(stack_frame *frame)
	{
		cell return_address = parent->frame_offset(frame);
		if(return_address == (cell)-1)
			return;

		code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame));
		gc_info *info = compiled->block_gc_info();

		assert(return_address < compiled->size());
		int index = info->return_address_index(return_address);
		if(index == -1)
			return;

		u8 *bitmap = info->gc_info_bitmap();
		cell base = info->spill_slot_base(index);
		cell *stack_pointer = (cell *)(parent->frame_successor(frame) + 1);

		for(cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++)
		{
			if(bitmap_p(bitmap,base + spill_slot))
				visitor->visit_handle(&stack_pointer[spill_slot]);
		}
	}
Пример #8
0
	void operator()(object *obj)
	{
		workhorse->visit_slots(obj);
	}
Пример #9
0
	void trace_embedded_literals(code_block *compiled)
	{
		data_visitor.visit_embedded_literals(compiled);
	}
Пример #10
0
	void trace_code_block_objects(code_block *compiled)
	{
		data_visitor.visit_code_block_objects(compiled);
	}
Пример #11
0
	void trace_contexts()
	{
		data_visitor.visit_contexts();
	}
Пример #12
0
	void trace_roots()
	{
		data_visitor.visit_roots();
	}
Пример #13
0
	void trace_object(object *ptr)
	{
		data_visitor.visit_slots(ptr);
		if(ptr->type() == ALIEN_TYPE)
			((alien *)ptr)->update_address();
	}
Пример #14
0
	void trace_handle(cell *handle)
	{
		data_visitor.visit_handle(handle);
	}
Пример #15
0
	void operator()(code_block *compiled, cell size)
	{
		workhorse->visit_code_block_objects(compiled);
		workhorse->visit_embedded_literals(compiled);
	}
Пример #16
0
 void operator()(code_block* stub) { visitor->visit_handle(&stub->owner); }
Пример #17
0
 void operator()(instruction_operand op) {
   if (op.rel_type() == RT_LITERAL)
     op.store_value(visitor->visit_pointer(op.load_value()));
 }