Hi,
I did some investigation. Notice the constructor is inline and I could not get it to link except by defining it like that; generates multiple definition linker error otherwise.
I added a printf in the constructor, compiled it, and ran objdump on it and here what I got:
Code:
000000000023b780 <_ZN6tantan13maskSequencesEPhS0_iPKPKdddddddPKh>:
t = (T *) malloc(n * sizeof(T));
23b780: 48 b8 60 08 23 00 00 movabs $0x230860,%rax
23b787: 00 00 00
const uchar *maskTable) {
23b78a: 41 57 push %r15
basic_vector<T>::basic_vector(size_type n) {
23b78c: 49 bf f8 a2 25 00 00 movabs $0x25a2f8,%r15
23b793: 00 00 00
23b796: 41 56 push %r14
23b798: 49 89 ce mov %rcx,%r14
23b79b: 41 55 push %r13
23b79d: 4d 89 c5 mov %r8,%r13
23b7a0: 41 54 push %r12
std::vector<float> p(seqEnd - seqBeg);
23b7a2: 49 89 f4 mov %rsi,%r12
const uchar *maskTable) {
23b7a5: 55 push %rbp
std::vector<float> p(seqEnd - seqBeg);
23b7a6: 49 29 fc sub %rdi,%r12
const uchar *maskTable) {
23b7a9: 48 89 fd mov %rdi,%rbp
23b7ac: 53 push %rbx
t = (T *) malloc(n * sizeof(T));
23b7ad: 4a 8d 3c a5 00 00 00 lea 0x0(,%r12,4),%rdi
23b7b4: 00
23b7b5: 48 89 f3 mov %rsi,%rbx
23b7b8: 48 83 ec 78 sub $0x78,%rsp
23b7bc: 89 54 24 14 mov %edx,0x14(%rsp)
basic_vector<T>::basic_vector(size_type n) {
23b7c0: 4c 89 7c 24 40 mov %r15,0x40(%rsp)
23b7c5: c5 fb 11 44 24 18 vmovsd %xmm0,0x18(%rsp)
23b7cb: c5 fb 11 4c 24 20 vmovsd %xmm1,0x20(%rsp)
23b7d1: c5 fb 11 54 24 28 vmovsd %xmm2,0x28(%rsp)
23b7d7: c5 fb 11 5c 24 30 vmovsd %xmm3,0x30(%rsp)
23b7dd: c5 fb 11 64 24 38 vmovsd %xmm4,0x38(%rsp)
23b7e3: c5 fb 11 6c 24 08 vmovsd %xmm5,0x8(%rsp)
t = (T *) malloc(n * sizeof(T));
23b7e9: ff d0 callq *%rax
vec_alloc = n;
23b7eb: 4c 89 64 24 50 mov %r12,0x50(%rsp)
printf ("inline vector<float>::vector(size_type n):basic_vector<float>(%d)\n",n);
23b7f0: 4c 89 e6 mov %r12,%rsi
23b7f3: 48 bf 10 7e 25 00 00 movabs $0x257e10,%rdi
23b7fa: 00 00 00
23b7fd: 48 ba f0 a7 22 00 00 movabs $0x22a7f0,%rdx
23b804: 00 00 00
t = (T *) malloc(n * sizeof(T));
23b807: 48 89 44 24 48 mov %rax,0x48(%rsp)
inline vector<float>::vector(size_type n):basic_vector<float>(n){
23b80c: 48 b8 b8 a3 25 00 00 movabs $0x25a3b8,%rax
23b813: 00 00 00
23b816: 48 89 44 24 40 mov %rax,0x40(%rsp)
printf ("inline vector<float>::vector(size_type n):basic_vector<float>(%d)\n",n);
23b81b: 31 c0 xor %eax,%eax
vec_capacity = n;
23b81d: 4c 89 64 24 58 mov %r12,0x58(%rsp)
vec_size = 0;
23b822: 48 c7 44 24 60 00 00 movq $0x0,0x60(%rsp)
23b829: 00 00
printf ("inline vector<float>::vector(size_type n):basic_vector<float>(%d)\n",n);
23b82b: ff d2 callq *%rdx
float *probabilities = BEG(p);
When I remove the printf, I do not see the rest of the constructor which shows that it does not get inlined!
Code:
000000000023b780 <_ZN6tantan13maskSequencesEPhS0_iPKPKdddddddPKh>:
t = (T *) malloc(n * sizeof(T));
23b780: 48 b8 60 08 23 00 00 movabs $0x230860,%rax
23b787: 00 00 00
const uchar *maskTable) {
23b78a: 41 56 push %r14
23b78c: 49 89 ce mov %rcx,%r14
23b78f: 41 55 push %r13
23b791: 41 89 d5 mov %edx,%r13d
23b794: 41 54 push %r12
23b796: 55 push %rbp
23b797: 48 89 f5 mov %rsi,%rbp
23b79a: 53 push %rbx
23b79b: 48 89 fb mov %rdi,%rbx
std::vector<float> p(seqEnd - seqBeg);
23b79e: 48 89 f7 mov %rsi,%rdi
23b7a1: 48 29 df sub %rbx,%rdi
23b7a4: 48 c1 e7 02 shl $0x2,%rdi
const uchar *maskTable) {
23b7a8: 48 83 ec 30 sub $0x30,%rsp
23b7ac: c5 fb 11 44 24 28 vmovsd %xmm0,0x28(%rsp)
23b7b2: c5 fb 11 4c 24 20 vmovsd %xmm1,0x20(%rsp)
23b7b8: c5 fb 11 54 24 18 vmovsd %xmm2,0x18(%rsp)
23b7be: c5 fb 11 5c 24 10 vmovsd %xmm3,0x10(%rsp)
23b7c4: c5 fb 11 64 24 08 vmovsd %xmm4,0x8(%rsp)
23b7ca: ff d0 callq *%rax
getProbabilities(seqBeg, seqEnd, maxRepeatOffset,
23b7cc: c5 fb 10 64 24 08 vmovsd 0x8(%rsp),%xmm4
23b7d2: c5 fb 10 5c 24 10 vmovsd 0x10(%rsp),%xmm3
23b7d8: 45 31 c0 xor %r8d,%r8d
23b7db: 49 89 c4 mov %rax,%r12
23b7de: c5 fb 10 54 24 18 vmovsd 0x18(%rsp),%xmm2
23b7e4: 4c 89 f1 mov %r14,%rcx
23b7e7: 44 89 ea mov %r13d,%edx
The C++ core for the above objdump is:
Code:
void maskSequences(uchar *seqBeg,
uchar *seqEnd,
int maxRepeatOffset,
const const_double_ptr *likelihoodRatioMatrix,
double repeatProb,
double repeatEndProb,
double repeatOffsetProbDecay,
double firstGapProb,
double otherGapProb,
double minMaskProb,
const uchar *maskTable) {
std::vector<float> p(seqEnd - seqBeg);
float *probabilities = BEG(p);
getProbabilities(seqBeg, seqEnd, maxRepeatOffset,
likelihoodRatioMatrix, repeatProb, repeatEndProb,
repeatOffsetProbDecay, firstGapProb, otherGapProb,
probabilities);
maskProbableLetters(seqBeg, seqEnd, probabilities, minMaskProb, maskTable);
}
I guess that the compiler does not inline and invoke empty inline constructors even if they delegate the base class constructor.
How can I force it to do so?
The only way to get it done is through removing the constructor delegation and calling the base class constructor from within the derived class constructor.
Thanks,
Karim.