VM: refactor the immediate_p check out of visit_pointer()
This avoids reassigning to slots that are never changed. It makes the minor-gc pass 2% faster.locals-and-roots
parent
33d5ecefd5
commit
6b95813dbc
|
@ -162,15 +162,14 @@ template <typename Fixup> struct slot_visitor {
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
cell slot_visitor<Fixup>::visit_pointer(cell pointer) {
|
cell slot_visitor<Fixup>::visit_pointer(cell pointer) {
|
||||||
if (immediate_p(pointer))
|
|
||||||
return pointer;
|
|
||||||
|
|
||||||
object* untagged = fixup.fixup_data(untag<object>(pointer));
|
object* untagged = fixup.fixup_data(untag<object>(pointer));
|
||||||
return RETAG(untagged, TAG(pointer));
|
return RETAG(untagged, TAG(pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup> void slot_visitor<Fixup>::visit_handle(cell* handle) {
|
template <typename Fixup> void slot_visitor<Fixup>::visit_handle(cell* handle) {
|
||||||
|
if (!immediate_p(*handle)) {
|
||||||
*handle = visit_pointer(*handle);
|
*handle = visit_pointer(*handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fixup>
|
template <typename Fixup>
|
||||||
|
@ -386,9 +385,11 @@ void slot_visitor<Fixup>::visit_embedded_literals(code_block* compiled) {
|
||||||
|
|
||||||
auto update_literal_refs = [&](instruction_operand op) {
|
auto update_literal_refs = [&](instruction_operand op) {
|
||||||
if (op.rel.type() == RT_LITERAL) {
|
if (op.rel.type() == RT_LITERAL) {
|
||||||
fixnum value = op.load_value(op.pointer);
|
cell value = op.load_value(op.pointer);
|
||||||
|
if (!immediate_p(value)) {
|
||||||
op.store_value(visit_pointer(value));
|
op.store_value(visit_pointer(value));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
compiled->each_instruction_operand(update_literal_refs);
|
compiled->each_instruction_operand(update_literal_refs);
|
||||||
}
|
}
|
||||||
|
@ -505,28 +506,29 @@ void slot_visitor<Fixup>::visit_instruction_operands(code_block* block,
|
||||||
cell rel_base) {
|
cell rel_base) {
|
||||||
auto visit_func = [&](instruction_operand op){
|
auto visit_func = [&](instruction_operand op){
|
||||||
cell old_offset = rel_base + op.rel.offset();
|
cell old_offset = rel_base + op.rel.offset();
|
||||||
cell value = op.load_value(old_offset);
|
cell old_value = op.load_value(old_offset);
|
||||||
switch (op.rel.type()) {
|
switch (op.rel.type()) {
|
||||||
case RT_LITERAL: {
|
case RT_LITERAL: {
|
||||||
value = visit_pointer(value);
|
if (!immediate_p(old_value)) {
|
||||||
|
op.store_value(visit_pointer(old_value));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RT_ENTRY_POINT:
|
case RT_ENTRY_POINT:
|
||||||
case RT_ENTRY_POINT_PIC:
|
case RT_ENTRY_POINT_PIC:
|
||||||
case RT_ENTRY_POINT_PIC_TAIL:
|
case RT_ENTRY_POINT_PIC_TAIL:
|
||||||
case RT_HERE: {
|
case RT_HERE: {
|
||||||
cell offset = TAG(value);
|
cell offset = TAG(old_value);
|
||||||
code_block* compiled = (code_block*)UNTAG(value);
|
code_block* compiled = (code_block*)UNTAG(old_value);
|
||||||
value = RETAG(fixup.fixup_code(compiled), offset);
|
op.store_value(RETAG(fixup.fixup_code(compiled), offset));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RT_UNTAGGED:
|
case RT_UNTAGGED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
value = parent->compute_external_address(op);
|
op.store_value(parent->compute_external_address(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
op.store_value(value);
|
|
||||||
};
|
};
|
||||||
block->each_instruction_operand(visit_func);
|
block->each_instruction_operand(visit_func);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue