]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/layouts.hpp
vm: change "profiler" names to "counting_profiler"
[factor.git] / vm / layouts.hpp
index 2fba97d74736164b9fd9be6b7fe48a80c3dd4050..300b819b1fadcc96d612781959fe0d9220ce1072 100644 (file)
@@ -23,50 +23,46 @@ inline static cell align(cell a, cell b)
        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
-
-/* Canonical F object */
-#define F F_TYPE
-
-#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
@@ -78,9 +74,13 @@ enum
        FP_TRAP_INEXACT           = 1 << 4,
 };
 
+/* What Factor calls 'f' */
+static const cell false_object = F_TYPE;
+
 inline static bool immediate_p(cell obj)
 {
-       return (obj == F || 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)
@@ -96,51 +96,63 @@ inline static cell tag_fixnum(fixnum untagged)
        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 */
@@ -150,7 +162,7 @@ struct array : public object {
        /* 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
@@ -171,7 +183,7 @@ struct bignum : public object {
        /* tagged */
        cell capacity;
 
-       cell *data() { return (cell *)(this + 1); }
+       cell *data() const { return (cell *)(this + 1); }
 };
 
 struct byte_array : public object {
@@ -180,7 +192,12 @@ 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 */
@@ -193,49 +210,10 @@ struct string : public object {
        /* tagged */
        cell hashcode;
 
-       u8 *data() { 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;
+       u8 *data() const { return (u8 *)(this + 1); }
 };
 
-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 {
@@ -254,16 +232,16 @@ 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 */
@@ -292,8 +270,8 @@ struct quotation : public object {
        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;
 };
@@ -307,6 +285,16 @@ struct alien : public object {
        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 {
@@ -314,12 +302,12 @@ 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;
 };
@@ -329,13 +317,13 @@ struct callstack : public object {
        /* 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 {
@@ -343,7 +331,15 @@ 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_) {}
 };
 
 }