return (a + (b-1)) & ~(b-1);
}
-inline static cell align8(cell a)
+inline static cell alignment_for(cell a, cell b)
{
- return align(a,8);
+ return align(a,b) - a;
}
+static const cell data_alignment = 16;
+
#define WORD_SIZE (signed)(sizeof(cell)*8)
-#define TAG_MASK 7
-#define TAG_BITS 3
+#define TAG_MASK 15
+#define TAG_BITS 4
#define TAG(x) ((cell)(x) & TAG_MASK)
#define UNTAG(x) ((cell)(x) & ~TAG_MASK)
#define RETAG(x,tag) (UNTAG(x) | (tag))
/*** Tags ***/
#define FIXNUM_TYPE 0
-#define BIGNUM_TYPE 1
+#define F_TYPE 1
#define ARRAY_TYPE 2
#define FLOAT_TYPE 3
#define QUOTATION_TYPE 4
-#define F_TYPE 5
-#define OBJECT_TYPE 6
+#define BIGNUM_TYPE 5
+#define ALIEN_TYPE 6
#define TUPLE_TYPE 7
-
-#define HEADER_TYPE 8 /* anything less than this is a tag */
-
-#define GC_COLLECTED 5 /* can be anything other than FIXNUM_TYPE */
-
-/*** Header types ***/
#define WRAPPER_TYPE 8
#define BYTE_ARRAY_TYPE 9
#define CALLSTACK_TYPE 10
#define STRING_TYPE 11
#define WORD_TYPE 12
#define DLL_TYPE 13
-#define ALIEN_TYPE 14
-#define TYPE_COUNT 15
+#define TYPE_COUNT 14
-/* Not real types, but code_block's type can be set to this */
-#define PIC_TYPE 16
-#define FREE_BLOCK_TYPE 17
+enum code_block_type
+{
+ code_block_unoptimized,
+ code_block_optimized,
+ code_block_counting_profiler,
+ code_block_pic
+};
/* Constants used when floating-point trap exceptions are thrown */
enum
inline static bool immediate_p(cell obj)
{
- return (obj == false_object || TAG(obj) == FIXNUM_TYPE);
+ /* We assume that fixnums have tag 0 and false_object has tag 1 */
+ return TAG(obj) <= F_TYPE;
}
inline static fixnum untag_fixnum(cell tagged)
return RETAG(untagged << TAG_BITS,FIXNUM_TYPE);
}
-inline static cell tag_for(cell type)
-{
- return type < HEADER_TYPE ? type : OBJECT_TYPE;
-}
+#define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
+
+struct object {
+ NO_TYPE_CHECK;
+ cell header;
-struct object;
+ cell size() const;
+ template<typename Fixup> cell size(Fixup fixup) const;
-struct header {
- cell value;
+ cell binary_payload_start() const;
+ template<typename Fixup> cell binary_payload_start(Fixup fixup) 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() {
-#ifdef FACTOR_DEBUG
- assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
-#endif
+ /* 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
+ {
+ return (header & 1) == 1;
}
- cell hi_tag() {
- check_header();
- return value >> TAG_BITS;
+ cell type() const
+ {
+ return (header >> 2) & TAG_MASK;
}
- bool forwarding_pointer_p() {
- return TAG(value) == GC_COLLECTED;
+ void initialize(cell type)
+ {
+ header = type << 2;
}
- object *forwarding_pointer() {
- return (object *)UNTAG(value);
+ cell hashcode() const
+ {
+ return (header >> 6);
}
- void forward_to(object *pointer) {
- value = RETAG(pointer,GC_COLLECTED);
+ void set_hashcode(cell hashcode)
+ {
+ header = (header & 0x3f) | (hashcode << 6);
}
-};
-#define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
+ bool forwarding_pointer_p() const
+ {
+ return (header & 2) == 2;
+ }
-struct object {
- NO_TYPE_CHECK;
- header h;
- cell *slots() { return (cell *)this; }
+ object *forwarding_pointer() const
+ {
+ return (object *)UNTAG(header);
+ }
+
+ void forward_to(object *pointer)
+ {
+ header = ((cell)pointer | 2);
+ }
};
/* Assembly code makes assumptions about the layout of this struct */
/* tagged */
cell capacity;
- cell *data() { return (cell *)(this + 1); }
+ cell *data() const { return (cell *)(this + 1); }
};
/* These are really just arrays, but certain elements have special
/* tagged */
cell capacity;
- cell *data() { return (cell *)(this + 1); }
+ cell *data() const { return (cell *)(this + 1); }
};
struct byte_array : public object {
/* tagged */
cell capacity;
- template<typename Scalar> Scalar *data() { return (Scalar *)(this + 1); }
+#ifndef FACTOR_64
+ cell padding0;
+ cell padding1;
+#endif
+
+ template<typename Scalar> Scalar *data() const { return (Scalar *)(this + 1); }
};
/* Assembly code makes assumptions about the layout of this struct */
/* tagged */
cell hashcode;
- u8 *data() { return (u8 *)(this + 1); }
+ u8 *data() const { return (u8 *)(this + 1); }
};
-/* The compiled code heap is structured into blocks. */
-struct heap_block
-{
- cell header;
-
- bool marked_p() { return header & 1; }
- void set_marked_p(bool marked)
- {
- if(marked)
- header |= 1;
- else
- header &= ~1;
- }
-
- cell type() { return (header >> 1) & 0x1f; }
- void set_type(cell type)
- {
- header = ((header & ~(0x1f << 1)) | (type << 1));
- }
-
- cell size() { return (header >> 6); }
- void set_size(cell size)
- {
- header = (header & 0x2f) | (size << 6);
- }
-};
-
-struct free_heap_block : public heap_block
-{
- free_heap_block *next_free;
-};
-
-struct code_block : public heap_block
-{
- 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 */
-
- void *xt() { return (void *)(this + 1); }
-};
+struct code_block;
/* Assembly code makes assumptions about the layout of this struct */
struct word : public object {
cell pic_def;
/* TAGGED alternative entry point for direct tail calls. Used for inline caching */
cell pic_tail_def;
- /* TAGGED call count for profiling */
+ /* TAGGED call count for counting_profiler */
cell counter;
/* TAGGED machine code for sub-primitive */
cell subprimitive;
- /* UNTAGGED execution token: jump here to execute word */
- void *xt;
+ /* UNTAGGED entry point: jump here to execute word */
+ void *entry_point;
/* UNTAGGED compiled code block */
code_block *code;
- /* UNTAGGED profiler stub */
- code_block *profiling;
+ /* UNTAGGED counting_profiler stub */
+ code_block *counting_profiler;
};
/* Assembly code makes assumptions about the layout of this struct */
cell cached_effect;
/* tagged */
cell cache_counter;
- /* UNTAGGED */
- void *xt;
+ /* UNTAGGED entry point; jump here to call quotation */
+ void *entry_point;
/* UNTAGGED compiled code block */
code_block *code;
};
cell expired;
/* untagged */
cell displacement;
+ /* untagged */
+ cell address;
+
+ void update_address()
+ {
+ if(base == false_object)
+ address = displacement;
+ else
+ address = UNTAG(base) + sizeof(byte_array) + displacement;
+ }
};
struct dll : public object {
/* tagged byte array holding a C string */
cell path;
/* OS-specific handle */
- void *dll;
+ void *handle;
};
-struct stack_frame
-{
- void *xt;
+struct stack_frame {
+ /* Updated by procedure prologue with procedure start address */
+ void *entry_point;
/* Frame size in bytes */
cell size;
};
/* tagged */
cell length;
- stack_frame *frame_at(cell offset)
+ stack_frame *frame_at(cell offset) const
{
return (stack_frame *)((char *)(this + 1) + offset);
}
- stack_frame *top() { return (stack_frame *)(this + 1); }
- stack_frame *bottom() { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
+ stack_frame *top() const { return (stack_frame *)(this + 1); }
+ stack_frame *bottom() const { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
};
struct tuple : public object {
/* tagged layout */
cell layout;
- cell *data() { return (cell *)(this + 1); }
+ cell *data() const { return (cell *)(this + 1); }
+};
+
+struct data_root_range {
+ cell *start;
+ cell len;
+
+ explicit data_root_range(cell *start_, cell len_) :
+ start(start_), len(len_) {}
};
}