Commit 5f4d519b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Better: can callq an indirect

parent 5b5a069a
......@@ -706,6 +706,31 @@ void Assembler::callq(Register r) {
emitByte(0xd3);
}
void Assembler::callq(Indirect mem) {
int src_idx = mem.base.regnum;
int rex = 0;
if (src_idx >= 8) {
assert(0 && "check this");
rex |= REX_B;
src_idx -= 8;
}
assert(src_idx >= 0 && src_idx < 8);
if (rex)
emitRex(rex);
emitByte(0xff);
assert(-0x80 <= mem.offset && mem.offset < 0x80);
if (mem.offset == 0) {
emitModRM(0b00, 2, src_idx);
} else {
emitModRM(0b01, 2, src_idx);
emitByte(mem.offset);
}
}
void Assembler::retq() {
emitByte(0xc3);
}
......
......@@ -163,6 +163,7 @@ public:
void call(Immediate imm); // the value is the offset
void callq(Register reg);
void callq(Indirect reg);
void retq();
void leave();
......
......@@ -553,8 +553,9 @@ void Rewriter::_decref(RewriterVar* var) {
assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO);
//assembler->trap();
assembler->mov(assembler::Indirect(reg, offsetof(Box, cls)), assembler::RAX);
assembler->mov(assembler::Indirect(assembler::RAX, offsetof(BoxedClass, tp_dealloc)), assembler::R11);
assembler->callq(assembler::R11);
assembler->callq(assembler::Indirect(assembler::RAX, offsetof(BoxedClass, tp_dealloc)));
//assembler->mov(assembler::Indirect(assembler::RAX, offsetof(BoxedClass, tp_dealloc)), assembler::R11);
//assembler->callq(assembler::R11);
}
// Doesn't call bumpUse, since this function is designed to be callable from other emitting functions.
......
......@@ -6483,6 +6483,11 @@ extern "C" void setGlobal(Box* globals, BoxedString* name, Box* value) {
if (globals->cls == module_cls) {
// Note: in optimized builds, this will be a tail call, which will
// preserve the return address, letting the setattr() call rewrite itself.
// XXX this isn't really safe in general, since the guards that led to this
// path need to end up in the rewrite. I think this is safe for now since
// writing the module case won't accidentally work for the dict case, but
// we should make all the entrypoints (the ones that look at the return address)
// be noinline.
setattr(static_cast<BoxedModule*>(globals), name, value);
} else {
RELEASE_ASSERT(globals->cls == dict_cls, "%s", globals->cls->tp_name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment