C++的汇编代码虚拟功能在Perf Report中调用?
我正在为虚拟函数呼叫性能进行一些分析,并且在阅读完善报告时,我得到了:
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论