<commit_before>#include "master.hpp"

namespace factor
{

code_heap::code_heap(cell size)
{
	if(size > ((u64)1 << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size);
	seg = new segment(align_page(size),true);
	if(!seg) fatal_error("Out of memory in code_heap constructor",size);

	cell start = seg->start + getpagesize() + seh_area_size;

	allocator = new free_list_allocator<code_block>(seg->end - start,start);

	/* See os-windows-x86.64.cpp for seh_area usage */
	safepoint_page = (void *)seg->start;
	seh_area = (char *)seg->start + getpagesize();
}

code_heap::~code_heap()
{
	delete allocator;
	allocator = NULL;
	delete seg;
	seg = NULL;
}

void code_heap::write_barrier(code_block *compiled)
{
	points_to_nursery.insert(compiled);
	points_to_aging.insert(compiled);
}

void code_heap::clear_remembered_set()
{
	points_to_nursery.clear();
	points_to_aging.clear();
}

bool code_heap::uninitialized_p(code_block *compiled)
{
	return uninitialized_blocks.count(compiled) > 0;
}

bool code_heap::marked_p(code_block *compiled)
{
	return allocator->state.marked_p(compiled);
}

void code_heap::set_marked_p(code_block *compiled)
{
	allocator->state.set_marked_p(compiled);
}

void code_heap::clear_mark_bits()
{
	allocator->state.clear_mark_bits();
}

void code_heap::free(code_block *compiled)
{
	FACTOR_ASSERT(!uninitialized_p(compiled));
	points_to_nursery.erase(compiled);
	points_to_aging.erase(compiled);
	all_blocks.erase((cell)compiled);
	allocator->free(compiled);
}

void code_heap::flush_icache()
{
	factor::flush_icache(seg->start,seg->size);
}

struct clear_free_blocks_from_all_blocks_iterator
{
	code_heap *code;

	clear_free_blocks_from_all_blocks_iterator(code_heap *code) : code(code) {}

	void operator()(code_block *free_block, cell size) {
		std::set<code_block*>::iterator erase_from =
			code->all_blocks.lower_bound(free_block);
		std::set<code_block*>::iterator erase_to =
			code->all_blocks.lower_bound((code_block*)((char*)free_block + size));

		code->all_blocks.erase(erase_from, erase_to);
	}
};

void code_heap::sweep()
{
	clear_free_blocks_from_all_blocks_iterator clearer(this);
	allocator->sweep(clearer);
#ifdef FACTOR_DEBUG
	verify_all_blocks_set();
#endif
}

struct all_blocks_set_verifier {
	std::set<cell> *all_blocks;

	all_blocks_set_verifier(std::set<cell> *all_blocks) : all_blocks(all_blocks) {}

	void operator()(code_block *block, cell size)
	{
		FACTOR_ASSERT(all_blocks->find((cell)block) != all_blocks->end());
		// XXX check block size
	}
};

void code_heap::verify_all_blocks_set()
{
	all_blocks_set_verifier verifier(&all_blocks);
	allocator->iterate(verifier);
}

code_block *code_heap::code_block_for_address(cell address)
{
	std::set<cell>::const_iterator blocki =
		all_blocks.upper_bound((code_block*)address);
	FACTOR_ASSERT(blocki != all_blocks.begin());
	--blocki;
	code_block* found_block = (code_block*)*blocki;
	FACTOR_ASSERT((cell)found_block->entry_point() <= address
		/* XXX this isn't valid during fixup. should store the size in the map
		&& address - (cell)found_block->entry_point() < found_block->size()*/);
	return found_block;
}

struct all_blocks_set_inserter {
	code_heap *code;

	all_blocks_set_inserter(code_heap *code) : code(code) {}
<commit_msg>vm: fix types after rebase<commit_after>#include "master.hpp"

namespace factor
{

code_heap::code_heap(cell size)
{
	if(size > ((u64)1 << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size);
	seg = new segment(align_page(size),true);
	if(!seg) fatal_error("Out of memory in code_heap constructor",size);

	cell start = seg->start + getpagesize() + seh_area_size;

	allocator = new free_list_allocator<code_block>(seg->end - start,start);

	/* See os-windows-x86.64.cpp for seh_area usage */
	safepoint_page = (void *)seg->start;
	seh_area = (char *)seg->start + getpagesize();
}

code_heap::~code_heap()
{
	delete allocator;
	allocator = NULL;
	delete seg;
	seg = NULL;
}

void code_heap::write_barrier(code_block *compiled)
{
	points_to_nursery.insert(compiled);
	points_to_aging.insert(compiled);
}

void code_heap::clear_remembered_set()
{
	points_to_nursery.clear();
	points_to_aging.clear();
}

bool code_heap::uninitialized_p(code_block *compiled)
{
	return uninitialized_blocks.count(compiled) > 0;
}

bool code_heap::marked_p(code_block *compiled)
{
	return allocator->state.marked_p(compiled);
}

void code_heap::set_marked_p(code_block *compiled)
{
	allocator->state.set_marked_p(compiled);
}

void code_heap::clear_mark_bits()
{
	allocator->state.clear_mark_bits();
}

void code_heap::free(code_block *compiled)
{
	FACTOR_ASSERT(!uninitialized_p(compiled));
	points_to_nursery.erase(compiled);
	points_to_aging.erase(compiled);
	all_blocks.erase((cell)compiled);
	allocator->free(compiled);
}

void code_heap::flush_icache()
{
	factor::flush_icache(seg->start,seg->size);
}

struct clear_free_blocks_from_all_blocks_iterator
{
	code_heap *code;

	clear_free_blocks_from_all_blocks_iterator(code_heap *code) : code(code) {}

	void operator()(code_block *free_block, cell size) {
		std::set<cell>::iterator erase_from =
			code->all_blocks.lower_bound((cell)free_block);
		std::set<cell>::iterator erase_to =
			code->all_blocks.lower_bound((cell)free_block + size);

		code->all_blocks.erase(erase_from, erase_to);
	}
};

void code_heap::sweep()
{
	clear_free_blocks_from_all_blocks_iterator clearer(this);
	allocator->sweep(clearer);
#ifdef FACTOR_DEBUG
	verify_all_blocks_set();
#endif
}

struct all_blocks_set_verifier {
	std::set<cell> *all_blocks;

	all_blocks_set_verifier(std::set<cell> *all_blocks) : all_blocks(all_blocks) {}

	void operator()(code_block *block, cell size)
	{
		FACTOR_ASSERT(all_blocks->find((cell)block) != all_blocks->end());
		// XXX check block size
	}
};

void code_heap::verify_all_blocks_set()
{
	all_blocks_set_verifier verifier(&all_blocks);
	allocator->iterate(verifier);
}

code_block *code_heap::code_block_for_address(cell address)
{
	std::set<cell>::const_iterator blocki =
		all_blocks.upper_bound(address);
	FACTOR_ASSERT(blocki != all_blocks.begin());
	--blocki;
	code_block* found_block = (code_block*)*blocki;
	FACTOR_ASSERT((cell)found_block->entry_point() <= address
		/* XXX this isn't valid during fixup. should store the size in the map
		&& address - (cell)found_block->entry_point() < found_block->size()*/);
	return found_block;
}

struct all_blocks_set_inserter {
	code_heap *code;

	all_blocks_set_inserter(code_heap *code) : code(code) {}

{'fraction_non_alphanumeric': 0.14161760148744965, 'fraction_numerical': 0.0030988534242330336, 'mean_word_length': 6.900856793145655, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7510811', 'n_tokens_mistral': 2484, 'n_tokens_neox': 2386, 'n_words': 372}