#define TYPE_COUNT 14
- #define FORWARDING_POINTER 5 /* can be anything other than FIXNUM_TYPE */
-
enum code_block_type
{
code_block_unoptimized,
struct object;
- struct header {
- cell value;
+ #define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
+
+ struct object {
+ NO_TYPE_CHECK;
+ cell header;
+
+ cell size() const;
+ cell binary_payload_start() const;
- /* Default ctor to make gcc 3.x happy */
- explicit header() { abort(); }
+ cell *slots() const { return (cell *)this; }
- explicit header(cell value_) : value(value_ << TAG_BITS) {}
+ template<typename Iterator> void each_slot(Iterator &iter);
- void check_header() const
+ /* Only valid for objects in tenured space; must cast to free_heap_block
+ to do anything with it if its free */
+ bool free_p() const
{
- #ifdef FACTOR_DEBUG
- assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
- #endif
+ return (header & 1) == 1;
}
- cell hi_tag() const
+ cell type() const
{
- check_header();
- return value >> TAG_BITS;
+ return (header >> 2) & TAG_MASK;
}
- bool forwarding_pointer_p() const
+ void initialize(cell type)
{
- return TAG(value) == FORWARDING_POINTER;
+ header = type << 2;
}
- object *forwarding_pointer() const
+ cell hashcode() const
{
- return (object *)UNTAG(value);
+ return (header >> 6);
}
- void forward_to(object *pointer)
+ void set_hashcode(cell hashcode)
{
- value = RETAG(pointer,FORWARDING_POINTER);
+ header = (header & 0x3f) | (hashcode << 6);
}
- };
- #define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
-
- struct object {
- NO_TYPE_CHECK;
- header h;
-
- cell size() const;
- cell binary_payload_start() const;
+ bool forwarding_pointer_p() const
+ {
+ return (header & 2) == 2;
+ }
- cell *slots() const { return (cell *)this; }
+ object *forwarding_pointer() const
+ {
+ return (object *)UNTAG(header);
+ }
- /* Only valid for objects in tenured space; must fast to free_heap_block
- to do anything with it if its free */
- bool free_p() const
+ void forward_to(object *pointer)
{
- return h.value & 1 == 1;
+ header = ((cell)pointer | 2);
}
};
cell nth(cell i) const;
};
-/* The compiled code heap is structured into blocks. */
-struct code_block
-{
- cell header;
- cell owner; /* tagged pointer to word, quotation or f */
- cell literals; /* tagged pointer to array or f */
- cell relocation; /* tagged pointer to byte-array or f */
-
- bool free_p() const
- {
- return (header & 1) == 1;
- }
-
- code_block_type type() const
- {
- return (code_block_type)((header >> 1) & 0x3);
- }
-
- void set_type(code_block_type type)
- {
- header = ((header & ~0x7) | (type << 1));
- }
-
- bool pic_p() const
- {
- return type() == code_block_pic;
- }
-
- bool optimized_p() const
- {
- return type() == code_block_optimized;
- }
-
- cell size() const
- {
- return header & ~7;
- }
-
- void *xt() const
- {
- return (void *)(this + 1);
- }
-};
+struct code_block;
/* Assembly code makes assumptions about the layout of this struct */
struct word : public object {
/* Number of entries in a polymorphic inline cache */
cell max_pic_size;
+ /* Incrementing object counter for identity hashing */
+ cell object_counter;
+
// contexts
void reset_datastack();
void reset_retainstack();
// run
void primitive_exit();
- void primitive_micros();
+ void primitive_system_micros();
+ void primitive_nano_count();
void primitive_sleep();
void primitive_set_slot();
// objects
void primitive_special_object();
void primitive_set_special_object();
+ void primitive_identity_hashcode();
+ void compute_identity_hashcode(object *obj);
+ void primitive_compute_identity_hashcode();
cell object_size(cell tagged);
cell clone_object(cell obj_);
void primitive_clone();
inline void write_barrier(object *obj, cell size)
{
- char *start = (char *)obj;
- for(cell offset = 0; offset < size; offset += card_size)
- write_barrier((cell *)(start + offset));
+ cell start = (cell)obj & -card_size;
+ cell end = ((cell)obj + size + card_size - 1) & -card_size;
+
+ for(cell offset = start; offset < end; offset += card_size)
+ write_barrier((cell *)offset);
}
+ // data heap checker
+ void check_data_heap();
+
// gc
void end_gc();
void start_gc_again();
void inline_gc(cell *data_roots_base, cell data_roots_size);
void primitive_enable_gc_events();
void primitive_disable_gc_events();
- object *allot_object(header header, cell size);
- object *allot_large_object(header header, cell size);
+ object *allot_object(cell type, cell size);
+ object *allot_large_object(cell type, cell size);
template<typename Type> Type *allot(cell size)
{
- return (Type *)allot_object(header(Type::type_number),size);
+ return (Type *)allot_object(Type::type_number,size);
}
inline void check_data_pointer(object *pointer)
void primitive_resize_byte_array();
template<typename Type> byte_array *byte_array_from_value(Type *value);
- template<typename Type> byte_array *byte_array_from_values(Type *values, cell len);
//tuples
void primitive_tuple();
void primitive_fclose();
//code_block
- relocation_type relocation_type_of(relocation_entry r);
- relocation_class relocation_class_of(relocation_entry r);
- cell relocation_offset_of(relocation_entry r);
void flush_icache_for(code_block *block);
- int number_of_parameters(relocation_type type);
void *object_xt(cell obj);
void *xt_pic(word *w, cell tagged_quot);
void *word_xt_pic(word *w);
void *get_rel_symbol(array *literals, cell index);
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
template<typename Iterator> void iterate_relocations(code_block *compiled, Iterator &iter);
- void store_address_2_2(cell *ptr, cell value);
- void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift);
- void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value);
void update_literal_references(code_block *compiled);
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
void update_word_references(code_block *compiled);
void save_callstack_bottom(stack_frame *callstack_bottom);
template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
- /* Every object has a regular representation in the runtime, which makes GC
- much simpler. Every slot of the object until binary_payload_start is a pointer
- to some other object. */
- template<typename Iterator> void do_slots(object *obj, Iterator &iter)
- {
- cell scan = (cell)obj;
- cell payload_start = obj->binary_payload_start();
- cell end = scan + payload_start;
-
- scan += sizeof(cell);
-
- while(scan < end)
- {
- iter((cell *)scan);
- scan += sizeof(cell);
- }
- }
-
//alien
char *pinned_alien_offset(cell obj);
cell allot_alien(cell delegate_, cell displacement);
void init_factor(vm_parameters *p);
void pass_args_to_factor(int argc, vm_char **argv);
void start_factor(vm_parameters *p);
+ void stop_factor();
void start_embedded_factor(vm_parameters *p);
void start_standalone_factor(int argc, vm_char **argv);
char *factor_eval_string(char *string);
// os-windows
#if defined(WINDOWS)
- void sleep_micros(u64 usec);
const vm_char *vm_executable_path();
const vm_char *default_image_path();
void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length);