Skip to content

runtime interp

ceragon edited this page Jun 3, 2022 · 3 revisions

解释执行

寄存器基础

X86_64 寄存器

标号 作用
rax 返回值
rbx 被调用者保存
rcx 第4个参数
rdx 第3个参数
rsi 第2个参数
rdi 第1个参数
rbp 被调用者保存
rsp 栈指针
r8 第5个参数
r9 第6个参数
r10 调用者保存
r11 调用者保存
r12 被调用者保存
r13 被调用者保存
r14 被调用者保存
r15 被调用者保存

JVM 定义的寄存器作用

标号 作用 jvm名称 jvm作用 编号
rsp 栈寄存器 4
rsi 第2个参数 j_rarg0 参数0 6
rdx 第3个参数 j_rarg1 参数1 2
rcx 第4个参数 j_rarg2 参数2 1
r8 第5个参数 j_rarg3 参数3 8
r9 第6个参数 j_rarg4 参数4 9
rdi 第1个参数 j_rarg5 参数5 7
r10 调用者保存 rscratch1 10
r11 调用者保存 rscratch2 11
r12 被调用者保存 r12_heapbase 12
r15 被调用者保存 r15_thread 15

常用操作

寄存器变址寻址

class Address {
    Register         _base;
    int              _disp;
    Address(Register base, ByteSize disp)
    : _base(base),
      _index(noreg),
      _xmmindex(xnoreg),
      _scale(no_scale),
      _disp(in_bytes(disp)),
      _isxmmindex(false){
    }
};
inline int      in_bytes(ByteSize x)  { return x._size; }

movptr

void MacroAssembler::movptr(Address dst, Register src) {
    movq(dst, src);
}

void Assembler::movq(Address dst, Register src) {
    emit_operand(src, dst);
}

void Assembler::emit_operand(Register reg, Address adr,
                             int rip_relative_correction) {
    emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp,
               adr._rspec,
               rip_relative_correction);
}

void Assembler::emit_operand(Register reg, Register base, Register index,
                             Address::ScaleFactor scale, int disp,
                             RelocationHolder const& rspec,
                             int rip_relative_correction) {
    // 以设置 JavaThread -> _anchor -> _last_Java_sp 为例
    // reg 是 last_java_sp 所在的寄存器,或者是 rsp 寄存器
    // base 是 r15 寄存器,存储了 JavaThread 对象的首地址
    // disp 是 _last_Java_sp 字段在 JavaThread 对象中的偏移字节值
    
    // 假设 reg==rsp,则 encode(reg) = 4,regenc = 32 = 0x20
    
    int regenc = encode(reg) << 3;
    // 假设 base = r15,则 encode(base) = 15-8 =7, baseenc = 7
    int baseenc = base->is_valid() ? encode(base) : 0;
    if (base->is_valid()) {
        if (index->is_valid()) {
        } else if (base == rsp || base == r12) {
            // base 是 r15
        } else {
            // [base + disp8]
            // [01 reg base] disp8
            // 0x40 | 0x20 | 0x07 == 0x67 == 0110_0111
            // 将 0110_0111 赋值给 _end
            emit_int8(0x40 | regenc | baseenc);
            // 将偏移量赋值到 _end
            emit_int8(disp & 0xFF);
        }
    }
}


class AbstractAssembler : public ResourceObj  {
    void emit_int8(int8_t x) {
        code_section()->emit_int8(x); 
    }
};

class CodeSection {
    address     _start;           // first byte of contents (instructions)
    address     _end;             // current end address
    // 效果是将 x 赋值到 _end 指向的地方,同时 _end 指针 +1
    void emit_int8 (int8_t x)  {
        // 将 x 的值赋值给 _end 指向的地址
        *((int8_t*)end()) = x;
        // 此时将 _end 的值+1
        set_end(end() + sizeof(int8_t)); 
    }
    address end() const { 
        return _end; 
    }
    void set_end(address pc)       {
       _end = pc; 
    }
};

寄存器编号

class RegisterImpl: public AbstractRegisterImpl {
    int   encoding() const { return (intptr_t)this; }
};

static int encode(Register r) {
    // 寄存器的编号
    int enc = r->encoding();
    // 超过8 也就是 r8 
    if (enc >= 8) {
        enc -= 8;
    }
    return enc;
}

设置栈指针

void MacroAssembler::set_last_Java_frame(Register last_java_sp,
                                         Register last_java_fp,
                                         address  last_java_pc) {
    if (!last_java_sp->is_valid()) {
        last_java_sp = rsp;
    }
    if (last_java_fp->is_valid()) {
        movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()),
               last_java_fp);
    }
    if (last_java_pc != NULL) {
        Address java_pc(r15_thread,
                    JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset());
        lea(rscratch1, InternalAddress(last_java_pc));
        movptr(java_pc, rscratch1);
    }
    movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), last_java_sp);
}

Clone this wiki locally