کامپایل افزایشی Zig: ریبیلد ۵۰ میلیثانیهای
خلاصهٔ کاملتر
نویسنده که عضو تیم اصلی Zigه، میگه کامپایل افزایشی یکی از تأثیرگذارترین کارهاییه که روش وقت گذاشته: کامپایلر تشخیص میده از آخرین بیلد کدوم تابعها و تعریفها عوض شدن، فقط همونها رو دوباره کامپایل میکنه و بایتهای حاصل رو مستقیم توی باینری خروجی وصله میزنه. به گفتهٔ اون، این قابلیت الان از حالت اثبات مفهوم دراومده و بیشتر اعضای تیم روزانه ازش استفاده میکنن.
اولین بخش خط لولهٔ کامپایلر هر فایل سورس رو میخونه، به AST تبدیلش میکنه و بعد با پاسی به اسم AstGen به یه نمایش میانی به اسم ZIR میرسه. چون این کار برای هر فایل یه تابع خالصه و هیچ حالت مشترکی نداره، هم راحت روی چند ترد پخش میشه هم میشه ZIR هر فایل رو روی دیسک کش کرد و فقط وقتی فایل عوض شد دوباره ساختش. این تیکه سالهاست بهصورت پیشفرض تو Zig فعاله.
سختترین بخش، تحلیل معناییه (بررسی نوعها و اجرای comptime). Zig کامپایل رو به قطعههایی به اسم «واحد تحلیل» میشکنه — لایوت یه struct، نوع یا مقدار یه تعریف سطح کانتینر، و بدنهٔ یه تابع رانتایم — و موقع تحلیل هر واحد، وابستگیهاش به بقیهٔ واحدها رو ثبت میکنه. کنار این، هر واحد به هشِ یه ناحیه از سورس هم وابستهست، پس وقتی فایل عوض میشه کامپایلر از روی هش میفهمه از کجا باید شروع کنه و موج تحلیل مجدد تا کجا جلو بره.
کدجنریشن AIR رو به MIR تبدیل میکنه و چون هر دو در سطح تکتابع کار میکنن، دقیقاً همون دانهبندی کامپایل افزایشی رو دارن؛ برای همین هیچکدوم اصلاً کش نمیشن. گره اصلی لینکره: باید کد جدید رو بنویسه بدون اینکه بقیهٔ باینری بههم بریزه. برای این کار انتزاعی به اسم link.MappedFile اضافه شده که فایل خروجی رو مموریمپ میکنه و یه درخت از «گره»ها روش نگه میداره.
وقتی جا کم بیاد، همین لایه خودش بقیهٔ گرهها رو جابهجا میکنه و هر گرهٔ تغییرکرده رو «کثیف» علامت میزنه تا لینکر بعداً آدرسها و relocationها رو درست کنه. رشد نمایی اندازهٔ گرهها باعث میشه این جابهجایی خیلی کم پیش بیاد. یه نکتهٔ عملی هم هست: نسخهٔ 0.16.0 هنوز چند تا از این قابلیتهای لینکر رو نداره، پس فعلاً باید شاخهٔ master رو برداشت تا 0.17.0 برسه.
نکات کلیدی:
- ریبیلد یه اپلیکیشن واقعی با کامپایل افزایشی Zig حدود ۵۰ تا ۷۰ میلیثانیه طول میکشه
- ZIR هر فایل روی دیسک کش میشه و فقط با تغییر همون فایل دوباره ساخته میشه
- گراف وابستگی «واحدهای تحلیل» مشخص میکنه با هر تغییر چی باید دوباره تحلیل بشه
- AIR و MIR چون در سطح تکتابعان اصلاً کش نمیشن
- انتزاع link.MappedFile لینک افزایشی رو ممکن میکنه و جابهجاییهای فایل رو مدیریت میکنه
- برای امتحان کردنش فعلاً به شاخهٔ master نیاز داری، نه نسخهٔ تگخوردهٔ 0.16.0




