سؤال

والمؤسسة مخادعة بسيطة لتوليد دينامية رمز في إطار C / C ++ لقد تم تغطيتها في سؤال آخر . هل هناك أي مقدمات لطيف في الموضوع مع أمثلة التعليمات البرمجية؟

وعيناي بدأت تنزف يحدق في المجمعين JIT المفتوحة المصدر معقدة للغاية عندما احتياجاتي أكثر تواضعا.

هل هناك نصوص جيدة حول هذا الموضوع والتي لا تحمل شهادة الدكتوراه في علوم الكمبيوتر؟ أنا أبحث عن أنماط جيدا البالية، أشياء لمشاهدة لاعتبارات الأداء، وما يمكن أن الموارد الإلكترونية أو القائم على شجرة أن تكون ذات قيمة متساوية. يمكنك أن تفترض معرفة العمل من (وليس فقط x86) و لغة التجميع.

هل كانت مفيدة؟

المحلول

وكذلك نمط لقد استعملت في محاكاة غني عن شيء مثل هذا:

typedef void (*code_ptr)();
unsigned long instruction_pointer = entry_point;
std::map<unsigned long, code_ptr> code_map;


void execute_block() {
    code_ptr f;
    std::map<unsigned long, void *>::iterator it = code_map.find(instruction_pointer);
    if(it != code_map.end()) {
        f = it->second
    } else {
        f = generate_code_block();
        code_map[instruction_pointer] = f;
    }
    f();
    instruction_pointer = update_instruction_pointer();
}

void execute() {
    while(true) {
        execute_block();
    }
}

وهذا هو التبسيط، ولكن الفكرة هي هناك. في الأساس، في كل مرة يطلب من المحرك لتنفيذ "كتلة الأساسي" (عادة ما يكون كل شيء حتى القادم المرجع التحكم في التدفق أو وظيفة كاملة في الإمكان)، فإنه سيتم البحث عنه لمعرفة ما إذا تم بالفعل إنشاء ذلك. إذا كان الأمر كذلك، تنفيذه، وإلا إنشائه، إضافته ومن ثم تنفيذ.

وشطف تكرار:)

وأما بالنسبة للرمز جيل، الذي يحصل معقدة بعض الشيء، ولكن الفكرة هي أن تنبعث من "وظيفة" المناسبة التي يعمل عمل كتلة الأساسي الخاص في سياق VM الخاص بك.

وتحرير: لاحظ بأنني لم تظهر أية تحسينات سواء، ولكن هل سألت ل"مقدمة لطيف"

وتحرير 2: نسيت أن أذكر واحدة من الصعود سرعة الأكثر إنتاجية على الفور يمكنك تطبيق مع هذا النمط. في الأساس، إذا كنت <م> لا إزالة كتلة من شجرة الخاص بك (يمكنك العمل حوله إذا كنت تفعل ولكن هي طريقة أكثر بساطة إذا كنت لا تفعل)، ثم يمكنك ان "سلسلة" لبنات معا لتجنب عمليات البحث. وهنا يكمن مفهوم. كلما عدت من و () وعلى وشك القيام "update_instruction_pointer"، وإذا كانت كتلة لك تنفيذها فقط المنتهية في أي مكالمة، والقفز غير المشروط، أو لم تنته في التحكم في التدفق في كل شيء، ثم يمكنك "إصلاح" لها تعليمات المتقاعد مع أحزاب اللقاء المشترك المباشر إلى كتلة التالي انها سوف تنفيذ (السبب أنه سوف يكون دائما نفس واحدة) <م> إذا لديك emited بالفعل. هذا يجعل من ذلك يتم تنفيذ أكثر وأكثر في كثير من الأحيان في VM وأقل وأقل في وظيفة "execute_block".

نصائح أخرى

وأنا لست على علم بأي مصادر تتعلق على وجه التحديد JITs، ولكن أتصور أنه الى حد كبير مثل مترجم العادي، بساطة فقط إذا لم تكن قلقة بشأن الأداء.

وأسهل طريقة هي أن تبدأ مع مترجم VM. ثم، لكل تعليمات VM، وتوليد رمز التجميع أن المترجم كان قد أعدم.

لتذهب أبعد من ذلك، وأتصور أنك سوف تحليل رموز بايت VM وتحويلها إلى نوع من شكل وسيط مناسب (ثلاثة رمز عنوان؟ SSA؟) ومن ثم تحسين وإنشاء التعليمات البرمجية كما هو الحال في أي مترجم آخر.

لكومة أساس VM، فإنه قد يساعد على تتبع عمق كومة "الحالي" كما كنت ترجمة رموز بايت في شكل وسيط، وعلاج كل موقع كومة كمتغير. على سبيل المثال، إذا كنت تعتقد أن عمق كومة الحالي هو 4، وترى "دفع" تعليمات، قد تولد مهمة ل"stack_variable_5" وزيادة وقت الترجمة كومة مضادة، أو شيء من هذا القبيل. على "إضافة" عندما عمق كومة من 5 قد تولد رمز "stack_variable_4 = stack_variable_4 + stack_variable_5" وإنقاص العداد الترجمة الوقت المكدس.

ومن الممكن أيضا لترجمة رمز القائمة كومة إلى أشجار بناء الجملة. الحفاظ على كومة وقت الترجمة. يؤدي كل "دفع" تعليمات تمثيل الشيء الذي دفع ليتم تخزينها على المكدس. مشغلي خلق العقد شجرة بناء الجملة التي تشمل المعاملات الخاصة بهم. على سبيل المثال، "XY +" قد يتسبب في كومة لاحتواء "فار (X)"، ثم "فار (X) فار (Y)" ثم زائد للملوثات العضوية الثابتة على حد سواء مراجع فار قبالة ويدفع "الجمع (فار (X)، فار (Y)) ".

والحصول على نفسك نسخة من كتاب جويل Pobar على الدوار (عندما يكون خارج)، والخوض من خلال المصدر لفي SSCLI . حذار، الجنون يكمن في:)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top