4 /* The compiled code heap is structured into blocks. */
7 // header format (bits indexed with least significant as zero):
9 // bits 1-2: type (as a code_block_type)
11 // bits 3-23: code size / 8
12 // bits 24-31: stack frame size / 16
14 // bits 3-end: code size / 8
16 cell owner; /* tagged pointer to word, quotation or f */
17 cell parameters; /* tagged pointer to array or f */
18 cell relocation; /* tagged pointer to byte-array or f */
22 return (header & 1) == 1;
25 code_block_type type() const
27 return (code_block_type)((header >> 1) & 0x3);
30 void set_type(code_block_type type)
32 header = ((header & ~0x7) | (type << 1));
37 return type() == code_block_pic;
40 bool optimized_p() const
42 return type() == code_block_optimized;
51 size = header & 0xFFFFF8;
52 FACTOR_ASSERT(size > 0);
56 cell stack_frame_size() const
61 return (header >> 20) & 0xFF0;
64 void set_stack_frame_size(cell frame_size)
66 FACTOR_ASSERT(size() < 0xFFFFFF);
67 FACTOR_ASSERT(!free_p());
68 FACTOR_ASSERT(frame_size % 16 == 0);
69 FACTOR_ASSERT(frame_size <= 0xFF0);
70 header = (header & 0xFFFFFF) | (frame_size << 20);
73 template<typename Fixup> cell size(Fixup fixup) const
78 void *entry_point() const
80 return (void *)(this + 1);
83 /* GC info is stored at the end of the block */
84 gc_info *block_gc_info() const
86 return (gc_info *)((u8 *)this + size() - sizeof(gc_info));
91 factor::flush_icache((cell)this,size());
94 template<typename Iterator> void each_instruction_operand(Iterator &iter)
96 if(to_boolean(relocation))
98 byte_array *rels = (byte_array *)UNTAG(relocation);
101 cell length = (rels->capacity >> TAG_BITS) / sizeof(relocation_entry);
103 for(cell i = 0; i < length; i++)
105 relocation_entry rel = rels->data<relocation_entry>()[i];
106 iter(instruction_operand(rel,this,index));
107 index += rel.number_of_parameters();
113 VM_C_API void undefined_symbol(void);
115 inline code_block *word::code() const {
116 FACTOR_ASSERT(entry_point != NULL);
117 return (code_block*)entry_point - 1;
120 inline code_block *quotation::code() const {
121 FACTOR_ASSERT(entry_point != NULL);
122 return (code_block*)entry_point - 1;