کامپایل مجدد پویا

در علم رایانه، **کامپایل مجدد پویا** (به انگلیسی Dynamic recompilation، گاهی اوقات به اختصار **dynarec** یا شبه مخفف **DRC**) از مزیت‌های برخی شبیه‌سازها و ماشینهای مجازی است که در آن سیستم ممکن است بخشی از یک برنامه *را در حین اجرا* مجدداً کامپایل کند. با کامپایل کردن کد در حین اجرا، سیستم می‌تواند کد تولید شده را متناسب با محیط زمان اجرا برنامه تنظیم کند و با استفاده از اطلاعاتی که در دسترس کامپایلر استاتیک سنتی نیست، کد کارآمدتری را تولید کند.

## کاربردها
بیشتر کامپایلرهای دینامیکی برای تبدیل کد ماشین بین معماری‌ها در زمان اجرا استفاده می‌شوند. این کار اغلب در شبیه‌سازی پلتفرم‌های بازی قدیمی مورد استفاده قرار می‌گیرد. در موارد دیگر، یک سیستم ممکن است از کامپایل مجدد پویا به عنوان بخشی از یک استراتژی بهینه‌سازی تطبیقی برای اجرای یک برنامه قابل حمل مانند جاوا یا NET. Common Language Runtime در قالب بایت‌کد استفاده کند. همچنین دیباگرهای پر سرعت از کامپایل مجدد پویا استفاده می‌کنند تا سربار حافظه را در اکثر تکنیک‌های تخلیه (deoptimization) و سایر ویژگی‌ها مانند dynamic thread migration کاهش دهند.

## وظایف
وظایف اصلی که یک کامپایلر مجدد پویا بر عهده دارد عبارتند از:
* خواندن کد ماشین از پلتفرم مبدأ
* انتشار کد ماشین برای پلتفرم مقصد

یک کامپایلر مجدد پویا همچنین می‌تواند برخی از کارهای کمکی را انجام دهد:
* مدیریت حافظه پنهان کد باز کامپایل شده
* بروزرسانی شمارش چرخه‌های سپری شده روی پلتفرم‌هایی که دارای ثبات تعداد چرخه هستند
* مدیریت چک کردن وقفه
* ارائه یک رابط برای سخت‌افزار پشتیبانی مجازی، به عنوان مثال GPU
* بهینه‌سازی ساختارهای کدهای سطح بالاتر برای اجرای کارآمد روی سخت‌افزار هدف

## مثال
فرض کنید یک برنامه در یک شبیه‌ساز در حال اجرا است و نیاز به کپی کردن یک رشته منتهی به تهی دارد. این برنامه در اصل برای یک پردازنده بسیار ساده کامپایل شده‌است. این پردازنده فقط می‌تواند یک بایت را به طور همزمان کپی کند و باید این کار را ابتدا با خواندن آن از رشته مبدا به یک ثبات انجام دهد، سپس آن را از آن ثبات به رشته مقصد بنویسد. برنامه اصلی ممکن است چیزی شبیه به این باشد: 
```asm
beginning:
    mov A,[first string pointer]    ; Put location of first character of source string
                                    ; in register A
    mov B,[second string pointer]   ; Put location of first character of destination string
                                    ; in register B
loop:
    mov C,[A]            ; Copy byte at address in register A to register C
    mov [B],C            ; Copy byte in register C to the address in register B
    inc A                ; Increment the address in register A to point to
                         ; the next byte
    inc B                ; Increment the address in register B to point to
                         ; the next byte
    cmp C,#0             ; Compare the data we just copied to 0 (string end marker)
     jnz loop            ; If it wasn't 0 then we have more to copy, so go back
                         ; and copy the next byte
end:                     ; If we didn't loop then we must have finished,
                         ; so carry on with something else.
```
 شبیه‌ساز ممکن است روی یک پردازنده اجرا شود که در کپی کردن رشته‌ها بسیار خوب عمل می‌کند و شبیه‌ساز می‌تواند از این مزیت استفاده کند. شبیه‌ساز ممکن است دنباله‌ای از دستورالعمل‌ها جهت کپی رشته را تشخیص دهد و تصمیم بگیرد که آنها را درست قبل از اجرا با کارایی بیشتر بازنویسی کند تا سرعت بیشتری در شبیه‌سازی ایجاد کند.

دستورالعملی در پردازنده جدید ما بنام *movs وجود دارد که* به‌طور خاص برای کپی کردن رشته‌ها به‌طور کارآمد طراحی شده‌است. دستورالعمل‌های تئوریک ما ۱۶ بایت را به‌طور همزمان کپی می‌کند، بدون اینکه آنها را در یک ثبات به نام C در بین آنها بارگیری کنیم، اما در صورت کپی کردن ۰ بایت (که نشانگر پایان یک رشته‌است) متوقف می‌شود و پرچم صفر را تنظیم می‌کند. همچنین می‌داند که آدرس رشته‌ها در ثبات‌های A و B قرار خواهد گرفت، بنابراین هر بار که اجرا شود، A و B را ۱۶ بار افزایش می‌دهد، برای عملیات بعدی آماده است.

کد جدید باز کامپایل شده ما ممکن است چیزی شبیه به این باشد: 
```asm
beginning:
    mov A,[first string pointer]    ; Put location of first character of source string
                                    ; in register A
    mov B,[second string pointer]   ; Put location of first character of destination string
                                    ; in register B
loop:
    movs [B],[A]            ; Copy 16 bytes at address in register A to address
                            ; in register B, then increment A and B by 16
     jnz loop               ; If the zero flag isn't set then we haven't reached
                            ; the end of the string, so go back and copy some more.
end:                        ; If we didn't loop then we must have finished,
                            ; so carry on with something else.
```
 فواید افزایش سرعت کاملاً محسوس است زیرا پردازنده لازم نیست دستورالعمل‌های زیادی را برای انجام همان کار بارگذاری کند، همچنین دستورالعمل movs احتمالاً توسط طراح پردازنده بهینه می‌شود تا از دنباله دستورالعمل‌های استفاده شده در مثال اول بهینه تر عمل کند. به عنوان مثال، ممکن است در پردازنده، برای افزایش A و B استفاده از پردازش موازی بهتر عمل کند، در حالی که هنوز هم بایت را کپی می‌کند.

## کاربرد

### همه منظوره
* بسیاری از ماشین‌های مجازی جاوا دارای قابلیت کامپایل مجدد پویا هستند.
* Rosetta اپل برای Mac OS X در x86، اجازه می‌دهد تا کد PowerPC با معماری x86 اجرا شود.
* نسخه‌های بعدی شبیه‌ساز Mac 68K در سیستم عامل کلاسیک Mac برای اجرای کد 680x0 روی سخت‌افزار PowerPC استفاده شده‌است.
* Psyco، کامپایلر تخصصی پایتون است.
* پروژه HP Dynamo، نمونه ای از یک بهینه‌ساز پویا دودویی شفاف.
* DynamoRIO، جانشین منبع باز Dynamo که با مجموعه‌های دستورالعمل ARM , x86-64 و IA-64 (Itanium) کار می‌کند.
* دستگاه مجازی Vx32 از کامپایل مجدد پویا استفاده می‌کند تا معماری x86 وابسته به سیستم عامل را برای افزونه‌های برنامه ایمن ایجاد کند.
* کامپیوتر مجازی مایکروسافت برای Mac، برای اجرای کد x86 در PowerPC استفاده می‌شود.
* QEMU، یک شبیه‌ساز کامل سیستم عامل متن باز.
* OVPsim , یک شبیه‌ساز کامل سیستم آزاد.
*VirtualBox از کامپایل مجدد پویا استفاده می‌کند.
* Valgrind، یک ابزار برنامه‌نویسی برای اشکال زدایی حافظه، تشخیص نشت حافظه و پروفایل، از کامپایل مجدد پویا استفاده می‌کند.

### بازی
* MAME از کامپایل مجدد پویا در شبیه‌سازهای CPU برای MIPS , SuperH , PowerPC و حتی واحدهای پردازش گرافیکی Voodoo استفاده می‌کند.
* ۱۹۶۴، یک شبیه‌ساز Nintendo 64 برای سخت‌افزار x86.
* Wii64، شبیه‌ساز Nintendo 64 برای Wii.
* WiiSX، یک شبیه‌ساز Sony PlayStation برای Nintendo Wii است.
* Mupen64Plus، شبیه‌ساز چند پلتفرمی Nintendo 64.
* Yabause، یک شبیه‌ساز چند پلتفرم کیوان است.
* قابلیت سازگاری به عقب Xbox 360 (یعنی بازی‌های در حال اجرا که برای Xbox اصلی نوشته شده‌اند) به‌طور گسترده‌ای فرض می‌شود که از کامپایل مجدد پویا استفاده می‌کند.
* PPSSPP، یک شبیه‌ساز قابل حمل Sony PlayStation Portable. recompilers برای x86 و ARM.
* PSEmu Pro، شبیه‌ساز سونی پلی استیشن.
* Ultrahle، اولین شبیه‌ساز Nintendo 64 است که بازی‌های تجاری را به‌طور کامل اجرا می‌کند.
* PCSX2، یک شبیه‌ساز Sony PlayStation 2، دارای یک بازکامپایلر به نام "microVU"، جانشین "SuperVU" است.
* Dolphin، Nintendo GameCube و شبیه‌ساز Wii، گزینه dynarec را دارد.
* GCemu , یک شبیه‌ساز بازی Nintendo GameCube.
* NullDC، یک شبیه‌ساز Sega Dreamcast برای x86.
* GEM , یک شبیه‌ساز Nintendo Game Boy برای MSX از یک کامپایل مجدد پویا بهینه استفاده می‌کند.
* DeSmuME , یک شبیه‌ساز Nintendo DS، گزینه dynarec را دارد.
* PSP Soywiz , شبیه‌ساز قابل حمل سونی پلی استیشن، دارای گزینه dynarec است.
* RPCS3، شبیه‌ساز سونی پلی استیشن ۳. دوباره پردازنده PPU و SPU را بر روی پردازنده سلول برای x86-64 انجام می‌دهد
* Decaf-emu، شبیه‌ساز Wii U، با استفاده از کتابخانه libbinrec، از recompilation پویا (JIT) از PowerPC32 تا سخت‌افزار کد x86_64 استفاده می‌کند (خود کتابخانه می‌تواند روی هر معماری سخت‌افزاری اجرا شود).

## جستارهای وابسته
* کامپایل مجدد دودویی
* ترجمه دودویی
* مقایسه نرم‌افزار مجازی سازی پلتفرم
* تدوین فقط در زمان
* ابزار دقیق (برنامه‌نویسی رایانه)

## منابع

## پیوند به بیرون
* آموزش کامپایل مجدد پویا
* پست‌های وبلاگ در مورد نوشتن یک کامپایل مجدد پویا MIPS به PPC

رده:کامپایلرسازی
رده:نرم‌افزار برابرسازی
رده:نرم‌افزارهای مجازی‌سازی