คุณพบข้อผิดพลาดในการสร้างรหัสใน jitter .NET 4 x86 มันเป็นสิ่งที่ผิดปกติมากมันจะล้มเหลวก็ต่อเมื่อรหัสไม่ได้รับการปรับให้เหมาะสม รหัสเครื่องมีลักษณะดังนี้:
State a = s[0, 0];
013F04A9 push 0 ; index 2 = 0
013F04AB mov ecx,dword ptr [ebp-40h] ; s[] reference
013F04AE xor edx,edx ; index 1 = 0
013F04B0 call 013F0058 ; eax = s[0, 0]
013F04B5 mov dword ptr [ebp-4Ch],eax ; $temp1 = eax
013F04B8 movsx eax,byte ptr [ebp-4Ch] ; convert sbyte to int
013F04BC mov dword ptr [ebp-44h],eax ; a = s[0, 0]
Console.WriteLine(a == s[0, 0]); // False
013F04BF mov eax,dword ptr [ebp-44h] ; a
013F04C2 mov dword ptr [ebp-50h],eax ; $temp2 = a
013F04C5 push 0 ; index 2 = 0
013F04C7 mov ecx,dword ptr [ebp-40h] ; s[] reference
013F04CA xor edx,edx ; index 1 = 0
013F04CC call 013F0058 ; eax = s[0, 0]
013F04D1 mov dword ptr [ebp-54h],eax ; $temp3 = eax
; <=== Bug here!
013F04D4 mov eax,dword ptr [ebp-50h] ; a == s[0, 0]
013F04D7 cmp eax,dword ptr [ebp-54h]
013F04DA sete cl
013F04DD movzx ecx,cl
013F04E0 call 731C28F4
ความสัมพันธ์ที่เต็มไปด้วยจำนวนชั่วคราวและการทำสำเนารหัสเป็นเรื่องปกติสำหรับรหัสที่ไม่ได้เพิ่มประสิทธิภาพ คำสั่งที่ 013F04B8 นั้นโดดเด่นนั่นคือการแปลงที่จำเป็นจาก sbyte เป็นจำนวนเต็ม 32 บิต ฟังก์ชันตัวช่วยสร้าง getter ของอาร์เรย์ส่งคืน 0x0000000FF เท่ากับ State.BUG และต้องแปลงเป็น -1 (0xFFFFFFFF) ก่อนที่จะสามารถเปรียบเทียบค่าได้ คำสั่ง MOVSX เป็นคำสั่ง Sign eXtension
สิ่งเดียวกันเกิดขึ้นอีกครั้งที่ 013F04CC แต่คราวนี้ไม่มีคำสั่ง MOVSX ที่จะทำการแปลงเดียวกัน นั่นคือสิ่งที่ชิปล้มลงคำสั่ง CMP เปรียบเทียบ 0xFFFFFFFF กับ 0x000000FF และนั่นเป็นเท็จ ดังนั้นนี่คือข้อผิดพลาดของการละเว้นตัวสร้างโค้ดล้มเหลวในการปล่อย MOVSX อีกครั้งเพื่อดำเนินการ sbyte เดียวกันกับการแปลง int
สิ่งที่ผิดปกติอย่างยิ่งเกี่ยวกับข้อผิดพลาดนี้คือมันทำงานได้อย่างถูกต้องเมื่อคุณเปิดใช้งานเครื่องมือเพิ่มประสิทธิภาพตอนนี้ก็รู้ว่าจะใช้ MOVSX ในทั้งสองกรณี
สาเหตุที่เป็นไปได้ที่ข้อผิดพลาดนี้ตรวจไม่พบเป็นเวลานานเนื่องจากการใช้ sbyte เป็นประเภทฐานของ enum ค่อนข้างหายากที่จะทำ การใช้อาเรย์หลายมิตินั้นมีประโยชน์เช่นกันการรวมกันนั้นเป็นอันตรายถึงชีวิต
มิฉะนั้นเป็นข้อผิดพลาดที่สำคัญสวยที่ฉันพูด มันอาจจะยากที่จะคาดเดาได้ว่าฉันจะมีแค่ 4.6.1 x86 jitter ที่จะทำการทดสอบเท่านั้น x64 และ jitter 3.5 x86 สร้างรหัสที่แตกต่างกันมากและหลีกเลี่ยงข้อผิดพลาดนี้ วิธีแก้ปัญหาชั่วคราวเพื่อดำเนินการต่อไปคือการลบ sbyte เป็นประเภทฐาน enum และปล่อยให้เป็นค่าเริ่มต้นintดังนั้นจึงไม่จำเป็นต้องมีส่วนขยายสัญญาณ
คุณสามารถยื่นข้อผิดพลาดได้ที่ connect.microsoft.com การลิงก์ไปยัง Q + A นี้น่าจะเพียงพอที่จะบอกพวกเขาทุกสิ่งที่พวกเขาจำเป็นต้องรู้ แจ้งให้เราทราบหากคุณไม่ต้องการใช้เวลาและฉันจะดูแลมัน