You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafficserver.apache.org by GitBox <gi...@apache.org> on 2021/07/20 01:25:30 UTC
[GitHub] [trafficserver] ywkaras commented on issue #8003: Overhead of dynamic_cast
ywkaras commented on issue #8003:
URL: https://github.com/apache/trafficserver/issues/8003#issuecomment-882973667
If you're doing a dynamic cast of a pointer, and checking that the result is not zero with an assert, you can use this instead:
https://github.com/apache/trafficserver/blob/ea5be6f04c2a087f0581f4cb2c67f693c7ff71f6/include/tscore/ink_assert.h#L72
If you're doing a dynamic cast of a reference, and not catching any exception it might throw, you can use this instead:
https://github.com/apache/trafficserver/blob/ea5be6f04c2a087f0581f4cb2c67f693c7ff71f6/include/tscore/ink_assert.h#L90
But TS will get into a corrupt state, rather than abort, in a release build if the cast is invalid.
If you're actually using dynamic_cast for runtime type detection, you can instead keep track of the type in a member variable, or use typeid:
```
enum class T { B, C };
struct A
{
A(T t_) : t(t_) {}
virtual ~A();
T t;
};
struct B : public A
{
B() : A(T::B) {}
};
struct C : public A
{
C() : A(T::C) {}
};
B * a_to_b1(A *a)
{
return a->t == T::B ? static_cast<B *>(a) : nullptr;
}
B * a_to_b2(A *a)
{
return dynamic_cast<B *>(a);
}
#include <typeinfo>
B * a_to_b3(A *a)
{
return typeid(*a) == typeid(B) ? static_cast<B *>(a) : nullptr;
}
```
Here is the resulting assembler (compiled with O3)
```
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 15, 4 sdk_version 10, 15, 4
.globl __Z7a_to_b1P1A ## -- Begin function _Z7a_to_b1P1A
.p2align 4, 0x90
__Z7a_to_b1P1A: ## @_Z7a_to_b1P1A
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
xorl %eax, %eax
cmpl $0, 8(%rdi)
cmoveq %rdi, %rax
popq %rbp
retq
.cfi_endproc
## -- End function
.globl __Z7a_to_b2P1A ## -- Begin function _Z7a_to_b2P1A
.p2align 4, 0x90
__Z7a_to_b2P1A: ## @_Z7a_to_b2P1A
.cfi_startproc
## %bb.0:
testq %rdi, %rdi
je LBB1_1
## %bb.2:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq __ZTI1A@GOTPCREL(%rip), %rsi
movq __ZTI1B@GOTPCREL(%rip), %rdx
xorl %ecx, %ecx
popq %rbp
jmp ___dynamic_cast ## TAILCALL
LBB1_1:
xorl %eax, %eax
retq
.cfi_endproc
## -- End function
.globl __Z7a_to_b3P1A ## -- Begin function _Z7a_to_b3P1A
.p2align 4, 0x90
__Z7a_to_b3P1A: ## @_Z7a_to_b3P1A
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
pushq %rbx
pushq %rax
.cfi_offset %rbx, -24
testq %rdi, %rdi
je LBB2_5
## %bb.1:
movq %rdi, %rbx
movq (%rdi), %rax
movq -8(%rax), %rax
movq 8(%rax), %rdi
cmpq __ZTS1B@GOTPCREL(%rip), %rdi
je LBB2_4
## %bb.2:
movq __ZTS1B@GOTPCREL(%rip), %rsi
callq _strcmp
testl %eax, %eax
je LBB2_4
## %bb.3:
xorl %ebx, %ebx
LBB2_4:
movq %rbx, %rax
addq $8, %rsp
popq %rbx
popq %rbp
retq
LBB2_5:
callq ___cxa_bad_typeid
.cfi_endproc
## -- End function
.section __TEXT,__const
.globl __ZTS1B ## @_ZTS1B
.weak_definition __ZTS1B
__ZTS1B:
.asciz "1B"
.section __DATA,__const
.globl __ZTI1B ## @_ZTI1B
.weak_definition __ZTI1B
.p2align 3
__ZTI1B:
.quad __ZTVN10__cxxabiv120__si_class_type_infoE+16
.quad __ZTS1B
.quad __ZTI1A
```
Explicitly keeping track of the type looks like it would probably be faster. Not clear if using typeid would be any faster.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org