Optimization problem
When the method 'CLPController::StopPlaying' is called from the 'CLPController::SetLogTime', a floating point value is remaining on the top of the FPU stack:
00AC4575 call CLPController::StopPlaying (0AC3090h)
00AC457A fstp qword ptr [esi+24h]
'CLPController::StopPlaying' indirectly calls the ::MoveWindowW function which sometimes empties the FPU stack. It causes a crash at a next FPU instruction (in the another place) because the 'invalid instruction' flag is set.
Both methods are noninline and are defined in the same .cpp file.
In this place the problem can be solved by adding any __asm instruction which suppresses optimisation, but we can't be sure we've fixed this problem anywhere.
Sergey Ryazanov,
Transas, VTS Department
--
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
/O2 /G7 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LOG_IMPL" /D "_AFXEXT" /D "_HASLANGDLL_" /D "ENABLE_ASSURE" /D "ENABLE_TRACE" /D "USE_WINSOCK2" /D "_WINDLL" /D "_AFXDLL" /D "_UNICODE" /Gm /EHsc /MD /Zp1 /GR /Yu"GUI\StdGUI.h" /Fp".\..\..\VCOBJ\Release Unicode\Log\Log.pch" /Fo".\..\..\VCOBJ\Release Unicode\Log\\" /Fd".\..\..\VCOBJ\Release Unicode\Log\vc70.pdb" /W4 /nologo /c /Zi
// FULL_TIME - double
c:\work\current\vts\src\log\logplay\lpservice.cpp --
void CLPController::SetLogTime(FULL_TIME time) {
00AC4500 push esi
00AC4501 mov esi,ecx
_assure( Player != NULL );
00AC4503 cmp dword ptr [esi+4],0
00AC4507 push edi
00AC4508 mov edi,dword ptr [__impassure_fail (0ACDBF8h)]
00AC450E jne CLPController::SetLogTime+29h (0AC4529h)
00AC4510 push 8Dh
00AC4515 push offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC451A push offset string L"" (0ACDEDCh)
00AC451F push offset string L"Player != 0" (0AD827Ch)
00AC4524 call edi
00AC4526 add esp,10h
GUARD_IF_NOT ( MinTime <= time && time <= MaxTime )
00AC4529 fld qword ptr [esp+0Ch]
00AC452D fcom qword ptr [esi+1Ch]
00AC4530 fnstsw ax
00AC4532 test ah,1
00AC4535 jne CLPController::SetLogTime+41h (0AC4541h)
00AC4537 fcom qword ptr [esi+2Ch]
00AC453A fnstsw ax
00AC453C test ah,41h
00AC453F jnp CLPController::SetLogTime+5Fh (0AC455Fh)
00AC4541 push 8Fh
00AC4546 fstp st(0)
00AC4548 push offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC454D push offset string L"" (0ACDEDCh)
00AC4552 push offset string L"MinTime <= time && t"... (0AD8D68h)
00AC4557 call edi
{
time = MinTime;
00AC4559 fld qword ptr [esi+1Ch]
00AC455C add esp,10h
}
if (IsTimeEqual(LogTime, time)) return;
00AC455F fld qword ptr [esi+24h]
00AC4562 fsub st,st(1)
00AC4564 fabs
00AC4566 fcomp qword ptr [__real@4059000000000000 (0AD4788h)]
00AC456C fnstsw ax
00AC456E test ah,5
00AC4571 jnp CLPController::SetLogTime+90h (0AC4590h)
StopPlaying();
00AC4573 mov ecx,esi
00AC4575 call CLPController::StopPlaying (0AC3090h)
// __asm { fwait } // this code solves the problem
LogTime = time;
00AC457A fstp qword ptr [esi+24h]
OnTimeChanged();
00AC457D mov eax,dword ptr [esi]
00AC457F mov ecx,esi
00AC4581 call dword ptr [eax+20h]
NeedleDown();
00AC4584 mov ecx,esi
00AC4586 call CLPController::NeedleDown (0AC4000h)
00AC458B pop edi
00AC458C pop esi
}
00AC458D ret 8
00AC4590 pop edi
NeedleDown();
00AC4591 fstp st(0)
00AC4593 pop esi
}
00AC4594 ret 8
c:\work\current\vts\src\log\logplay\lpservice.cpp --
void CLPController::StopPlaying()
{
00AC3090 push esi
00AC3091 mov esi,ecx
_assure( Player != NULL );
00AC3093 cmp dword ptr [esi+4],0
00AC3097 push edi
00AC3098 mov edi,dword ptr [__impassure_fail (0ACDBF8h)]
00AC309E jne CLPController::StopPlaying+45h (0AC30D5h)
00AC30A0 push 0D2h
00AC30A5 push offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC30AA push offset string L"" (0ACDEDCh)
00AC30AF push offset string L"Player != 0" (0AD827Ch)
00AC30B4 call edi
00AC30B6 add esp,10h
if ( IsPlaying () )
00AC30B9 cmp dword ptr [esi+4],0
00AC30BD jne CLPController::StopPlaying+45h (0AC30D5h)
00AC30BF push 6Ch
00AC30C1 push offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC30C6 push offset string L"" (0ACDEDCh)
00AC30CB push offset string L"Player != 0" (0AD827Ch)
00AC30D0 call edi
00AC30D2 add esp,10h
00AC30D5 mov eax,dword ptr [esi+4]
00AC30D8 cmp byte ptr [eax+219h],0
00AC30DF pop edi
00AC30E0 je CLPController::StopPlaying+5Ah (0AC30EAh)
{
Player -> Stop ();
00AC30E2 mov ecx,eax
00AC30E4 mov edx,dword ptr [ecx]
00AC30E6 pop esi
00AC30E7 jmp dword ptr [edx+30h]
00AC30EA pop esi
}
}
00AC30EB ret

