C++的汇编代码虚拟功能在Perf Report中调用?

发布于 2025-02-11 11:43:19 字数 1960 浏览 2 评论 0原文

我正在为虚拟函数呼叫性能进行一些分析,并且在阅读完善报告时,我得到了:

mov (%rbx),%rdi   # move "this" pointer to %rdi
mov (%rdi),%rax   # move vtable pointer to %rax
mov %rbp,%rsi     # move first virtual function parameter to %rsi
callq *38         # absolute address call? why?

它通过callq *38来调用虚拟函数并找出这是一个绝对地址函数调用,跳到绝对地址38,我的问题是为什么它在此处使用绝对地址,而不是从vtable entries中获取地址(通过%rax)?

我使用的是Perf版本4.15.18,ObjDump向我展示:

48 8b 3b      mov  (%rbx),%rdi
48 8b 07      mov  (%rdi),%rax
48 89 ee      mov  %rbp,%rsi
ff 50 38      callq *0x38(%rax)
48 83 c3 08   add %0x8,%rbx

示例代码以在我的测试环境下重现问题:

#include <vector>
struct A {
    virtual int v1(int x) {
        return x+1;
    }

    virtual int v2(int x) {
        return x+2;
    }

    virtual int v3(int x) {
        return x+3;
    }
};

struct B:A {
    int v3(int x) override {
        return x+4;
    }
};

struct C:A {
    int v2(int x) override {
        return x+5;
    }
};

int main(){
    B b;
    C c;
    std::vector<A*> vs = {&b, &c};
    int t = 0;
    while (true) {
        t = vs[0]->v3(t);
        t = vs[1]->v3(t);
    }
    return 0;
}

用g ++ 7.5.0通过g ++ test.cc -o3,Perf Perf Perf 4.15。 18个节目:

...
mov %eax,%esi
mov (%rbx),%rdi
mov (%rdi),%rdx
callq *10
mov 0x8(%rbx),%rdi
mov %eax,%esi
mov (%rdi),%rdx
callq *10
jmp 68
...

objdump显示:

89 c6         mov %eax,%esi
48 8b 3b      mov (%rbx),%rdi
48 8b 17      mov (%rdi),rdx
ff 52 10      callq *0x10(%rdx)
48 8b 7b 08   mov 0x8(%rbx),%rdi
89 c6         mov %eax,%esi
48 8b 17      mov (%rdi),rdx
ff 52 10      callq *0x10(%rdx)

I'm doing some profiling for virtual function call performance and when read the perf report, I got this:

mov (%rbx),%rdi   # move "this" pointer to %rdi
mov (%rdi),%rax   # move vtable pointer to %rax
mov %rbp,%rsi     # move first virtual function parameter to %rsi
callq *38         # absolute address call? why?

It calls virtual function via callq *38, I've tried to search AT&T assembly syntax manual and find out this is an absolute address function call which jumps to absolute address 38, my question is why it uses absolute address here instead of getting the address from vtable entries(via %rax)?

I'm using perf version 4.15.18, and objdump shows me:

48 8b 3b      mov  (%rbx),%rdi
48 8b 07      mov  (%rdi),%rax
48 89 ee      mov  %rbp,%rsi
ff 50 38      callq *0x38(%rax)
48 83 c3 08   add %0x8,%rbx

Example code to reproduce the problem under my test environment:

#include <vector>
struct A {
    virtual int v1(int x) {
        return x+1;
    }

    virtual int v2(int x) {
        return x+2;
    }

    virtual int v3(int x) {
        return x+3;
    }
};

struct B:A {
    int v3(int x) override {
        return x+4;
    }
};

struct C:A {
    int v2(int x) override {
        return x+5;
    }
};

int main(){
    B b;
    C c;
    std::vector<A*> vs = {&b, &c};
    int t = 0;
    while (true) {
        t = vs[0]->v3(t);
        t = vs[1]->v3(t);
    }
    return 0;
}

Compiled with g++ 7.5.0 via g++ test.cc -O3, perf 4.15.18 shows:

...
mov %eax,%esi
mov (%rbx),%rdi
mov (%rdi),%rdx
callq *10
mov 0x8(%rbx),%rdi
mov %eax,%esi
mov (%rdi),%rdx
callq *10
jmp 68
...

objdump shows:

89 c6         mov %eax,%esi
48 8b 3b      mov (%rbx),%rdi
48 8b 17      mov (%rdi),rdx
ff 52 10      callq *0x10(%rdx)
48 8b 7b 08   mov 0x8(%rbx),%rdi
89 c6         mov %eax,%esi
48 8b 17      mov (%rdi),rdx
ff 52 10      callq *0x10(%rdx)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文