6 void factor_vm::primitive_special_object()
8 fixnum n = untag_fixnum(ctx->peek());
9 ctx->replace(special_objects[n]);
12 void factor_vm::primitive_set_special_object()
14 fixnum n = untag_fixnum(ctx->pop());
15 cell value = ctx->pop();
16 special_objects[n] = value;
19 void factor_vm::primitive_identity_hashcode()
21 cell tagged = ctx->peek();
22 object *obj = untag<object>(tagged);
23 ctx->replace(tag_fixnum(obj->hashcode()));
26 void factor_vm::compute_identity_hashcode(object *obj)
29 if(object_counter == 0) object_counter++;
30 obj->set_hashcode((cell)obj ^ object_counter);
33 void factor_vm::primitive_compute_identity_hashcode()
35 object *obj = untag<object>(ctx->pop());
36 compute_identity_hashcode(obj);
39 void factor_vm::primitive_set_slot()
41 fixnum slot = untag_fixnum(ctx->pop());
42 object *obj = untag<object>(ctx->pop());
43 cell value = ctx->pop();
45 cell *slot_ptr = &obj->slots()[slot];
47 write_barrier(slot_ptr);
50 /* Allocates memory */
51 cell factor_vm::clone_object(cell obj_)
53 data_root<object> obj(obj_,this);
55 if(immediate_p(obj.value()))
59 cell size = object_size(obj.value());
60 object *new_obj = allot_object(obj.type(),size);
61 memcpy(new_obj,obj.untagged(),size);
62 new_obj->set_hashcode(0);
63 return tag_dynamic(new_obj);
67 /* Allocates memory */
68 void factor_vm::primitive_clone()
70 ctx->replace(clone_object(ctx->peek()));
73 /* Size of the object pointed to by a tagged pointer */
74 cell factor_vm::object_size(cell tagged)
76 if(immediate_p(tagged))
79 return untag<object>(tagged)->size();
82 /* Allocates memory */
83 void factor_vm::primitive_size()
85 ctx->push(from_unsigned_cell(object_size(ctx->pop())));
88 struct slot_become_fixup : no_fixup {
89 std::map<object *,object *> *become_map;
91 explicit slot_become_fixup(std::map<object *,object *> *become_map_) :
92 become_map(become_map_) {}
94 object *fixup_data(object *old)
96 std::map<object *,object *>::const_iterator iter = become_map->find(old);
97 if(iter != become_map->end())
104 struct object_become_visitor {
105 slot_visitor<slot_become_fixup> *workhorse;
107 explicit object_become_visitor(slot_visitor<slot_become_fixup> *workhorse_) :
108 workhorse(workhorse_) {}
110 void operator()(object *obj)
112 workhorse->visit_slots(obj);
116 struct code_block_become_visitor {
117 slot_visitor<slot_become_fixup> *workhorse;
119 explicit code_block_become_visitor(slot_visitor<slot_become_fixup> *workhorse_) :
120 workhorse(workhorse_) {}
122 void operator()(code_block *compiled, cell size)
124 workhorse->visit_code_block_objects(compiled);
125 workhorse->visit_embedded_literals(compiled);
129 struct code_block_write_barrier_visitor {
132 explicit code_block_write_barrier_visitor(code_heap *code_) :
135 void operator()(code_block *compiled, cell size)
137 code->write_barrier(compiled);
141 /* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this
142 to coalesce equal but distinct quotations and wrappers. */
143 void factor_vm::primitive_become()
145 array *new_objects = untag_check<array>(ctx->pop());
146 array *old_objects = untag_check<array>(ctx->pop());
148 cell capacity = array_capacity(new_objects);
149 if(capacity != array_capacity(old_objects))
150 critical_error("bad parameters to become",0);
152 /* Build the forwarding map */
153 std::map<object *,object *> become_map;
155 for(cell i = 0; i < capacity; i++)
157 tagged<object> old_obj(array_nth(old_objects,i));
158 tagged<object> new_obj(array_nth(new_objects,i));
160 if(old_obj != new_obj)
161 become_map[old_obj.untagged()] = new_obj.untagged();
164 /* Update all references to old objects to point to new objects */
166 slot_visitor<slot_become_fixup> workhorse(this,slot_become_fixup(&become_map));
167 workhorse.visit_roots();
168 workhorse.visit_contexts();
170 object_become_visitor object_visitor(&workhorse);
171 each_object(object_visitor);
173 code_block_become_visitor code_block_visitor(&workhorse);
174 each_code_block(code_block_visitor);
177 /* Since we may have introduced old->new references, need to revisit
178 all objects and code blocks on a minor GC. */
179 data->mark_all_cards();
182 code_block_write_barrier_visitor code_block_visitor(code);
183 each_code_block(code_block_visitor);