DE19945992B4 - Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren - Google Patents

Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren Download PDF

Info

Publication number
DE19945992B4
DE19945992B4 DE19945992A DE19945992A DE19945992B4 DE 19945992 B4 DE19945992 B4 DE 19945992B4 DE 19945992 A DE19945992 A DE 19945992A DE 19945992 A DE19945992 A DE 19945992A DE 19945992 B4 DE19945992 B4 DE 19945992B4
Authority
DE
Germany
Prior art keywords
branch
instructions
compiler
code
interpreter
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
DE19945992A
Other languages
English (en)
Other versions
DE19945992A1 (de
Inventor
Richard A. Lethin
Joseph A. Bank
Charles D. Garrett
Mikayo Kawasaki Wada
Mitsuo Kawasaki Sakurai
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Fujitsu Ltd
Original Assignee
Fujitsu Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Fujitsu Ltd filed Critical Fujitsu Ltd
Publication of DE19945992A1 publication Critical patent/DE19945992A1/de
Application granted granted Critical
Publication of DE19945992B4 publication Critical patent/DE19945992B4/de
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/455Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
    • G06F9/45504Abstract machines for programme code execution, e.g. Java virtual machine [JVM], interpreters, emulators

Abstract

Computerarchitektur-Emulationssystem, welches eine Quellen-Computerarchitektur auf einer Ziel-Computerarchitektur emuliert, mit:
einer Interpretierereinrichtung zum individuellen Übersetzen eines Quellen-Objektcodes in einen entsprechenden übersetzten Objektcode und zum Bestimmen einer Anzahl von Ausführungen von Verzweigungsinstruktionen im Quellen-Objektcode; und
einer Kompilierereinrichtung zum Gruppieren von Instruktionen des Quellen-Objektcodes in ein Segment, wenn eine Anzahl von Ausführungen einer entsprechenden Verzweigungsinstruktion eine Schwellenanzahl überschreitet, und zum dynamischen Kompilieren des Segments,
bei welchem die Interpretierereinrichtung und die Kompilierereinrichtung Aufgaben sind, die gleichzeitig in einem Mehraufgaben-Betriebssystem in Echtzeit operieren,
und mit einer Einrichtung zum Steuern einer Kompilierungsrate von zu kompilierenden Segmenten durch die Erhöhung der Schwellenanzahl, wenn eine Warteschlage zum Speichern der zu übersetzenden Segmente eine vorherbestimmte Kapazität erreicht.

Description

  • HINTERGRUND DER ERFINDUNG
  • Die vorliegende Erfindung bezieht sich auf die Technik von Objektcode-Übersetzern, die auf einem Hostverarbeitungssystem operieren, um ein zweites Betriebssystem zu emulieren. Insbesondere betrifft die vorliegende Erfindung die Technik dynamischer Objektcode-Übersetzer, die eine Analyse und Berechnung eines Original-Objektcode-Instruktionssatzes in Echtzeit während der Ausführung auf einem Hostprozessor, der einen Hostprozessor-Objektcode-Instruktionssatz aufweist, durchführen.
  • Auf dem Gebiet von Objektcode-Übersetzern ist es notwendig, einen Objektcode, der für einen Computer entwickelt wurde, auf einem anderen Computer mit einer unterschiedlichen Computerarchitektur zu konvertieren. Konvertierungsverfahren für einen derartigen Objektcode enthalten ein herkömmliches Verfahren, das als "statisches Objektcode-Konvertierungsverfahren" bezeichnet wird, und bei dem Instruktionsanweisungen vor der Ausführung zuerst in einen Objektcode einer zweiten Architektur konvertiert werden. Ein zweites Verfahren ist ein "dynamisches Objektcode-Konvertierungsverfahren", bei dem ein erster Objektcode in einen zweiten Objektcode während der Ausführung von Instruktionen konvertiert wird.
  • In der Technik statischer Objektcode-Konvertierungsverfahren wird die Ausführungszeit von der für die Konvertierung erforderlichen Zeit nicht beeinflußt. Die physische Größe des konvertierten Objektcodes wird jedoch bei der Ausführung der statischen Objektcode-Konvertierung groß. Mit anderen Worten nimmt beim statischen Objektcode-Konvertie rungsverfahren eine Anzahl von Betriebsschritten im konvertierten Objektcode unweigerlich zu. Folglich entsteht insofern ein Problem, als sich die Leistung des konvertierten Objektcodes verschlechtert, und es zu Ineffizienzen kommt.
  • Andererseits wird beim dynamischen Objektcode-Konvertierungsverfahren die Größe des konvertierten Objektcodes relativ klein im Vergleich zum statischen konvertierten Objektcode. Das herkömmliche dynamische Objektcode-Konvertierungsverfahren weist jedoch insofern ein Problem auf, als alle Objekte, einschließlich selten verwendeter Objekte, konvertiert werden. Mit anderen Worten kann das herkömmliche dynamische Objektcode-Konvertierungsverfahren Objekte, die mehrere Male ausgeführt werden, nicht effizient erkennen, und dadurch nimmt die Zeit, die für die Konvertierung des Original-Objektcodes erforderlich ist, auf Kosten der Effizienz zu.
  • Aus der US 5,751,892 A ist ein Software-Emulationsverfahren bekannt, bei dem die Anzahl von Zweiginstruktionsausführungen während eines Zeitintervalls gezählt werden und auf Grund dieser Rate ein Segment kompiliert wird. Ferner wird das Gruppieren von Instruktionen auf der Basis von Startwerten besshrieben.
  • KURZFASSUNG DER ERFINDUNG
  • Demgemäß ist es ein Objekt der vorliegenden Erfindung, einen Objektcode-Übersetzer vorzusehen, der die bekannten Probleme eliminiert, während er eine dynamische Optimierung des übersetzten Objektcodes vorsieht.
  • Es ist ein weiteres Objekt der vorliegenden Erfindung, ein Hauptprogramm zu profilieren, bis ein Kompilierer das Kompilieren vollendet hat, wobei dieses Profil vom Kompilierer zum Kompilieren und Optimieren des Programms verwendet wird.
  • Es ist noch ein weiteres Objekt der vorliegenden Erfindung, während der dynamischen Optimierung und Kompilierung vom nicht-übersetzten Code zum übersetzten zu springen.
  • Es ist noch ein weiteres Objekt der vorliegenden Erfindung, einen dynamischen optimierenden Objektcode-Übersetzer mit einer Software-Rückkopplung vorzusehen, der die Diffe renz zwischen einer Anzahl von Übersetzungsanforderungen, die an den Kompilierer gesendet werden, und einer Anzahl vollendeter Übersetzungen berechnet.
  • Es ist noch ein weiteres Objekt der vorliegenden Erfindung, eine dynamische Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache vorzusehen, während das Programm läuft.
  • Ferner ist ein Objekt der vorliegenden Erfindung, einen dynamischen Objektcode-Übersetzer vorzusehen, der Segmente zur Übersetzung aus einer Vielzahl von Startparametern bestimmt, die Verzweigungen in einem Quellen-Objektcode entsprechen.
  • Die Objekte der Erfindung werden durch die Merkmale des Anspruchs 1 und durch die Merkmale der übrigen unabhängigen Ansprüche erreicht.
  • KURZE BESCHREIBUNG DER ZEICHNUNGEN
  • Diese und andere Objekte und Vorteile der vorliegenden Erfindung gehen aus der folgenden Beschreibung der bevorzugten Ausführungsformen in Verbindung mit den beigeschlossenen Zeichnungen hervor und werden dadurch besser verständlich, wobei:
  • 1 ein Blockbild einer höheren Architektur eines OOCT-Systems gemäß einer bevorzugen Ausführungsform der vorliegenden Erfindung ist;
  • 2 ein Flußdiagramm ist, das Hauptkomponenten einer optimierenden Objektcode-Übersetzung zusammen mit einem Steuerfluß zur Kompilierung eines Abschnitts eines Originalcodes veranschaulicht;
  • 3 ein Flußdiagramm ist, das den Steuerfluß in einer optimierenden Objektcode-Übersetzung während der normalen Ausführung veranschaulicht;
  • 4 eine schematische Darstellung ist, die einen OOCT-Puffer für eine Einstellung von Variablen veranschaulicht;
  • 5a, 5b und 5c schematische Darstellungen sind, welche die Struktur einer Übersetzungstabelle veranschaulichen;
  • 6 ein Blockbild eines Interpretierers zum Einspringen in ein Segment und Verlassen desselben ist;
  • 7 ein Blockbild eines Kompilierungsverfahrens ist, um ein Segment zu schaffen, um das Segment durch einen Interpretierer erreichbar zu machen, um alte Segmente unerreichbar zu machen, und um alte Segmente zu löschen;
  • 8 ein Blockbild ist, das eine Struktur eines Verzweigungsdatensatzes bzw. engl. BRANCH_RECORD veranschaulicht;
  • 9 eine schematische Darstellung ist, welche eine Struktur eines Verzweigungsprotokolls als Teil einer großen Hash-Tabelle veranschaulicht, die BRANCH_RECORDs speichert;
  • 10 eine schematische Darstellung ist, welche eine Struktur eines L1-Cache veranschaulicht, der ein zweidimensionales Array von BRANCH_L1_RECORDs darstellt;
  • 11 eine schematische Darstellung ist, die ein Verfahren zur Ausführung des Betriebs des L1-Cache durch einen Interpretierer ist;
  • 12 eine schematische Darstellung ist, die eine allgemeine Struktur eines Kompilierers gemäß einer Ausführungsform der vorliegenden Erfindung veranschaulicht;
  • 13 eine schematische Darstellung ist, die ein Beispiel eines Blockwählers gemäß einer Ausführungsform der vorliegenden Erfindung veranschaulicht;
  • 14 ein Blockbild einer Codeübersicht mit zwei externen Einsprungpunkten ist, wobei Füllzeichen zwischen der Einsprung- bzw. engl. ENTRY-Instruktion und der Sprungnach- bzw. engl. GOTO-Instruktion eingefügt wurden;
  • 15 ein Blockbild ist, das ein OASSIGN-Einfügungsbeispiel veranschaulicht;
  • 16 ein Blockbild ist, das ein Beispiel einer Totcodeeliminierung und Adressenprüfungseliminierung veranschaulicht;
  • 17 ein Blockbild eines Beispiels einer Adressenprüfungseliminierung ist;
  • 18 ein Blockbild eines Beispiels einer gemeinen Teilausdruckeliminierung bzw. engl. Common Subexpression Elimination ("CSE") ist;
  • 19 ein Blockbild einer Kopierpropagation bzw. engl. Copy Propagation ist;
  • 20 insbesondere ein Beispiel einer konstanten Faltung bzw. engl. Constant Folding veranschaulicht;
  • 21 insbesondere ein Beispiel des obigen Prozesses gemäß einer Ausführungsform der vorliegenden Erfindung veranschaulicht, der eine Vergleichsinfrastruktur aufweist;
  • 22 insbesondere ein Beispiel der Codegenerierung für dieselbe Instruktion mit unterschiedlichen umgebenden Instruktionen veranschaulicht;
  • 23 eine Systemkonfiguration gemäß der zweiten Ausführungsform der vorliegenden Erfindung veranschaulicht, die zur dynamischen optimierenden Objektcode-Übersetzung verwendet wird;
  • 24 eine Systemkonfiguration gemäß der dritten Ausführungsform der vorliegenden Erfindung veranschaulicht, die zur gleichzeitigen dynamischen Übersetzung verwendet wird;
  • 25 eine Differenz zwischen der Kombination eines Interpretierers und Kompilierers, beispielsweise während der Ausführung als eine Aufgabe, und ihrer Trennung, beispielsweise in verschiedene Aufgaben, gemäß einer dritten Ausführungsform der vorliegenden Erfindung veranschaulicht;
  • 26 eine Übersetzungstabelle gemäß einer vierten Ausführungsform der vorliegenden Erfindung veranschaulicht, die zur Aufzeichnung verwendet wird, welche Instruktionen übersetzbar sind und welche nicht;
  • 27 veranschaulicht, wie das Verfahren die Belastung der Profilierung auf den Emulator gemäß einer vierten Ausführungsform der vorliegenden Erfindung reduziert;
  • 28 eine allgemeine Strukturdarstellung eines dynamischen Übersetzungssystems mit getrenntem Interpretierer und Kompilierer gemäß einer fünften Ausführungsform der vorliegenden Erfindung veranschaulicht;
  • 29 Komponenten eines Software-Rückkopplungsmecha nismus gemäß einer fünften Ausführungsform der vorliegenden Erfindung veranschaulicht;
  • 30 veranschaulicht, wie gemäß einer sechsten Ausführungsform der vorliegenden Erfindung eine Warteschlange zum Halten von Übersetzungsanforderungen verwendet wird, während die Übersetzungsaufgabe belegt ist;
  • 31 veranschaulicht, wie die OOCT-Anforderungswarteschlange kostengünstige gemeinsam genutzte Speicheranforderungen mit Systemaufrufanforderungen gemäß einer sechsten Ausführungsform der vorliegenden Erfindung kombiniert;
  • 32 zeigt, wie gemäß einer siebenten Ausführungsform der vorliegenden Erfindung ein dynamischer Übersetzer Seitenfehler verursachen kann, die während der normalen Ausführung der Quelleninstruktionen nicht auftreten würden;
  • 33 den Algorithmus zur Behebung von Seitenfehlern während der Übersetzung und die Fortsetzung der Übersetzung gemäß einer siebenten Ausführungsform der vorliegenden Erfindung zeigt;
  • 34 ein Muster eines Steuerflusses in einem dynamischen Übersetzungssystem mit einem Verzweigungsprofilierer gemäß einer achten Ausführungsform der vorliegenden Erfindung veranschaulicht;
  • 35 veranschaulicht, wie gemäß einer neunten Ausführungsform der vorliegenden Erfindung der dynamische Übersetzer Verzweigungprofilinformationen verwendet, um die Ausführungswahrscheinlichkeit eines Basisblocks zu berechnen.
  • DETAILLIERTE BESCHREIBUNG DER BEVORZUGTEN AUSFÜHRUNGSFORMEN
  • Nun wird detailliert auf die bevorzugten Ausführungsformen der vorliegenden Erfindung bezuggenommen, wovon Beispiele in den beigeschlossenen Zeichnungen veranschaulicht sind, wobei sich ähnliche Bezugszahlen durchgehend auf ähnliche Elemente beziehen.
  • ERSTE AUSFÜHRUNGSFORM DER VORLIEGENDEN ERFINDUNG
  • I. SYSTEMÜBERBLICK
  • Die vorliegende Erfindung bezieht sich allgemein auf einen optimierenden Objektcode-Übersetzer, nachstehend "OOCT", der eine dynamische Kompilierung eines Mikroprozessor-Instruktionssatzes als Teil eines Computerarchitektur-Emulationssystems durchführt. Die Kompilierung ist dynamisch, da es keinen einfachen Zugriff auf den Applikationsinstruktionssatz vor der Laufzeit gibt. Die Verwendung eines Kompilierers als Teil des Objektcode-Übersetzungssystems ermöglicht es dem System, eine Analyse und Optimierungen durchzuführen, welche die Leistung der Emulation gegenüber auf Schablonen basierenden Übersetzungen und auf Schablonen basierenden Interpretationen zu verbessern.
  • Der Hostprozessor für die Emulation ist vorzugsweise ein im Handel erhältlicher Prozessor, wie der Intel Pentium Pro. Die Architektur des Pentium Pro-Instruktionssatzes erleichtert die Manipulation verschiedener Datengrößen, und erleichtert dadurch die Emulation sowohl von 16 Bit- als auch 8 Bit-Objektcode-Instruktionen. Die 16 Bit- und 8 Bit-Objektcode-Instruktionen können für eine Originalapplikation auf einem zweiten Prozessor, wie einem Prozessor der K-Serie von Fujitsu, ausgebildet sein.
  • Die Durchführung sinnvoller Optimierungen vom Kompilierer-Typ ist nur durch die Kenntnis eines Instruktionsflußgraphen möglich. In einem traditionellen Kompilierer ist der Flußgraph gegeben und gut definiert, da die gesamte Routine einer vollständigen Sprachanalyse unterzogen wird, bevor die Optimierung beginnt. Bei einem OOCT ist dies nicht der Fall. Bevor das Programm läuft, ist der Ort der Instruktionen im Speicherbild unbekannt. Dies ist darauf zurückzuführen, daß die Instruktionen eine variable Länge mit willkürlichen intervenierenden Sätzen von Nicht-Instruktionsdaten aufweisen. Der Ort der Instruktionen ist unbekannt, ebenso wie der Ort aller Verbindungspunkte in die Instruktionen.
  • Daher muß zur Bestimmung des Flußgraphen das Programm laufen gelassen werden. Zuerst läßt ein Interpretierer das Programm laufen. Während der Interpretierer das Programm ausführt, informiert der Interpretierer den OOCT jedesmal, wenn er eine Verzweigungsoperation durchführt. Diese Protokollierung von Informationen identifiziert einige der Instruktionen und einige der Verbindungspunkte. Während das Programm läuft, werden die Informationen über den Flußgraphen zwar vollständiger, jedoch niemals ganz vollständig. Das OOCT-System ist ausgebildet, mit Teilinformationen über den Flußgraphen zu arbeiten: die Optimierung wird an potentiell unvollständigen Flußgraphen durchgeführt, und das System ist ausgebildet, das Ersetzen des optimierten Codes mit zunehmender Verfügbarkeit von Informationen zu gestatten.
  • Die dynamische Kompilierung wählt auf der Basis der vom Interpretierer gesammelten Profilinformationen, welche Teile des Textes zu optimieren sind. Wenn die Anzahl von Malen, die irgendeine Verzweigung ausgeführt wird, eine Schwellenanzahl überschreitet, wird das Ziel dieser Verzweigung ein Startparameter für die Kompilierung. Der Startparameter ist ein Startpunkt für eine Sprachanalyse eines Teils der K-Instruktionen, die als Einheit zu kompilieren sind. Dies wird Segment genannt.
  • Ein Segment enthält Hostprozessorinstruktionen, die aus der Optimierung der Originalprozessorinstruktionen vom Startparameter resultieren. Ein Segment wird als Einheit installiert und deinstalliert. Wenn der Interpretierer den OOCT aufruft, um über eine Verzweigung zu informieren, kann der OOCT wählen, die Steuerung in das Segment zu transfe rieren, wenn der Code für das Ziel existiert. Ähnlich kann dz Segment einen Code zum Transferieren der Steuerung zurück zum Interpretierer enthalten.
  • Ein Segment selbst kann unvollständig sein, so daß das Segment nur einen Teilsatz der möglichen Flußpfade vom Originalprogramm repräsentiert. Diese unvollständige Repräsentation beeinflußt jedoch nicht den korrekten Betrieb der Emulation. Wenn ein neuer, unvorhergesehener Flußpfad durch den Originalcode auftritt, springt der Steuerfluß zurück zum Interpretierer. Später kann dasselbe Segment ersetzt werden, um den neuen Steuerfluß zu berücksichtigen.
  • II. OOCT-CODESTRUKTUR
  • Gemäß einer Ausführungsform der vorliegenden Erfindung kann der OOCT unter einer herkömmlichen Betriebssystemumgebung wie Windows laufen. Gemäß einer zweiten Ausführungsform der vorliegenden Erfindung kann der OOCT jedoch eingerichtet sein, mit einer Emulations-Firmware auf einem zweiten Betriebssystem verbunden zu werden, wie dem KOI-Betriebssystem von Fujitsu.
  • III. ARCHITEKTUR
  • 1 veranschaulicht die höhere Architektur des OOCT-Systems 100. 1 veranschaulicht zwei Aufgaben, nämlich einen Interpretierer 110 und einen Kompilierer 104. Der Interpretierer 110 und der Kompilierer 104 operieren gleichzeitig unter einem Mehraufgaben-Betriebssystem. Die zwei Aufgaben können beide durch einen Verzweigungsprotokollierer 112 auf ein Verzweigungsprotokoll zugreifen, und können auch auf die kompilierten Codesegmente 108 zugreifen. Außerdem kann der Interpretierer 110 Kompilierungsanforderungen an den Kompilierer 104 senden. Eine vollständigere Beschreibung der Kommunikation zwischen den beiden Aufgaben erfolgt im nachstehend angegebenen Kommunikationsabschnitt.
  • KOMPILIERUNGSFLUSSSTEUERUNG
  • 2 veranschaulicht die Hauptkomponenten des OOCT 100 zusammen mit dem Steuerfluß zur Kompilierung eines Abschnitts des Originalcodes. Die Haupt-OOCT-Stufen sind wie folgt. Zuerst profiliert der Interpretierer 110 Verzweigungsinformationen durch die Kommunikation mit dem Verzweigungsprotokollierer 112. Der Verzweigungsprotokollierer 112 verwendet dann ein Startparameter-Auswahlverfahren, um zu bestimmen, welche Startparameter an den Kompilierer 104 zu senden sind. Anschließend verwendet der Blockwähler 114 den Startparameter und die Verzweigungsprofilinformationen, um ein Segment des zu kompilierenden Originalcodes zu wählen. Dann schafft der Blockwähler 114 einen Steuerflußgraphen (CFG), der die zu kompilierenden Originalinstruktionen beschreibt, und reicht den CFG an die Blockaufbaueinheit 116 weiter.
  • Anschließend flacht die Blockaufbaueinheit 116 den Steuerflußgraphen zu einer linearen Liste von Instruktionen ab. Die optimierende Codegenerierungseinheit 118 führt die tatsächliche Kompilierung der Originalinstruktionen in übersetzte Codesegmentinstruktionen durch. Der produzierte übersetzte Code, zusammen mit Informationen über das Segment, das kompiliert wird, wird schließlich zur Segmentinstallationseinheit 120 weitergereicht, die den Code für den Interpretierer 110 verfügbar macht.
  • OOCT-AUSFÜHRUNGSSTEUERFLUSS
  • 3 veranschaulicht den Steuerfluß im OOCT während der normalen Ausführung. Während der Interpretierer 110 den Code ausführt, kann der OOCT in den Verzweigungsprotokollierer 112 einspringen, wenn er bestimmte Instruktionen aus führt. Der Verzweigungsprotokollierer 112 kann entweder zum Interpretierer 110 zurückspringen, oder, wenn das Ziel der Verzweigung bereits kompiliert wurde, in eines der installierten Segmente des kompilierten Codes einspringen. Vom kompilierten Code können Übergänge von Segment zu Segment oder zurück zum Interpretierer 110 durchgeführt werden. Der kompilierte Code kann entweder den Interpretierer 110 aufrufen, um eine einzelne Originalinstruktion auszuführen, oder kann zum Interpretierer 110 springen, wobei die gesamte Steuerung an den Interpretierer 110 weitergereicht wird.
  • Eine Beschreibung der ersten Ausführungsform der vorliegenden Anmeldung wird wie folgt unterteilt. Der erste Abschnitt beschreibt die Schnittstelle zwischen dem Interpretierer 110 und dem Kompilierer 104. Der zweite Abschnitt beschreibt die Modifikationen, die am Interpretierer 110 für den OOCT durchgeführt wurden. Der dritte Abschnitt beschreibt den Kompilierer 104. Der abschließende Abschnitt beschreibt eine Windows-Testumgebung.
  • Der Beschreibung der ersten Ausführungsform folgt eine Beschreibung der zweiten bis neunten Ausführungsform der vorliegenden Erfindung.
  • IV. KONMMUNIKATION (GEMEINSAME EINHEIT)
  • Der Interpretierer 110 und der Kompilierer 104 kommunizieren miteinander auf verschiedenen Wegen. Der Interpretierer 110 zeichnet Verzweigungsinformationen in ein Verzweigungsprotokoll auf, indem er mit dem Verzweigungsprotokollierer 112 kommuniziert. Der Kompilierer 104 kann auch das Verzweigungsprotokoll lesen. Der Kompilierer 104 schafft kompilierte Codesegmente und speichert ihre Einsprungpunkte in der Übersetzungstabelle, die der Interpretierer 110 liest. Der Interpretierer 110 sendet auch Startparameteradressen an den Kompilierer 104 über einen Puffer. Der Quel lencode, der sowohl vom Kompilierer 104 als auch vom Interpretierer 110 für diese Kommunikation verwendet wird, befindet sich im gemeinsamen Verzeichnis. Dieser Abschnitt beschreibt, wie die Kommunikation funktioniert.
  • GEMEINSAM GENUTZTER OOCT-PUFFER
  • Die gesamte Kommunikation zwischen dem Kompilierer 104 und dem Interpretierer 110 wird durch den OOCT-Pufferbereich geführt, der eine große Region des gemeinsam genutzten Speichers ist. Bestimmte Kommunikation verwendet auch Systemaufrufe, um Nachrichten vom Interpretierer 110 an den Kompilierer 104 und zurück zu senden.
  • Die nachstehende Tabelle 1 veranschaulicht eine Abbildung der statisch zugeordneten Teile des OOCT-Puffers. Der Rest des Puffers wird dynamisch für verschiedene Datenstrukturen zugeordnet, die in der auch nachstehend angegebenen Tabelle 2 gezeigt werden. Einige Felder im statisch zugeordneten Teil des OOCT-Puffers zeigen auf Datenstrukturen im dynamisch zugeordneten Teil. Diese Zeiger haben hochgestellte Nummern, um darzustellen, wohin sie zeigen. Das Zonenfeld im statisch zugeordneten Teil hat beispielsweise die Nummer 2, und das Zonenfeld zeigt auf die Zonenspeicher-Datenstruktur im dynamisch zugeordneten Teil, die auch die Nummer 2 hat.
  • Tabelle 1: Der statisch zugeordnete Teil des OOCT-Puffers
    Figure 00140001
  • Figure 00150001
  • Figure 00160001
  • Figure 00170001
  • Figure 00180001
  • Figure 00190001
  • Im dynamisch zugeordneten Teil des OOCT-Puffers sind die Größen von Datenstrukturen von verschiedenen Variablen abhängig. Eine ist die Anzahl von Systemseiten, die vom Betriebssystem für den Originalprozessor, wie den ASP von Fujitsu, verwendet werden. Für jede Seite eines ASP-Adressenraums, der zu übersetzende Instruktionen enthält, gibt es eine übersetzte Seite in der Übersetzungstabelle. Eine weitere Variable ist die Anzahl von Verzweigungsinstruktionen, die das System zu protokollieren erwartet. Aktuell erwartet es 220 Verzweigungen, was die Größe des BRANCH_RECORD-Arrays und die Verzweigungs-Anfangsblocktabelle beeinflußt. Die Anzahl der Interpretierer 110 beeinflußt die Größe des L1-Verzweigungsprotokollierer-Cache, da es für jede Aufgabe einen Cache gibt.
  • 4 veranschaulicht eine Abbildung des OOCT-Puffers für eine Einstellung der Variablen. In 4 beträgt die Anzahl von ASP-Seiten 10 MB ASP-Instruktionen, die Anzahl der Interpretierer ist 4, und die Gesamtgröße des OCCT-Puffers beträgt 128 MB.
  • Tabelle 2: Der dynamisch zugeordnete Teil des OOCT-Puffers
    Figure 00200001
  • Figure 00210001
  • VERZWEIGUNGSPROTOKOLL (VERZWEIGUNGSPROTOKOLLIERER 112)
  • Die Verzweigungsprotokoll-Datenstrukturen sind das BRANCH_RECORD-Array, die Verzweigungs-Anfangsblocktabelle und die Verzweigungs-L1-Caches. Für eine Erläuterung, wie der Verzweigungsprotokollierer 112 arbeitet, siehe bitte nachstehend angegebener Abschnitt über Interpretierermodifikationen. Dieser Abschnitt beschreibt, wie das Verzweigungsprotokoll verwendet wird, um Informationen vom Interpretierer 110 zum Kompilierer 104 zu kommunizieren.
  • 4 veranschaulicht den OOCT-Puffer nach der Initialisierung. Die Größen der Regionen sind maßstabgetreu gezeichnet. Für dieses Beispiel beträgt die Größe des OOCT-Puffers 128 MB, die Anzahl von ASP-Seiten beträgt 2560, die Anzahl von Interpretierern 110 beträgt 2, und die erwartete Anzahl von Verzweigungsinstruktionen beträgt 220.
  • Der Kompilierer 104 liest das Verzweigungsprotokoll, um herauszufinden, wie viele Male eine bedingte Verzweigungsinstruktion eingeschlagen wurde, und wie viele Male eine bedingte Verzweigungsinstruktion nicht eingeschlagen wurde. Der Kompilierer 104 verwendet diese Informationen auf zwei Wegen. Erstens, wenn der Kompilierer 104 die Instruktionen einer Sprachanalyse unterzieht, versucht der Kompilierer 104 nur die Instruktionen der Sprachanalyse zu unterziehen, die am häufigsten ausgeführt wurden. Wenn eine bedingte Verzwei gungsinstruktion auftritt, prüft er, wie viele Male sie sich verzweigt hat, und wie viele Male sie fehlgeschlagen ist. Zweitens, wenn der Kompilierer 104 einen Code generiert, versucht der Kompilierer, die wahrscheinlichste Nachfolgerinstruktion einer bedingten Verzweigung unmittelbar nach der Verzweigungsinstruktion zu plazieren. Dadurch läuft der generierte Code schneller. Um mitzuteilen, welcher Nachfolger wahrscheinlicher ist, verwendet der Kompilierer 104 Verzweigungsprotokollinformationen. Für nähere Einzelheiten siehe bitte nachstehende Informationen über den Kompilierer 104.
  • BRANCH_Get_Record (ooct/compiler/branch.c)
  • Wenn der Kompilierer 104 Verzweigungsprotokollinformationen lesen will, ruft er die Prozedur BRANCH_Get_Record mit der Adresse der Verzweigungsinstruktion auf. Diese Prozedur schlägt die Verzweigung im Verzweigungsprotokoll nach und führt einen Zeiger auf eines der Elemente des BRANCH_RECORD-Arrays zurück. Dann kann der Kompilierer 104 sehen, wie viele Male die Verzweigungsinstruktion ausgeführt wurde, wie viele Male sie sich verzweigt hat, und wie viele Male sie fehlgeschlagen ist.
  • ÜBERSETZUNGSTABELLE (ÜBERSETZUNGSEINHEIT)
  • Die Übersetzungstabelle enthält Informationen über jede Instruktion im ASP-Adressenraum. Die Übersetzungstabelle zeichnet auf, ob die Instruktion das Ziel einer Verzweigung ist (JOIN), ob die Instruktion zum Kompilierer 104 als Startparameter gesendet wurde (BUFFERED), und ob es einen kompilierten Einsprungpunkt für das Segment gibt (ENTRY). Wenn der OOCT initialisiert wird, ist die Übersetzungstabelle leer. Wenn die Verzweigungsinstruktionen protokol liert werden, werden ihre Ziele als JOIN-Punkte markiert. Wenn die Verzweigung mehrere Male als die Schwelle ausführt, wird das Ziel als Startparameter an den Kompilierer 104 gesendet, und der Übersetzungstabelleneintrag wird als BUFFERED markiert. Nachdem der Kompilierer 104 die Kompilierung der übersetzten Version beendet, speichert er die Adressen von Einsprungpunkten in der Übersetzungstabelle und markiert sie als ENTRYs.
  • 5a, 5b und 5c veranschaulichen die Struktur einer Übersetzungstabelle gemäß einer bevorzugten Ausführungsform der vorliegenden Erfindung. Wie in 5a veranschaulicht, wird eine ASP-Adresse in zwei Teile geteilt. Die oberen 20 Bits sind die Seitennummer, und die unteren 12 Bits sind die Seitendistanz.
  • 5b veranschaulicht, daß die Seitennummer als Index in die Übersetzungstabelle erster Ordnung verwendet wird. Die Seiten, die der ASP bearbeitet, sind in der Tabelle erster Ordnung. Die Seiten, die der ASP nicht verwendet, haben keine Zeiger, da es niemals eine Instruktion mit dieser Seitennummer geben wird. Die Zeiger zeigen in die Übersetzungstabelle zweiter Ordnung. Das Hinzufügen einer Seitendistanz zum Zeiger ergibt einen Übersetzungstabelleneintrag.
  • Wie in 5c veranschaulicht, ist jeder Eintrag 32 Bits lang, und seine Felder sind unten dargestellt. Das erste Bit besagt, ob die ASP-Instruktion ein Verbindungspunkt ist. Das zweite besagt, ob es einen Segmenteinsprungpunkt für die Instruktion gibt. Das dritte besagt, ob die Instruktion zum Kompilierer 104 als Startparameter gesendet wurde. Die anderen Bits des Übersetzungstabelleneintrags sind die Einsprungpunktadresse für die Instruktion, wenn es eins gibt, oder 0 gibt, falls kein Einsprungpunkt vorliegt.
  • Da die K-Maschinenarchitektur Instruktionen mit variabler Länge aufweist, hat die Übersetzungstabelle einen Eintrag für jede ASP-Adresse, einschließlich der Adressen, die in der Mitte der Instruktionen und Datenadressen liegen. Dies macht die Tabelle sehr groß, es vereinfacht jedoch das Vorhaben der Lokalisierung des Übersetzungstabelleneintrags für eine Adresse. Die Struktur der Übersetzungstabelle ist in 5a, 5b und 5c gezeigt. Wie oben angegeben, hat die Übersetzungstabelle zweiter Ordnung einen 32 Bit-Eintrag für jede ASP-Adresse. Wenn daher der ASP-10 MB Raum verwendet, verwendet die Übersetzungstabelle zweiter Ordnung 40 MB. Es gibt verschiedene Prozeduren und Makros, welche die Einträge der Übersetzungstabelle lesen und schreiben:
  • TRANS_Set_Entry_Flag (ooct/common/trcommon.h)
  • sDas Makro TRANS_Set_Entry_Flag schaltet eine der Flaggen JOIN, ENTRY oder BUFFERED des Übersetzungstabelleneintrags ein. Es verwendet eine Assembliersprachinstruktion mit dem Verriegelungspräfix, so daß es das Bit automatisch setzt.
  • TRANS_Reset_Entry_Flag (ooct/common/trcommon.h)
  • Das Makro TRANS_Reset_Entry_Flag schaltet eine der Flaggen JOIN, ENTRY oder BUFFERED des Übersetzungstabelleneintrags aus. Es verwendet eine Assembliersprachinstruktion mit dem Verriegelungspräfix, so daß es das Bit automatisch zurücksetzt.
  • TRANS_Entry_FlagP (ooct/common/trcommon.h)
  • Das Makro TRANS_Entry_FlagP liest den Zustand einer der Flaggen JOIN, ENTRY oder BUFFERED des Übersetzungstabelleneintrags und führt ihn zurück.
  • TRANS_Test_And_Set_Entry_Flag (ooct/common/trcommon.h)
  • Die Prozedur TRANS_Test_And_Set_Entry_Flag liest automatisch den Zustand einer der Flaggen JOIN, ENTRY oder BUFFERED, und schaltet sie ein, wenn sie nicht bereits eingeschaltet war. Sie führt den Zustand der Flagge zurück, bevor sie die Prozedur aufruft.
  • TRANS_Set_Entry_Address (ooct/common/trcommon.h)
  • Die Prozedur TRANS_Set_Entry_Address schreibt die Einsprungpunktadresse des Übersetzungstabelleneintrags. Sie verwendet eine Assembliersprachinstruktion mit dem Verriegelungspräfix, so daß sie die Adresse automatisch schreibt. Es ist zu beachten, daß eine Einsprungpunktadresse die Adresse einer Zielinstruktion ist, wenn keine Segmentverriegelung besteht, jedoch die Adresse einer SEGMENT_GATE-Datenstruktur ist, wenn eine Segmentverriegelung besteht.
  • TRANS_Get_Entry_Address (ooct/common/trcommon.h)
  • Die Prozedur TRANS_Get_Entry_Address liest die Einsprungpunktadresse des Übersetzungstabelleneintrags und führt diese zurück. Es ist zu beachten, daß eine Einsprungpunktadresse die Adresse einer Zielinstruktion ist, wenn keine Segmentverriegelung besteht, jedoch die Adresse einer SEGMENT_GATE-Datenstruktur ist, wenn eine Segmentverriege lung besteht.
  • SEGMENTE
  • Ein Segment ist eine Einheit eines kompilierten Codes, der vom KOI-System ausgeführt werden kann. Nachstehend angegebenes Material über den Kompilierer 104 beschreibt, wie der Kompilierer 104 den Interpretierer 110 über ein Segment informiert, wie der Interpretierer 110 in das Segment einspringt und dieses verläßt, und wie der Kompilierer 104 den Interpretierer 110 anweist, die Verwendung eines Segments zu stoppen und zu einem anderen zu wechseln.
  • Wenn ein Segment geschaffen wird, gibt es einige ASP-Instruktionsadressen, wo der Interpretierer 110 in das Segment einspringen kann. Für jede dieser Adressen schafft der Kompilierer 104 einen Einsprungpunkt in das Segment. Ein Einsprungpunkt ist ein spezieller Punkt im Segment, wo der Interpretierer 110 hinspringen darf. An anderen Punkten im Segment nimmt der kompilierte Code an, daß bestimmte Werte in Registern vorliegen, so daß es nicht sicher ist, dorthin zu springen. Um dem Interpretierer 110 mitzuteilen, wo die Einsprungpunkte sind, ruft der Kompilierer 104 TRANS_Set_Entry_Address für jede n.te TRANS_Get_Entry_Address auf.
  • Der Interpretierer 110 prüft auf kompilierte Codesegmente, wenn sie in den Verzweigungsprotokollierer 112 einspringen. Sie rufen TRANS_Entry_FlagP auf, um zu sehen, ob die aktuelle ASP-Adresse einen Einsprungpunkt aufweist. Wenn sie dies tut, rufen sie TRANS_Get_Entry_Address auf, um die Adresse zu lesen. Wenn die Segmentverriegelung ein ist, verriegeln sie das Segment (siehe unten) und springen dann zum Einsprungpunkt. Wenn die Segmentverriegelung aus ist, springen sie nur zum Einsprungpunkt. Der kompilierte Code entscheidet, wenn er aussteigen soll. Dies geschieht üblicherweise, wenn er eine Instruktion ausführen muß, die nicht Teil desselben Segments ist, so springt er zum Interpretierer 110.
  • Der Kompilierer 104 kann ein kompiliertes Codesegment löschen und den Interpretierer 110 anweisen, ein anderes zu verwenden. Der Kompilierer 104 tut dies, indem er das ENTRY-Bit des Übersetzungstabelleneintrags ausschaltet, die Einsprungpunktadresse ändert und dann das ENTRY-Bit wieder einschaltet.
  • SEGMENTVERRIEGELUNG
  • Die Segmentverriegelung ist ein optionales Merkmal des OOCT-Systems. Da der Verzweigungsprotokollierer 112 mit dem Laufen des Systems mehr Informationen sammelt, kann der Kompilierer 104 eine neue Version eines Segments produzieren, die besser ist als die alte. Die Segmentverriegelung ermöglicht dem Kompilierer 104, ein altes Segment durch ein neues zu ersetzen und den vom alten Segment verwendeten Speicher erneut zu beanspruchen. Leider macht die Segmentverriegelung den Verzweigungsprotokollierer 112 und den kompilierten Code langsamer. Daher kommt es zu einem Abtausch zwischen der Zeit zur Ausführung des OOCT-Codes und dem Raum, den er verwendet. Dieser Abschnitt beschreibt, wie die Segmentverriegelung arbeitet.
  • Der Segmentverriegelungscode hat zwei Hauptteile. Der erste Teil ist eine Schnittstelle für alle Teile des OOCT-Systems mit Ausnahme der Segmentverriegelungsimplementation.
  • Diese Schnittstelle garantiert, daß sich ein Segment nur in einem von vier gut definierten Zuständen befinden kann, und Zustände auf gut definierten Wegen automatisch ändert. Der zweite Teil ist die Implementation der Segmentverriegelung selbst, wodurch die von der Schnittstelle gegebenen Garantien erfüllt werden.
  • AUSBILDUNG (DESIGN)
  • Die Zustände, in denen sich ein Segment befinden kann, werden in Tabelle 3 gezeigt. Ein Segment kann entweder erreichbar oder unerreichbar sein, und es kann entweder verriegelt oder unverriegelt sein. Segmente sind erreichbar, wenn es einen oder mehrere Einsprungpunkte in die Übersetzungstabelle gibt. Es ist unerreichbar, wenn es keine Einsprungpunkte in das Segment in der Übersetzungstabelle gibt. Ein Einsprungpunkt ist eine Struktur, die eine Verriegelung und eine Instruktionsadresse enthält. Die Verriegelung, die gleichzeitig von mehr als einem Interpretierer 110 verwendet werden kann, zählt, wie viele Interpretierer 110 den Einsprungpunkt und das diesen enthaltende Segment verwenden. Ein Segment ist verriegelt, wenn einer oder mehrere seiner Einsprungpunkte verriegelt sind. Es ist unverriegelt, wenn alle seiner Einsprungpunkte unverriegelt sind.
  • Der Kompilierer 104 kann ein Segment erneut beanspruchen und löschen, wenn es unerreichbar und unverriegelt ist, er kann es jedoch nicht erneut beanspruchen, wenn es erreichbar oder verriegelt ist. Jedes Segment beginnt im Zustand U/U, wenn es der Kompilierer 104 schafft. Es bewegt sich in einen Zustand R/U, wenn der Kompilierer 104 seine Einsprungpunkte in die Übersetzungstabelle schreibt. Es kann sich zu einem Zustand R/L und zurück zu R/U bewegen, während Interpretierer 110 in das Segment einspringen und dieses verlassen. Der Kompilierer 104 kann ein neues Segment schaffen, das dieselben Instruktionen übersetzt wie ein altes Segment. In diesem Fall überschreibt er die Einsprungpunkte des alten Segments in der Übersetzungstabelle, wodurch es unerreichbar wird. Wenn der Kompilierer 104 den letzten Eintrag des Segments überschreibt, geht es vom Zustand R/L zu U/L, wenn es von einem Interpretierer 110 verwendet wird, oder vom Zustand R/U zu U/U, wenn es von keinem Interpretierer 110 verwendet wurde. Schließlich geben alle das Segment verwendenden Interpretierer 110 ihre Verriegelungen frei, und das Segment befindet sich im Zustand U/U. Der Kompilierer 104 kann dann das Segment erneut beanspruchen und es löschen, da es von keinem Interpretierer 110 verwendet wird, und keiner in dieses springen kann.
  • Tabelle 3: Die Zustände, in denen sich ein Segment befinden kann.
    Figure 00300001
  • 6 veranschaulicht einen Interpretierer 110 zum Einspringen in ein Segment 122 und verlassen desselben gemäß einer Ausführungsform der vorliegenden Erfindung. Das Segment 122 in der Mitte der Zeichnung ist die Codeeinheit, die vom Kompilierer 104 produziert wird. Das Segment 122 muß zu jeder Zeit, wenn es vom Interpretierer 110 verwendet wird, verriegelt sein. Demgemäß wird ein Verriegelungszähler (nicht gezeigt) inkrementiert, bevor in das Segment 122 eingesprungen wird, und der Verriegelungszähler wird dekrementiert, nachdem das Segment 122 verlassen wurde. Da der Interpretierer 110 den Einsprungpunkt nicht nachschlagen und den Einsprungpunkt automatisch verriegeln kann, muß bestimmt werden, ob der Einsprungpunkt, nachdem er verriegelt wurde, nicht geändert wurde.
  • 7 veranschaulicht ein Verfahren des Kompilierers 104, um ein Segment zu schaffen, das Segment durch den Interpretierer 110 erreichbar zu machen, alte Segmente unerreichbar zu machen, und alte Segmente zu löschen. In Schritt S200 schafft der Kompilierer 104 ein neues Segment und fügt assoziierte Einsprungpunkte zur Übersetzungstabelle hinzu. wenn ein Einsprungpunkt in Schritt S200 hinzugefügt wird, kann ein älterer Einsprungpunkt umgeschrieben werden. Der ältere Einsprungpunkt ist nun unerreichbar, und kann demgemäß erneut verwendet werden, wenn keine Aufgabe (wie der Interpretierer 110 oder Kompilierer 104) eine Verriegelung darauf hält. Der alte Einsprungpunkt wird auf eine Liste zum erneuten Beanspruchen (nicht gezeigt) gesetzt.
  • Der Schritt 202 veranschaulicht, wie der Kompilierer 104 die Liste zum erneuten Beanspruchen verwendet. Der Schritt 202 prüft, ob ein Einsprungpunkt verriegelt ist. Wenn der Einsprungpunkt nicht verriegelt ist, dann wird der Einsprungpunkt von keinem Interpretierer 110 verwendet, und kann daher aus dem Segment, zu dem er gehört, entfernt werden. Wenn das Segment jedoch keine weiteren Einsprungpunkte hat, dann wird das Segment nicht von einer Aufgabe (wie dem Interpretierer 110 und Kompilierer 104) verwendet, und keine Aufgabe kann in dieses springen. Daher kann das Segment gelöscht werden.
  • Die Segmentverriegelungsschnittstelle ermöglicht, daß mehrere Teile des OOCT die Details der Synchronisation ignorieren, da sich ein Segment immer in einem gut definierten Zustand zu befinden scheint, und alle Zustandsübergänge automatisch zu erfolgen scheinen. Innerhalb des Segmentverriegelungscodes erfolgen jedoch die Übergänge nicht automatisch, da das Intel-Ziel einen derartig komplizierten Be trieb in der Hardware nicht unterstützt. Daher läßt der Segmentverriegelungscode die Übergänge automatisch erscheinen.
  • IMPLEMENTATION
  • Die Prozeduren zum Ausführen des Interpretierers 110 und Kompilierers 104 sind in 6 bzw. 7 veranschaulicht. Die beiden Prozeduren arbeiten zusammen, um sicherzustellen, daß jeder Übergang automatisch erscheint. Die Zahlenreferenzen in der folgenden Beschreibung beziehen sich auf 6 und 7.
  • Es gibt sechs mögliche Übergänge unter den vier Zuständen der Segmentschnittstelle, und sie fallen in vier Gruppen. Der erste Übergang ist U/U zu R/U, wenn der Kompilierer 104 ein Segment erreichbar macht, indem er seine Einsprungpunkte in die Übersetzungstabelle schreibt (*6). Da der Kompilierer 104 die einzige Aufgabe ist, die in die Übersetzungstabelle schreiben darf, ist keine Synchronisation notwendig, um diesen Übergang automatisch zu machen.
  • Die zweite Gruppe von Übergängen ist R/U zu U/U und der ähnliche von R/L zu U/L. Diese geschehen, wenn der Kompilierer 104 den letzten Einsprungpunkt eines Segments in der Übersetzungstabelle überschreibt (*306). Obwohl der Kompilierer 104 einen neuen Einsprungpunkt automatisch in die Übersetzungstabelle schreiben kann, kann der Interpretierer 110 einen Einsprungpunkt nicht automatisch lesen und verriegeln (*301, *302). Der Interpretierer 110 muß den Einsprungpunkt in einer Operation lesen und ihn in einer anderen Operation verriegeln. Dies führt zu einem potentiellen Problem, daß, wenn ein Interpretierer 110 einen alten Einsprungpunkt aus der Übersetzungstabelle liest, der Kompilierer 104 dann einen neuen schreibt, und der Interpretierer 110 anschließend den alten Einsprungpunkt verriegelt. In diesem Fall nimmt der Kompilierer 104 an, daß der Einsprungpunkt unerreichbar ist, aber der Interpretierer 110 kann in das Segment einspringen, was ein Fehler ist. Um dieses Problem zu verhindern, prüft der Interpretierer 110, daß die Übersetzungstabelle denselben Einsprungpunkt nach der Verriegelung enthält (*303). Wenn die Übersetzungstabelle denselben Einsprungpunkt enthält, ist es weiterhin erreichbar, und es ist sicher, in das Segment einzuspringen. Wenn die Übersetzungstabelle nicht denselben Eintrag enthält, muß der Interpretierer 110 seine Verriegelung freigeben und darf nicht in das Segment einspringen.
  • Die dritte Gruppe von Übergängen ist R/U zu R/L und umgekehrt von R/L zu R/U. Der erste geschieht, wenn ein Interpretierer 110 den Einsprungpunkt aus der Übersetzungstabelle liest und diesen verriegelt (*302). Der zweite geschieht, wenn der Interpretierer 110 ein Segment an seinem Ausgang verläßt (*304) und zur Entriegelungsprozedur geht (*305). Es ist wichtig, daß die Verriegelungs- und Entriegelungsinstruktionen nicht selbst im Segment sind, da jedesmal, wenn das Segment entriegelt wird, der Kompilierer 104 dieses löschen kann (*3011).
  • Der vierte Übergang ist von U/L zu U/U. Er geschieht auch, wenn der Interpretierer 110 ein Segment verläßt (*304) und zur Entriegelungsprozedur geht (*305). Nachdem dieser Übergang eintritt, wird das Segment entriegelt, und der Kompilierer 104 führt die beiden Tests durch (*309, *3010) und löscht das Segment.
  • Da der Interpretierer 110 die Verriegelung auf einem Segment für einen willkürlichen Zeitraum halten kann, ist es ineffizient, den Kompilierer 104 auf eine Verriegelung warten zu lassen. Daher versucht der Kompilierer 104 nicht, Einsprungpunkte zu verriegeln, um den Interpretierer 110 daran zu hindern, diese zu verwenden. Statt dessen macht er das Segment nur unerreichbar und prüft später, ob die Verriegelung freigegeben wurde (*309). Sobald die Verriegelung freigegeben wird, kann der Einsprungpunkt frei gemacht und erneut verwendet werden.
  • ÜBERWACHUNNGSNACHRICHTENWARTESCHLANGEN
  • Der Interpretierer 110 sendet Startparameteradressen an den Kompilierer 104. Es werden zwei Nachrichtenwarteschlangen verwendet, um sie zu senden. Die erste verwendet die KOI-Systemaufrufe ScMsgSnd und ScMsgRcv zum Senden und Empfangen von Startparametern. Die zweite Warteschlange verwendet einen gemeinsam genutzten Speicherbereich im OOCT-Puffer. Der gemeinsam genutzte Bereich wird branch_Seed_Buffer genannt.
  • Der Grund für die Verwendung von zwei Warteschlangen ist, daß jede einen Vorteil und einen Nachteil hat. Der KOI-Systemaufruf ist für den Interpretierer 110 kostspielig in der Verwendung, so daß er nicht sehr häufig verwendet werden sollte. Der AOI-Systemaufruf ermöglicht es jedoch dem Kompilierer 104 zu blockieren, wenn keine Startparameter zu kompilieren sind. Dies ermöglicht, daß das KOI-System die CPU des Kompilierers 104 verwendet, um einige andere Arbeiten zu erledigen. Der Vorteil des gemeinsam genutzten Speicherpuffers ist, daß er sehr kostengünstig für den Interpretierer 110 ist, und der Nachteil ist, daß der Kompilierer 104 nicht blockieren kann, wenn es keine Startparameter gibt.
  • Durch die Verwendung beider Warteschlangen nützt der OOCT die Vorteile beider Verfahren. Wenn der Kompilierer 104 untätig ist, ruft er ScMsgRcv auf, um zu blockieren. In diesem Fall sendet der Interpretierer 110 den nächsten Startparameter mit einem ScMsgSnd-Aufruf, um den Kompilierer 104 aufzuwecken. wenn der Kompilierer 104 arbeitet, sendet der Interpretierer 110 Startparameter durch den branch_Seed_Buffer-Bereich, was schneller ist. Nachdem der Kompilierer 104 eine Kompilierung beendet, prüft er auf einen sch_Seed_Buffer-Bereich. Wenn es welche gibt, kompiliert er sie. Wenn er alle Startparameter beendet, ruft er erneut ScMsgRcv auf und blockiert.
  • V. INTERPRETIERERMODIFIKATIONEN (AUSFÜHRUNGSEINHEIT)
  • Die Ausbildung des OOCT enthält drei Typen von Modifikationen am Interpretierer 110. Erstens muß der OOCT vom Interpretierer 110 initialisiert werden. Zweitens wurde der Interpretierer 110 modifiziert, um eine Verzweigungsprotokollierung zu verwenden. Schließlich wurde der Interpretierer 110 modifiziert, um Übergänge zum und aus dem kompilierten Code zu ermöglichen. Dieses Dokument beschreibt die Details dieser Modifikationen.
  • Der OOCT-Interpretierercode kann in zwei Modi laufen, OOCT_PERFORMANCE_MODE und OOCT_DEBUG_MODE. Diese Dokumentation beschreibt alle Merkmale des OOCT_PERFORMANCE_MODE und gibt an, wo sich der OOCT_DEBUG_MODE davon unterscheidet.
  • INITIALISIERUNG
  • Bevor der OOCT irgendeinen Code kompiliert oder irgendwelche Verzweigungen protokolliert, ruft der Interpretierer 110 OOCT_INIT auf, um die OOCT-Datenstrukturen zu initialisieren. OOCT_INIT und die Prozeduren, die dadurch aufgerufen werden, führen die folgenden Schritte durch.
  • Die Übersetzungstabelle initialisieren. Die MCD-Instruktion informiert den OOCT über die Seiten im Adressenraum des Systems. Die Prozedur TRANS_Execution_Init schafft die Übersetzungstabelle erster Ordnung so, daß die Einträge für Systemseiten auf Übersetzungstabellen-Arrays zweiter Ordnung zeigen. Diese Arrays werden bei der Initialisierung auf Null gesetzt. Für genauere Details über die Übersetzungstabelle siehe Kommunikationsabschnitt.
  • Verzweigungsprotokollierer 112 initialisieren. Die Prozedur BRANCH_Execution_Init initialisiert den Speicher im OOCT_buffer für einige Datenstrukturen. Erstens gibt es das Verzweigungsprotokoll selbst, das Profilinformationen über Verzweigungsinstruktionen enthält. Zweitens gibt es einen Cache erster Ordnung (L1), der den Verzweigungsprotokollierer 112 schneller operieren läßt. Drittens gibt es einen Startparameterpuffer, der vom Verzweigungsprotokollierer 112 zum Kompilierer 104 gesendete Startparameter enthält. Viertens gibt es einige globale Funktionen, die der kompilierte Code aufruft. Ihre Adressen werden im OOCT_buffer während BRANCH_Execution_Init gespeichert. Für nähere Informationen über das Verzweigungsprotokoll und den Cache erster Ordnung siehe obiger Abschnitt über den Verzweigungsprotokollierer 112.
  • Stapelspeicher des Kompilierers 104 zuordnen. Der Kompilierer 104 verwendet einen speziellen großen Stapel, der im OOCT_buffer zugeordnet wird.
    • 1. Zonenspeicher des Kompilierers 104 zuordnen. Der Kompilierer 104 verwendet diesen Speicher im OOCT_buffer während der Kompilierung.
    • 2. Den kompilierten Segmentspeicher zuordnen. Der kompilierte Code wird in diesem Bereich des OOCT_buffer plaziert.
    • 3. Statistische Informationen auf Null setzen. Die meisten Informationen im OOCT-Statistikbereich werden zurückgesetzt, wenn der OOCT initialisiert wird.
  • VERZWEIGUNGSPROTOKOLLIERER
  • SCHNITTSTELLE ZUM INTERPRETIERER
  • Wenn der Interpretierer 110 eine Verzweigungsinstruktion im Systemcode ausführt, und das OOCT-Modusbit gesetzt ist, ruft der Interpretierer 110 den Verzweigungsprotokollierer 112 durch eine der folgenden Routinen auf:
    Figure 00370001
    Figure 00380001
  • Diese vier Routinen prüfen auf einen kompilierten Einsprungpunkt für die Zieladresse und springen zum Einsprungpunkt, wenn er existiert. Wenn er nicht existiert, dann aktualisieren die Routinen das Verzweigungsprotokoll durch das Aufrufen von branch_L1_Touch (siehe nächster Abschnitt), und springen dann zur Abholroutine des Interpretierers 110.
  • AKTUALISIERUNG VON VERZWEIGUNGSPROTOKOLLTABELLEN
  • 8 veranschaulicht eine Struktur eines BRANCH_RECORD gemäß einer bevorzugten Ausführungsform der vorliegenden Erfindung.
  • Der Verzweigungsprotokolliercode zählt, wie viele Male eine Verzweigung ausgeführt hat. Es gibt zwei Datenstrukturen, die der Verzweigungsprotokollierer 112 zum Speichern der Zählungen verwendet. Erstens gibt es das Verzweigungsprotokoll, das von allen simulierten Prozessoren in einem Mehrprozessorsystem gemeinsam genutzt wird. Zweitens gibt es einen Cache erster Ordnung (L1) für jeden simulierten Prozessor im System. Die Verzweigungsausführungszählungen werden zuerst in den Cache geschrieben und dann in das Verzweigungsprotokoll geschrieben. Dieser Abschnitt beschreibt die Struktur der L1-Caches und des Verzweigungsprotokolls. Er beschreibt auch, wie der Verzweigungsprotokollierer 112 diese verwendet.
  • Die Informationen für jede Verzweigung werden in einer Struktur gespeichert, die BRANCH_RECORD genannt wird. Sie enthält die Adresse der Verzweigung, das Ziel der Verzweigung, die Fehlschlag-Instruktion nach der Verzweigung, die ungefähre Anzahl von Malen, welche die Verzweigung ausgeführt hat, und die ungefähre Anzahl von Malen, welche die Verzweigung eingeschlagen wurde. Das letzte Feld des BRANCH_RECORD ist ein Zeiger auf einen anderen BRANCH_RECORD. Er wird verwendet, um den BRANCH_RECORD in einer verketteten oder verknüpften Liste zu verbinden.
  • Die Hash-Tabelle ist als Array verketteter Listen organisiert.
  • 9 veranschaulicht die Struktur des Verzweigungsprotokolls. Es ist eine große Hash-Tabelle, die BRRNCH_RECORDs speichert. Jeder Interpretierer 110 hat seine eigene Kopie der variablen local_branch_header_table, sie zeigen jedoch alle auf dasselbe Array im OOCT-Pufferbereich. Die Elemente der local_branch_header_table sind Zeiger auf Listen von BRANCH_RECORDs. Die Prozedur zum Finden eines BRANCH_RECORD für eine Verzweigung weist 3 Schritte auf.
    • 1. Hash-Codieren der Zieladresse. (index = BRANCH_HASH(destination_address) % BRANCH_TABLE_SIZE.)
    • 2. Kopf der Liste bzw. engl. head of list ermitteln. (list = local_branch_header_table[index].)
    • 3. Liste abwärts durchgehen, bis ein Datensatz mit derselben Verzweigungsadresse gefunden wird. (while (list->branch_address! = branch_address) list = list->next.)
  • 9 veranschaulicht insbesondere, daß die variable local_branch_header_table ein Array von Zeigern auf Listen ist. Jede Liste enthält BRANCH_RECORDs, die dieselbe Zieladresse aufweisen. Wenn es keine Liste gibt, ist der Zeiger in der local_branch_header_table NULL.
  • Das Verzweigungsprotokoll enthält alle Informationen über Verzweigungen, es weist jedoch auch zwei Probleme auf. Erstens sind das Nachschlagen und Einfügen von BRANCH_RECORDs langsame Operationen. Sie sind zu langsam durchzuführen, jedesmal wenn der Interpretierer 110 eine Verzweigung protokolliert. Zweitens verwendet jeder Interpretierer 110 dasselbe Verzweigungsprotokoll. Um die Listen der BRANCH_RECORDs konsistent zu halten, kann nur eine Ausführung zu einer Zeit auf das Verzweigungsprotokoll zugreifen. Dies verlangsamt das Mehrprozessorsystem noch mehr als das Einprozessorsystem. Um diese Probleme zu beheben, gibt es einen L1-Cache für jeden Interpretierer 110. Auf den L1-Cache kann rasch zugegriffen werden, und die Interpretierer 110 können auf ihre L1-Caches parallel zugreifen. Jeder L1-Cache ist ein zweidimensionales Array von BRANCH_L1_RECORD-Strukturen. Die Basisadresse des Arrays wird in der variablen branch_L1_table gespeichert.
  • 10 veranschaulicht die Struktur des L1-Cache. Der Cache ist ein zweidimensionales Array von BRANCH_L1_RECORDs. Die erste Dimension ist BRANCH_L1_SETS (aktuell 32), und die zweite Dimension ist BRANCH_L1_SETSIZE (aktuell 4). Jede Reihe des Arrays ist ein Satz. Dieselbe Verzweigungsinstruktion verwendet immer denselben Satz des Cache, er kann jedoch an verschiedenen Plätzen sein.
  • Wie in 10 veranschaulicht, ist der L1-Cache in Sätzen organisiert. Die Satznummer für eine Verzweigung ist gleich (branch_address + branch_destination) % BRANCH_L1_SETS. Die 4 Mitglieder des Satzes halten die 4 neuesten Verzweigungen mit derselben Satznummer. Dies wird 4-Weg-Satzassoziativität genannt. Sie verbessert die Leistung des Cache, wenn einige Verzweigungen nahezu zur gleichen Zeit ausgeführt werden, die dieselbe Satznummer aufweisen.
  • 11 veranschaulicht ein Verfahren zur Ausführung des Betriebs des L1-Cache durch den Interpretierer 110 gemäß einer Ausführungsform der vorliegenden Erfindung. Mit anderen Worten veranschaulicht 11 ein Verzweigungsprotokollierverfahren unter Verwendung des L1-Cache.
  • Das optimierende Objektcode-Übersetzungsverfahren verwendet zwei Speicherformen zum Aufzeichnen nicht-kompilierter Verzweigungen, nämlich
    • 1. ein Verzweigungsprotokoll mit einer sich dynamisch ändernden Größe proportional zur Anzahl aufgezeichneter Verzweigungen, und
    • 2. einen Verzweigungs-Cache, der als L1-Cache bezeichnet wird, in dem eine begrenzte Anzahl nichtkompilierter aufgezeichneter Verzweigungen in einer Reihenfolge gespeichert werden, die den Zugriff erweitert.
  • Das Verzweigungsprotokoll und der L1-Cache repräsentieren virtuelle Speicherstellen, die von einem Betriebssystem verwaltet werden. Daher wird die Bezeichnung "L1-Cache" willkürlich dem Cache zum Speichern nicht-kompilierter Verzweigungen verliehen und sollte nicht mit dem 'L1-Cache' verwechselt werden, der allgemein auf einem Prozessor wie dem Pentium Pro zu finden ist.
  • Der optimierende Objektcode-Übersetzer gemäß der vorliegenden Erfindung sieht vor, daß der Interpretierer 110 eine Vielzahl verschiedener Verzweigungsprotokollierroutinen aufrufen kann. Jede Verzweigungsprotokollierroutine selbst ruft jedoch eine Subroutine auf, die entscheidet, zum kompi lierten Code zu springen, oder eine Verzweigungsinstruktion zu protokollieren. Diese Subroutine wird insbesondere in 11 veranschaulicht.
  • Angesichts des Obigen wird, um das Verzweigungsprotokollierverfahren mit dem L1-Cache auszuführen, zuerst das Verfahren in Schritt S400 gestartet. In Schritt S401 prüft der Interpretierer 110 zuerst auf einen kompilierten Codeeinsprungpunkt für das Verzweigungsziel (d.h. ob das betreffende Segment vorher kompiliert wurde). Wenn ein Einsprungpunkt vorliegt, d.h. "Ja", gibt es ein kompiliertes Segment, und der Fluß springt zu Schritt S402 zur unmittelbaren Ausführung des kompilierten Codesegments. Die Ausführung des kompilierten Codesegments geht dann weiter, bis eine Endflagge erreicht wird, und der Fluß springt anschließend für die Ausführung des nächsten Segments zurück. Selbstverständlich wird die Verzweigung im Verzweigungsprotokoll nicht aufgezeichnet, daß die Verzweigung bereits kompiliert wurde.
  • Wenn in Schritt S401 kein Einsprungpunkt vorliegt, d.h. "Nein", dann gibt es keinen kompilierten Code, welcher der Verzweigungsinstruktion entspricht. Der Fluß geht dann zu Schritt S404 weiter, und der Interpretierer 110 sieht im L1-Cache nach, um zu bestimmen, ob eine mögliche Übereinstimmung zwischen der Verzweigung und der Vielzahl von Verzweigungen besteht, die im L1-Cache gespeichert sind.
  • Schritt S404 bestimmt, ob eine Übereinstimmung zwischen der Verzweigung und der Vielzahl von Verzweigungen besteht, die im L1-Cache gespeichert sind. Der L1-Cache ist in eine Vielzahl von Sätzen geteilt, wobei jeder Satz mit einer eindeutigen Satznummer bezeichnet ist. Gemäß einer Ausführungsform der vorliegenden Erfindung enthält jeder Satz vier Ver zweigungen.
  • Schritt S404 bestimmt zuerst eine Cache-Satznummer "S", die der aktuellen Verzweigungsadresse entspricht, wobei S = (branch_address + branch_destination) % BRANCH_L1_SETS. Als nächstes wird jedes Element der branch_L1_table[S] sequentiell gegen die aktuelle Verzweigungsadresse und das Ziel geprüft. Wenn eine Übereinstimmung detektiert wird, d.h. "Ja", dann geht der Fluß zu Schritt S406 weiter, und die Felder "encountered_sub_count" (ein Feld, das angibt, wie viele Male die Verzweigung gefunden wurde) und "taken_sub_count" (ein Feld, das angibt, wie viele Male die Verzweigung eingeschlagen wurde) werden aktualisiert. Anschließend geht der Fluß zu Schritt S407 weiter.
  • In Schritt S407 wird bestimmt, ob die aktuelle Verzweigungsadresse größer als eine vorherbestimmte Schwellenanzahl gefunden wurde. Der bevorzugte Schwellenwert liegt in der Größenordnung von 1000 Bits. So wird das Feld encountered_sub_count mit dem Schwellenwert in Schritt S407 verglichen. wenn der Schwellenwert überschritten wird, d.h. "Ja", dann geht der Fluß zu Schritt S410 weiter, und die im Cache gespeicherten Informationen für diese Verzweigung werden in das Verzweigungsprotokoll zurückgeschrieben. Wenn der Schwellenwert hingegen nicht überschritten wird, d.h. "Nein", dann geht der Fluß zu Schritt S412 weiter. Schritt S412 ist ein Ende der aktuellen Subroutine, die zu IC-FETCH02 springt, d.h. dem Einsprungpunkt des Interpretierers 110.
  • Wenn sich die korrekte Verzweigung nicht im Cache befindet, d.h. "Nein" in Schritt S404, dann geht der Fluß zu Schritt S408 weiter, und ein BRANCH_L1_RECORD (d.h. der Datensatz, der alle Felder, die aktualisiert werden können, enthält, wie encountered_sub_count und taken_sub_count) im oben mit "S" bezeichneten Satz wird aus dem L1-Cache entfernt und in das Verzweigungsprotokoll geschrieben. Als nächstes werden die aktuellen Verzweigungsinformationen in den mit "S" bezeichneten Satz geschrieben. Außerdem wird während des Schreibens des aktuellen Verzweigungsdatensatzes in den Satz "S" der aktuelle Verzweigungsdatensatz als erstes Element des Satzes plaziert. Dies ist darauf zurückzuführen, daß dieselbe Verzweigung wahrscheinlich erneut ausgeführt wird, wodurch die Leistung und Effizienz des Systems zunehmen. Mit anderen Worten werden die Sätze S404 rascher ausgeführt. Auch wenn sich die Verzweigung im Cache befindet, d.h. "Ja", kann sie in das Verzweigungsprotokoll kopiert werden, wenn sie eine große Anzahl von Malen ausgeführt hat, seit sie das letzte Mal geräumt wurde.
  • Wenn der L1-Cache verwendet wird, ist die Schrittsequenz fast immer S400, S404, S406, S407 und S412. Demgemäß versucht die vorliegende Erfindung, diese Schritte so schnell wie möglich zu machen. Wenn die aktuellen Verzweigungsinformationen in das erste Element des Satzes gesetzt werden, machen die Verzweigungsinformationen den Schritt S404 schneller, da der Interpretierer 110 dieselbe Verzweigung wahrscheinlich erneut ausführt.
  • Das oben angegebene Verzweigungsprotokollierverfahren reduziert die Belastung für den Prozessor durch das Ausführen eines Codes, der vorher kompiliert wurde, und das Erweitern eines Zugangs zu oft aufgerufenen Verzweigungsinstruktionen, welche die Schwellenhöhe zur Kompilierung noch nicht erreicht haben. In dieser Hinsicht ist der Hauptzweck des OOCT, den Schritt S400 dazu zu bringen, die "Ja" Ver zweigung nahezu jedesmal einzuschlagen. Wenn eine Verzweigung häufig ausgeführt wird, dann sollte ein kompiliertes Codesegment für ihr Ziel vorliegen.
  • Ein zweiter Zweck ist, den "Nein"-Pfad, der Schritt S401 folgt, schneller zu machen, so daß Verzweigungen, die noch nicht kompiliert wurden, die Programmausführung nicht merkbar verlangsamen. Der langsamste Teil des "Nein"-Pfads wird als "Räumung" bezeichnet. In beiden Schritten S408 und S410 werden Verzweigungsinformationen aus dem L1-Cache "geräumt" und in das Verzweigungsprotokoll geschrieben. Es wird notwendig, die Informationen einer Verzweigung zu räumen, um einen Startparameter an den Kompilierer zu senden, der veranlaßt, daß ein kompilierter Code generiert wird, und den Schritt S400 veranlaßt, für diese Verzweigung in der Zukunft "Ja" zu antworten.
  • Es ist jedoch nicht notwendig, die Informationen der Verzweigung jedesmal zu räumen, wenn eine nicht-kompilierte Verzweigungsadresse ausgeführt wird. Eine Räumung alle 100 Ausführungen oder weniger ist oft OK. Daher versucht die vorliegende Erfindung, die Geschwindigkeit der Schritte S400, S404, S406, S407 und S412 zu steigern, die keine Räumungen enthalten. So wird immer der schnellere Pfad eingeschlagen, außer es passiert eines von zwei Dingen. In Schritt S404 ist es möglich, daß die Verzweigungsinformationen im Satz nicht gefunden werden, daher wird der "Nein"-Pfad zu S408 eingeschlagen. Wenn die Verzweigung öfter als die "Schwellen"anzahl von Malen ausgeführt wurde, wird in Schritt S407 der "Ja"-Pfad zu S410 eingeschlagen, der auch eine Räumung enthält.
  • Im OOCT_DEBUG_MODE wird das L1-Cacheverfahren weiterhin verwendet, die Schwelle zur Räumung des Cache wird jedoch auf 1 gesetzt, so daß die Informationen bei jeder Verzweigungsausführung in das Verzweigungsprotokoll geschrieben werden. Dies macht den OOCT_DEBUG_MODE viel langsamer.
  • STARTPARAMETERAUSWAHL (engl. = SEED SELECTION)
  • Wenn eine Verzweigungsinstruktion sehr häufig ausgeführt wird, sendet der Verzweigungsprotokollierer 112 seine Zieladresse an den Kompilierer 104. Diese Adresse wird 'Startparameter' genannt, und das Auswählen von Startparametern ist ein sehr wichtiger Teil des OOCT-Systems.
  • Startparameter sollten Adressen sein, die am Beginn einer Prozedur oder am Kopf einer Schleife stehen. Daher sendet der Verzweigungsprotokollierer 112 nur Startparameter, die das Ziel einer unbedingten Verzweigung sind. Startparameter sollten Adressen sein, die häufig ausgeführt werden, so daß ein Verzweigungsziel nur ein Startparameter wird, wenn sein Feld encountered_count größer als eine Schwelle ist. Die Schwelle wird im OOCT-Puffer im mit seed_production_threshold bezeichneten Feld gespeichert. Die Schwelle kann sich mit der Zeit ändern, was im nächsten Abschnitt beschrieben wird.
  • SETZEN DER SCHWELLE (engl. = THRESHOLD SETTING)
  • Es gibt zwei nachteilige Dinge bei der Verwendung einer festgelegten Schwelle, um zu entscheiden, ob ein Startparameter gesendet wird. Erstens kann die Schwelle zu hoch ein, während der Kompilierer 104 untätig ist. In diesem Fall gibt es für den Kompilierer 104 nützliche Arbeiten zu verrichten, aber der Verzweigungsprotokollierer 112 sagt dem Kompilierer 104 nicht, was zu tun ist. Zweitens kann die Schwelle zu niedrig sein, während die Nachrichtenwarteschlange voll ist. In diesem Fall versucht der Verzweigungsprotokollierer 112 einen Startparameter zu senden, obwohl der Startparameter nicht in die Warteschlange paßt, was Zeitverschwendung ist.
  • Glücklicherweise ist es möglich, die beiden Situation zu detektieren, wenn der Kompilierer 104 untätig ist, und wenn die Nachrichtenwarteschlange voll ist, und die Schwelle zu ändern. Der Verzweigungsprotokollierer 112 detektiert in der Prozedur branch_Update_Entry durch das Lesen des als num_monitor_seed_messages bezeichneten OOCT-Pufferfeldes, daß der Kompilierer 104 untätig ist. Wenn dieses Feld 0 ist, hat der Kompilierer 104 alle Startparameter, die gesendet wurden, beendet. Die Schwelle ist zu hoch, daher senkt sie der Verzweigungsprotokollierer 112. Der Verzweigungsprotokollierer 112 detektiert eine volle Nachrichtenwarteschlange in der Prozedur branch_Send_Seed, wenn er einen Startparameter zu senden versucht, und bekommt einen Fehlercode, der anzeigt, daß die Nachricht nicht gesendet wurde. Die Schwelle ist zu niedrig, daher erhöht sie der Verzweigungsprotokollierer 112.
  • Im OOCT_DEBUG_MODE ändert sich die Schwelle nie. Ihr Wert wird in diesem Fall auf das dritte Argument der OOCT_INIT-Prozedur gesetzt.
  • MEHRAUFGABEN-BEHANDLUNG (engl. = HANDLING MULTITASKING)
  • Der OOCT läuft auf einem Mehrprozessorsystem mit mehrfachen Interpretierern 110. Diese Aufgaben haben individuelle Verzweigungs-L1-Caches, sie verwenden jedoch dieselbe Verzweigungsprotokolltabelle. Wenn Verzweigungsinformationen aus dem L1-Cache in die Verzweigungsprotokolltabelle geräumt werden, belegt der Interpretierer 110 ein Protokoll auf der Tabelle, so daß es zu keinem Konflikt mit irgendeiner anderen Ausführung kommt. Es gibt zwei mögliche Wege, einen Streit um die Verzweigungsprotokollverriegelung zu behandeln. Der erste ist, einen Interpretierer 110 warten zu lassen, bis die Verriegelung verfügbar ist, und dann die Verriegelung zu erhalten und ihre Verzweigungsinformationen zu schreiben. Dies läßt den Interpretierer 110 langsamer laufen, macht jedoch das Verzweigungsprotokoll genauer. Der zweite ist aufzugeben, ohne die Verzweigungsinformationen zu schreiben, wenn der Interpretierer 110 die Verriegelung nicht erhalten kann. Dieser Weg macht den Interpretierer 110 schneller, verliert jedoch einige Verzweigungsprotokollierinformationen. Der OOCT verwendet den zweiten Weg, da die Geschwindigkeit des Interpretierers 110 wichtiger ist als die Genauigkeit des Verzweigungsprotokolls. Die Verzweigungsprotokollinformationen müssen nur ungefähr korrekt sein, damit das System gut funktioniert.
  • Wenn der OOCT mit mehrfachen Interpretierern 110 läuft, ist eine der Aufgaben die spezielle Masteraufgabe, die OOCT_INIT aufruft, um den OOCT-Puffer und die Verzweigungsprotokollier-Datenstrukturen zu initialisieren. Die anderen Aufgaben sind Slaveaufgaben, die nur einige lokale Variablen und ihre Verzweigungs-L1-Caches initialisieren müssen. Die Slaveaufgaben rufen SlaveOOCT_Init auf, nachdem die Masteraufgabe die Initialisierung des OOCT_-buffer beendet hat. Die Synchronisation zwischen Master- und Slaveaufgaben verwendet die folgenden Verfahren.
  • Masterverfahren
    • 1. MCD-Instruktion ausführen, um OOCT einzuschalten.
    • 2. OOCT_INIT aufrufen, wodurch der OOCT-Puffer und Verzweigungsprotokollier-Datenstrukturen initialisiert werden.
    • 3. Slaveaufgaben aufwecken.
    • 4. Zum Interpretierer springen.
  • Slaveverfahren
    • 1. Gehe zu Schlafmodus. Aufwachen, wenn Masteraufgabe ausführt (Schritt 3 oben).
    • 2. S1aveOOCT_Inti aufrufen, wodurch der individuelle Verzweigungs-L1-Cache der Aufgabe initialisiert wird.
    • 3. Zum Interpretierer springen.
  • BENUTZER/SYSTEMRAUMÜBERGÄNGE
  • Das OOCT-System kompiliert nur Instruktionen von den Systemseiten des ASP-Adressenraums. Es ignoriert die Benutzerseiten. Das OOCTSTS-Bit des individuellen Bereichs des Interpretierers 110 steuert, ob der Verzweigungsprotokollierer 112 aufgerufen wird oder nicht. Dieses Bit wird hauptsächlich von den beiden Makros NEXT_CO und NEXT_OUN gesteuert. Es gibt jedoch einen Fall, wo der OOCT-Code dieses Bit setzen muß. Wenn ein kompiliertes Codesegment mit einer nicht-festgelegten Verzweigungsinstruktion endet, kann es PSW_IA veranlassen, sich vom Systemraum zum Benutzerraum zu bewegen, was erfordert, daß OOCTSTS auf 0 gesetzt wird. Daher springt ein kompiliertes Codesegment, das mit einer nicht-festgelegten Verzweigung endet, zur Routine branch_Exit_Log, welche die Zieladresse prüft und das OOCTSTS-Bit korrekt setzt.
  • KOMPILIERTE CODESCHNITTSTELLE
  • ÜBERGANG ZUM/VOM KOMPILIERTEN CODE
  • Der Interpretierer 110 transferiert die Ausführung zum kompilierten Code, wenn der Interpretierer 110 eine Verzweigungsprotokollierroutine aufruft, und er ein kompiliertes Codesegment für das Verzweigungsziel findet (siehe 11). Wenn die Segmentverriegelung ausgeschaltet ist, springt der Interpretierer 110 direkt zum Einsprungpunkt. Wenn die Segmentverriegelung eingeschaltet ist, muß der Interpretierer 110 versuchen, das Segment zu verriegeln, bevor er zum Einsprungpunkt springt. Wenn er das Segment verriegelt, dann springt er zum Einsprungpunkt. Wenn er das Segment nicht verriegeln kann, springt er zurück zum Interpretierer 110.
  • Es gibt einige Wege zur Ausführung, um ein kompiliertes Codesegment zu verlassen, die in Tabelle 4 beschrieben werden. Wenn die Steuerung zum Interpretierer 110 zurückspringt, haben in allen Fällen die ESI- und EDI-Register korrekte werte, und der individuelle Bereich des Interpretierers 110 hat perfekten K-Status.
  • Tabelle 4: Wie die Steuerung ein kompiliertes Codesegment verläßt
    Figure 00520001
  • Wenn die Segmentverriegelung ein ist, hält der Interpretierer 110 eine Verriegelung auf dem kompilierten Codesegment, während er diesen Code ausführt. Er muß diese Verriegelung freigeben, nachdem er das Segment verläßt, so daß der kompilierte Code einige Prozeduren im Verzweigungsprotokollierer 112 aufruft, welche die Verriegelung freigeben, und dann zum Interpretierer 110 springen.
  • UNTERBRECHUNGEN
  • Es gibt einige Unterbrechungen, die eintreten können, während der kompilierte Code ausführt, wie IO-Unterbrechungen oder MCHK-Unterbrechungen. Der kompilierte Code prüft das INTINF-Feld des individuellen Bereichs, um zu detektieren, ob eine Unterbrechung eingetreten ist. Er prüft dieses Feld innerhalb irgendeiner möglichen unendlichen Schleife, die sicherstellt, daß er die Unterbrechung nicht für immer ignoriert. wenn eine Unterbrechung eintritt, ruft der kompilierte Code die Interpretierer 110-Routine IU_OINTCHK mit perfektem K-Status auf. Er erwartet, daß der Interpretierer 110 zum kompilierten Code zurückspringt.
  • INTERPRETIERERRÜCKRUFE
  • Einige K-OP-Codes werden vom OOCT nicht übersetzt. Statt dessen ruft der kompilierte Code die Interpretierer 110-Subroutine IC_OOCT auf, um den OP-Code zu interpretieren und zum kompilierten Code zurückzuspringen. Der kompilierte Code stellt sicher, daß die ESI- und EDI-Register die korrekten Werte aufweisen, und daß der individuelle Bereich perfekten K-Status hat, bevor IC_OOCT aufgerufen wird.
  • Wenn der Interpretierer 110 während der Ausführung der IC_OOCT-Subroutine einen Fehler detektiert, ruft er die Prozedur OOCT_EXCP auf, und springt nicht zum kompilierten Code zurück. Wenn die Segmentverriegelung eingeschaltet ist, gibt OOCT_EXCP die Segmentverriegelung frei.
  • AUSNAHMEN
  • Wenn ein übersetzter OP-Code eine unmaskierte Ausnahme, wie eine Operationsausnahme oder eine Nullteilerausnahme, aufweist, ruft der kompilierte Code eine Interpretierer-Subroutine IC_PGMxx auf, wobei xx die Fehlercodenummer zwischen 01h und 21h ist. Der Interpretierer 110 versucht, die Ausnahme zu behandeln und zurückzuspringen. Wenn der Interpretierer 110 nicht zurückspringen kann, ruft er OOCT_EXCP auf, wodurch jede Segmentverriegelung freigegeben wird.
  • VERWENDUNG GLOBALER FUNKTIONEN
  • Einige K-OP-Codes, wie Zeichenverarbeitungsoperationen, werden in eine große Anzahl von Ziel-OP-Codes übersetzt. Die Herstellung mehrfacher Übersetzungen dieser OP-Codes würde zu viele der Segmentspeicher-Resubroutinen verwenden, die globale Funktionen genannt werden, und die der kompilierte Code aufruft, um diese OP-Codes auszuführen. Diese globalen Funktionen sind genauso wie Interpretierer 110-Routinen, die K-OP-Codes ausführen, außer daß sie speziell geschrieben sind, um vom kompilierten Code aufgerufen zu werden, und zum kompilierten Code zurückzuspringen. Es gibt globale Funktionen für fünf OP-Codes, SBE, CC, MV, TS und C. Versuche zeigen, daß die globalen Funktionen viel schneller sind als der Aufruf des IC_OOCT-Einsprungpunkts des Interpretierers 110, und sie verwenden viel weniger Speicher als das mehrfache Kompilieren des OP-Codes in Zielinstruktionen.
  • VI. KOMPILIERER
  • ÜBERBLICK
  • Bevor auf die Details der Kompilierung eingegangen wird, ist es wichtig, auf hoher Ebene den Hauptzweck des Kompilierers 104 zu verstehen, und die Struktur des Kompilierers 104 zu verstehen. Der Zweck des Kompilierers 104 ist die Übersetzung häufig ausgeführter Teile des aktuellen Ausführungsprogramms in einen optimierten Zielcode, und diesen Code für den Interpretierer 110 zur Ausführung verfügbar zu machen.
  • 12 veranschaulicht insbesondere eine allgemeine Struktur eines Kompilierers 104. Der Kompilierer 104 empfängt Startparameter vom Verzweigungsprotokollierer 112 (oben diskutiert), die den Kompilierungsprozeß starten. Der Startparameter ist die Adresse einer Originalinstruktion, die das Ziel einer großen Anzahl von Verzweigungen im aktuellen Ausführungsprogramm gewesen ist. Dies soll einen Startpunkt bilden, um einen häufig ausgeführten Teil des aktuellen Ausführungsprogramms zu finden. Der Blockwähler 114 verwendet diesen Startparameter zusammen mit anderen Informationen, die vom Verzweigungsprotokollierer 112 vorgesehen werden, um Abschnitte des Programms zu wählen, die kompiliert werden sollten.
  • Sobald der zu kompilierende Originalcode gewählt wurde, wird er drei Hauptstufen unterworfen. Die erste Stufe ist die Konvertierung der K-OP-Codes in eine Zwischensprache (IL), die vom Rest des Kompilierers 104 verwendet wird. Die Zwischensprache wird vom IL-Generator 124 generiert. Die zweite Stufe führt verschiedene Analysen und optimierende Transformationen an der IL mittels der oben angegebenen Optimierung durch, die für Referenzzwecke als Optimierer 126 bezeichnet wird. Die Endstufe konvertiert die IL in einen relativierbaren Maschinencode und wird als optimierende Codegenerierungseinheit 118 bezeichnet.
  • Der End-Job des Kompilierers 104 ist, den optimierten Code für den Interpretierer 110 verfügbar zu machen. Dann wird eine Segmentdatenstruktur mit einer Kopie des optimierten Codes durch eine Segmentinstallationseinheit geschaffen. Anschließend wird das Segment in einen gemeinsam genutzten Bereich innerhalb des OOCT-Puffers (nicht dargestellt) installiert. Die Übersetzungstabelle wird schließlich aktualisiert, so daß alle Verzweigungen vom Interpretierer 110 zum kompilierten K-Code statt dessen den neuen Zielcode verwenden.
  • Der Rest dieses Abschnitts diskutiert detailliert jede der obigen Kompilierer 104-Stufen. Am Ende des Abschnitts werden auch einige andere verschiedene Implementationseinzelheiten erörtert.
  • BLOCKWAHL (engl. = BLOCK PICKING)
  • Der Kompilierer 104 empfängt eine einzelne Startparameteradresse, um die Kompilierung zu starten. Beginnend beim Startparameter liest er Originalinstruktionen, bis er etwas wie einen Prozedurrumpf gelesen hat. Dann reicht er diesen Satz von Originalinstruktionen zur nächsten Kompilierer 104-Stufe, der IL-Generierung, weiter. Die Instruktionseinheiten, die der Kompilierer 104 liest, werden Basisblöcke genannt, so daß diese Stufe als Blockwähler, d.h. Blockwähler 114, bezeichnet wird.
  • Ein Basisblock ist eine Sequenz von Instruktionen, wo die Steuerung nur bei der ersten Instruktion einspringen kann, und nur bei der letzten Instruktion ausspringen kann. Das bedeutet, daß nur die erste Instruktion das Ziel einer Verzweigung sein kann, und nur die letzte Instruktion eine Verzweigungsinstruktion sein kann. Es bedeutet auch, daß, wenn die erste Instruktion des Blocks ausgeführt wird, dann alle Instruktionen ausgeführt werden.
  • BLOCKWÄHLER
  • 13 veranschaulicht ein Beispiel des Blockwählers 114 gemäß einer Ausführungsform der vorliegenden Erfindung. Die Prozedur OOCT_ParseFrom implementiert den Blockwähler 114. Er liest einen Basisblock zu einer Zeit. Ein Basisblock endet aus einem von fünf Gründen.
    • 1. Wenn der Sprachanalysierer eine Verzweigungsinstruktion liest, endet der Block mit der Verzweigung
    • 2. Wenn die nächste Instruktion bereits einer Sprachanalyse unterzogen wurde, dann endet der Block mit der aktuellen Instruktion, da jeder K-OP-Code nur einmal in einem Segment auftreten sollte.
    • 3. Wenn die nächste Instruktion ein Verbindungspunkt ist, dann endet der Block mit der aktuellen Instruktion, da sich Verbindungspunkte am Beginn eines Basisblocks befinden müssen.
    • 4. Wenn die aktuelle Instruktion ein Faktor ist, und darauf Daten anstelle von Instruktionen gefolgen könnten, dann endet der Block mit der aktuellen Instruktion.
    • 5. Wenn die aktuelle Instruktion eine illegale Instruktion ist, dann endet der Block mit der aktuellen Instruktion.
  • Nach dem Lesen jedes Blocks entscheidet der Blockwähler 114 in Abhängigkeit von der Weise, wie der Block geendet hat, welche Aktion als nächstes zu unternehmen ist. Die möglichen Aktionen sind in Tabelle 5 veranschaulicht. Tabelle 5: Aktion nach dem Lesen eines Blocks
    Figure 00580001
  • Ein Beispiel wird in 13 veranschaulicht. Der Blockwähler 114 beginnt an der Startparameterinstruktion, die eine LB-Instruktion ist. Da dies keine Verzweigungs- oder Endfaktorinstruktion ist, geht er zur nächsten Instruktion weiter. Diese ist eine TH-Instruktion, die eine bedingte Verzweigung ist. Der Blockwähler 114 stoppt das Lesen des Blocks wegen der bedingten Verzweigung. Er setzt das Lesen neuer Blöcke sowohl an der LH- als auch der LF-Instruktion fort. Wenn er die SVC-Instruktion liest, beendet der Blockwähler 114 diesen Block, da SVC eine Endfaktorinstruktion ist. Wenn er die GO Instruktion liest, beendet der Blockwähler 114 diesen Block, da GO eine Verzweigungsinstruktion ist. Er setzt das Lesen an der L8 Instruktion fort, da sie ein Verzweigungsziel ist. Nachdem er die ST8 Instruktion liest, beendet der Blockwähler 114 den Block, da er bereits die nächste Instruktion gelesen hat.
  • Es gibt eine Obergrenze für die Anzahl von Instruktionen, die der Blockwähler 114 liest. Der Zweck dieser Grenze ist zu verhindern, daß dem Kompilierer 104 während der Kompilierung der Quelleninstruktionen der Speicher ausgeht. Die Grenze wird von der Konstante MAX_KINST_NUM in OOCT_trace.c gesetzt, und sie beträgt derzeit 500.
  • Der Blockwähler 114 kann einen Seitenfehler verursachen, wenn er versucht, eine Instruktion zu lesen. Wenn er einen Seitenfehler erhält, stoppt der Blockwähler 114 das Lesen des aktuellen Blocks, setzt jedoch das Lesen ab irgendeinem Verzweigungsziel fort, das er noch nicht versucht hat. Dies ermöglicht dem Kompilierer 104, ein Segment zu schaffen, auch wenn er nicht alle Instruktionen, die von einem Startparameter erreicht werden können, einer Sprachanalyse unterziehen kann.
  • BLOCKAUFBAU (BLOCK LAYOUT)
  • Nach der Auswahl der Basisblöcke ruft der Blockwähler die Prozedur OOCT_GenerateIL auf, um die IL-Instruktionen zu generieren, die der Rest des Kompilierers 104 verwenden wird. Zu dieser Zeit ist es möglich, die Reihenfolge der Blöcke umzuordnen. Dies wird Blockaufbau genannt, und es hilft dem Kompilierer 104, einen besseren Code für den Pentium Pro-Prozessor zu produzieren, da der Pentium Pro schneller läuft, wenn bedingte Vorwärtsverzweigungen nicht eingeschlagen werden.
  • Das Beispiel in 13 wird herangezogen. Es hat eine bedingte Verzweigung, die TH-Instruktion. In den Originalinstruktionen ist der Fehlschlag-Basisblock derjenige, der mit LH beginnt, und der Zielblock ist derjenige, der mit LF beginnt. Wenn die bedingte Verzweigung 75% der Zeit eingeschlagen wird, dann läuft er schneller, wenn der LF-Basisblock in die Fehlschlag-Position und der LH-Basisblock in die eingeschlagene Verzweigungsposition gebracht wird.
  • Die OOCT_GenerateIL-Prozedur baut die Blöcke gemäß den Informationen im Verzweigungsprotokoll auf. Sie bringt die üblichsten Nachfolger bedingter Verzweigungen in die Fehlschlag-Position, wann immer sie kann. Diese Prozedur produziert eine Liste von IL-Instruktionen, die zu den Optimierungsphasen des Kompilierers 104 weitergereicht werden.
  • GENERIERUNG DER ZWISCHENSPRACHE (IL)
  • Der Abschnitt diskutiert den Prozeß der Generierung der Kompilierer 104-Zwischensprach (IL)-Repräsentation für die K-Codes. Vor der direkten Erörterung, wie die IL generiert wird, wird ein Überblick über die IL gegeben, und Datenstrukturen, die wichtig zu verstehen sind, werden beschrieben.
  • IL-ÜBERBLICK
  • Die Hauptanalyse- und Transformationsdurchläufe des Kompilierers 104 operieren in einer Zwischensprache, die ein spezieller maschinenunabhängiger Instruktionssatz ist. Die Verwendung einer Zwischensprache ist aus zwei Hauptgründen eine Standard-Kompilierer 104-Technik. Erstens hat eine IL typischerweise eine Architektur, die eine Analyse und Transformationen vereinfacht. Zweitens ermöglicht eine IL vielen verschiedenen Quellensprachen, dieselben Optimierungs- und Codegenerierungsstufen zu verwenden, und erleichtert die erneute Zielrichtung auf verschiedene Plattformen.
  • Die vom OOCT verwendete IL (ab hier nur als IL bezeichnet) ist derzeit aus 40 verschiedenen OP-Codes zusammengesetzt, die in Tabelle 6 aufgelistet sind. Die Instruktionen fallen in drei Hauptkategorien. Erstens gibt es funktionelle OP-Codes, wie ADD und LOAD, die ein geradliniges Mapping auf Standard-Maschinen-OP-Codes aufweisen. Zweitens gibt es OP-Codes, die den Steuerfluß behandeln, wie LABEL und CGOTO. Schließlich gibt es eine Anzahl spezieller OP-Codes, welche als spezielle Marker vom Kompilierer 104 verwendet werden, die nicht direkt dem Code entsprechen, der vom hinteren Ende generiert wird. Diese speziellen Marker-OP-Codes werden in einem getrennten Abschnitt beschrieben. Da die IL eine virtuelle Maschine repräsentiert, ist es geradlinig, andere OP-Codes zur IL hinzuzufügen, wenn eine weitere Funktionalität erforderlich ist.
  • Die IL besteht aus Instruktionen, von denen jede einen der OP-Codes, einen Typ und eine Anzahl von Pseudoregisterargumenten spezifiziert. Die vom Kompilierer 104 unterstützten Typen sind 8 Bit-, 16 Bit- und 32-Bitwerte mit und ohne Vorzeichen. Abgesehen von Zwischenwerten, die vom SET-OP-Code verwendet werden, und Werten, die mit dem LOAD-OP-Code aus dem Speicher geladen werden, werden alle Argumente mit Pseudoregistern weitergereicht. Pseudoregister sind einfach die Register der virtuellen IL-Maschine. Der Kompilierer 104 gestattet eine willkürliche Anzahl von Pseudoregistern, von denen jedes eine vordefinierte Größe (z.B. 16 Bits) hat. Jedes Pseudoregister entspricht direkt einer spezifizierten Speicherstelle. Für den OOCT sind diese Speicherstellen in den OOCT-spezifischen Teilen des individuellen Bereichs. Dieses Mapping von Pseudoregistern in Speicherstellen hat zwei Vorteile. Erstens wird die IL rationalisiert. Die IL-Operationen, um allgemein verwendete Werte in temporäre Speicher zu laden, und sie in den Speicher zurückzuladen, sind nicht erforderlich. Zweitens kann der Kompilierer 104 oft allgemein verwendete Werte Maschinenregistern zuordnen, wodurch redundantes Laden oder Speichern eliminiert wird.
  • Tabelle 6: IL-OP-Codes
    Figure 00620001
  • Figure 00630001
  • Figure 00640001
  • SPEZIELLE IL-OP-CODES
  • Die OOCT-IL enthält einige OP-Codes, die spezielle Zwecke haben. Die meisten IL-OP-Codes entsprechen dem Code, der im hinteren Ende generiert wird. Statt dessen arbeiten diese speziellen Instruktionen als Wegweiser für den Kompilierer 104, daß etwas Spezielles geschieht. Die IL enthält die folgenden speziellen OP-Codes: ENTRY, SYNC, EXTMOD und OASSIGN. Dieser Abschnitt diskutiert die ersten drei dieser OP-Codes. OASSIGNs werden nachstehend umfassend erläutert.
  • Der OP-Code ENTRY markiert einen Punkt, wo die Steuerung in den Flußgraphen einspringen kann. Der vom OOCT generierte Code kann mehrfache externe Einsprungpunkte aufweisen, die externe Verbindungspunkte repräsentieren. Jeder der externen Einsprünge hat eine entsprechende ENTRY IL-Instruktion. Die ENTRY-Instruktionen treten am Ende des Codes auf und werden unmittelbar von einer GOTO-Instruktion gefolgt, die zu einer Sprungmarke innerhalb des Hauptrumpfes des Codes springt. Der Grund, daß ein Einsprung verwendet wird, anstatt daß der externe Einsprung direkt zur Sprungmarke springen gelassen wird, ist, es dem Codegenerator zu ermöglichen, Füllzeichen zwischen ENTRY und dem Sprung zur Sprungmarke einzufügen.
  • 14 veranschaulicht eine Übersicht über einen Code mit zwei externen Einsprungpunkten, wo Füllzeichen zwischen der ENTRY-Instruktion und der GOTO-Instruktion eingefügt wurden. Mit anderen Worten veranschaulicht 14 insbesondere ein Einsprungbeispiel gemäß einer Ausführungsform der vorliegenden Erfindung.
  • Der OP-Code SYNC wird verwendet, um zu garantieren, daß ein Bereich von Pseudoregistern in den Speicher geräumt wird. Insbesondere verwendet der OOCT den OP-Code SYNC, um zu garantieren, daß alle K-Register in den Speicherstellen sind, wo der Interpretierer 110 sie zu finden erwartet. Der SYNC arbeitet als Direktive für den Registerzuordner, wobei sie anzeigt, daß ein Pseudoregister, das sich in einem Maschinenregister befindet, welches modifiziert wurde, geleert werden sollte. Ein SYNC arbeitet auch als Verwendung aller lebendigen Daten, was verhindert, daß der Kompilierer 104 einen toten Code eliminiert, der nur den Effekt hat, K-Register zu modifizieren.
  • Der OP-Code EXTMOD wird verwendet, um anzuzeigen, daß ein Pseudoregister modifiziert ist, der Kompilierer 104 verfügt jedoch über keine Einzelheiten darüber, wie das Register modifiziert wurde. So hat der EXTMOD zwei Effekte. Erstens arbeitet er als Barriere gegen Optimierungen wie Constant Folding oder Copy Propagation. Zweitens zwingt er den Registerzuordner des Kompilierers 104 dazu, Füllzeichen vor der nächsten Verwendung des Pseudoregisters einzufügen. Im OOCT werden EXTMOD-Instruktionen nach einem Rückruf zum Interpretierer 110 verwendet, um anzuzeigen, welche K-Register modifiziert worden sein können.
  • IL-DATENSTRUKTUREN
  • Vor der Diskussion, wie die IL aus den K-OP-Codes aufgebaut wird, ist es nützlich, die im Kompilierer 104 verwendeten Hauptdatenstrukturen zu kennen.
  • ZONE (compiler/zone.[h,c])
  • Die Speicherzuordnung im Kompilierer 104 wird mit einer ZONE genannten Abstraktion behandelt. Die ZONE-Abstraktion ist ein effizienter Weg zur Speicherzuordnung, so daß er sofort freigegeben werden kann. Mit der ZONE-Abstraktion ist die Zuordnung schnell, und der Programmierer muß sich keine Sorgen über Speicherlecks machen, da eine Zerstörung der ZONE den gesamten verwendeten Speicher erneut beansprucht.2
  • Im Kompilierer 104 wird eine ZONE geschaffen, und alle Aufrufe, die Speicher zuordnen (d.h. was normalerweise malloc-Aufrufe wären), rufen ZONE_Alloc mit der anfänglich geschaffenen ZONE auf. Wenn der Kompilierer 104 fertig ist, ruft er ZONE_Destroy auf, was die Zuordnung der gesamten ZONE rückgängig macht (d.h. äquivalent zu einem Freimachen für den gesamten Speicher).
  • Die zugrundeliegende Implementation der ZONE verwendet 'Stücke' des Speichers. Wenn die ZONE geschaffen wird, kann sie an einem Block mit einer Größe von 0 × 2000 Bytes 'malloc' ausführen. Aufrufe von ZONE_Alloc verwenden dieses 'Stück' des Speichers, bis es verbraucht ist. Wenn kein Platz ist, eine ZONE_Alloc-Anforderung mit den anfänglichen 0 × 2000 Bytes zu bedienen, wird ein neues 'Stück' geschaffen. Weitere ZONE_Alloc-Aufrufe verwenden dieses 'Stück', bis es auch verbraucht ist.
  • Im Kompilierer 104 sind die Dinge durch die Tatsache, daß der gesamte Speicher vor-zugeordnet ist, etwas kompliziert, und so kann malloc nicht aufgerufen werden. Statt dessen wird eine spezielle ZONE-Zuordnereinheit (die ZALLOC-Einheit) verwendet. Der ZONE-Zuordner wird mit einem großen Speicherpool intitialisiert (beispielsweise 0 × 10 000 Bytes). Er teilt den Speicher in Stücke mit gleicher Größe, welche die ZONE zur Zuordnung verwendet, und behält eine Liste freier Stücke. So werden die 'malloc'-Anforderungen durch einen Aufruf von ZALLOC_get_chunk ersetzt, der ein freies 'Stück' Speicher zurückgibt. Ähnlich werden die Aufrufe zur 'Freigabe' in ZONE_Destroy durch Aufrufe von ZALLOC_free_chunk ersetzt. In der aktuellen Implementation ist die maximale Zuordnungsgröße, die von ZONE_Alloc behandelt werden kann, die anfängliche Stückgröße. Diese Grenze könnte durch die Änderung der ZALLOC Einheit 'festgelegt' werden, um Zuordnungen variabler Größe zu behandeln, anstatt einfach eine Größe zu behandeln (siehe Segmentzuordnungseinheit für ein Beispiel dieses Typs eines Zuordners). Es gibt zwei Gründe, warum dies hier nicht durchgeführt wurde. Erstens ist ein Zuordner mit variabler Größe viel komplexer und schafft Probleme wie eine Fragmentierung. Zweitens kann die Stückgröße mit wenig bis gar keinen Einbußen sehr groß gemacht werden. wenn das Stück ausreichend groß ist, fordert der Kompilierer 104 nur eine einzelne Zuordnung an, die größer ist als die Stückgröße, wenn der Kompilierer 104 sowieso keinen Speicher mehr gehabt hätte. So gibt es keinen echten Vorteil bei der Generalisierung der ZALLOC-Einheit, um Zuordnungen mit variabler Größe zu behandeln.
  • IL_CTXT (compiler/oc_common/include/il_internal.h)
  • Der Kompilierer 104 hält eine einzelne Datenstruktur, die IL_CTXT, um den aktuellen Zustand der Kompilierung zu verfolgen. Die IL_CTXT-Datenstruktur speichert einen Zeiger zu einer verketteten Liste von IL_NODEs, die den aktuell kompilierten Code repräsentieren. Die IL_CTXT speichert auch eine Anzahl verschiedener Felder, die während des gesamten Kompilierungsprozesses verwendet werden, wie die ZONE- und IL_FRAME-Struktur, die verwendet werden. Jede der Stufen des Kompilierers 104 hat die IL_CTXT als Argument und nimmt an dieser Datenstruktur Modifikationen vor, beispielsweise eine Anzahl der Stufen addieren, oder IL_NODEs entfernen.
  • IL_NODE (compiler/oc_common/include/il_internal.h)
  • Die IL_NODE-Datenstruktur repräsentiert eine einzelne abstrakte Instruktion in der Zwischensprache des Kompilierers 104, wie aus einem K-OP-Code übersetzt.
  • Die IL_NODES, die aus den K-OP-Codes generiert werden, werden in einer doppelt verketteten Liste gehalten. Zeiger auf die ersten und letzten Elemente in dieser Liste werden in der IL_CTXT gehalten. Diese Liste repräsentiert den Code, an dem der Kompilierer 104 aktuell arbeitet. Jeder Durchlauf des Kompilierers 104 quert diese Liste und generiert entweder Informationen über den Code in der Liste oder transformiert die Liste.
  • Jede IL_NODE enthält ein Operationsfeld 'op', das die Grundbeschaffenheit der Instruktion anzeigt. Sie enthält auch einen Vektor von Operandenfeldern, welche die Operanden der Instruktion repräsentieren. Die Interpretation der Operandenfelder ist vom Operationstyp der Instruktion abhängig. Zusätzlich zu den Operations- und Operandenfeldern enthalten alle IL_NODEs eine Anzahl von Feldern, die von allen Knotentypen gemeinsam genutzt werden, wie K pc der Instruktion, aus welcher der Knoten übersetzt wurde, die Startadresse des für den Knoten generierten Zielmaschinencodes, etc.
  • Die Anzahl von Operandenfeldern in einem Knoten variiert gemäß dem Operationstyp. Tatsächlich können in einigen Fällen zwei Knoten desselben Typs eine verschiedene Anzahl von Operanden aufweisen; die Anzahl von Operanden für eine Aufrufoperation ist beispielsweise von der Anzahl von Argumenten abhängig, die zum Zielverfahren weitergereicht wurden. Diese Variation der Anzahl von Operanden bedeutet, daß IL_NODEs keine konsistente Größe aufweisen, und daß der Operandenvektor das letzte Element in der IL_NODE-Struktur ist. Der Operandenvektor wird als einen Eintrag lang deklariert, und IL_NODES werden durch die Berechnung/Zuordnung des gesamten Speicherbetrags, der für die gemeinsamen Felder und die Operandenfelder notwendig ist, und durch das Umformen des zugeordneten Speichers zu einem IL_NODE-Zeiger zugeordnet.
  • In den meisten, jedoch nicht in allen Fällen erfordert jeder Operand tatsächlich zwei aufeinanderfolgende Einträge im Operandenvektor. Der Eingangsoperand [i] des Pseudoregisters, in dem der Operand zu finden ist. Wenn der Operand ein Zieloperand ist, zeigt Operand[i+1] zu einer Liste von Knoten, die den Wert verwenden, der von dieser Operation definiert wird; wenn der Operand ein Quellenoperand ist, zeigt Operand [I+1] zu einer Liste von Knoten, die Definitionen für den Wert enthalten.
  • Wenn eine Operation einen Zieloperanden aufweist, wird dieser Operand immer in Operand[0] und Operand[1] gespeichert.
  • Wenn Operand[i] ein Quellen-(Eingangs- oder Verwendungs-)Operand ist, ist dies auch Operand[i+2]; d.h. alle Quellenregister müssen an das Ende der Liste der Operanden kommen.
  • Auf Operandenfelder in einem Knoten wird niemals direkt zugegriffen. Der Zugriff erfolgt eher durch einen großen Satz von Makros in Form von ILOP_xxx(N), wobei N ein Zeiger zu einer IL_NODE ist. Diese Makros wissen, wie verschiedene Operanden im Operandenvektor für alle verschiedenen Instruktionstypen gespeichert werden.
  • Einige der Knotentypen sind wie folgt (diese Liste ist nicht vollständig):
  • Unäre Operationen
  • Diese repräsentieren eine Varietät einfacher unärer (1 Quellenoperand) Instruktionen, die eine Zuweisung enthalten.
    • Typ der Typ der Operation
    • ILOP_DEST(N) Zielregister; wo das Resultat hingeht
    • ILOP_DEST_use(N) Liste von Instruktionen, die das Zielregister verwenden
    • ILOP_SRC(N) Quellenregister
    • ILOP_SRC_def(N) Liste von Instruktionen, welche die Quelle definieren
  • Binäre Operationen
  • Eine Große Anzahl binärer (2 Quellenoperanden) Instruktionen werden von dieser Kategorie repräsentiert.
    • Typ der Typ der Operation
    • ILOP_DEST(N) Zielregister; wo das Resultat hingeht
    • ILOP_DEST_use(N) Liste von Instruktionen, die das Zielregister verwenden
    • ILOP_SRC1(N) erstes Quellenregister
    • ILOP_SRC1_def(N) Liste von Instruktionen, welche die erste Quelle definieren
    • ILOP_SRC2(N) zweites Quellenregister
    • ILOP_SRC2_def(N) Liste von Instruktionen, welche die zweite Quelle definieren
    • ILOP_DIVEX(N) Dieser Operand tritt nur für die DIV- und REM-Operationen auf, und zeigt auf eine (Singleton) Liste, die den Knoten enthält, der den Start der Nullteilungsausnahme repräsentiert, sofern eine vorliegt.
  • LABEL
  • Eine LABEL-Instruktion repräsentiert einen Punkt im Code, wohin sich Verzweigungen verzweigen können. Sie enthält die folgenden Operanden:
    • ILOP_LABEL(N) Eindeutige ganze Zahl, welche die Sprungmarke (engl. label) identifiziert.
    • ILOP_LABEL_refs(N) Liste von Instruktionen, die auf diese Sprungmarke bezugnehmen
    • ILOP_LABEL_live(N) BITSET, der zeigt, welche Register an dieser Sprungmarke lebendig sind.
    • ILOP_LABEL_rd(N) Vektor von Listen der Definitionen jedes Registers, der diese Sprungmarke erreicht.
    • ILOP_LABEL_misc(N) Platz für jeden Durchlauf, um private Informationen über die Sprungmarke anzuhängen.
  • GOTO
  • Eine GOTO-Instruktion repräsentiert eine unbedingte Verzweigung zu einer Sprungmarke.
    • ILOP_LABEL(N) Eindeutige ganze Zahl, welche die Zielsprungmarke identifiziert.
    • ILOP_LABEL_refs(N) Singleton-Liste der Ziel-LABEL-Instruktion.
  • CGOTO
  • Eine CGOTO-Instruktion repräsentiert eine bedingte Verzweigung zu einer Sprungmarke. Sie enthält dieselben Operan den wie die GOTO-Instruktion sowie einige zusätzliche Operanden.
    • ILOP_COND(N) Register, das die Bedingung enthält, bei der zu verzweigen ist. Dieses Register muß einen Wert vom Booleschen (B1) Typ enthalten. Die Verzweigung wird eingeschlagen, wenn die Bedingung TRUE ist.
    • ILOP_COND_def(N) Liste von Instruktionen, die dieses Register definieren.
    • ILOP_COND_live(N) BITSET, der zeigt, welche Register lebendig sind, wenn die Verzweigung nicht eingeschlagen wird.
  • Zusätzlich zu den instruktionsspezifischen ILOP-Makros gibt es eine Anzahl generischer Makros, die bei jeder Instruktion verwendet werden können.
    • ILOP_HasDEST Gibt TRUE (WAHRT) zurück, wenn die Instruktion ein Zielregister aufweist. In diesem Fall können die ILOP_DEST- und ILOP_DEST_use-Makros bei dieser Instruktion verwendet werden.
    • IL_OP_START, IL_OP_DONE, IL_OP_NEXT Werden zur Iteration durch die Quellenregister einer Instruktion verwendet. IL_OP_START führt einen IL_OP_INDEX zurück, der auf das erste derartige Quellenregister bezugnimmt. IL_OP_DONE testet einen IL_OP_INDEX, um zu sehen, ob er auf ein Quellenregister bezugnimmt; true wird zurückgeführt, wenn dies nicht der Fall ist. IL_OP_NEXT wird verwendet, um zum nächsten Quellenregister weiter zu gehen.
    • IL_OP, IL_OP_def Diese führen das bestimmte Quellenregister und die Definitionsliste dafür für einen gegebenen IL_OP_INDEX zurück. Diese 5 Makros werden allgemein in einer Schleife der Form verwendet: for (op=IL_OP_START(n); !IL_OP_DONE(n,op); op=IL_OP_NEXT(n,op)) {use_IL_OP(n, IL_FRAME (compiler/oc_common/include/il_frame.h, compiler/OOCT_Frame.c).
  • Die IL_FRAME-Datenstruktur wird verwendet, um Informationen über den Kontext zu geben, in dem der kompilierte Code laufen wird. Der Rahmen bzw. engl. frame definiert die Größe und Speicherstelle für jedes der Pseudoregister, wie die Pseudoregister andere Pseudoregister überlappen, und welche Maschinenregister im Registerzuordner legal zu verwenden sind. Zusätzlich definiert die IL_FRAME-Struktur, ob ein C-Stapelrahmen für den Code, der kompiliert wird, erforderlich ist oder nicht. Im OOCT werden keine C-Stapelrahmen verwendet.
  • Im Kompilierer 104 wird die IL_FRAME-Struktur durch die Funktionen in OOCT_Frame.c aktualisiert. Diese Funktionen erstellen jedes der Pseudoregister, die den K-Registern und PSW Stellen entsprechen. Ferner werden die temporären Pseudoregister des Kompilierers 104 so gesetzt, daß sie dem Arbeitsraumbereich des Interpretierers 110 entsprechen. Es werden auch Informationen darüber erstellt, wie die K-Register einander überlappen.
  • NL_LIST (compiler/oc_common/[include, src]/nl_nodelist.h
  • An vielen Plätzen verwendet der Kompilierer 104 Listen von IL_NODEs, die NL_LIST-Datenstruktur sieht eine Abstraktion für die Manipulation dieser Knotenlisten vor. Beispielsweise schafft die oben angegebene UseDef-Analyse Listen von IL_NODEs, die eine gegebene Definition verwenden, und Listen von IL_NODEs, welche die Definition für eine gegebene Verwendung sein können. Die NL_LIST-Abstraktion ist geradlinig, sie sieht die Fähigkeit zum Schaffen, Entfernen, Ersetzen, Suchen und Iterieren von Knotenlisten vor.
  • K-OP-CODE FÜR DIE IL-ÜBERSETZUNG
  • Nachdem der oben angegebene Blockwähler 114 gewählt hat, welche K-OP-Codes zu kompilieren sind, involviert die Übersetzung der K-OP-Codes in die IL drei Hauptschritte. Der erste Schritt ist die Bestimmung der Reihenfolge, in welcher der Code für die Basisblöcke generiert wird. Das Blockaufbauverfahren ist vorstehend angegeben. Zweitens, während die Basisblöcke der K-OP-Codes durch das Blockaufbauverfahren gewählt werden, werden die OP-Codes untersucht, um zu bestimmen, ob sie in einen 'logischen OP-Code' kombiniert werden können. Schließlich wird eine IL-Generierungsprozedur auf der Basis des K-OP-Codes und seiner Argumente aufgerufen.
  • Opcode Combination (compiler/ooct_opcode_combine.c)
  • Einige Sequenzen von K-OP-Codes können als einzelner 'logischer' OP-Code beschrieben werden. Beispielsweise wurde bestimmt, daß eine Sequenz von zwei TR-Instruktionen zum Testen des Werts eines 32 Bit-Registerpaares durch das Testen jeder der einzelnen Hälften verwendet wurde. Diese beiden TR-Instruktionen repräsentieren einen logischen 32 Bit-Test-OP-Code, der in der K-Architektur nicht verfügbar ist. Der Code, den die IL-Aufbauprozeduren für die beiden TR-Instruktionen schaffen würden, ist viel weniger effizient als der Code, der geschaffen werden könnte, wenn dieses Muster erkannt werden würde. Da der OOCT-Software ist, ist es glücklicherweise einfach, einen neuen OP-Code hinzuzufügen, eine spezielle Einheit, welche die Muster erkennt, zu haben und statt dessen die effiziente IL zu generieren.
  • Vor der Generierung der Standard-IL für einen gegebenen OP-Code wird die Routine OOCT_opcode_combine aufgerufen. Diese Routine wiederholt alle Muster, die definiert wurden, wobei sie versucht, einen 'logischen' OP-Code zu verwenden, wenn er geeignet ist. Derzeit sind nur zwei Muster definiert, es ist jedoch geradlinig, zusätzliche Kombinationen zu definieren. wenn eines der Muster übereinstimmt, wird die IL-Aufbauprozedur für diesen logischen OP-Code verwendet, um die IL-Instruktionen zu schaffen, und OOCT_opcode_combine führt TRUE zurück, um anzuzeigen, daß die normale IL-Aufbauprozedur nicht aufgerufen werden muß.3
  • IL Building Procedures (compiler/ooct_il_uild.c)
  • Für jeden K-OP-Code gibt es eine spezifische IL-Aufbauprozedur. Die IL-Aufbauprozeduren verwenden zwei Typen von Argumenten, die Adresse der Instruktion, und eine Liste von Argumenten, die sich in den Feldern in der Originalinstruktion befinden. Die IL-Aufbauprozeduren verwenden auch einen gemeinsam genutzten, globalen variablen global_gen_state, der verwendet wird, um die Pseudoregister und Sprungmarken während der Generierung der IL zu verfolgen. Jede der IL-Aufbauprozeduren fügt IL-Instruktionen zur IL_CTXT-Struktur hinzu. Alle der IL-Generierungsroutinen schaffen einen LABEL_IL_NODE mit der Adresse der Originalinstruktion als Identifikator der Sprungmarke (wenn die Sprungmarke nicht das Ziel einer anderen Instruktion ist, wird sie früh im Optimierungsprozeß eliminiert), es wird jedoch nicht allgemein versucht, Optimierungen durchzuführen, was späteren Kompilierer 104-Stufen überlassen wird, es werden aber einige Spezialfälle behandelt, wie das Prüfen auf Ausnahmen, die zur Kompilierungszeit detektiert werden können.
  • Die meisten der IL-Aufbauprozeduren sind geradlinig oder direkt, sobald die IL und die Originalinstruktion des Codes generiert werden, um bekannt oder vertraut zu werden. Es gibt einige Tips, die helfen, den Code zu verstehen:
    Der IL-Aufbau wurde so ausgebildet, daß die Kompilierung irgendeines gegebenen OP-Codes leicht für eine Diagnose abgeschaltet werden kann. Dies wird hauptsächlich mit dem Makro REALLY_COMPILE und den Makros COMPILE_SECTION_XX gesteuert. Wenn REALLY_COMPILE ausgeschaltet ist, bauen alle IL-Aufbauroutinen einfach Aufrufe (oder Sprünge) zurück zum Interpretierer 110 auf. Wenn COMPILE_SECTION_X ausgeschaltet ist, bauen alle IL-Aufbauroutinen für OP-Codes im Abschnitt Nummer X einfach Aufrufe (oder Sprünge) zurück zum Interpretierer 110 auf.
  • Da die IL typisiert ist, ist es kritisch, Pseudoregister mit der korrekten Größe mit dem korrekten Typ zu verwenden. Um beispielsweise einen 16 Bit-wert in ein 32 Bit-Register zu laden, wird zuerst eine 16 Bit-Ladung in ein 16 Bit-Pseudoregister vorgenommen, und dann wird eine CVT-Operation verwendet, um den 16 Bit-Wert in einen 32 Bit-Wert umzuformen (das Makro LOAD_CVT32 tut dies).
  • Wann immer ein Rückruf oder Sprung zum Interpretierer 110 eingefügt wird, muß SYNC hinzugefügt werden, um sicherzustellen, daß der Interpretierer 110 die korrekten werte für die K-Register aufweist. Der kompilierte Code versucht nicht, den Wert des ESI-Registers zu halten, wie es geht (tatsächlich wird er verwendet, um andere Werte zu halten). So muß der generierte Code vor einem Aufruf oder Sprung zum Interpretierer 110 den korrekten Wert in das ESI-Register setzen. Wenn ein Rückruf erfolgt, muß der Code auch eine EXTMOD-Instruktion für jedes Pseudoregister enthalten, das vom Rückruf modifiziert worden sein kann (das Makro MODIFIES_REG tut dies).
  • Ein Code zur Behandlung von Ausnahmebedingungen (wie Überlauf) ist nicht ausgerichtet. Statt dessen wird der Code am Ende der Liste von IL-Instruktionen generiert. Dadurch kann der allgemeine Fall als Fehlschlag kompiliert werden, was typischerweise die Leistung des generierten Codes verbessert.
  • Einsprungpunkte, Unterbrechungsprüfungen
  • Zusätzlich zur IL, die für jeden vom Blockwähler 114 gewählten K-OP-Code generiert wird, wird eine IL für Einsprungpunkte, Unterbrechungsprüfungen generiert.
  • Um zu ermöglichen, daß mehr Optimierungen eintreten, wird jedes Verzweigungsziel nicht als externer Einsprungpunkt eingeschlossen (externe Einsprungpunkte arbeiten als Barriere für Optimierungen). Insbesondere sind die einzigen Ziele, die zu externen Einsprungpunkten gemacht werden sollten, jene, zu denen von außerhalb des Segments gesprungen wird. Wenn ein gegebenes Segment kompiliert wird, sind Teilinformationen darüber im Verzweigungsprotokoll verfügbar, welche Ziele dieses Kriterium erfüllen (für Informationen über das Verzweigungsprotokoll siehe oben). Der Kompilierer 104 verwendet diese Informationen, um zu wählen, welche Basisblöcke externe Einsprünge haben sollten. Für jeden dieser Einsprünge wird eine ENTRY_IL_NODE zusammen mit einer GOTO_IL_NODE generiert, der zur generierten IL für die Originaleinsprunginstruktion springt.
  • Die OOCT-Spezifikationen zeigen an, daß der Kompilierer 104 Unterbrechungsprüfungen innerhalb irgendeiner Schleife einfügen sollte. Wenn die IL generiert wird, wird eine konservative Schätzung gemacht, indem Unterbrechungsprüfungen innerhalb jeder Rückwärts-Verzweigung innerhalb des Segments und vor irgendeiner berechneten Sprunginstruktion eingefügt werden. Die Unterbrechungsprüfung wird nach der Sprungmarke für die letzte Originalinstruktion im Basisblock eingefügt. Wie bei anderen Ausnahmebedingungen wird der IL-Code für die Unterbrechung nicht ausgerichtet generiert, so daß der Normalfall einfach der Fehlschlag der bedingten Verzweigung ist.
  • BESCHREIBUNG DES MITTLEREN ENDES DES KOMPILIERERS
  • ÜBERBLICK ÜBER DAS MITTLERE ENDE
  • Der Hauptzweck des 'mittleren Endes' des Kompilierers 104 ist die Verbesserung der Qualität der IL, so daß ein besserer Code in der Codegenerierungsstufe generiert wird. Der Rest des Kompilierers 104 ist als Serie von Durchläufen strukturiert, die entweder eine Analyse der IL durchführen, oder eine Transformation durchführen, welche die IL modifiziert. Die Durchläufe können mehrfache Male angelegt werden, obwohl es einige Abhängigkeiten zwischen Durchläufen gibt. Ab diesem Punkt hat der Rest des Kompilierers 104 keine besondere Kenntnis von K-Instruktionen, er hat nur mit der IL zu tun.
  • Der Rest dieses Abschnitts ist wie folgt unterteilt. Als erstes wird die Stufe diskutiert, welche die OASSIGN-Einfügung vornimmt. Als zweites werden Analysedurchläufe des Kompilierers 104 diskutiert. Schließlich werden Transformationsdurchläufe (welche die Hauptoptimierungen vornehmen) des Kompilierers 104 diskutiert.
  • 15 veranschaulicht teilweise ein OASSIGN-Einfügungsbeispiel.
  • OASSIGN INSERTION (compiler/ooct_add_overlap_defs.c).
  • Der OASSIGN-OP-Code ist eine spezielle Markerinstruktion, die ein Aliasing zwischen Pseudoregistern explizit macht. Die Notwendigkeit von OASSIGN entsteht im OOCT, da einige K-OP-Codes 16 Bit-Register verwenden, während andere Opera tionen 32 Bit-Register verwenden, welche als Alias der 16 Bit-Register fungieren. Im OOCT werden getrennte Pseudoregister für alle der 16 Bit- und 32 Bit-Register verwendet. So überlappen einander einige der Pseudoregister implizit. Dies schafft zwei Probleme. Das erste Problem betrifft Optimierungsdurchläufe, die inkorrekte Transformationen vornehmen. Für jede Pseudoregisterdefinition verfolgt der Kompilierer 104 die Instruktionen, die diese Definition verwenden, und für jede Pseudoregisterverwendung verfolgt der Kompilierer 104 ihre Definitionen. Diese Informationen werden use/def-Informationen genannt. Der Kompilierer 104 verwendet use/def-Informationen in Durchläufen wie dem Constant Folding-Durchlauf. Wenn Pseudoregister als Alias füreinander fungieren können, erfordert dies die use/def-Berechnung, und der Kompilierer 104 reicht diese "use" dieser Informationen weiter, um viel komplexer zu sein. Ein zweites Problem, das durch überlappende Pseudoregister geschaffen wird, liegt in der Registerzuordnung. Wenn der Registerzuordner gleichzeitig zwei überlappende Pseudoregister Maschinenregistern zuweist, kann eine Modifikation eines Registers erfordern, daß das andere Register ungültig gemacht wird. Allgemein ist die Verfolgung dieser Informationen sehr schwierig und schafft eine unnötige Komplexität.
  • Anstatt diese schwierigen Probleme anzugehen und signifikant zur Komplexität des Kompilierers 104 beizutragen, wurde ein Verfahren zum Einfügen spezieller Marker-OASSIGN-Instruktionen ausgebildet, das es dem Kompilierer 104 ermöglichen würde, das Problem zu ignorieren. Ein spezieller Kompiliererdurchlauf unmittelbar nach der IL-Generierung fügt OASSIGNs ein. Nach diesem Kompilierer 104-Durchlauf wird anderen Analysedurchläufen gestattet anzunehmen, daß Pseudoregister einander nicht überlappen (in bezug auf die use/def-Analyse). Ferner ist die Registerzuordnung unter Verwendung von OASSIGNs ziemlich einfach zu behandeln. Wann immer der Registerzuordner zu einem OASSIGN kommt, leert er die Quelle an ihrer Definition und füllt das Ziel nach dem OASSIGN ein. Dieses Verfahren verwendet den Alias-Speicher, um zu garantieren, daß jede Verwendung der Überlappungsdefinition den korrekten Wert verwendet.
  • Die OASSIGN-Einfügung wird in zwei Stufen behandelt. Zuerst wird eine spezielle Version der UseDef-Analyse laufen gelassen. Diese Version von UseDef kennt Pseudoregisterüberlappungen, und schafft Verwendungslisten und Definitionslisten, die überlappende Pseudoregister enthalten. Der Rest des Kompilierers 104 ist nicht vorbereitet, use/def-Listen zu behandeln, die überlappende Pseudoregister enthalten, daher sollte diese Option für UseDef allgemein nicht verwendet werden. Nachdem diese Analyse vorgenommen wurde, nimmt die Prozedur OOCT_Add_Overlap_Defs die tatsächliche Einfügung von OASSIGNs vor. OASSIGN wird für jede Verwendung eingefügt, die eine Überlappungsdefinition aufweist (d.h. eine Definition, die ein Pseudoregister definiert, welches das Pseudoregister der Verwendung überlappt), und für eine Überlappung erreichende Definitionen an Sprungmarken.
  • 15 veranschaulicht ein Beispiel eines Falls, wo OASSIGN eingefügt werden würde. In dem Beispiel überlappen einander die Pseudoregister GRPAIR1 und GR1, so daß die Zuweisung zu GRPAIR1 in der ersten Zeile des Codes eine implizite Modifikation von GR1 ist. OASSIGN macht dies explizit.
  • ANALYSEDURCHLÄUFE
  • UseDef (compiler/oc_common/src/oc_usedef.c)
  • Die Berechnung der Verwendungen einer gegebenen Definition und der potentiellen Definitionen für eine gegebene Verwendung ist eine der grundlegendsten Kompilierer 104-Analysen. Jeder Kompilierer 104-Optimierungsdurchlauf verwendet die use/def-Informationen. Jede der IL-Instruktionen kann ein Pseudoregisterargument, das (in ein Ziel) eingeschrieben wird, und eines oder mehrere Pseudoregisterargumente, die (aus einem src) ausgelesen werden, aufweisen. Nach der UseDef-Analyse hat jedes Ziel eine damit assoziierte Liste, die Zeiger auf alle IL-Instruktionen speichert, welche diesen Wert verwenden könnten (du chain genannt). Ähnlich hat jedes src eine damit assoziierte Liste, die alle IL-Instruktionen speichert, welche diesen Wert definieren (auch ud chain genannt). Das Verfahren zur Berechnung der use/def-Informationen wird nachstehend beschrieben. Es ist ein iteratives Verfahren, das versucht, einen festgelegten Punkt zu erreichen (d.h. bis weitere Iterationen keine Änderungen mehr durchführen).
  • Die folgenden Schritte wiederholen, bis es zu keiner Änderung der erreichenden Definitionen an irgendeiner Sprungmarke mehr kommt.
  • Die Definitionsliste für jedes Pseudoregister in regdefs (ein Array von NL-LISTs, indexiert von einem Pseudoregister) löschen.
  • Über die IL_NODEs in statischer Programmreihenfolge iterieren.
  • Wenn die Instruktion ein Pseudoregister verwendet, die Definition des Pseudoregisters aus regdefs zur ud chain des Operanden kopieren.
  • Wenn die Instruktion eine Verzweigung ist, die regdefs mit den erreichenden Definitionen kombinieren, die im LABEL der Verzweigung gespeichert sind. Änderungen der erreichenden Definitionen verursachen, daß die gesamte Schleife wiederholt wird.
  • Wenn die Instruktion ein LABEL ist, die regdefs mit den erreichenden Definitionen bereits am LABEL kombinieren.
  • Wenn die Instruktion ein Pseudoregister definiert, die Definitionsliste in regdefs so setzen, daß sie nur diese Instruktion enthält.
  • Wenn die Instruktion eine unbedingte Verzweigung ist, das regdefs Array ändern, damit es der Satz von erreichenden Definitionen ist, die am nächsten LABEL gespeichert sind. Dies wird durchgeführt, da die Instruktionen in ihrer statischen Reihenfolge verarbeitet werden, und die Definitionen, welche die unbedingte Verzweigung erreichen, nicht dieselben sind wie jene, die ihren statischen Nachfolger erreichen.
  • Live Variable Analysis (compiler/oc_common/src/oc_usedef.c)
  • Eine weitere Form der Analyse betrifft lebendige variable Informationen. Die lebendige Variablenanalyse wird hauptsächlich zur Registerzuordnung verwendet, kann jedoch auch zur Induktion variabler Transformationen und zur Totcodeeliminierung verwendet werden. Ein Pseudoregister wird als lebendig an einem bestimmten Punkt in einem Programm angesehen, wenn das Pseudoregister entlang einem Ausführungspfad verwendet werden kann, bevor es neu definiert wird. Die lebendige Variablenanalyse markiert auch die letzte Verwendung eines gegebenen Pseudoregisters (eine Verwendung ist die letzte Verwendung, wenn es keine möglichen Ausführungspfade gibt, auf denen das Pseudoregister verwendet wird, bevor es neu definiert wird). Das zur Berechnung der lebendigen variablen Informationen verwendete Grundverfahren wird nachstehend erläutert. Es arbeitet, indem wiederholte Rückwärtsdurchläufe über den Code durchgeführt werden, bis ein festgelegter Punkt erreicht ist.
  • Die folgenden Schritte wiederholen, bis es zu keiner Änderung mehr der erreichenden Definitionen an irgendeiner Sprungmarke kommt.
  • Lebendig löschen (ein Bitsatz von Pseudoregistern).
  • Über die IL_NODEs in umgekehrter statischer Programmreihenfolge iterieren.
  • Wenn die Instruktion ein Pseudoregister verwendet, das Bit des Pseudoregisters lebendig setzen. Wenn das Pseudoregister vorher nicht lebendig war, als letzte Verwendung markieren.
  • Wenn die Instruktion eine Verzweigung ist, lebendig mit den lebendigen Registern kombinieren, die am LABEL der Verzweigung gespeichert sind. Änderungen an den lebendigen Registern verursachen, daß die gesamte Schleife wiederholt wird.
  • Wenn eine Instruktion ein LABEL ist, lebendig mit den lebendigen Pseudoregistern bereits an der Sprungmarke kombinieren.
  • Wenn die Instruktion ein Pseudoregister definiert, Pseudoregister aus lebendig löschen.
  • Wenn die Instruktion eine unbedingte Verzweigung ist, lebendig löschen. Dies wird durchgeführt, da bei der Verarbeitung der Instruktion in ihrer umgekehrten statischen Reihenfolge die lebendigen Variablen an der unbedingten Verzweigung nicht dieselben sind wie jene an ihrem Nachfolger.
  • Register Allocation (compiler/oc_common/src/oc_regalloc.c)
  • Die Registerzuordnung im Kompilierer 104 wird in zwei Stufen durchgeführt. Die erste Stufe nimmt eine Analyse des Codes vor, und bestimmt einen Satz empfohlener Registerzuweisungen auf der Basis eines Modells höherer Ordnung der Zielmaschine. Die zweite Stufe verwendet die Analyse von der ersten Stufe zusammen mit einem weniger abstrakten Maschinenmodell, um den Code tatsächlich zu modifizieren, physische Register zu verwenden. Dieser Abschnitt diskutiert die erste Stufe.
  • Das Registerzuordnungsverfahren basiert auf der traditionellen Technik der Verwendung der Graphfärbung. Die Knoten des 'Graphen' sind lebendige Pseudoregisterbereiche, mit Kanten zwischen lebendigen Bereichen, die einander überlappen. Eine N-Farbgraphfärbung weist eine von N Farben jedem Knoten zu, so daß keine zwei verbundenen Knoten dieselbe Farbe haben. wenn der Graph lebendiger Bereiche N gefärbt sein kann (wobei N die Anzahl verfügbarer physischer Register ist), wird klarerweise ein Register jedem lebendigen Bereich zugewiesen. Leider ist die Graphfärbung ein ernstes NP-Problem (d.h. es erfordert exponentielle Zeit), daher wird in der Praxis Heuristik verwendet.
  • Die Registerzuordnung ist ein komplexes Verfahren mit mehreren Schritten. Die Schritte werden nachstehend detailliert beschrieben.
  • 1. Teilen unabhängiger lebendiger Bereiche und Zuordnung von REGINFO-Strukturen
  • Die Funktion ComputeRegInfo tut dies. Sie teilt jedes Pseudoregister in unabhängige lebendige Bereiche, und ordnet eine REGINFO-Struktur für jeden zu. Die REGINFO-Struktur wird verwendet, um Informationen über den betreffenden lebendigen Bereich zu halten, der für die Registerzuordnung verwendet wird, und hält schließlich das 'Ziel'register -das physische Register, das für den lebendigen Bereich zugeordnet wird. Da eine 1:1 Entsprechung zwischen lebendigen Pseudoregisterbereichen (ein logisches Konstrukt) und REGINFO-Strukturen besteht, wird der Ausdruck REGINFO oft verwendet, um sich sowohl auf den lebendigen Bereich als auch auf die Datenstruktur zu beziehen.
  • ComputeRegInfo führt das Teilen lebendiger Bereiche nahezu als Nebeneffekt der Zuordnung der REGINFO-Strukturen durch. Die Funktion arbeitet, indem sie mit einer Definition beginnt, die noch keine REGINFO aufweist, eine neue REGINFO dafür schafft, dann rekursiv alle ihre Verwendungen und alle ihre Definitionen (und alle ihre Verwendungen ...) ansieht, und die neue REGINFO mit jeder Definition und Verwendung, die erreichbar ist, assoziiert.
  • Sobald alle REGINFOs geschaffen worden sind, werden sie in 'einfache' und 'komplexe' geteilt. Eine 'einfache' REGINFO:
    Hat exakt eine Definition und eine Verwendung.
  • Die Verwendung folgt unmittelbar der Definition.
  • Die Verwendung ist nicht der 2. Operand einer BINOP (zielspezifischen Voraussetzung).
  • Alle anderen REGINFOs sind komplex. Jede REGINFO erhält eine eindeutige ID, wobei die komplexen im Bereich [0..c->ri_complex] liegen, und die einfachen im Bereich [c->ri_complex..c->ri total] liegen. Der Zweck dieser Teilung ist, Speicher beim Halten der Konfliktmatrix zu sparen, die als BITSETs in jeder REGINFO gespeichert ist. Der Effekt der obigen Definition von 'einfach' ist, daß keine zwei einfachen REGINFOs jemals in einen Konflikt miteinander treten können.
  • 2. Berechnung von Konflikten und Kompatibilitäten
  • Der nächste Schritt ist die Berechnung des Konfliktgraphen der REGINFO-Strukturen. Zwei REGINFOs stehen in einem Konflikt, wenn ihre lebendigen Bereiche überlappen. Zwei REGINFOs sind kompatibel, wenn sie durch Kopieren verbunden werden. In einem Konflikt stehende REGINFOs können nicht demselben Register zugewiesen werden, da sie gleichzeitig lebendig sind. Zwei kompatible REGINFOs sollten demselben Register zugewiesen werden, wenn möglich, da dies eine Kopie eliminiert.
  • Die Konflikte sind entweder als Graph (mit einem Knoten für jede REGINFO und einer ungerichteten Kante, die jeden REGINFO-Knoten mit jedem anderen Knoten verbindet, mit dem er in Konflikt steht -- dies ist die Ansicht, die bei Graphfärbungsverfahren verwendet wird) oder als symmetrische binäre Matrix vorstellbar. Diese letztere Form liegt dem näher, wie die Konflikte tatsächlich gespeichert werden.
  • Jede REGINFO enthält einen einzelnen BITSET, der eine (ein Teil einer) Reihe der Konfliktmatrix ist. Da keine zwei einfachen REGINFOs miteinander in einem Konflikt stehen können, besteht der untere rechte Quadrant der Matrix nur aus Nullen. Da die Matrix symmetrisch ist, ist der obere rechte Quadrant die Transposition des unteren linken. Folglich muß nur die linke Seite der Matrix gespeichert werden. Daher sind die Konflikt-BITSETs nur jeweils c->ri_complex-Bits anstelle von c->ri_total.
  • Zur Bestimmung, ob zwei REGINFOs, A und B, mit den BITSETs in Konflikt stehen, ist es notwendig, zuerst einen Test zu machen, um zu sehen, ob sie einfach oder komplex sind (id mit c->ri_complex vergleichen). Wenn eine der beiden komplex ist, das seiner ID entsprechende Bit im Konflikt-BITSET der anderen REGINFO ansehen. Wenn beide komplex sind, kann jedes Bit angesehen werden; sie müssen gleich sein. Wenn keine komplex ist, stehen sie nicht in einem Konflikt.
  • Konflikte werden aus den Lebendigkeitsinformationen berechnet, die in der IL gespeichert sind (generiert durch ComputeLive). ComputeConflicts führt einen Einzeldurchlauf über den IL-Code durch, wobei der BITSET komplexer REGINFOs, die am aktuellen Punkt lebendig sind, aus den gesetzten Pseudoregistern, die an diesem Punkt lebendig sind, generiert wird. Während jede komplexe REGINFO zum lebendigen Satz hinzugefügt wird, wird sie markiert, daß sie mit jeder REGINFO, die bereits im lebendigen Satz ist, in Konflikt steht. Beim Auffinden jeder einfachen REGINFO wird sie markiert, daß sie mit dem aktuellen lebendigen Satz in Konflikt steht.
  • 3. Sortieren der REGINFOs nach 'Registerpriorität'
  • OC-SortRI setzt Prioritäten unter den REGINFO-Strukturen auf der Basis verschiedenster abstimmbarer Parameter. Die Gewichtsparameter sind zueinander relativ, daher hat eine Multiplikation aller davon mit einer Konstante keinen Effekt.
  • OC_RegAllocConflictWeight:
  • Auf die Graphfärbung des Konfliktgraphen gelegtes Gewicht. Höhere Einstellungen dieses Parameters begünstigen Zuordnungen, die mehr verschiedene REGINFOs in Register geben, ungeachtet davon, wie oft diese REGINFOs tatsächlich verwendet werden. Es ist zu beachten, daß REGINFOs mit weniger Verwendungen auch dazu tendieren, eine kürzere Lebenszeit aufzuweisen, und daher gegenüber REGINFOs mit langer Lebenszeit wahrscheinlich begünstigt werden.
  • OC_RegAllocDefWeight: Auf Definitionen gelegtes Gewicht. Höhere Werte von OC_RegAllocDefWeight begünstigen REGINFOs mit mehr verschiedenen Definitions-IL-Anweisungen.
  • OC_RegAllocUseWeight: Auf Verwendungen gelegtes Gewicht. Sowohl OC_RegAllocDefWeight als auch OC_RegAllocUseWeight tendieren dazu, REGINFOs mit langer Lebenszeit und vielen uses/defs zu begünstigen (obwohl nicht REGINFOs, die lange Zeit nur 'herumhängen', ohne verwendet zu werden).
  • OC_RegAllocResortRate: Dieser Parameter steuert, wie viel er sortiert, um eine gute Färbung zu erhalten. Wenn OC_RegAllocConflictWeight gleich 0 ist, ist dies irrelevant und sollte 0 sein (= = Unendlichkeit). Kleine Zahlen (> 0) bedeuten mehr aufgewendete Zeit und eine besser Färbung.
  • 4. Registerwahl
  • Die REGINFOs in einer Serie von Zwangsbedingungen. Die ersten Zwangsbedingungen sind erforderlich, so wird nach ihrer Anwendung, wenn keine Register übrig sind, die REGINFO nicht einem Register zugewiesen (Ziel = –1). Die übrigen Zwangsbedingungen sind erwünscht, aber nicht erforderlich, so wird, wenn irgendeine gegebene Zwangsbedingung dazu führen würde, daß der Satz möglicher Register leer wird, diese übersprungen. Sobald alle Zwangsbedingungen angewendet wurden, wird das Register mit der niedrigsten Nummer aus dem Satz gewählt und dieses verwendet.
  • TYPE [erforderlich]: muß ein Register wählen, das einen wert dieses Typs halten kann (Info von Maschinenmodell).
  • INUSE [erforderlich]: kann kein Register wählen, das bereits einer REGINFO zugeordnet wurde, welche in einem Konflikt steht (oder irgend etwas, das diese überlappt).
  • BASEREGS [erforderlich]: kann kein Register verwenden, daß der Rahmen als etwas wie frame/stack/base pointer reserviert.
  • CLOBBERED: es wird versucht, kein Register zu verwenden, daß von jemandem während der Lebenszeit der REGINFO zerstört wird.
  • DEF CONSTRAINTS: es wird versucht, ein Register zu verwenden, das die DEST-Zwangsbedingungen vom Maschinenmodell für jede IL erfüllt, die diese REGINFO definiert.
  • USE CONSTRAINTS: es wird versucht, ein Register zu verwenden, das die SRC-Zwangsbedingungen vom Maschinenmodell für jede IL erfüllt, die diese REGINFO definiert.
  • COMPATIBILITY: es wird versucht, ein Register zu verwenden, das mit einer anderen REGINFO in der Kompatibilitätsliste kompatibel ist, dem bereits ein Register zugewiesen wurde.
  • Sobald alle REGINFOs Registern zugewiesen wurden (oder dies fehlgeschlagen ist), wird ein erneuter Durchlauf über die REGINFOs durchgeführt, wobei nach über die Kompatibilitätszwangsbedingung zu ändernden Registern gesucht wird (d.h. kompatible REGINFOs, die nach dieser zugewiesen wurden, und die aus irgendeinem anderen Grund nicht in dasselbe Register gehen konnten).
  • TRANSFORMATIONS-(OPTIMIERUNGS-)DURCHLÄUFE
  • Die Transformationsdurchläufe befinden sich im Kern des optimierenden Kompilierers 104. Jeder Durchlauf macht einen Versucht, einen Teil des Codes neu zu schreiben, so daß die Bedeutung des Codes gleich bleibt, der produzierte Endcode jedoch schneller läuft. Einige der Transformationsdurchläufe verbessern selbst nicht die Qualität des Codes, sondern ermöglichen statt dessen anderen Durchläufen, den Code zu verbessern. So tendieren die Durchläufe dazu, am besten in Kombinationen zu arbeiten, und sind weniger effektiv, wenn sie allein verwendet werden. Daher werden viele Durchläufe wie Dead Code Elimination wiederholt laufen gelassen.
  • Dead Code Elimination (compiler/oc_common/src/oc_usedef.c)
  • Der Totcode-Eliminierungsdurchlauf (OC_ElimDeadCode) entfernt jeden Code, der tot ist, sowohl auf der Basis der Datenfluß- als auch der Steuerflußinformationen. Datenflußinformationen werden verwendet, um IL_NODEs zu eliminieren, die keine Nebeneffekte haben, und deren Ergebnisse ungenutzt sind. Steuerflußinformationen werden zur Entfernung aller IL_NODEs verwendet, die niemals ausgeführt werden (unerreichbarer Code). Ferner wird eine bestimmte neue Verzweigungszielsetzung vorgenommen. Das verwendete Verfahren wird nachstehend beschrieben.
  • Die folgenden Schritte wiederholen, bis keine Änderungen mehr gemacht werden.
    • 1. Über die IL_NODEs in statischer Programmreihenfolge iterieren. a) Wenn die Instruktion unerreichbar ist, diese entfernen. Die Instruktion ist unerreichbar, wenn sie ein LABEL ist, das nicht das Ziel irgendeiner anderen Instruktion ist, oder wenn sie ein GOTO oder CGOTO zur nächsten Instruktion ist, oder wenn die Instruktion direkt nach einer unbedingten Verzweigung steht und kein LABEL ist. b) Wenn die Instruktion keinen Nebeneffekt hat, und sie keine andere Verwendung als sich selbst hat, diese entfernen. c) Wenn eine festgelegte Verzweigungsinstruktion zu einer unbedingten Verzweigung springt, die Instruktion neu zielrichten (z.B. ein GOTO zu einem GOTO). d) Auf eine bedingte Verzweigung zur nächsten Instruktion prüfen, die von einer Verzweigung nach anderswo gefolgt wird (L2). In diesem Fall wird die Bedingung umgekehrt, und die bedingte Verzweigung wird neu auf L2 zielgerichtet.
  • 16 veranschaulicht insbesondere ein Beispiel einer Totcodeeliminierung und Adressenprüfungseliminierung.
  • (compiler/ooct_elim_achk.c)
  • Der Durchlauf zur Adressenprüfungseliminierung verwendet Datenflußanalysetechniken, um unnötige Adressenausrichtungsprüfungen zu eliminieren. Der Code arbeitet mittels der Durchführung einer Wertinferenz über eine Algebra von gerade und ungerade. Mit anderen Worten wird der Code analysiert, um zu bestimmen, ob an irgendeinem gegebenen Punkt ein Pseudoregister einen geraden, ungeraden oder unbekannten Wert enthält. Diese Analyse wird global durchgeführt und arbeitet quer über Verzweigungen. Dies bedeutet, daß sie für Schleifen und durch andere Steuerflüsse arbeitet, und besonders gut arbeitet, wenn eine einfache Aufrollung von Schleifen vorgenommen wird.4 Das verwendete Verfahren wird nachstehend beschrieben. Es ist ein iteratives Verfahren, das versucht, einen konservativen festgelegten Punkt zu erreichen. Werte werden auf drei Hauptwegen abgeleitet. Erstens kann, wenn ein Pseudoregister einer Konstanten zugewiesen wird, der Wert abgeleitet werden. Zweitens kann, wenn ein Pseudoregister das Resultat einer Operation mit bekannten Argumenten ist, der Wert abgeleitet werden. Beispielsweise werden zwei gerade Zahlen addiert, um eine weitere gerade Zahl zu ergeben. Schließlich liefern bedingte Verzweigungen Informationen über den Wert von Pseudoregistern. Wenn beispielsweise ein Pseudoregister auf den geraden Zustand getestet wird, wissen wir, daß es entlang einer Verzweigung gerade ist, und daß es entlang der anderen Verzweigung ungerade ist.
  • Die folgenden Schritte wiederholen, bis es zu keiner Änderung der überlagerten (interferenced) Werte an irgendeiner Sprungmarke mehr kommt.
    • 1. Die Definitionsliste für jedes Pseudoregister in infvals löschen (ein Array von INFVALs, indexiert von einem Pseudoregister).
    • 2. Über die IL_NODEs in statischer Programmreihenfolge iterieren. a) wenn die Instruktion angesichts der aktuell bekannten Inferenzwerte vereinfacht werden kann, die Instruktion durch die einfachere Version ersetzen. Änderungen der Instruktion verursachen, daß die gesamte Schleife wiederholt wird. b) Die infvals auf der Basis der Ausführung der aktuellen Instruktion aktualisieren. i) Wenn die Instruktion bedingt ist, von der ein Wert abgeleitet werden kann, die am Ziel-LABEL und CGOTO gespeicherten Inferenzwerte mit dem geeigneten Inferenzwert aktualisieren. ii) Wenn die Instruktion unbedingt ist und ein Pseudoregister definiert, den Wert dieses Pseudoregisters in infvals aktualisieren. Der wert ist unbekannt, außer die Operation ist ein SET, oder ist ein Spezialfall, wie die Addition von zwei geraden Zahlen. c) Wenn die Instruktion ein LABEL ist, die infvals mit den Inferenzwerten bereits an der Sprungmarke kombinieren. d) Wenn die Instruktion eine Verzweigung ist, die infvals mit den an der Sprungmarke der Verzweigung gespeicherten Inferenzwerten kombinieren. Änderungen der infvals verursachen, daß die gesamte Schleife wiederholt wird. e) Wenn die Instruktion eine bedingte Verzweigung ist, werden alle von dieser Bedingung abgeleiteten Werte mit infvals kombiniert. f) Wenn die Instruktion eine unbedingte Verzweigung ist, das infvals-Array ändern, um die am nächsten LABEL gespeicherten Inferenzwerte zu werden. Dies wird durchgeführt, um die Instruktionen in ihrer statischen Reihenfolge zu verarbeiten, und die abgeleiteten Werte an der unbedingten Verzweigung sind nicht dieselben wie jene an ihrem statischen Nachfolger.
  • 17 veranschaulicht insbesondere ein Beispiel der Adressenprüfungseliminierung. Um die Leistung der Analyse zu verbessern, kann ein Pseudoregister andere Werte annehmen als einfach ODD, EVEN oder UNKNOWN. Ein Pseudoregister kann auch als EQUIVALENT zu einem anderen Pseudoregister oder EQUIVALENT zu einer binären Operation von zwei Pseudoregistern markiert werden. Dies verbessert die Qualität der Analyse, indem ermöglicht wird, daß Informationen über ein Pseudoregister zu anderen Pseudoregistern propagiert werden. Beispielsweise wird angenommen, daß das Pseudoregister R1 und das Pseudoregister R2 für äquivalent befunden werden. Wenn das Verfahren zeigen kann, daß R1 gerade ist (beispielsweise über ein Verzweigungstestergebnis), muß auch R2 gerade sein.
  • Es ist zu beachten, daß das Verfahren ein konservatives ist, die Werte, die abgeleitet werden, müssen monoton ansteigen. Mit anderen Worten, wenn zu irgendeiner Zeit während der Ausführung das Verfahren bestimmt, daß ein Wert an einem Punkt im Programm EVEN ist, muß es der Fall sein, daß der Wert wirklich EVEN ist. Das Verfahren zeigt niemals an, daß ein Pseudoregister während einer Iteration EVEN ist, und daß es während einer anderen Iteration UNKNOWN ist. Aus dieser Eigenschaft kann geradlinig die Beendigung des Verfahrens abgeleitet werden.
  • Hoisting (compiler/oc_common/src/oc_hoist.c)
  • Hoisting, das allgemein als schleifeninvariante Codebewegung bezeichnet wird, ist der Prozeß der Bewegung von Berechnungen, die in bezug auf eine Schleife außerhalb dieser Schleife konstant sind. Dies sieht allgemein eine Beschleunigung vor, da der Code nur ein einziges Mal anstatt von einmal für jede Schleifeniteration ausgeführt wird.
    • 1. IL neu numerieren (d.h. so daß die id-s in einer Reihenfolge sind).
    • 2. Für jede Rückwärtsverzweigung (d.h. eine potentielle Schleife) Dinge auszuhoisten versuchen. a) Wenn es einen weiteren Einsprungpunkt in die Schleife gibt, wird nichts aus dieser Schleife ausgehoistet. b) Über die IL_NODEs innerhalb der Schleife in statischer Reihenfolge iterieren. i) Wenn ein Knoten die folgenden Bedingungen erfüllt, kann er gehoistet werden: (a) Er verwendet oder definiert kein 'echtes Register'. (b) Er verwendet kein innerhalb der Schleife gesetztes Pseudoregister. (c) Er hat keine Nebeneffekte. ii) Für irgendeine OP, die gehoistet werden kann, jedes Pseudoregister, die sie definiert, neu benennen. iii) Den IL_NODE über die Schleife bewegen. iv) Alle IL_NODEs neu numerieren. v) Wenn eine Verzweigung detektiert wird, zum Ziel der Verzweigung überspringen (da nicht bestimmt werden kann, ob die Verzweigung ausgeführt wird, kann der Code nicht gehoistet werden).
  • Der Hoisting-Durchlauf ist für den OOCT nicht immer effektiv. Der Hauptgrund dafür ist, daß viele Schleifen auch Einsprungpunkte sind, so daß sie mehrfache Einsprünge in die Schleife aufweisen und vom Hoisting-Durchlauf nicht berücksichtigt werden. Dieses Problem könnte mittels der Durchführung einer "Sprungmarkenteilung" behoben werden, wobei eine neue Sprungmarke geschaffen wird, die als Ziel für die Schleife verwendet wird. Gehoistete Operationen können dann zwischen die Originalsprungmarke und die neu geschaffene Sprungmarke gehoben werden. Dies wird bald implementiert.
  • Common Subexpression Elimination (CSE) (compiler/oc_common/src/oc.cse.c)
  • Common Subexpression Elimination (CSE) ist eine Technik, die zur Eliminierung redundanter Berechnungen dient. Der Kompilierer 104 verwendet ein globales CSE-Verfahren.
  • Das Grundverfahren wird nachstehend zusammen mit einem Erläuterungsbeispiel in 18 beschrieben.
    • 1. Während der Durchführung von Änderungen für jede IL_NODE, die ein Ziel aufweist (Zeile 1 im Beispiel) folgendes tun: a) Paarweise alle Verwendungen des Ziels prüfen, um zu sehen, ob eine die andere dominiert (A dominiert B, wenn alle Pfade zu B durch A gehen müssen). Für jedes derartige Paar A und B (Zeile 2 und 4) folgendes tun: ii) Prüfen, ob A und B 'übereinstimmen' (gleicher OP-Code und gleiche Quellen), wenn nicht, zum nächsten Paar von Ausdrücken gehen. A und B sind ein 'allgemeiner Teilausdruck'. iii) Ausgehend von A und B auf folgende Weise einen größeren allgemeinen Teilausdruck zu finden versuchen. Wenn A und B Ziele aufweisen, und das Ziel von B eine eindeutige Verwendung C hat (Zeile 5), prüfen, ob das Ziel von A irgendeine Verwendung D hat (Zeile 3), so daß D C dominiert, und D mit C übereinstimmt. Wenn dies der Fall ist, D und C zum allgemeinen Teilausdruck hinzufügen, und einen größeren Teilausdruck mit A=D, B = C zu finden versuchen. (iv) Da nun zwei allgemeine Klammerausdrücke A (Zeilen 2, 3) und B (Zeilen 4, 5) vorliegen, muß der Code neu geschrieben werden, so daß die Verwendungen von B nun statt dessen A verwenden. Wenn das Ziel von A vor der Verwendung durch B geändert werden könnte, wird eine Kopie in ein neues Pseudoregister verwendet.
  • 18 veranschaulicht insbesondere ein Beispiel der Common Subexpression Elimination (CSE).
  • Copy Propagation (compiler/oc_common/src/oc_copyprop.c)
  • Copy Propagation ist eine Transformation, die versucht, Verwendungen des Ziels einer Zuweisung durch die Quelle der Zuweisung zu ersetzen. Während Copy Propagation selbst nicht die Qualität des Codes verbessert, wird häufig ein Code produziert, wo das Ergebnis einer Zuweisung nicht länger verwendet wird, und so kann die Zuweisung eliminiert werden. Das Copy Propagation-Verfahren wird nachstehend beschrieben.
    • 1. Für jede ASSIGN-Operation. a) Wenn die Quelle von ASSIGN eine einzige Definition aufweist, und die einzige Verwendung dieser Definition ASSIGN ist, und das Ziel von ASSIGN zwischen der Definition und ASSIGN weder modifiziert noch verwendet wird, dann die Definition in eine Definition für das Ziel von ASSIGN modifizieren und ASSIGN entfernen. b) Für jede Verwendung des Ziels von ASSIGN testen, ob ASSIGN die einzige Definition dieser Verwendung ist, und testen, ob die ASSIGN-Quelle zwischen ASSIGN und der Verwendung sowohl lebendig als auch gültig ist. wenn beide Tests wahr sind, die Verwendung des Ziels durch eine Verwendung der Quelle ersetzen.
  • 19 veranschaulicht insbesondere ein Beispiel einer Copy Propagation. 20 veranschaulicht insbesondere ein Beispiel einer Constant Folding.
  • Constant Folding (compiler/oc_common/src/oc_cfold.c)
  • Constant Folding ist eine Transformation, die Operationen an konstanten Werten zur Kompilierzeit untersucht. Wenn die IL zwei Konstanten miteinander addiert, ersetzt Constant Folding beispielsweise diese IL-Instruktionen durch eine einzige SET-Instruktion, die das Ziel der Addition der Summe der beiden Konstanten zuweist.
  • Das Verfahren für den Constant Folding-Durchlauf ist sehr geradlinig. Jede IL-Instruktion wird der Reihe nach untersucht. Für jede arithmetische und logische Operation (ADD, SUB, BAND, BOR, etc.) wird, wenn alle ihre Argumente Konstanten sind, die IL-Operation durch eine SET-Operation ersetzt, die das Ziel im Pseudoregister auf den wert der Operation an den konstanten Argumenten setzt.
  • Pattern Matching (compiler/oc_common/src/oc_pattern.c)
  • Der Kompilierer 104 hat auch einen Musterübereinstimmungs- bzw. engl. Pattern Matching-Optimierungsdurchlauf, der bekannte Muster von IL-Instruktionen durch effizientere Versionen ersetzt. Es gibt derzeit keine Muster, die allgemein mit vom OOCT generierten IL-Mustern übereinstimmen, so daß der Pattern Matching-Durchlauf nicht durchgeführt wird.
  • ZIELCODEGENERIERUNG
  • Nachdem die IL generiert wurde, und die Transformationen durchgeführt wurden, um die Qualität des Codes zu verbessern, werden drei Kompilierer 104-Hauptdurchläufe verwendet, um den Code zu generieren. Bis zu diesem Punkt waren die IL und die Transformationsdurchläufe maschinenunabhängig, diese drei Durchläufe sind jedoch stark von der Zielarchitektur abhängig.
  • INSTRUCTION FOLDING (compiler/oc_common/src/ix86_ifold.c)
  • Die OOCT-IL ist eine RISC-ähnliche Architektur, die ohne Modifikation nicht effizient auf die Zielarchitektur abgebildet wird. Insbesondere wäre es suboptimal, eine Zielinstruktion für jede IL-Instruktion zu emittieren. Da die Zielarchitektur eine CISC-Architektur ist, können oft mehrfache IL-Instruktionen zu einer einzigen Zielinstruktion kombiniert werden. Der Instruktionsfaltungs- bzw. engl. Instruction Folding-Durchlauf ist ausgebildet, um dieses Problem zu lösen, indem Gruppen von IL-Instruktionen markiert werden, die zu einer einzigen Zielinstruktion kombiniert werden können.
  • Der Instruction Folding-Durchlauf arbeitet, indem nach einer von einer Anzahl verschiedener vordefinierte Instruktionskombinationen gesucht wird. Die folgenden Kombinationen werden verwendet:
    • • Konstanten werden in verschiedene Operationen gefaltet, wie ADD, SUB, etc.
    • • SETCC-Instruktionen werden in die Instruktion gefaltet, auf deren Basis sie die Bedingungscodes setzen.
    • • DIV-, REM-Paare mit denselben Argumenten werden zusammen gefaltet.
    • • ADD-, SUB- und ASL-Operationen können in eine einzige 'lea'-Operation oder in die Adressenberechnung von LOAD oder STORE gefaltet werden.
    • • 16 Bit BSWAP-, STORE-Kombinationen werden in zwei getrennte 8 Bit-Speicherungen gefaltet.
    • • LOAD-Operationen werden in verschiedene Operationen gefaltet, wenn ihr Ergebnis als zweites Argument verwendet wird.
  • Der Instruction Folding-Durchlauf entscheidet einfach, wenn Instruktionen gefaltet werden sollten, er führt die tatsächliche Faltung nicht aus, die dem Maschinencode-Generierungsdurchlauf überlassen wird. Der Instruction Folding-Durchlauf markiert zu faltende Instruktionen auf zwei Wegen. Erstens kann jeder Operand eines Knotens mit einem "fold"-Bit markiert werden. Zweitens werden Instruktionen, von denen alle Verwendungen in eine andere Instruktion gefaltet sind, mit einer IL_COMBINE-Flagge und mit dem mmFold-Feld markiert, das Informationen über den Weg liefert, auf dem die Instruktion gefaltet wird. Der Registerzuordner und die Maschinencodegenerierung verwenden diese Felder, um korrekt zu arbeiten.
  • Target REGISTER ALLOCATION (compiler/oc_common/src/ix86_regalloc.c)
  • Sobald der Registerzuordner (RegAlloc) Register für alle REGINFOs gewählt hat, die er wählen kann, ist es notwendig, den Code durchzugehen und ihn zu modifizieren, um diese physischen Register anstelle der Pseudoregister zu verwenden. Ferner ist es notwendig, einige zusätzliche Pseudoregister temporär in reale Register zu geben, so daß der Assemblierer den Code für diese Instruktionen generieren kann. Dies wird im allgemeinen das Einfügen eines Leer- und Füllcodes erfordern, um die Werte zu speichern und wiederherzustellen, die der RegAlloc in diese Register plaziert hat. Um dies durchzuführen, verwendet OC_RegUseAlloc einen Zwangszuordner (GetReg) und fügt Leer- und Füllzeichen ein, um Register erneut zu verwenden.
  • OC_RegUseAlloc führt einen einzelnen Durchlauf über den Code durch, wobei der Zustand der physischen Register in einem 'stat'-Array modifiziert und verfolgt wird. Das stat-Array zeichnet auf, was in jedem Register zu einem gegebenen Moment ist (oder sein sollte), und ob der Wert im Register oder die Leerstelle (oder beide) korrekt ist. OC_RegUseAlloc arbeitet als Serie von Stufen, von denen jede spezifische Modifikationen an den aktuell verarbeiteten Instruktionen vornimmt. wenn mehrfache IL-Instruktion durch den Instruction Folding-Durchlauf zusammen gefaltet wurden, werden sie als einzige Instruktion behandelt. Die Stufen sind wie folgt:
    • 1. Wenn die Instruktion irgendein physisches Register direkt verwendet, sicherstellen, daß jegliche Füllzeichen in diesen Registern nach dieser Verwendung auftreten. Die Instruktion modifizieren, um Register zu verwenden, die den Pseudoregistern durch die RegAlloc-Analyse zugeordnet wurden. Alle Register verriegeln, so daß sie nicht erneut verwendet werden.
    • 2. Die Instruktion modifizieren, um Register zu verwenden, die durch GetReg-Aufrufe der vorhergehenden Instruktion temporären zugeordnet wurden. Alle diese Register verriegeln.
    • 3. Die Statusinformationen im stat-Array säubern, um alle Register zu reflektieren, welche die Instruktion zerstört, wobei Leerzeichen nach Bedarf eingefügt werden. Das Zielregister in das Register ändern, das vom RegAlloc zugeordnet wurde, sofern dies geschehen ist (es ist zu beachten, daß es nicht notwendig ist, dieses Register zu verriegeln, da es verwendet werden kann, um ein src zu halten, wenn notwendig).
    • 4. Den Code modifizieren, um Quellen in das Register zu geben, wo dies für die Zielcodegenerierung notwendig ist. Dies involviert einen Aufruf von GetReg für jene Quellenoperanden, die in Registern sein müssen.
    • 5. Alle Register, die verriegelt wurden, freigeben.
    • 6. Ziele festlegen, um reale Register zu verwenden, wo dies für den Zielcode notwendig ist. Dies involviert einen Aufruf von GetReg.
    • 7. Das stat-Array finalisieren, um das Ergebnis dieser Operation zu reflektieren, und alle verwendeten Register festlegen, wobei ihre 'before'-Stellen in die nächste Instruktion gesetzt werden (so daß jegliche Leer/Füllzeichen nach dieser vollendeten Instruktion plaziert werden).
  • Es ist wichtig, daß stat-Array zu verstehen. Es ist ein Array von Datenstrukturen, die von einem physischen Register (alle Register unter MM_NumRegs sind physische Register) indexiert werden, das den Status eines gegebenen physischen Registers anzeigt. Die Struktur enthält die folgenden Felder:
    • 1. ri: Die REGINFO-Struktur, die das Pseudoregister identifiziert, das aktuell mit diesem realen Register assoziiert ist (kann 0 sein, um keine Assoziation anzuzeigen). Dies kann entweder ein Pseudoregister, das diesem Register vom RegAlloc zugeordnet wurde, oder ein von GetReg temporär zugewiesenes sein.
    • 2. alt_ri: Eine REGINFO-Struktur, die ein zusätzliches Pseudoregister identifiziert, das auch in diesem Register ist. Dies wird verwendet, wenn GetReg ein Pseudoregister einem physischen Register zuweist, während der RegAlloc ein anderes hierher (in ri) gegeben hat.
    • 3. flags: Flaggen zum Identifizieren des Zustands des Registers. RegValid wird beispielsweise verwendet, um anzuzeigen, daß der Wert im Register gültig ist. Wenn RegValid nicht gesetzt ist, muß das Register gefüllt werden, bevor es verwendet werden kann. Für eine vollständige Beschreibung der möglichen Flaggen siehe ix86_regalloc.
    • 4. before: Die Instruktion, wo Leer- oder Füllzeichen für dieses Register plaziert werden sollten.
  • MASCHINENCODEGENERIERUNG
  • Der Maschinencode für das Ziel wird in zwei Durchläufen generiert. Der erste Durchlauf wird zur Bestimmung der Größe der Instruktionen verwendet, so daß Verzweigungsdistanzen berechnet werden können. Der zweite Durchlauf nimmt die tatsächliche Codegenerierung vor. Die beiden Durchläufe sind identisch, außer daß der erste den Code in einen Arbeitspuffer generiert, und nicht die korrekten Verzweigungsdistanzen aufweist, so daß nahezu der gesamte Code gemeinsam genutzt wird.
  • Beide Durchläufe bestehen aus einem Einzeldurchlauf durch die IL-Instruktionen der Reihe nach. Für jede Instruktion wird eine durch den OP-Code und Typ indexierte Tabelle verwendet, um eine Funktion zur Generierung des Codes wiederaufzufinden. Diese Codegenerierungsfunktionen verwenden EMIT-Makros, die ein generalisiertes Verfahren zur Generierung von Zielinstruktionen sind, ohne daß die genaueren Details des Ziels bekannt sein müssen (siehe ix86_Asm_Emit.[h,c]). Diese Makros vereinfachen die Assemblierung von Instruktionen, die irgendeinen der Zieladressierungsmodi verwenden.
  • SEGMENTVERWALTUNG
  • Der vom OOCT kompilierte Code wird innerhalb einer SEGMENT-Datenstruktur gespeichert. Es gibt zahlreiche wichtige Themen, die mit der Verwaltung von Segmenten assoziiert sind. Erstens haben Segmente einen speziellen Speicherzuordner, um die Segmentspeicherung zu behandeln. Zweitens wird diskutiert, wie Segmente geschaffen und in das System installiert werden. Drittens wird diskutiert, wie Segmente gelöscht werden (wenn diese Option eingeschaltet ist). Schließlich wird die Segmentverriegelung diskutiert, wenn die Segmentlöschung ein ist.
  • SEGMENT ALLOCATOR (compiler/SegAlloc.[h,c])
  • Die Speicherverwaltung für Segmente im OOCT wird mit einem speziellen Zuordner bearbeitet. Zur Zeit der OOCT-Initialisierung wird der Segmentzuordner bzw. engl. Segment Allocator (SegAlloc) mit einem großen Speicherstück initialisiert. Dann sieht die SegAlloc-Einheit die Fähigkeit vor, ein ungenutztes Speicherstück mit variabler Größe (wie malloc) anzufordern, um ein vorher zugeordnetes Speicherstück frei zu machen (wie free), und eine Statistik über die aktuelle Speicherverwendung anzufordern.
  • Der SegAlloc ist komplexer als der ZONE-Zuordner, da er eine variable Größenzuordnung behandeln muß. Der SegAlloc verwendet ein ziemlich standardmäßiges Zuordnungsverfahren. Der Zuordner hält eine sortierte freie Liste von Stücken und verwendet einen 32 Bit-Anfangsblock für zugeordnete Blöcke, um ihre Größe anzuzeigen. Um ein Speicherstück zuzuordnen, wird die freie Liste nach einem Stück durchsucht, das zur angeforderten Größe paßt. Wenn der Rest des Stücks größer ist als eine Mindestgröße, wird er geteilt, und der Rest wird zur freien Liste hinzugefügt. Um ein Stück frei zu machen, wird es zur freien Liste hinzugefügt. Da die Geschwindigkeit des Freimachens von Speicher kein kritischer Faktor ist, wird die freie Liste nach benachbarten freien Blöcken durchsucht, die zu einem einzelnen freien Block kombiniert werden.
  • SEGMENTSCHAFFUNG UND -INSTALLATION
  • (compiler/ooct_trace.c, compiler/SegMgr.[h,c])
  • Nachdem die Hauptstufen der Kompilierung vollendet sind, ist das Endergebnis ein Speicherblock, der den verschieblichen Zielcode enthält. Der nächste Schritt ist die Schaffung eines Segments für diesen Code, und die Installation dieses Segments in den für Segmente zugeordneten Raum. OOCT_Install nimmt diese Funktion vor. Anfänglich wird Platz für das Segment in der ZONE-Speicherregion zugeordnet. Das Segment wird mit einer Liste der Basisblöcke, die vom Blockwähler 114 gewählt werden (so daß die Segmente später gesucht werden können, um herauszufinden, ob sie eine gegebene Originalinstruktion enthalten), und mit dem generierten Code initialisiert. Ein Aufruf von SEGMGR_Install macht das Segment zu einem kontinuierlichen Speicherblock und kopiert diesen in den Raum, der unter Verwendung der SegAlloc-Einheit für Segmente zugeordnet wurde.
  • Nachdem das Segment geschaffen und in den Segmentzuordnungsraum bewegt wurde, muß die Übersetzungstabelle, die anzeigt, welche Originalinstruktionen für sie kompilierten Code haben, aktualisiert werden. Für jede der Originalinstruktionen, die externe Einträge sind, wird die Übersetzungstabelle mit der korrekten Adresse im für diesen Eintrag generierten Code aktualisiert. Ferner wird die Übersetzungstabelle mit der TRANS_ENTRY_FLAG markiert, um anzuzeigen, daß die K-Instruktion einen gültigen Eintrag hat.
  • SEGMENTLÖSCHUNG (compiler/ooct_trace.c, compiler/SegDel.[h,c])
  • wenn der Kompilierer 104 einen Eintrag in die Übersetzungstabelle schreibt, kann er einen alten überschreiben, der sich bereits darin befand. Kein Interpretierer 110 wird den alten Eintrag lesen und zum alten Segment springen können. Wenn ein Segment keine Einträge in der Übersetzungstabelle aufweist, und es keinen Interpretierer 110 gibt, der das Segment verwendet, kann es gelöscht werden, und sein Speicher kann für ein anderes Segment verwendet werden. Dieser Abschnitt beschreibt, wie der Kompilierer 104 detektiert, daß ein Segment gelöscht werden kann, und dieses dann löscht. Der Kommunikationsabschnitt beschreibt auch detailliert die Segmentverriegelung und die Segmentlöschung.
  • Wenn der Kompilierer 104 einen Einsprungpunkt in der Übersetzungstabelle überschreibt, stellt er den alten Einsprungpunkt auf eine Löschliste. Nach der Installation eines neuen Segments ruft der Kompilierer 104 SEGGEL_TryDeletions auf. Diese Prozedur prüft jeden Eintrag auf der Löschliste. Wenn kein Interpretierer einen Einsprungpunkt verwendet, wird er gelöscht, so daß er später erneut verwendet werden kann.
  • Jedes Segment hat darin einen Einsprungpunktzähler. Wenn ein Einsprungpunkt gelöscht wird, verringert der Kompi lierer 104 den Einsprungpunktzähler um das Segment, das ihn enthält. Wenn der Einsprungpunktzähler eines Segments 0 erreicht, verwendet kein Interpretierer 110 das Segment, und kein neuer Interpretierer 110 kann in dieses springen. Der Kompilierer 104 löscht das Segment und macht seinen Speicher für eine Verwendung durch andere Segmente frei.
  • SEGMENTVERRIEGELUNG
  • Jeder Einsprungpunkt in ein Segment hat einen Zähler, der als Verriegelung für den Einsprungpunkt arbeitet. Der Zähler zeichnet die Anzahl von Interpretierern 101 auf, die den Einsprungpunkt verwenden. wenn der Zähler größer als Null ist, werden der Einsprungpunkt und sein Segment verriegelt, und der Kompilierer 104 löscht diese nicht. Das wichtigste Merkmal der Einsprungpunktverriegelung ist, daß die Instruktionen, die das Segment verriegeln und entriegeln, nicht Teil des Segments selbst sind. Dadurch wird es dem Interpretierer 110 ermöglicht, beliebige Instruktionen im Segment auszuführen, außer es hält die Verriegelung. Die Dokumentation für den Kompilierer 104 und Interpretierer 110 erläutert detailliert den Segmentverriegelungsmechanismus.
  • ANDERE THEMEN
  • Es gibt zahlreiche andere Themen betreffend den Kompilierer 104, die nicht gut in andere Abschnitte passen, jedoch wichtig zu verstehen sind.
  • STACK WARPING (common/ooct_warp.[c,h])
  • Der Kompilierer 104 wird anfänglich einem kleinen Stapel zugeordnet, der nicht dynamisch expandiert. Da der Kompilierer 104 zahlreiche rekursive Prozeduren verwendet, ist leider oft die Größe des Stapels, den er benötigt, größer als die vorgesehene. Bei auf GranPower laufenden Programmen wurden Situationen beobachtet, in denen Seitenfehler vom Kompilierer 104 aufgrund eines Stapelüberlaufs nicht behoben werden konnten. Anstatt zu versuchen, Abschnitte des Kompilierers 104 neu zu schreiben, oder zu bestimmen, wie Seitenfehler aufgrund eines Stapelüberlaufs korrekt zu behandeln sind, wird ein viel größerer Stapel verwendet als jener, der vom OOCT_buffer zugeordnet wurde. Die Größe dieses Stapels wurde so gewählt, daß die Stapelgröße niemals ein einschränkender Faktor sein würde (andere Faktoren, wie die ZONE-Größe, sind eine größere Einschränkung). Um diesen Stapel zu verwenden, wurde eine saubere Schnittstelle ausgebildet, OOCT_Warp_Stack, die es ermöglicht, daß eine Funktion unter Verwendung des großen Stapelraums des OOCT aufgerufen wird. Beim Rücksprung von OOCT_Warp_Stack bleibt der Stapelzeiger unverändert. Wenn in den Kompilierer 104 über ooct_Compile_Seed eingesprungen wird, dem Haupteinsprungpunkt, um einen Startparameter zu kompilieren, wird er daher unter Verwendung von OOCT_Warp_Stack aufgerufen.
  • ASSERTIONEN (common/assert.[c,h])
  • Der Code im Kompilierer 104 hat eine große Anzahl von Assertionsanweisungen. Assertionen werden im gesamten Kompilierer 104 verwendet, um Konsistenzeinschränkungen zu prüfen, und für andere Fehlerzustände. Assertionen spielen zwei wichtige Rollen. In der Diagnoseumgebung verursacht ein Assertionsausfall, daß das Programm anhält, während zur Verfolgung des Problems nützliche Informationen angezeigt oder gespeichert werden. In der Produktionsumgebung werden Asser tionen verwendet, um Fehlerzustände einzufangen, und für einen sicheren Ausgang aus der Kompilierung, wenn diese Zustände auftreten. wenn der Kompilierer 104 beispielsweise über keinen Speicher mehr verfügt, verursacht eine Assertion, daß der Kompilierer 104 die Kompilierung dieses Startparameters abbricht.
  • SERVICEROUTINE (common/service.h)
  • Die Serviceeinheit sieht Dienste vor, welche in Standard-C-Bibliotheken typischerweise vorgesehen werden, wie printf und memset, die vom KOI-Monitor nicht vorgesehen werden. Diese Einheit soll die Notwendigkeit wegabstrahieren, diese Systemaufrufe im Windows- und Firmware-Aufbau anders zu behandeln. Es gibt zwei grundlegende Implementationen dieser Serviceroutinen, eine für das Wintest-Projekt und die andere für den Firmware-Aufbau.
  • VIII. WINDOWS-TESTUMGEBUNG
  • Die Windows-Testumgebung spielt eine wesentliche Rolle bei der raschen Entwicklung und den Tests des OOCT-Systems. Durch die Entwicklung unter Windows werden Standard-Diagnosewerkzeuge unter MSVC vorgesehen. Ferner sind nützliche Werkzeuge wie Profilierer verfügbar. Zu Testzwecken wurden spezielle Testverfahren unter Windows entwickelt, welche die Testgeschwindigkeit und den Testumfang erweitert haben.
  • Zuerst wird die simulierte Granpower-Umgebung beschrieben. Dann wird die Vergleichseinheit diskutiert, welche die meisten der fortgeschrittenen Testtechniken vornimmt. Schließlich werden Codeauszüge des Kompilierers 104 beschrieben.
  • SIMULIERTE GRANPOWER-UMGEBUNG
  • Zur Durchführung der anfänglichen Tests des OOCT sowie der fortgeschritteneren Tests und der Leistungsanalyse war ein Interpretierer notwendig, der unter Windows laufen würde. Der Interpretierer 110 selbst erforderte keine Modifikationen, aber Initialisierungsaufrufe und AOI-Systemaufrufe, die auf dem GranPower-System zur Verfügung stehen, mußten geschrieben werden. Ferner war, damit der OOCT unter Windows läuft, eine Ausbildung notwendig, um mehrfache 'Aufgaben' laufen zu lassen, da der Kompilierer 104 als getrennte Aufgabe vom Interpretierer 110 läuft.
  • INITIALISIERUNG
  • Der erste Teil der Schaffung einer simulierten Umgebung unter Windows war die Schaffung eines Codes zur korrekten Initialisierung von KOI-Datenstrukturen und zur Simulation der KOI-Initialisierungs-API für die OOCT-Aufgabe. Der Interpretierer 110 erwartet, daß eine Anzahl von Datenstrukturen geeignet initialisiert wird, um irgendeinen Code auszuführen. Ferner steuern bestimmte Datenstrukturelemente, ob der OOCT verwendet wird. Indem unser Initialisierungscode auf dem Firmware-Initialisierungsprozeß basiert, Simulation der korrekten Initialisierung, um den Interpretierer 110 laufen zu lassen, und einen Teil seines Grundverhaltens zu steuern. Ähnlich wurde grundsätzlich eingerichtet, daß die KOI-Initialisierungs-API für die OOCT-Aufgabe auf dem von der Firmware verwendeten Code läuft. Dadurch wurde ermöglicht, daß das anfängliche Schreiben und Testen von Schnittstellen zwischen dem Interpretierer 110 (wie Aufrufe von OOCT_Init) unter Standard-Windows-Diagnoseumgebungen arbeitet. Es wurde auch geradlinig, die Schnittstelle zu ändern und zu testen.
  • AOI-SYSTEMAUFRUFE (wintest/MiscStubs.c, wintest/MsgStubs.c)
  • Der Interpretierer 110 erwartet, in einer Umgebung zu laufen, in der alle AOI-Systemaufrufe verfügbar sind. Um eine ausführbare Anweisung auch nur zu kompilieren und zu verbinden, müssen Fragmente für die AOI-Systemaufrufe geschaffen werden. Viele der Systemaufrufe haben keine Signifikanz, wenn das System unter Windows getestet wird, und so werden diese Aufrufe einfach als Leerfunktionen belassen (nur da für Verbindungszwecke). Implementationen der AOI-Systemaufrufe werden zur Zeitsteuerung (ScGtmSet, ScGtmRef) und für messsgAlc, ScMsgSnd, ScMsgRcv verwendet.
  • Der OOCT ist stark von den Systemaufrufen zur Nachrichtenweiterleitung für die Interprozeßkommunikation zwischen den Ausführungen und dem Kompilierer 104 abhängig. Unter Windows wird eine Scheinversion dieser AOI-Systemaufrufe verwendet, um zu ermöglichen, daß Anknüpfungen innerhalb derselben Aufgabe kommunizieren (siehe oben). Die Windows Version der Nachrichtensystemaufrufe implementiert die vollständige Spezifikation der Systemaufrufe unter Verwendung von Verriegelungen und Nachrichtenwarteschlangen.
  • GETRENNTE ANKNÜPFUNGEN (THREADS) FÜR OMPILIERER/AUSFÜHRUNGEN
  • Um die Implementation und Diagnose unter Windows zu vereinfachen, wurden getrennte Anknüpfungen für den Kompilierer 104 und den Interpretierer 110 anstelle von getrennten Prozessen verwendet. Die Verwendung von Anknüpfungen vereinfacht die Nachrichtenweiterleitungsimplementation zwischen den beiden 'Aufgaben'. Ferner wird die Diagnose leichter, da sowohl ein einzelnes Diagnoseprogramm für beide Aufgaben (Interpretierer 110 und Kompilierer 104) verwendet werden kann, als auch das Diagnoseprogramm ausgebildet ist, auf mehrfachen Anknüpfungen zu arbeiten (uns ist kein Diagnoseprogramm bekannt, das Werkzeuge für eine Diagnose mehrfacher Prozesse aufweist).
  • VERGLEICHSEINHEIT
  • Der OOCT verwendet ein einzigartiges Testverfahren, das sich als äußerst wertvoll erwiesen hat. Da der OOCT kompilierte Code Ergebnisse produzieren sollte, die genau gleich sind wie jene des Interpretierers 110, wurde ein Weg geschaffen, diese Ergebnisse direkt zu vergleichen. Unter der Windows Testumgebung wurde eine Fähigkeit eingebaut, sowohl unter dem OOCT als auch dem Interpretierer 110 Programme laufen zu lassen, und automatisch Zwischenergebnisse zu vergleichen. Diese Vergleiche können willkürlich fein abgestuft werden, bis zu Prüfungen nach jeder Instruktion. Zusammen mit der Fähigkeit, das Verhalten von Programmen zu vergleichen, wurde ein automatischer Testgenerator geschrieben. Der Testgenerator schafft einen 'zufälligen' Code, der dann laufen gelassen und verglichen wird. Diese automatische Testgenerierung und dieser Vergleich sehen eine äußerst umfangreiche Programmfolge vor, um zu verifizieren, daß der OOCT korrekt arbeitet. Ferner wurde ein äußerst wertvoller Weg zur Lokalisation auftretender Störungen vorgesehen, da der automatische Vergleich auf den Platz zeigt, wo sich der kompilierte Code und der Interpretierer 110 erstmals unterscheiden.
  • Dieser Abschnitt beschreibt die Vergleichseinheit in zwei Stufen. Zuerst wird die Infrastruktur beschrieben, die zum Vergleichen der Ergebnisse des kompilierten Codes mit jenen des Interpretierers 110 verwendet wird. Als zweites wird die Generierung des Zufallscodes beim Testen beschrieben.
  • VERGLEICHSINFRASTRUKTUR
  • Die Vergleichsinfrastruktur basiert auf der Idee, zwei Versionen desselben K-Programms laufen zu lassen, wo der Maschinenzustand der simulierten K-Maschine (Register und Speicher) zu spezifischen Zeiten gezielt geprüft wird. Die Ergebnisse dieser Prüfpunkte werden dann verglichen, um zu bestimmen, ob die kompilierte Version und interpretierte Version dieselben Ergebnisse liefern.
  • 21 veranschaulicht insbesondere ein Beispiel des obigen Prozesses, der eine Vergleichsinfrastruktur gemäß einer Ausführungsform der vorliegenden Erfindung aufweist. In der Praxis wird der Vergleichstest als zwei Windows-Prozesse laufen gelassen. Der Stammprozeß läuft auf dem vollständigen OOCT-System mit einer Verzweigungsprotokollierung und Kompilierung. Der Nebenprozeß läuft nur als interpretierte Version von KOI. Beide Prozesse schreiben ihre Prüfpunktprotokolle in den Speicher (der Nebenprozeß schreibt in den gemeinsam genutzten Speicher), um ihren Effekt auf den simulierten K-Maschinenzustand aufzuzeichnen. Das Stammverfahren vergleicht die Daten in den Protokollen und berichtet über Diskrepanzen.
  • CODEGENERIERUNG
  • Die Generierung des Zufallscodes für die Vergleichstests wird von drei Einheiten durchgeführt. Zuerst sieht der K-Assemblierer einen Mechanismus zur Produktion des K-Maschinencodes unter Verwendung von C-Funktionsaufrufen vor. Als zweites werden Einheiten zur Schaffung verschiedener Arten von Basisblöcken von K-OP-Codes vorgesehen. Schließlich ermöglicht die Zufallssteuerflußeinheit die Generierung eines Codes mit vielen verschiedenen Steuerflußtypen.
  • K Assembler (wintest/OOCT_Assemble.[h,c])
  • Der K-Assemblierer sieht einen geradlinigen Mechanismus zur Generierung des K-Codes aus dem Inneren eines C-Programms vor. Jeder K-OP-Code hat eine Funktion, die zur Assemblierung von Instruktionen spezifisch für diesen OP-Code verwendet wird. Die individuellen Instruktionen nehmen als Argumente einen Zeiger zum Speicher, wo der Code zu speichern ist, einen (möglicherweise leeren) Sprungmarkennamen, und ein Argument für jedes in der Instruktion verwendete Feld. Die Funktion kombiniert einfach die Felder in ihre korrekten Plätze und schreibt den Code in den Puffer. Da Verzweigungen zu einer Sprungmarke vor der Definition der Sprungmarke eintreten können, wird ein zweiter Durchlauf über den Code verwendet, um das Verzweigungsziel zu lösen.
  • Einheiten zur Schaffung des Zufalls-K-OP-Codes (wintest/GenArith.c, wintest/GenCassist.c, Wintest/GenMisc.C)
  • Zum Testen verschiedener Typen von Instruktionen wurden individuelle Einheiten geschaffen, welche Basisblöcke (geradliniger Code) generieren, die diese Typen von Instruktionen enthalten. Insbesondere werden Einheiten geschaffen, welche die arithmetischen und Verschiebungsoperationen, die C assist-Instruktionen und alle anderen vom OOCT implemen tierten Instruktionen generieren. Die Hauptschnittstelle zu den Einheiten erfolgt durch eine Fi1lBasicBlock-Routine. Diese Routine nimmt als Argumente einen Speicherpuffer und eine Anzahl von Instruktionen, und schreibt die gegebene Anzahl von Instruktionen (zufällig gewählt) in den Puffer. Die FillBasicBlock-Routine wählt zufällig aus einem Array von Instruktionen generierenden Funktionen, um Instruktionen hinzuzufügen. Die Einheiten enthalten eine Instruktionen generierende Funktion für jeden K-OP-Code, der generiert werden kann. Diese Instruktionen generierende Funktion wählt geeignete Zufallswerte für die Argumente an den Assemblierer und assembliert die Instruktionen. Instruktionen werden nicht völlig zufällig generiert. Statt dessen werden sie mit bestimmten Einschränkungen generiert. Wenn beispielsweise ein Register zufällig als Ziel gewählt wird, werden niemals die Basisregister verwendet. Der Code ist auch auf die Verwendung einer Anzahl vordefinierter Speicherstellen beschränkt. In unseren Tests haben sich diese Beschränkungen nicht als sehr signifikant erwiesen. Wenn sie sich in der Zukunft als signifikant erweisen, ist es möglich, einige der Einschränkungen unter Verwendung eines komplexeren Prozesses zu reduzieren.
  • Die Verwendung von Zufallstests ist wichtig, da Testinteraktionen zwischen vielen verschiedenen Instruktionen getestet werden, was für einen Kompilierer 104 wie den OOCT besonders wichtig ist. Im OOCT kann sich der durch das Kompilieren einer Instruktion produzierte Code in Abhängigkeit von umgebenden Instruktionen wesentlich unterscheiden.
  • 22 veranschaulicht insbesondere ein Beispiel der Codegenerierung für dieselbe Instruktion mit verschiedenen umgebenden Instruktionen. Ferner testen Zufallstest viele Fälle, die Programmierer nicht testen würden.
  • Die Einheiten zur Schaffung von Zufalls-K-OP-Codes sind an sich für bestimmte Testtypen effektiv. Bei der Implementation eines neuen OP-Codes hat es sich beispielsweise als sehr effektives Verfahren erwiesen, eine einfache Schleife zu schaffen, die einen Basisblock von Instruktionen unter Verwendung dieses OP-Codes ausführt. Während die individuellen Einheiten effektiv sein können, ist zum vollständigen Testen bestimmter Aspekte des Kompilierers 104 ein komplexerer Steuerfluß erforderlich.
  • Die Einheit zur Schaffung eines Zufallssteuerflusses (wintest/Gdom control flow creation unit (GenControl)) wird zur Schaffung von Tests verwendet, die komplexere Typen von Steuerflüssen verwenden als geradlinige Codes. GenControl startet mit einem einzelnen Basisblock und führt eine bestimmte Anzahl von Transformationen durch (zufällig gewählt). Die Transformationen, die derzeit durchgeführt werden, sind wie folgt:
    Ein Basisblock kann in zwei Basisblöcke geteilt werden.
    Ein Basisblock kann durch ein Rhombuszeichen ersetzt werden. Dies repräsentiert eine bedingte Verzweigung, wo sich die zwei Pfade wieder miteinander verbinden.
    Ein Basisblock kann durch eine Schleife ersetzt werden.
    Ein Basisblock kann durch drei Basisblöcke ersetzt werden, wobei ein Funktionsaufruf an den zweiten Basisblock erfolgt und zum dritten zurückspringt.
  • Nachdem die spezifizierte Anzahl von Transformationen an den Basisblöcken durchgeführt wurde, existiert ein zufällig generierter Steuerflußgraph, der mit Instruktionen gefüllt werden muß. Dies besteht aus zwei Teilen. Zur Generierung des Codes für die Basisblöcke selbst werden die Einheiten zur Schaffung eines Zufalls-K-OP-Codes verwendet, die im vorhergehenden Abschnitt diskutiert wurden. Der zweite Teil ist, Instruktionen zur Durchführung der Verzweigungen und Schleifen einzufüllen. Schleifen verwenden eine vordefinierte Schablone, die eine Anzahl von Malen iteriert. Für bedingte Verzweigungen wird eine Zufallstestinstruktion verwendet.
  • KOMPILIERERCODEAUSZÜGE
  • Für Diagnosezwecke und für Optimierungszwecke werden zahlreiche Codeauszugsmechanismen im OOCT unter Windows verwendet. Es gibt zwei Hauptauszugsmechanismen. Erstens kann während der Kompilierung ein Auszug einer Codeliste vorgenommen werden, welche die K-OP-Codes enthält, die kompiliert werden, die IL, und (wenn er generiert wurde) den Zielcode. Der zweite Typ eines Auszugs ist ein Auszug des Zielcodes in eine Assemblierungsform, die für Testzwecke rückkompiliert und gegenverbunden werden kann.
  • Durch das Vornehmen eines Auszugs einer Kopie des IL-Codes nach bestimmten Stufen kann der Effekt eines gegebenen Kompilierer 104-Optimierungsdurchlaufs auf Korrektheit und Effektivität untersucht werden. Ferner kann durch die Untersuchung des produzierten Endcodes manuell untersucht werden, wie gut der Kompilierer 104 jeden K-OP-Code in die IL übersetzt, und die Qualität des für jede IL-Instruktion und jeden K-OP-Code produzierten Zielcodes. Diese Code-Auszüge werden unter Verwendung des COMBDUMP-Makros gesteuert, das zwischen Kompilierer 104-Durchläufen in OOCT_Optimize_IL_And_Gen_Code eingefügt wird (siehe compiler/ooct_trace.c). Dieses Makro ruft die OOCT_Combdump-Prozedur auf (siehe ooct_combdump.c), die über die K-OP-Codes und die IL-Instruktionen iteriert.
  • Aktuelle Profilierungswerkzeuge für Windows behandeln dynamisch generierte Codes nicht korrekt. Daher wird der zweite Typ eines Auszugs verwendet, so daß der dynamische Code von einem Lauf als statischer Code für einen anderen Lauf verwendet und korrekt profiliert werden kann. Dies wird in zwei Schritten erreicht. Im ersten Schritt wird das Programm mit der OC_DUMP-Flagge kompiliert (siehe compiler/ooct_dump.h), was bewirkt, daß jede K-OP-Code-Spur, die kompiliert ist, aufgezeichnet wird, und daß ein Auszug des Codes in eine Datei in einem rückkompilierbaren Format vorgenommen wird. Zweitens wird das Programm kompiliert und mit der OC_USEDUMP-Flagge laufen gelassen (siehe compiler/ooct_dump.h), welche die dynamische Kompilierung für den vorher kompilierten Code anstelle der Verwendung der statischen Version ausschaltet. Diese Version des Programms kann dann mit einem Profilierer laufen gelassen werden, um eine Statistik über die Qualität des Codes aufzuzeichnen.
  • ZWEITE AUSFÜHRUNGSFORM DER VORLIEGENDEN ERFINDUNG
  • DYNAMISCHE OPTIMIERENDE OBJEKTCODE-ÜBERSETZUNG
  • KURZFASSUNG DER ZWEITEN AUSFÜHRUNGSFORM
  • Eine Architekturemulation ist die Imitation einer Computerarchitektur durch eine andere Computerarchitektur, so daß der Maschinencode für die Originalarchitektur ohne Modifikation laufen gelassen werden kann. Eine Objektcode-Übersetzung ist der Prozeß der Übersetzung eines Maschinencodes für eine Computerarchitektur in den Maschinencode für eine andere Computerarchitektur. Das beschriebene dynamische optimierende Objektcode-Übersetzungssystem verwendet Kompiliereroptimierungstechniken, um eine höhere Leistung zu erzielen als eine auf einer Schablone basierende Objektcode-Übersetzung für eine Architekturemulation.
  • BESCHREIBUNG VON FIGUREN DER ZWEITEN AUSFÜHRUNGSFORM
  • 23 veranschaulicht eine Systemkonfiguration, die für die dynamische optimierende Objektcode-Übersetzung gemäß der zweiten Ausführungsform der vorliegenden Erfindung verwendet wird. 23 ist eine schematische Darstellung einer dynamischen Übersetzung gleichzeitig mit der interpretierten Ausführung von Programmen. Jeder Interpretierer kann Übersetzungsanforderungen an den Kompilierer senden. Der Kompilierer macht dann einen übersetzten Code für die Interpretiereraufgaben verfügbar. Auf einer Maschine mit mehrfachen Ausführungseinheiten können alle Prozesse gleichzeitig ausführen.
  • DETAILLIERTE BESCHREIBUNG DER ZWEITEN AUSFÜHRUNGSFORM
  • Das dynamische optimierende Objektcode-Übersetzungssystem nimmt eine dynamische Kompilierung eines Instruktionssatzes in einen anderen vor, um eine Leistungsverbesserung gegenüber einer auf einer Schablone basierenden Übersetzung oder interpretierten Emulation vorzusehen. Das dynamische optimierende Objektcode-Übersetzungssystem kombiniert eine beliebige Anzahl von Interpretierern, die eine Profilierung des laufenden Codes vornehmen, mit einem getrennten optimierenden Kompilierer. Der optimierende Kompilierer verwendet die Profilierungsinformationen aus dem laufenden Code, um häufig ausgeführte Teile des Codes zu bestimmen. Diese Teile werden dann kompiliert und den Interpretierern zur Verwendung geliefert. Die Gesamtstruktur des Systems ist in 23 gezeigt.
  • Die Durchführung bedeutender Optimierungen vom Kompilierer-Typ ist nur mit der Kenntnis des Instruktionsflußgraphen möglich. In einem traditionellen Kompilierer ist der Flußgraph gegeben und gut definiert, da die gesamte Routine einer vollständigen Sprachanalyse unterzogen wird, bevor die Optimierung beginnt. Für ein Architekturemulationssystem ist der zu kompilierende Code nicht verfügbar, bevor er tatsächlich laufen gelassen wird. Ferner können Instruktionen und Daten allgemein nicht differenziert werden, ohne daß tatsächlich ein Programm laufen gelassen wird.
  • Daher muß zur Bestimmung des Flußgraphen das Programm laufen gelassen werden. Ein Interpretierer wird verwendet, um das Programm das erste Mal laufen zu lassen. Während der Interpretierer das Programm ausführt, informiert er den dynamischen Kompilierer jedesmal, wenn er eine Verzweigungs operation durchführt. Diese Informationsprotokollierung identifiziert einige der Instruktionen und einige der Verbindungspunkte. Während das Programm läuft, werden die Informationen über den Flußgraphen vollständiger, obwohl sie nie ganz vollständig werden. Das System ist ausgebildet, mit Teilinformationen über den Flußgraphen zu arbeiten: die Optimierung wird an potentiell unvollständigen Flußgraphen durchgeführt, und das System ist ausgebildet zu gestatten, daß ein optimierter Code ersetzt wird, während mehr Informationen verfügbar werden.
  • Die dynamische Kompilierung wählt, welche Teile des Texts zu optimieren sind, auf der Basis der vom Interpretierer gesammelten Profilierungsinformationen. Wenn die Anzahl von Malen, die irgendeine Verzweigung ausgeführt wird, eine Schwelle überschreitet, wird das Ziel dieser Verzweigung ein Startparameter zur Kompilierung. Der Startparameter ist ein Startpunkt für eine Sprachanalyse eines Teil der als Einheit zu kompilierenden Quelleninstruktionen. Diese Einheit wird als Segment bezeichnet.
  • Ein Segment enthält die Instruktionen, die aus der Optimierung der Quelleninstruktionen aus dem Startparameter resultieren. Es wird als Einheit installiert und deinstalliert. Wenn der Interpretierer den Kompilierer aufruft, um ihn über eine Verzweigung zu informieren, kann er wählen, die Steuerung in das Segment zu transferieren, wenn der Code für das Ziel existiert. Ähnlich kann das Segment einen Code für den Transfer der Steuerung zurück zum Interpretierer enthalten.
  • Ein Segment kann unvollständig sein, wobei es nur einen Subsatz der möglichen Flußpfade aus dem Quellenprogramm repräsentiert. Diese unvollständige Repräsentation beeinflußt jedoch nicht den korrekten Betrieb der Emulation. Wenn ein neuer, unvorhergesehener Flußpfad durch den Originalcode entsteht, dann springt der Steuerfluß zum Interpretierer zurück. Später kann dasselbe Segment ersetzt werden, um den neuen Steuerfluß zu berücksichtigen.
  • BESONDERE OBJEKTE DER ZWEITEN AUSFÜHRUNGSFORM
  • Die Erfindung ist die Verwendung der optimierten Objektcode-Übersetzung für eine verbesserte Leistung in Architekturemulationssystemen.
  • ZUSAMMENFASSUNG DER ZWEITEN AUSFÜHRUNGSFORM
  • Das beschriebene dynamische optimierende Objektcode-Übersetzungssystem verwendet Kompiliereroptimierungstechniken, um eine höhere Leistung zu erzielen als eine auf einer Schablone basierende Objektcode-Übersetzung für eine Architekturemulation. Die Erfindung ist die Verwendung der optimierten Objektcode-Übersetzung für eine verbesserte Leistung in Architekturemulationssystemen.
  • DRITTE AUSFÜHRUNGSFORM
  • GLEICHZEITIGE DYNAMISCHE ÜBERSETZUNG
  • KURZFASSUNG DER DRITTEN AUSFÜHRUNGSFORM
  • Die dynamische Übersetzung ist ein Akt der Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache, während das Programm läuft. Das be schriebene gleichzeitige dynamische Übersetzungssystem führt eine Übersetzung gleichzeitig mit interpretierter Programmausführung durch.
  • BESCHREIBUNG VON FIGUREN DER DRITTEN AUSFÜHRUNGSFORM
  • 24 veranschaulicht eine Systemkonfiguration, die für die gleichzeitige dynamische Übersetzung gemäß der dritten Ausführungsform der vorliegenden Erfindung verwendet wird. 24 ist eine schematische Darstellung einer dynamischen Übersetzung gleichzeitig mit interpretierter Ausführung von Programmen. Jede Interpretiereraufgabe kann Übersetzungsanforderungen an die Kompiliereraufgabe senden. Die Kompiliereraufgabe macht dann den übersetzten Code für die Interpretiereraufgaben verfügbar. Auf einer Maschine mit mehrfachen Ausführungseinheiten können alle Prozesse gleichzeitig ausgeführt werden.
  • 25 veranschaulicht den Unterschied zwischen der Kombination eines Interpretierers und Kompilierers, beispielsweise während der Ausführung als eine Aufgabe, und ihrer Trennung, beispielsweise in verschiedene Aufgaben, gemäß einer vierten Ausführungsform der vorliegenden Erfindung. 25 ist eine schematische Latenzdarstellung mit kombinierten und getrennten Interpretierer- und Kompiliereraufgaben.
  • DETAILLIERTE BESCHREIBUNG DER DRITTEN AUSFÜHRUNGSFORM
  • Der Zweck der gleichzeitigen dynamischen Übersetzung ist, eine Leistungssteigerung gegenüber einem Interpretierer durch das Kompilieren eines Ausführungsprogramms in eine effizientere Form, während der Interpretierer noch läuft, vorzusehen. Zur Durchführung der dynamischen Übersetzung gleichzeitig mit der Ausführung eines Interpretierers läuft der Kompilierer als getrennte Aufgabe auf einem System mit mehrfachen Ausführungseinheiten. Die Kompiliereraufgabe ist ein Server, der Anforderungen zur Übersetzung einiger Instruktionen empfängt, und mit einem Stück übersetzten Code antwortet. Die Anordnung des Kompiliererservers als getrennte Aufgabe hat einige Vorteile. Erstens kann mehr als eine Interpretiereraufgabe an denselben Server Anforderungen stellen. Zweitens müssen die Interpretiereraufgaben nicht auf das Ergebnis einer Kompilierungsanforderung warten, bevor sie weitergehen. Drittens sind die Interpretierer und der Kompilierer gegen Fehler in anderen Aufgaben isoliert. Viertens können die Interpretierer und der Kompilierer unabhängig terminisiert werden, so daß die Arbeit gleichmäßiger über die Anzahl verfügbarer Prozessoren aufgeteilt wird. Jeder dieser Vorteile wird nachstehend detaillierter beschrieben.
  • Es gibt einige existierende dynamische Übersetzungssysteme, die keine getrennten Kompiliereraufgaben haben. Die virtuelle Java-Maschine von Sun Microsystems ist ein Beispiel [2]. Der Interpretierer in der virtuellen Maschine kann eine dynamische Übersetzungsanforderung ausgeben, indem er eine Prozedur aufruft. Der Interpretierer muß auf die Vollendung der Übersetzungsanforderung warten, bevor er die Ausführung des Programms fortsetzt. Ein weiteres Beispiel ist das dynamische OCT-Übersetzungssystem von Fujitsu, das eine Seite von Instruktionen zu einer Zeit übersetzt [1]. Im OCT-Übersetzungssystem muß der Interpretierer auf die vollendung der Übersetzungsanforderung warten, bevor er die Ausführung fortsetzt.
  • Es sind auch Übersetzungsserver für die statische Übersetzung des Java-Quellencodes in den Java-Bytecode verfügbar [3]. Diese Server bieten die Vorteile einer getrennten Kompiliereraufgabe zur statischen Übersetzung, jedoch nicht zur dynamischen Übersetzung, da sie nicht operieren, während das Java-Programm läuft.
  • Der erste Vorteil der Anordnung der getrennten Kompiliereraufgabe ist, daß mehrfache Interpretiereraufgaben Übersetzungsanforderungen an denselben Server stellen können. Sie müssen den Kompilierercode nicht in ihrem ausführbaren Bild enthalten, wodurch es viel kleiner wird. Sie haben keine Cache-Konflikte zwischen Interpretiererinstruktionen und Kompiliererinstruktionen oder zwischen Interpretiererdaten und Kompiliererdaten. Da auf nahezu allen modernen Prozessoren eine effiziente Cache-Nutzung wichtig ist, stellt dies einen signifikanten Vorteil dar.
  • Der zweite Vorteil einer getrennten Kompiliereraufgabe ist, daß die Interpretierer die Latenz des Kompilierers nicht sehen. 25 veranschaulicht die Differenz der Latenz. Mit der kombinierten Interpretierer- und Kompiliereraufgabe führt der Interpretierer keine Instruktionen aus, bis der Kompilierer die Übersetzung der Instruktionen beendet hat. Mit den getrennten Aufgaben nimmt der Interpretierer sofort die Ausführung von Instruktionen wieder auf, während der Kompilierer arbeitet. Die gesamte von den getrennten Aufgaben verrichtete Arbeit ist größer, da sie Übersetzungsanforderungen senden und empfangen müssen, die geringere Latenz bedeutet jedoch, daß Benutzer des Systems keine Pausen einhalten, während der Kompilierer arbeitet. Die Interpretiereraufgabe kann auch auf externe Ereignisse, wie Unterbrechungen, reagieren, während der Kompilierer ar beitet, was in der Anordnung der kombinierten Aufgaben nicht möglich sein kann. In der Praxis setzt die Tatsache, daß der Interpretierer die Latenz des Kompilierers in der kombinierten Anordnung sieht, eine Grenze für die Komplexität des Kompilierers und die Qualität des übersetzten Codes. Beispielsweise sollten Java Just-In-Time-Kompilierer schnell genug ausführen, so daß ein mit dem Java-System interagierender Benutzer keine Pause sieht, was einige komplexe Optimierungen ausschließt. Ähnlich führt das OCT-System nur eine Optimierung innerhalb einer einzigen übersetzten Instruktion durch, um die Kompilierungszeit zu reduzieren. Die Anordnung der getrennten Kompiliereraufgabe ermöglicht eine Optimierung quer über mehrfache Instruktionen.
  • Der dritte Vorteil der getrennten Kompiliereraufgabe ist, daß Fehler in den Interpretiereraufgaben und der Kompiliereraufgabe voneinander isoliert werden. Dies bedeutet, daß, wenn die Kompiliereraufgabe eine Adressenausnahme oder Ausnahmebedingung erhält, die Interpretiereraufgabe nicht beeinträchtigt wird. Der Kompilierer setzt sich selbst nach einem Fehler zurück und setzt die Arbeit an der nächsten Anforderung fort. Da die Interpretiereraufgaben nicht warten, bis der Kompilierer eine Übersetzungsanforderung beendet hat, merken sie nicht, wenn der Kompilierer einen Fehler erhält.
  • Der vierte Vorteil der getrennten Kompiliereraufgabe ist, daß sie die Belastung der Kompilierer- und Interpretiereraufgaben ausgleichen kann. Im dynamischen Übersetzungssystem gibt es Zeiten, wenn die Interpretiereraufgaben stark belegt sind und alle CPUs des Computers benötigen, und es gibt Zeiten, wenn die Interpretiereraufgaben untätig sind und die CPUs nicht genutzt werden. In der kombinierten In terpretierer- und Kompiliereranordnung wird die meiste Kompilierungsarbeit verrichtet, wenn die Interpretierer belegt sind, da der Kompilierer nur aufgerufen wird, wenn der Interpretierer läuft. Dies nützt die untätigen CPU-Zyklen nicht aus. In der Anordnung der getrennten Kompiliereraufgabe setzt der Kompilierer die Arbeit fort, wenn die Interpretierer untätig sind. Sie produziert einen übersetzten Code, den die Interpretierer wahrscheinlich in der Zukunft verwenden werden.
  • BESONDERE OBJEKTE DER DRITTEN AUSFÜHRUNGSFORM
  • Die dritte Ausführungsform der vorliegenden Erfindung ist auf die Verwendung einer dynamischen Übersetzung gleichzeitig mit mehrfachen Interpretierern, die auf einem System ausführen, mit mehrfachen physischen Ausführungseinheiten gerichtet, wobei eine kleinere ausführbare Bildgröße, eine reduzierte Cache-Konkurrenz, eine geringere Interpretiererausführungslatenz, eine Fehlerisolierung und ein besserer Belastungsausgleich vorgesehen werden.
  • ZUSAMMENFASSUNG DER DRITTEN AUSFÜHRUNGSFORM
  • Das beschriebene dynamische Übersetzungssystem führt eine Übersetzung gleichzeitig mit interpretierter Programmausführung durch. Das System verwendet einen getrennten Kompilierer, so daß er die Leistung der Interpretiereraufgaben nicht signifikant beeinträchtigt. Die Erfindung ist die Verwendung einer dynamischen Übersetzung gleichzeitig mit mehrfachen Interpretierern, die auf einem System ausführen, mit mehrfachen physischen Ausführungseinheiten, wobei eine kleinere ausführbare Bildgröße, eine reduzierte Cache-Konkurrenz, eine geringere Interpretiererausführungslatenz, eine Fehlerisolierung und ein besserer Belastungsausgleich vorgesehen werden.
  • VIERTE AUSFÜHRUNGSFORM DER VORLIEGENDEN ERFINDUNG
  • EMULATION WÄHREND DER DYNAMISCHEN ÜBERSETZUNG, UM DIE BELASTUNG DER PROFILIERUNG AUF DEN EMULATOR ZU REDUZIEREN
  • KURZFASSUNG DER VIERTEN AUSFÜHRUNGSFORM
  • Eine Architekturemulation ist die exakte Imitation einer Computerarchitektur durch eine andere Computerarchitektur, so daß der Maschinencode für die Originalarchitektur ohne Modifikation laufen gelassen werden kann. Eine Objektcode-Übersetzung ist der Prozeß der Übersetzung eines Maschinencodes für eine Computerarchitektur in den Maschinencode für eine andere Computerarchitektur. Das beschriebene dynamische optimierende Objektcode-Übersetzungssystem verwendet Kompiliereroptimierungstechniken, um eine höhere Leistung zu erzielen als eine auf einer Schablone basierende Objektcode-Übersetzung für eine Architekturemulation. Es ist jedoch eine Profilierung erforderlich, um die dynamische optimierende Objektcode-Übersetzung zu realisieren. Die Beschreibung erläutert ein Verfahren zur Reduktion der Belastung der Profilierung.
  • BESCHREIBUNG VON FIGUREN DER VIERTEN AUSFÜHRUNGSFORM
  • 26 veranschaulicht eine Übersetzungstabelle, die verwendet wird, um aufzuzeichnen, welche Instruktionen übersetzbar sind und welche nicht, gemäß einer vierten Ausführungsform der vorliegenden Erfindung. 26 ist eine Über setzungstabelle, die zeigt, welche Programme übersetzbar sind und welche nicht. In diesem Fall werden Programme in Einheiten von I Bytes gemessen. Der Emulator prüft, welchem Eintrag ein Verzweigungsnachfolger entspricht, wodurch bestimmt wird, ob er zu einem übersetzbaren Programm springt oder nicht.
  • 27 veranschaulicht, wie das Verfahren die Belastung der Profilierung auf den Emulator gemäß einer vierten Ausführungsform der vorliegenden Erfindung reduziert. 27 ist ein Flußdiagramm, das zeigt, wie der Emulator die Protokollierung für übersetzbare Programme einschaltet, und wie er sie für nicht-übersetzbare Programme ausschaltet. Die Trigger *1- und Trigger *2-Instruktionen sollten beide protokolliert werden, die Trigger *1-Instruktion kann jedoch nicht zwischen einem übersetzbaren Programm und einem nichtübersetzbaren Programm springen. Nur die Trigger *2-Instruktion kann zwischen ihnen springen. Die Protokollflagge, die sich merkt, ob der Emulator in einem übersetzbaren oder nicht-übersetzbaren läuft. Daher muß der Emulator bei Trigger *1-Instruktionen nicht die Übersetzungstabelle prüfen oder die Protokollflagge ändern. Er prüft nur, ob die Verzweigungsnachfolgerinstruktion bereits kompiliert wurde, und springt sofort zum kompilierten Code. Da Trigger *1-Instruktionen die am häufigsten verwendeten Trigger-Instruktionen repräsentieren, kann dieser Algorithmus die Belastung der Profilierung auf die Emulation reduzieren.
  • DETAILLIERTE BESCHREIBUNG DER VIERTEN AUSFÜHRUNGSFORM
  • Die dynamische optimierende Objektcode-Übersetzung realisiert eine hohe Leistung durch die Produktion schnellerer Instruktionen, sie führt jedoch zu Kosten hinsichtlich Speicher und Zeit. Daher werden in einer Architekturemulation sowohl die dynamische optimierende Objektcode-Übersetzung als auch die Emulation gemeinsam verwendet. Die Übersetzung wird für das Hauptprogramm verwendet, das häufig läuft und eine hohe Leistung benötigt. Und der Emulator arbeitet für kleinere Programme und auch zur Profilierung des Hauptprogramms, bis der Übersetzer die Kompilierung vollendet. Ein Profil wird vom Übersetzer verwendet, um das Programm zu kompilieren und zu optimieren.
  • Instruktionen, die von einem nicht-übersetzten Code zu einem übersetzten Code springen können, werden als Triggerinstruktionen bezeichnet. Wenn eine Triggerinstruktion von einem Nebenprogramm zu einem Hauptprogramm oder von einem Hauptprogramm zu einem Nebenprogramm springen kann, wird sie Trigger *2-Instruktion genannt. Wenn sie nur innerhalb eines Nebenprogramms oder eines Hauptprogramms springen kann, wird sie Trigger *1-Instruktion genannt. Da der Übersetzer nicht auf den Nebenprogrammen arbeitet, ist es nicht notwendig, die Trigger *1-Instruktionen in einem Nebenprogramm zu profilieren. Es ist notwendig, Trigger *1-Instruktionen in einem Hauptprogramm zu profilieren, da ein Teil des Programms übersetzt sein kann, während ein anderer Teil noch nicht übersetzt ist. Es ist notwendig, Trigger *2-Instruktionen sowohl in Neben- als auch Hauptprogrammen zu profilieren, da sie in ein anderes Hauptprogramm springen könnten.
  • Die Emulation nimmt drei Prüfungen nach der Ausführung einer Trigger *2-Instruktion vor (siehe 27). Zuerst prüft sie, ob der Übersetzer ein ist. Wenn er ein ist, prüft sie, ob der Nachfolger der Trigger *2-Instruktion übersetzbar ist oder nicht. Wenn er übersetzbar ist, dann setzt die Emulation die Protokollierflagge auf wahr und prüft, ob der Nachfolger übersetzt wurde, wobei sie zur übersetzten Version springt, wenn diese existiert.
  • Die Emulation nimmt nur zwei Prüfungen nach der Ausführung einer Trigger *1-Instruktion vor (siehe 27). Zuerst prüft sie, ob die Protokollierflagge ein oder aus ist. Wenn sie Flagge aus ist, dann ist diese Instruktion in einem Nebenprogramm, und sie muß nicht profiliert werden. Wenn die Flagge ein ist, dann prüft die Emulation, ob ihr Nachfolger übersetzt wurde oder nicht.
  • Haupt- und Nebenprogramme werden durch ihre Speicheradressen unterschieden (siehe 27). Der Emulator verwendet eine Übersetzungstabelle, um die Beziehung von übersetzbaren und nicht-übersetzbaren Programmadressen aufzuzeichnen. Für Trigger *1-Instruktionen, die sich niemals zwischen übersetzbaren Programmen und nicht-übersetzbaren Programmen bewegen, muß der Emulator nicht auf die Übersetzungstabelle zugreifen, da die Protokollierflagge diese Informationen bereits enthält.
  • Durch die Trennung des Verhaltens des Emulators für Trigger *1- und Trigger *2-Instruktionen in zwei Verfahren wird die Belastung der Profilierung auf die Emulation reduziert.
  • BESONDERE OBJEKTE DER VIERTEN AUSFÜHRUNGSFORM
  • Die vierte Ausführungsform der vorliegenden Erfindung ist auf ein verfahren zur Reduktion der Belastung der Profilierung auf den Emulator gerichtet, indem ein Code nach Triggerinstruktionen plaziert wird, die in und aus übersetz baren Instruktionen springen können, der prüft, ob der Verzweigungsnachfolger übersetzbar ist oder nicht, und indem ein Code nach allen anderen Triggern plaziert wird, der nur eine Flagge prüft, um zu sehen, ob sie übersetzbar ist oder nicht.
  • ZUSAMMENFASSUNG DER VIERTEN AUSFÜHRUNGSFORM
  • Es ist effektiv, die dynamische Objektcode-Übersetzung zusammen mit der Emulation zu verwenden, aber die Kosten von Profilierungsinstruktionen zur Führung des Übersetzers sind eine Belastung für die Emulation. Durch die Unterscheidung zwischen verschiedenen Typen profilierter Instruktionen ist es möglich, diese Belastung zu reduzieren. Die Erfindung ist ein Verfahren zur Reduktion der Belastung der Profilierung auf den Emulator, indem ein Code nach Trigger-Instruktionen plaziert wird, die in und aus übersetzbaren Instruktionen springen können, der prüft, ob der Verzweigungsnachfolger übersetzbar ist oder nicht, und indem ein Code nach allen anderen Triggern plaziert wird, der nur eine Flagge prüft, um zu sehen, ob sie übersetzbar ist oder nicht.
  • FÜNFTE AUSFÜHRUNGSFORM DER ERFINDUNG
  • SOFTWARE-RÜCKKOPPLUNG FÜR DIE DYNAMISCHE ÜBERSETZUNG
  • KURZFASSUNG DER FÜNFTEN AUSFÜHRUNGSFORM
  • Die dynamische Übersetzung ist ein Akt der Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache, während das Programm läuft. In einigen dynamischen Übersetzungssystemen ist die Aufgabe, die das Programm laufen läßt, Interpretierer genannt, von der Aufgabe, die das Programm übersetzt, Kompilierer genannt, getrennt. Die Rate, bei welcher der Interpretierer Anforderungen an den Kompilierer sendet, sollte mit der Rate übereinstimmen, bei welcher der Kompilierer die Anforderungen vollendet. Auch sollte die Rate, bei welcher der Interpretierer Anforderungen sendet, nicht auf Null fallen. Die Software-Rückkopplung sieht einen weg zum Ausgleichen der beiden Raten vor.
  • BESCHREIBUNG VON FIGUREN DER FÜNFTEN AUSFÜHRUNGSFORM
  • 28 veranschaulicht eine allgemeine Strukturdarstellung eines dynamischen Übersetzungssystems mit getrenntem Interpretierer und Kompilierer gemäß einer fünften Ausführungsform der vorliegenden Erfindung. 28 ist eine Strukturdarstellung eines dynamischen Übersetzungssystems. Der Interpretierer sendet Übersetzungsanforderungen an den Kompilierer. Der Kompilierer sendet einen übersetzten Code als Antwort zurück. Die Raten der Anforderungen und Antworten sollten gleich sein, damit das System am effizientesten läuft.
  • 29 veranschaulicht Komponenten eines Software-Rückkopplungsmechanismus gemäß einer fünften Ausführungsform der vorliegenden Erfindung. 29 ist eine Darstellung, die Komponenten eines Software-Rückkopplungssystems veranschaulicht. Die Vergleichsprozedur subtrahiert die Anzahl der Vollendungen von der Anzahl der Anforderungen. Die Anforderungsratenprozedur stellt die Rate auf der Basis dieser Differenz ein. Die Anforderungssendeprozedur sendet Anforderungen in Abhängigkeit von der aktuellen Rate.
  • DETAILLIERTE BESCHREIBUNG DER FÜNFTEN AUSFÜHRUNGSFORM
  • In einem dynamischen Übersetzungssystem sendet die Interpretiereraufgabe Anforderungen an die Kompiliereraufgabe. Die Anforderungen enthält Informationen, um dem Kompilierer mitzuteilen, welcher Abschnitt des Programms zu übersetzen ist. Der Kompilierer übersetzt den Abschnitt und antwortet mit einem übersetzten Code. Das Problem der Entscheidung, wann eine Anforderung zu senden ist, ist ein Beispiel eines Terminisierungsproblems. Die Rate, bei welcher die Interpretiereraufgabe Anforderungen stellt, sollte mit der Rate übereinstimmen, bei welcher der Kompilierer Anforderungen beendet. So wird der Kompilierer nicht untätig oder mit Anforderungen überladen.
  • Die Software-Rückkopplung ist ein Verfahren zum Ausgleichen der Raten von zwei Ereignissätzen [1]. Im dynamischen Übersetzungssystem ändert sie die Rate von Übersetzungsanforderungen, um gleich der Rate vollendeter Übersetzungen zu sein. Wie in 29 gezeigt hat das Software-Rückkopplungssystem drei Hauptteile. Der erste ist eine Prozedur zum Vergleichen der Anzahl von Übersetzungsanforderungen und der Anzahl vollendeter Übersetzungen. Der zweite ist eine Prozedur, welche die Rate von Übersetzungsanforderungen auf der Basis des Ergebnisses des Vergleichs ändert. Der dritte Teil ist eine Prozedur, um die Übersetzungsanforderungen zu stellen, die vom Ausgang der zweiten Prozedur abhängig sind.
  • Im dynamischen Übersetzungssystem zählt die Interpretiereraufgabe, wie oft eine Verzweigungsinstruktion zu einer bestimmten Zieladresse springt. Wenn diese Zählung eine Schwelle überschreitet, sendet der Interpretierer eine Über setzungsanforderung, welche die Zieladresse enthält. Der Schwellenwert ist der kritische Parameter, der vom Software-Rückkopplungsmechanismus eingestellt wird. Wenn die Schwelle niedriger ist als die meisten der Ausführungszählungen, ist die Rate von Übersetzungsanforderungen hoch. wenn die Schwelle höher ist als die meisten der Ausführungszählungen, ist die Rate von Anforderungen niedrig. Da die typische Größe einer Ausführungszählung mit dem Programm, das interpretiert wird, variiert, ist die Software-Rückkopplung ein idealer Weg, die Schwelle einzustellen, da sie sich an das Verhalten des Interpretierers automatisch anpaßt.
  • Im dynamischen Übersetzungssystem ist die Vergleichsprozedur des Software-Rückkopplungssystems sehr einfach. Sie berechnet nur die Differenz zwischen der Anzahl von an den Kompilierer gesendeten Übersetzungsanforderungen und die Anzahl vollendeter Übersetzungen.
  • Die Anforderungsratenprozedur ändert den Schwellenwert auf der Basis der von der Vergleichsprozedur berechneten Differenz. wenn die Differenz Null ist, dann ist die Schwelle zu hoch und hindert den Interpretierer daran, Übersetzungsanforderungen zu senden. In diesem Fall subtrahiert die Anforderungsratenprozedur eine Konstante von der Schwelle. Wenn die Differenz ihr maximal möglicher Wert ist, dann ist die Schwelle zu niedrig, und der Interpretierer sendet zu viele Übersetzungsanforderungen. In diesem Fall addiert die Anforderungsratenprozedur eine Konstante zur Schwelle.
  • Die Anforderungssendeprozedur wird aufgerufen, wenn der Interpretierer eine Verzweigungsinstruktion ausführt. Wenn die Verzweigungsinstruktion mehrere Male zur gleichen Ziel adresse gesprungen ist als die Schwelle, sendet der Interpretierer eine Übersetzungsanforderung, welche die Zieladresse enthält.
  • BESONDERE OBJEKTE DER FÜNFTEN AUSFÜHRUNGSFORM
  • Die Erfindung ist die Verwendung eines Software-Rückkopplunsmechanismus in einem dynamischen Übersetzungssystem mit getrennten Interpretierer- und Kompiliereraufgaben, um die Rate von vom Interpretierer gesendeten Übersetzungsanforderungen und die Rate von vom Kompilierer vollendeten Übersetzungen auszugleichen, ohne zu ermöglichen, daß der Kompilierer untätig wird.
  • Die Verwendung einer minimalen Schwelle, um dem Kompilierer zu ermöglichen, den Betrieb einzustellen.
  • ZUSAMMENFASSUNG DER FÜNFTEN AUSFÜHRUNGSFORM
  • In einem dynamischen Übersetzungssystem mit getrennten Interpretierer- und Kompiliereraufgaben sollte die Rate, bei welcher der Interpretierer Anforderungen an den Kompilierer sendet, mit der Rate übereinstimmen, bei welcher der Kompilierer die Anforderungen vollendet. Auch sollte die Rate, bei welcher der Interpretierer Anforderungen sendet, nicht auf Null fallen. Die Erfindung ist die Verwendung eines Software-Rückkopplungssystems in einem dynamischen Übersetzungssystem mit getrennten Interpretierer- und Kompiliereraufgaben, um die Rate von vom Interpretierer gesendeten Übersetzungsanforderungen und die Rate von vom Kompilierer vollendeten Übersetzungen auszugleichen, ohne zu ermöglichen, daß der Kompilierer untätig wird.
  • SECHSTE AUSFÜHRUNGSFORM DER ERFINDUNG
  • EINREIHEN VON ANFORDERUNGEN IN EINE WARTESCHLANGE FÜR DIE DYNAMISCHE ÜBERSETZUNG
  • KURZFASSUNG DER SECHSTEN AUSFÜHRUNGSFORM
  • Die dynamische Übersetzung ist ein Akt der Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache, während das Programm läuft. Für jedes Teilstück des Programms, das übersetzt wird, stellt das System eine Anforderung an den dynamischen Übersetzer. Anforderungen, die gestellt werden, während der dynamische Übersetzer belegt ist, werden in eine Warteschlange eingereiht und ausgegeben, wenn der Übersetzer untätig wird. Die Implementation des Einreihens in eine Warteschlange kombiniert Systemaufrufe und gemeinsam genutzte Speicherkommunikation, zum Reduzieren.
  • BESCHREIBUNG VON FIGUREN DER SECHSTEN AUSFÜHRUNGSFORM
  • 30 veranschaulicht, wie eine Warteschlange verwendet wird, um Übersetzungsanforderungen zu halten, während die Übersetzungsaufgabe belegt ist, gemäß einer sechsten Ausführungsform der vorliegenden Erfindung.
  • 31 veranschaulicht, wie die OOCT-Anforderungswarteschlange kostengünstige gemeinsam genutzte Speicheranforderungen mit Systemaufrufanforderungen gemäß einer sechsten Ausführungsform der vorliegenden Erfindung kombiniert.
  • DETAILLIERTE BESCHREIBUNG DER SECHSTEN AUSFÜHRUNGSFORM
  • Die Grundfunktion der Anforderungswarteschlange ist, sich Anforderungen zu merken, die gestellt werden, während der dynamische Übersetzer belegt ist, wie in 30 gezeigt. In jedem dynamischen Übersetzungssystem gibt es eine Obergrenze der Anzahl von Übersetzungen, die gleichzeitig durchgeführt werden können. Typischerweise ist die Grenze nur eine Übersetzung zu einer Zeit. Es besteht jedoch keine Grenze für die Gesamtanzahl gestellter Anforderungen oder die Rate, bei der sie gestellt werden. Daher ist es sehr wahrscheinlich, daß eine Übersetzungsanforderung eintreten wird, während der Übersetzer bereits belegt ist. Mit einer Anforderungswarteschlange wird die Übersetzungsanforderung in eine Warteschlange eingereiht und muß nicht wiederholt werden. Wenn der Übersetzer die Anforderung aus der Warteschlange nimmt, wird er die Übersetzung durchführen.
  • Im OOCT hat das dynamische Übersetzungssystem mehrfache Aufgaben, wobei eine die dynamische Übersetzungsaufgabe ist, die Anforderungen behandelt, und andere die Ausführungsaufgaben sind, die Übersetzungsanforderungen stellen. Die COOT-Implementation des Einreihens in eine Warteschlange verbessert eine naive Warteschlange unter Verwendung von weniger kostspieligem, gemeinsam genutzten Speicher zusammen mit Systemaufrufnachrichten, um die Anforderungswarteschlange zu bilden, wie in 31 gezeigt. Systemaufrufe allein sind ausreichend, um Startparameter von den Ausführungsaufgaben zur Übersetzungsaufgabe zu kommunizieren, und um es der Übersetzungsaufgabe zu ermöglichen, untätig zu werden, oder zu blockieren, wenn es keine ausstehenden Anforderungen gibt. Systemaufrufe sind jedoch kostspielige Operationen. Der gemeinsam genutzte Speicher kann verwendet werden, um die Anforderungsnachrichten von den Ausführungsaufgaben zur Übersetzungsaufgabe zu kommunizieren, die Übersetzungsaufgabe kann jedoch diese Nachrichten nicht blockieren, so daß sie kontinuierlich laufen müßte, um Nachrichten von einem einfachen gemeinsam genutzten Speicher zu empfangen.
  • Die OOCT-Implementation verwendet die besten Merkmale jedes Mechanismus, Systemaufruf und gemeinsam genutzter Speicher. Sie ermöglicht es der Übersetzungsaufgabe zu blockieren, während sie auf eine Systemaufrufnachricht wartet, kommuniziert jedoch Anforderungen durch den gemeinsam genutzten Speicher, wenn die Übersetzungsaufgabe bereits arbeitet.
  • Wie in 31 gezeigt, verwendet die OOCT-Anforderungswarteschlange zwei Arten von Nachrichten zwischen den Ausführungs- und Übersetzungsaufgaben, plus einen gemeinsam genutzten Speicherpuffer, auf den von beiden Aufgaben zugegriffen wird. Die erste Nachricht geht von der Übersetzungsaufgabe zur Ausführungsaufgabe. Sie teilt der Ausführungsaufgabe mit, einen Systemaufruf zum Senden der nächsten Anforderung zu verwenden. Diese Nachricht informiert die Ausführungsaufgabe, daß die Übersetzungsaufgabe den gemeinsam genutzten Speicherpuffer entleert hat und nun blockieren wird. Dann sendet die Ausführungsaufgabe eine Anforderung mit einem Systemaufruf. Die Übersetzungsaufgabe empfängt die Nachricht und beginnt eine Übersetzung. Nach dem Senden einer Anforderung mit einem Systemaufruf weiß die Ausführungsaufgabe, daß die Übersetzungsaufgabe belegt ist, daher sendet sie weitere Anforderungen direkt an den gemeinsam genutzten Speicherpuffer. Dies ist viel weniger kostspielig als die Verwendung eines weiteren Systemaufrufs. Wenn die Übersetzungsaufgabe eine Anforderung beendet, sieht sie im gemeinsam genutzten Speicherpuffer nach. Wenn sich in dem Puffer eine Anforderung befindet, wird sie entfernt und übersetzt. Wenn der gemeinsam genutzte Speicherpuffer leer ist, teilt die Übersetzungsaufgabe wieder der Ausführungsaufgabe mit, einen Systemaufruf zu verwenden.
  • Die Vorteile der OOCT-Anforderungswarteschlange sind, daß die Ausführungsaufgaben einen gemeinsam genutzten Speicher verwenden können, wenn sie Anforderungen bei einer hohen Rate senden, und die Übersetzungsaufgabe blockieren kann, wenn Anforderungen bei einer langsamen Rate ankommen.
  • BESONDERE OBJEKTE DER SECHSTEN AUSFÜHRUNGSFORM
  • Dieser Anspruch ist eine Übersetzung des Fujitsu-Patents auf japanisch, wobei ein Absatz hinzugefügt ist.
  • Die Erfindung ist ein Verfahren zum Fortsetzen einer Interpretation, während die Übersetzung häufig verzweigter Instruktionen gestartet wird, indem eine Nachricht an die Übersetzungsaufgabe gesendet wird, und zum Einreihen von Nachrichten an die Übersetzungsaufgabe in eine Warteschlange, wenn eine Übersetzung bereits begonnen hat, und eine Leistungsverbesserung gegenüber der Verwendung von sowohl Systemaufruf- als auch gemeinsam genutzten Speichermechanismen, um die Übersetzungsanforderungsnachrichten zu senden.
  • ZUSAMMENFASSUNG DER SECHSTEN AUSFÜHRUNGSFORM
  • Die beschriebene Übersetzungsanforderungswarteschlange ist ein Mechanismus zum Sammeln von Übersetzungsanforderungen, während eine andere Übersetzung ausführt. Sie ermög licht, daß die Ausführungsaufgaben unmittelbar nach dem Senden einer Anforderung weiterlaufen. Durch die Verwendung sowohl von einem gemeinsam genutzten Speicher als auch Systemaufrufen miteinander ist es möglich, die Effizienz der Übersetzungswarteschlange zu verbessern. Die Erfindung ist ein Verfahren zum Fortsetzen einer Interpretation, während die Übersetzung häufig verzweigter Instruktionen gestartet wird, indem eine Nachricht an die Übersetzungsaufgabe gesendet wird, und zum Einreihen von Nachrichten an die Übersetzungsaufgabe in eine Warteschlange, wenn eine Übersetzung bereits begonnen hat, und eine Leistungsverbesserung gegenüber der Verwendung von sowohl Systemaufruf- als auch gemeinsam genutzten Speichermechanismen, um die Übersetzungsanforderungsnachrichten zu senden.
  • SIEBENTE AUSFÜHRUNGSFORM DER VORLIEGENDEN ERFINDUNG
  • SEITENFEHLERBEHEBUNG FÜR DIE DYNAMISCHE ÜBERSETZUNG
  • KURZFASSUNG DER SIEBENTEN AUSFÜHRUNGSFORM
  • Die dynamische Übersetzung ist ein Akt der Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache, während das Programm läuft. Der dynamische Übersetzer muß die Quellenmaschineninstruktionen lesen, bevor er sie in Zielmaschineninstruktionen übersetzt. Während die Quelleninstruktionen gelesen werden, kann der Übersetzer einen Seitenfehler verursachen, indem er aus einem Speicher liest, der ausgelagert ist, es ist jedoch ineffizient, den Speicher einzulagern. Der beschriebene Übersetzer behebt Seitenfehler, ohne die ausgelagerten Daten zu lesen, und setzt die Übersetzung fort.
  • BESCHREIBUNG VON FIGUREN DER SIEBENTEN AUSFÜHRUNGSFORM
  • 32 zeigt, wie ein dynamischer Übersetzer wahrscheinlich Seitenfehler verursachen kann, die während der normalen Ausführung der Quelleninstruktionen nicht eintreten würden, gemäß einer siebenten Ausführungsform der vorliegenden Erfindung.
  • 33 zeigt den Algorithmus zur Behebung von Seitenfehlern während der Übersetzung und zum Fortsetzen der Übersetzung gemäß einer siebenten Ausführungsform der vorliegenden Erfindung.
  • DETAILLIERTE BESCHREIBUNG DER SIEBENTEN AUSFÜHRUNGSFORM
  • Ein dynamischer Übersetzer wird sehr wahrscheinlich auf Seiten zugreifen, die schlechte Kandidaten für das Kopieren in einen physischen Speicher sind, da er alle der möglichen Nachfolger einer Instruktion liest und nicht nur die Nachfolger, die tatsächlich ausgeführt werden. Beispielsweise, wie in 32 gezeigt, haben bedingte Verzweigungsinstruktionen zwei Nachfolger, den Fehlschlag-Nachfolger und den Verzweigung-eingeschlagen-Nachfolger. Wenn eine CPU eine bedingte Verzweigungsinstruktion ausführt, wenn die Verzweigung nicht eingeschlagen wird, dann wird die Verzweigung-eingeschlagen-Nachfolgerinstruktion niemals geladen. Daher wird sie keinen Seitenfehler verursachen. Wenn der dynamische Übersetzer die Verzweigungsinstruktion liest, versucht er, sowohl den Fehlschlag- als auch den Verzweigung-eingeschlagen-Nachfolger zu lesen, ohne zu wissen, welcher tatsächlich ausgeführt wird. Er könnte einen Seitenfehler verursachen, um die Verzweigungsnachfolgerinstruktion zu lesen, auch wenn sie niemals ausgeführt wird.
  • Das normale Verfahren zur Behandlung von Seitenfehlern ist, eine Seite in den angeforderten Speicher einzulagern, und den Speicherzugriff über Software vorzunehmen, und dann der Ausführung zu gestatten, nach der fehlerhaften Instruktion fortzusetzen. Dieses Verfahren hat zwei Nachteile. Erstens bracht es Zeit, eine Seite vom physischen Speicher zum Sicherungsspeicher zu bewegen, und eine andere vom Sicherungsspeicher zum physischen Speicher zu bewegen, und dann den Speicherzugriff durchzuführen. Zweitens wird der Satz von Speicherseiten, die darin eingelagert sind, geändert. Auf die Seite, die in den physischen Speicher kopiert wird, kann selten zugegriffen werden, bevor sie wieder ausgelagert wird, was bedeuten würde, daß es eine schlechte Idee war, sie in den physischen Speicher zu kopieren.
  • Da der dynamische Übersetzer häufigere Seitenfehler verursachen kann, ist es vorteilhaft, die Kosten dieser Seitenfehler zu reduzieren. Der dynamische Übersetzer minimiert die Kosten zusätzlicher Seitenfehler, indem er eine neue Seite nicht in den physischen Speicher kopiert, und eine Seite, die bereits im physischen Speicher ist, nicht entfernt. Dies spart die Kopierzeit und stellt auch sicher, daß eine Seite, auf die selten bezuggenommen wird, nicht einkopiert wird. Anstelle des Kopierens der Seite unterbricht der Seitenfehler-Handler den aktuellen Strom von Instruktionen im Übersetzer und führt die Steuerung zu einem vom Übersetzer vorgegebenen Prüfpunkt zurück.
  • Der Übersetzer liest Quelleninstruktionen in Einheiten, die Basisblöcke genannt werden. Wenn ein Seitenfehler eintritt, während er einen Basisblock liest, dann ignoriert der Übersetzer diesen Block, setzt jedoch die Übersetzung irgendwelcher anderen Blöcke fort. Nachdem alle Basisblöcke gelesen wurden, werden sie in einen Satz von Zielinstruktionen übersetzt. Das Verfahren des Ignorierens eines Basisblocks, der einen Seitenfehler verursacht, ist in 33 gezeigt. Bevor er einen Basisblock liest, legt der Übersetzer einen Prüfpunkt fest. Alle vor dem Prüfpunkt gelesenen Basisblöcke sind sicher und können von keinerlei Seitenfehlern beeinträchtigt werden, die nach dem Prüfpunkt geschehen. Dann versucht der Übersetzer, den nächsten Basisblock zu lesen. Wenn es einen Seitenfehler gibt, springt er sofort zum Prüfpunkt. Dadurch wird er veranlaßt, den Basisblock zu überspringen und zu versuchen, den nächsten zu lesen.
  • BESONDERE OBJEKTE DER SIEBENTEN AUSFÜHRUNGSFORM
  • Die Erfindung gemäß der siebenten Ausführungsform ist ein Weg, die Speicherzugriffskosten der dynamischen Übersetzung zu reduzieren, indem Seiten nicht in den physischen Speicher kopiert werden, während weiterhin gestattet wird, daß die Übersetzung fortgesetzt wird, wenn ein Speicherzugriff fehlschlägt.
  • ZUSAMMENFASSUNG DER SIEBENTEN AUSFÜHRUNGSFORM
  • Der beschriebene Mechanismus zum Beheben von Seitenfehlern ist ein weg, die Kosten der dynamischen Übersetzung zu reduzieren, wenn auf einen nicht-physisch abgebildeten Speicher zugegriffen wird. Er ermöglicht, daß die dynamische Übersetzung fortgesetzt wird, auch wenn nicht alle der Quellenmaschineninstruktionen aufgrund von Seitenfehlern gelesen werden können. Die Erfindung ist ein Weg, die Speicherzugriffskosten der dynamischen Übersetzung zu reduzieren, indem Seiten nicht in den physischen Speicher kopiert werden, während weiterhin gestattet wird, daß die Übersetzung fortgesetzt wird, wenn ein Speicherzugriff fehlschlägt.
  • ACHTE AUSFÜHRUNGSFORM DER VORLIEGENDEN ERFINDUNG
  • AUFZEICHNUNG VON AUSGÄNGEN AUS DEM ÜBERSETZTEN CODE FÜR DIE DYNAMISCHE ÜBERSETZUNG
  • KURZFASSUNG DER ACHTEN AUSFÜHRUNGSFORM
  • Die dynamische Übersetzung ist ein Akt der Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache, während das Programm läuft. Der dynamische Übersetzer wählt die zu übersetzenden Instruktionen, indem er sie profiliert, während sie ausführen. Die häufig ausgeführten Instruktionen werden übersetzt, und die selten ausgeführten werden dies nicht. Die übersetzten Instruktionen können bewirken, daß der Profilierer einige Instruktionen ausläßt, was dazu führen kann, daß häufig ausgeführte Instruktionen interpretiert werden. Durch die Aufzeichnung spezifischer Ausgänge aus dem übersetzten Code ist es möglich, alle der häufig ausgeführten Instruktionen zu profilieren und sicherzustellen, daß sie alle übersetzt werden.
  • BESCHREIBUNG VON FIGUREN DER ACHTEN AUSFÜHRUNGSFORM
  • 34 veranschaulicht ein Muster eines Steuerflusses in einem dynamischen Übersetzungssystem mit einem Verzweigungsprofilierer gemäß einer achten Ausführungsform der vorliegenden Erfindung.
  • DETAILLIERTE BESCHREIBUNG DER ACHTEN AUSFÜHRUNGSFORM
  • Wie im Dokument 'Verzweigungsprotokollierer für die dynamische Übersetzung' beschrieben, profiliert das dynamische Übersetzungssystem die Verzweigungsinstruktionen des Originalprogramms, während sie interpretiert werden, um zu bestimmen, welche Instruktionen häufig ausgeführt werden und welche nicht. Der Verzweigungsprotokollierer profiliert nur Verzweigungsinstruktionen und verläßt sich auf die Annahme, daß alle häufig ausgeführten Instruktionen durch häufig ausgeführte Verzweigungen erreicht werden. In einigen Fällen macht der dynamische Übersetzer selbst diese Annahme unwahr, da die Steuerung von den übersetzten Instruktionen zurück zu den interpretierten Instruktionen fließt, ohne daß eine profilierte Verzweigung ausgeführt wird. Der Übersetzer kann diese Fälle identifizieren, und er schafft spezielle übersetzte Instruktionen, die diesen Steuerfluß profilieren als wäre er eine Verzweigung.
  • 34 veranschaulicht, wie die Steuerung von interpretierten Instruktionen zu übersetzten Instruktionen und zurück fließt. Wo immer die Steuerung einen Ausgang aus übersetzten Instruktionen vornimmt, stellt der Übersetzer sicher, daß der Ausgang profiliert wird als wäre er eine Verzweigungsinstruktion. Es gibt einige Fälle, in denen die Steuerung von übersetzten zu interpretierten Instruktionen fließt.
  • Erstens gibt es Verzweigungen zu nicht-festgelegten Zielen. Der Übersetzer weiß nicht, welche Instruktion nach der Verzweigung ausgeführt wird, daher kann er diese Instruktion nicht in dieselbe Übersetzungseinheit kombinieren wie die Verzweigung. Statt dessen schafft er einen Ausgang aus dem übersetzten Code zurück zum interpretierten Code.
  • Zweitens gibt es Instruktionen, die aufgrund von Seitenfehlern während der Übersetzung nicht gelesen werden können. wie im Dokument 'Seitenfehlerbehebung für die dynamische Übersetzung' beschrieben, ignoriert der Übersetzer Blöcke von Instruktionen, die aufgrund eines Seitenfehlers nicht gelesen werden können. Daher muß das übersetzte Programm zu interpretierten Instruktionen zurückspringen, wenn es diese Blöcke erreicht.
  • Drittens werden einige Instruktionen selten ausgeführt, während die Übersetzung vorgenommen wird. Sie werden nicht übersetzt, da sie selten ausgeführt wurden, wie im Dokument 'Blockwahlschwelle für die dynamische Übersetzung' beschrieben. Sie können jedoch in der Zukunft häufiger ausgeführt werden, daher muß der Übersetzer Ausgänge zu diesen Instruktionen aufzeichnen. Dieses Merkmal ermöglicht es dem dynamischen Übersetzungssystem, sich an die Änderung von Ausführungsmustern anzupassen, welche die Verteilung häufig ausgeführter Instruktionen verändern.
  • Da die Ausfänge aus dem übersetzten Code aufgezeichnet werden, werden mehr Instruktionen übersetzt. Dies erhöht die Chance, daß eine übersetzte Version einer Instruktion existieren wird. Nachdem das dynamische Übersetzungssystem eine lange Zeit laufen gelassen wird, verursachen daher die meisten der Ausgänge aus einer übersetzten Einheit einen Sprung zu einer anderen übersetzten Einheit anstelle eines Sprungs zurück zum interpretierten Code. Dies hat einen direkten Vorteil durch die öftere Verwendung der schnelleren übersetzten Instruktionen und einen indirekten Vorteil durch die Ausführung der Verzweigungsprotokollierinstruktionen nicht so oft.
  • BESONDERE OBJEKTE DER ACHTEN AUSFÜHRUNGSFORM
  • Die achte Ausführungsform der vorliegenden Erfindung ist auf ein Verfahren gerichtet, um sicherzustellen, daß häufig ausgeführte Instruktionen übersetzt werden, auch wenn sie nicht durch irgendwelche profilierte Verzweigungen erreicht werden, indem die möglichen Ausgänge aus übersetzten Instruktionseinheiten profiliert werden.
  • ZUSAMMENFASSUNG DER ACHTEN AUSFÜHRUNGSFORM
  • Ein dynamisches Übersetzungssystem muß alle häufig ausgeführten Instruktionen lokalisieren und übersetzen, was durch Profilierverzweigungsinstruktionen erzielt werden kann. Die Übersetzung von Instruktionen wird jedoch Pfade zu Instruktionen schaffen, die keine profilierten Verzweigungen enthalten. Daher wird die Profilierung erweitert, um die Ausgänge aus übersetzten Instruktionen zu enthalten. Die Erfindung ist ein Verfahren, um sicherzustellen, daß häufig ausgeführte Instruktionen übersetzt werden, auch wenn sie nicht durch irgendwelche profilierte Verzweigungen erreicht werden, indem die möglichen Ausgänge aus übersetzten Instruktionseinheiten profiliert werden.
  • NEUNTE AUSFÜHRUNGSFORM DER VORLIEGENDEN ERFINDUNG
  • BLOCKWAHLSCHWELLE FÜR DIE DYNAMISCHE ÜBERSETZUNG
  • KURZFASSUNG DER NEUNTEN AUSFÜHRUNGSFORM
  • Die dynamische Übersetzung ist ein Akt der Übersetzung eines Computerprogramms in einer Maschinensprache in eine andere Maschinensprache, während das Programm läuft. Der dynamische Übersetzer sollte alle der häufig ausgeführten Teile des Quellenprogramms übersetzen und alle der selten ausgeführten Teile ignorieren. Um dies zu erzielen, profiliert das Übersetzungssystem Verzweigungsinstruktionen und übersetzt jene Instruktionen nicht, deren Ausführungswahrscheinlichkeit unter einer spezifizierten Schwelle liegt.
  • BESCHREIBUNG VON FIGUREN DER NEUNTEN AUSFÜHRUNGSFORM
  • 35 veranschaulicht, wie der dynamische Übersetzer Verzweigungsprofilinformationen verwendet, um die Ausführungswahrscheinlichkeit eines Basisblocks zu berechnen, gemäß einer neunten Ausführungsform der vorliegenden Erfindung.
  • DETAILLIERTE BESCHREIBUNG DER NEUNTEN AUSFÜHRUNGSFORM
  • Der Zweck eines dynamischen Übersetzers ist, die allgemeine Ausführungsgeschwindigkeit eines Computerprogramms zu verbessern, indem er es aus seinen ursprünglichen Quellen-Sprachinstruktionen in effizientere Ziel-Sprachinstruktionen übersetzt. Der Vorteil der dynamischen Übersetzung wird durch den Vergleich der Gesamtzeit für die Ausführung des Originalprogramms mit der für die Übersetzung des Programms erforderlichen Zeit plus der Zeit für die Ausführung des übersetzten Programms gemessen. Die zur Übersetzung irgendeines Teils des Programms erforderliche Zeit ist ungefähr konstant, daher wird der Vorteil der Übersetzung eines Teils hauptsächlich durch die Anzahl von Malen, die dieser Teil verwendet wird, bestimmt. Häufig ausgeführte Instruktionen sind es wert, übersetzt zu werden, selten ausgeführte Instruktionen sind es jedoch nicht wert, übersetzt zu werden.
  • Zur Messung der Frequenz verschiedener Instruktionen kann ein dynamisches Übersetzungssystem Verzweigungsinstruktionen profilieren. Unter Verwendung dieser Profilinformationen kann es eine häufig ausgeführte Instruktion wählen und an diesem Punkt die Übersetzung beginnen. Nach der anfänglichen Instruktion versucht der Übersetzer so viele häufig ausgeführte Nachfolgerinstruktionen zu lesen wie möglich, ohne die seltenen Nachfolger zu lesen. Die Blockwahlschwelle wird verwendet, um zu bestimmen, ob ein Nachfolger häufig oder selten ausgeführt wird.
  • Der dynamische Übersetzer liest Instruktionen in Einheiten, die Basisblöcke genannt werden. In einem Basisblock werden alle der Instruktionen die gleiche Anzahl von Malen ausgeführt, daher werden entweder alle häufig ausgeführt oder alle selten ausgeführt.
  • Der dynamische Übersetzer verwendet Profilinformationen aus Verzweigungsinstruktionen, um zu bestimmen, ob ein Basisblock häufig oder selten ausgeführt wird. Dieser Prozeß ist in 35 gezeigt. Der Übersetzer berechnet die Wahrscheinlichkeit, daß ein Ausführungspfad von der ersten übersetzten Instruktion zu einem gegebenen Basisblock eingeschlagen wird. Der erste Basisblock erhält eine Ausführungswahrscheinlichkeit von 100%, da er die erste Instruktion enthält. Wenn der aktuelle Block nur einen Nachfolger hat, dann hat der Nachfolger dieselbe Ausführungswahrscheinlichkeit wie der aktuelle Block. Wenn der aktuelle Block in einer bedingten Verzweigung endet, dann wird die Wahrscheinlichkeit des aktuellen Blocks zwischen den beiden Nachfol gern gemäß den Verzweigungsprofilinformationen geteilt. Wenn die Ausführungswahrscheinlichkeit des aktuellen Blocks beispielsweise 50% war, und er in einer Verzweigungsinstruktion endet, die 40 Mal ausgeführt und 10 Mal eingeschlagen wurde, dann wäre die Wahrscheinlichkeit des Verzweigung-eingeschlagen-Nachfolgers (50%·25% = 12,5%), und die Wahrscheinlichkeit des Fehlschlag-Nachfolgers wäre (50%·75% = 37,5%).
  • Eine variable Schwelle, die Blockwahlschwelle genannt wird, wird zum Auswählen häufig ausgeführter Blöcke verwendet. Wenn die Ausführungswahrscheinlichkeit eines Blocks größer als die oder gleich der Schwelle ist, dann wird dieser Block als häufig ausgeführt angesehen, und er wird übersetzt. Wenn die Ausführungswahrscheinlichkeit unter der Schwelle liegt, dann wird der Block als selten ausgeführt angesehen, und er wird nicht übersetzt.
  • Eine wichtige Eigenschaft dieses Blockwahlverfahrens ist, daß der Satz gewählter Blöcke verbunden ist. Es gibt kompliziertere Wege der Berechnung der Ausführungswahrscheinlichkeit, wie das Addieren der Wahrscheinlichkeiten aus allen Vorläufern. Dies kann jedoch zu nicht-zusammenhängenden Sätzen von Blöcken führen. Es ist möglich, nicht-zusammenhängende Sätze von Blöcken zu übersetzen, aber es gibt mehr Möglichkeiten zur Optimierung des übersetzten Codes, wenn er völlig zusammenhängend ist.
  • BESONDERE OBJEKTE DER NEUNTEN AUSFÜHRUNGSFORM
  • Die neunte Ausführungsform der vorliegenden Erfindung ist auf ein Verfahren zur Verbesserung der Effizienz der dynamischen Übersetzung gerichtet, indem Blöcke häufig aus geführter Instruktionen zur Übersetzung gewählt und Blöcke selten ausgeführter Instruktionen ignoriert werden, wobei eine Schwellenausführungswahrscheinlichkeit zur Trennung der häufig ausgeführten Blöcke von selten ausgeführten verwendet wird.
  • ZUSAMMENFASSUNG DER NEUNTEN AUSFÜHRUNGSFORM
  • Ein dynamisches Übersetzungssystem muß kostenproportional zur Anzahl übersetzter Instruktionen und nutzenproportional zur Anzahl von Malen sein, die eine übersetzte Instruktion ausgeführt wird. Daher ist es am effizientesten, nur häufig ausgeführte Instruktionen zu übersetzen, und die selten ausgeführten zu ignorieren. Die Erfindung ist ein Verfahren zur Verbesserung der Effizienz der dynamischen Übersetzung, indem Blöcke häufig ausgeführter Instruktionen zur Übersetzung gewählt und Blöcke selten ausgeführter Instruktionen ignoriert werden, wobei eine Schwellenausführungswahrscheinlichkeit zur Trennung der häufig ausgeführten Blöcke von selten ausgeführten verwendet wird.
  • Obwohl einige bevorzugte Ausführungsformen der vorliegenden Erfindung erläutert und beschrieben wurden, ist es für Fachleute klar, daß Änderungen in diesen Ausführungsformen vorgenommen werden können, ohne von den Prinzipien und dem Grundgedanken der Erfindung abzuweichen, deren Umfang in den Ansprüchen und ihren Äquivalenten definiert ist.

Claims (31)

  1. Computerarchitektur-Emulationssystem, welches eine Quellen-Computerarchitektur auf einer Ziel-Computerarchitektur emuliert, mit: einer Interpretierereinrichtung zum individuellen Übersetzen eines Quellen-Objektcodes in einen entsprechenden übersetzten Objektcode und zum Bestimmen einer Anzahl von Ausführungen von Verzweigungsinstruktionen im Quellen-Objektcode; und einer Kompilierereinrichtung zum Gruppieren von Instruktionen des Quellen-Objektcodes in ein Segment, wenn eine Anzahl von Ausführungen einer entsprechenden Verzweigungsinstruktion eine Schwellenanzahl überschreitet, und zum dynamischen Kompilieren des Segments, bei welchem die Interpretierereinrichtung und die Kompilierereinrichtung Aufgaben sind, die gleichzeitig in einem Mehraufgaben-Betriebssystem in Echtzeit operieren, und mit einer Einrichtung zum Steuern einer Kompilierungsrate von zu kompilierenden Segmenten durch die Erhöhung der Schwellenanzahl, wenn eine Warteschlage zum Speichern der zu übersetzenden Segmente eine vorherbestimmte Kapazität erreicht.
  2. Computerarchitektur-Emulationssystem nach Anspruch 1, bei welchem Verzweigungs-Objektcode-Instruktionen, die Segmenten entsprechen, welche nicht kompiliert sind, im Speicher gespeichert werden.
  3. Computerarchitektur-Emulationssystem nach Anspruch 2, bei welchem Segmente, die Verzweigungs-Objektcode-Instruktionen entsprechen, welche die Schwellenanzahl nicht überschritten haben, nicht kompiliert werden.
  4. Computerarchitektur-Emulationssystem nach Anspruch 1, bei welchem Segmente, die Verzweigungs-Objektcode-Instruktionen entsprechen, welche Segmenten entsprechen, die nicht kompiliert sind, im Speicher gespeichert werden, während die Interpretierereinrichtung die übersetzten Objektcode-Instruktionen ausführt.
  5. Computerarchitektur-Emulationssystem nach Anspruch 1, ferner mit: einer Verzweigungsprotokollierereinrichtung zum Speichern von Verzweigungsprofilinformationen der Verzweigungsinstruktionen, die von der Interpretierereinrichtung bestimmt werden.
  6. Computerarchitektur-Emulationssystem nach Anspruch 5, bei welchem die Verzweigungsprofilinformationen eine Verzweigungsadresse, einen Verzweigungsnachfolger, einen Nicht-Verzweigungsnachfolger, eine Verzweigungsausführungszählung und eine Verzweigung-eingeschlagen-Zählung enthalten, und die Verzweigungsprofilinformationen von der Interpretierereinrichtung während der Verzweigungsinstruktionsemulation protokolliert werden.
  7. Computerarchitektur-Emulationssystem nach Anspruch 1, ferner mit: einer Einrichtung zum Plazieren einer Codeflagge nach Verzweigungsinstruktionen, die einen Sprung in übersetzbare Instruktionen oder aus diesen ausführen; und einer Einrichtung zum Prüfen, ob Nachfolgerinstruktionen der entsprechenden Verzweigungsinstruktionen übersetzbar sind oder nicht, indem auf die entsprechende Codeflagge bezuggenommen wird.
  8. Computerarchitektur-Emulationssystem nach Anspruch 1, ferner mit: einer Einrichtung zum Initiieren einer Verzweigungsin struktion, wenn eine Anzahl von Ausführungen einer Nachfolgerinstruktion der Verzweigungsinstruktion einen Schwellenwert übersteigt.
  9. Computerarchitektur-Emulationssystem nach Anspruch 1, ferner mit: einer Einrichtung zum Kommunizieren zwischen der Interpretierereinrichtung und der Kompilierereinrichtung, während die Interpretierereinrichtung die Emulation des Quellencodes fortsetzt, um die Übersetzung von Segmenten, die häufig verzweigten Instruktionen entsprechen, zu initiieren.
  10. Computerarchitektur-Emulationssystem nach Anspruch 1, bei welchem die Kompilierereinrichtung ein optimiertes Objekt erzeugt, während jede Instruktion, die sich im Speicher befindet, der Reihe nach verfolgt wird, indem ein Profil verwendet wird, das der Adresse entspricht, an der die Kompilierung gestartet wurde.
  11. Computerarchitektur-Emulationssystem nach Anspruch 10, bei welchem die Kompilierereinrichtung einen Block bei der Detektion eines Seitenfehlers nicht kompiliert, so daß, wenn ein Block einen Seitenfehler verursacht, die Kompilierereinrichtung ein Objekt produziert, um Verzweigungsinformationen in der Verzweigungsprotokolliereinrichtung zu protokollieren.
  12. Computerarchitektur-Emulationssystem nach Anspruch 11, bei welchem, wenn ein Instruktionsausführungsprozeß in bezug auf eine vorherbestimmte Rate nicht rechtzeitig ausführt, die Kompilierereinrichtung die Ausführung unter Verwendung eines Profils verfolgt, prüft, ob eine Verzweigungszählung unter einer vorherbestimmten Anzahl liegt, und ein Objekt produziert, um Verzweigungsinformationen zu protokollieren.
  13. Computerarchitektur-Emulationssystem nach Anspruch 1, ferner mit: einer Verzweigungsprotokolliereinrichtung zum Speichern von Profilinformationen der Verzweigungsinstruktionen im Quellen-Objektcode, der die Anzahl von Ausführungen enthält, wobei die Verzweigungsprotokolliereinrichtung einen Cache zum Speichern von Profilinformationen häufig ausgeführter Verzweigungsinstruktionen und ein Verzweigungsprotokoll zum Speichern von Profilinformationen weniger häufig ausgeführter Verzweigungsinstruktionen enthält.
  14. Computerarchitektur-Emulationssystem nach Anspruch 13, bei welchem die Profilinformationen im Cache durch das Kombinieren von Verzweigungsadresseninformationen und Verzweigungszielinformationen organisiert werden.
  15. Computerarchitektur-Emulationssystem nach Anspruch 14, bei welchem die im Cache organisierten Profilinformationen in einer Vielzahl von Gruppen in absteigender Reihenfolge des Eintrags in die Gruppe gespeichert werden.
  16. Computerarchitektur-Emulationssystem nach Anspruch 1, bei welchem jede Verzweigungsinstruktion ein Startparameter ist, wobei die Kompilierereinrichtung ferner enthält: einen Blockwähler, der ein Segment des zu kompilierenden Quellen-Objektcodes auf der Basis des Startparameters und der Profilinformationen der Verzweigung auswählt, eine Blockaufbaueinheit, die das Segment in eine lineare Liste von Instruktionen abflacht, und eine optimierende Codegenerierungseinheit, welche die tatsächliche Kompilierung von Originalinstruktionen in übersetzte Codesegmentinstruktionen durchführt.
  17. Computerarchitektur-Emulationssystem nach Anspruch 17, bei welchem der Blockwähler einen Steuerflußgraphen schafft, der die zu kompilierenden Originalinstruktionen beschreibt, und den Steuerflußgraphen zur Blockaufbaueinheit weiterreicht.
  18. Computerarchitektur-Emulationssystem, welches eine Quellen-Computerarchitektur auf einem Ziel-Computerarchitektursystem emuliert, mit: einer Vielzahl von Interpretierereinrichtungen zum individuellen Übersetzen eines Quellen-Objektcodes in einen entsprechenden übersetzten Objektcode, wobei jede der Vielzahl von Interpretierereinrichtungen Quellen-Objektcode-Verzweigungsinformationen in Echtzeit profiliert, während sie übersetzte Objektcode-Instruktionen ausführt; und einer Kompilierereinrichtung zum Gruppieren von Quellen-Objektcode-Instruktionen von irgendeiner der Vielzahl von Interpretierereinrichtungen in Segmente auf der Basis entsprechender Verzweigungsinstruktionen im Quellen-Objektcode und zum dynamischen Kompilieren der Segmente des Quellen-Objektcodes, wenn die entsprechende Verzweigungsinstruktion größer ist als eine Schwellenanzahl, bei welchem die Interpretierereinrichtung und die Kompilierereinrichtung gleichzeitig in einem Mehraufgaben-Betriebssystem in Echtzeit operieren, und mit einer Einrichtung zum Steuern einer Kompilierungsrate von zu kompilierenden Segmenten durch die Erhöhung der Schwellenanzahl, wenn eine Warteschlage zum Speichern der zu übersetzenden Segmente eine vorherbestimmte Kapazität erreicht.
  19. Computerarchitektur-Emulationssystem nach Anspruch 18, bei welchem jede der Vielzahl von Interpretierereinrichtungen die Verzweigungs-Objektcode-Instruktionen profiliert und die Verzweigungs-Objektcode-Instruktionen speichert, welche die Schwellenanzahl nicht überschritten haben, indem ein Verzweigungsprotokollierer aufgerufen wird.
  20. Computerarchitektur-Emulationssystem, welches eine Quellen-Computerarchitektur auf einem Ziel-Computerarchitektursystem emuliert, mit: einer Interpretierereinrichtung zum individuellen Übersetzen eines Quellen-Objektcodes in einen entsprechenden übersetzten Objektcode, wobei die Interpretierereinrichtung Verzweigungsinstruktionen des Quellen-Objektcodes durch das Speichern einer Anzahl von Ausführungen für jede Verzweigungsinstruktion und Vergleichen der Anzahl von Ausführungen mit einer Schwellenanzahl profiliert, so daß Verzweigungsinstruktionen, welche die Schwellenanzahl überschreiten, Startparameter sind; und einer Kompilierereinrichtung zum Gruppieren der Quellen-Objektcode-Instruktionen in Segmente auf der Basis der Startparameter und dynamischen Kompilieren der Segmente des Quellen-Objektcodes während der Übersetzung und Profilierung durch die Interpretierereinrichtung, bei welchem die Interpretierereinrichtung und die Kompilierereinrichtung gleichzeitig in einem Mehraufgaben-Betriebssystem in Echtzeit operieren, und mit einer Einrichtung zum Steuern einer Kompilierungsrate von zu kompilierenden Segmenten durch die Erhöhung der Schwellenanzahl, wenn eine Warteschlage zum Speichern der zu übersetzenden Segmente eine vorherbestimmte Kapazität erreicht.
  21. Computerarchitektur-Emulationssystem nach Anspruch 20, bei welchem jedes Segment Instruktionen enthält, die aus der Optimierung des Quellen-Objektcodes auf der Basis eines entsprechenden Startparameters resultieren, und jedes Segment als Einheit installiert und deinstalliert wird.
  22. Computerarchitektur-Emulationssystem nach Anspruch 21, bei welchem Verzweigungs-Objektcode-Instruktionen, die Segmenten entsprechen, welche nicht kompiliert sind, im Speicher gespeichert werden, während Segmente, die Verzweigungs-Objektcode-Instruktionen entsprechen, welche die Schwellenanzahl nicht überschritten haben, nicht kompiliert werden.
  23. Computerarchitektur-Emulationssystem nach Anspruch 21, ferner mit: einer Verzweigungsprotokollierereinrichtung zum Speichern von Verzweigungsprofilinformationen der Verzweigungsinstruktionen, die von der Interpretierereinrichtung bestimmt werden, wobei die Verzweigungsprofilinformationen eine Verzweigungsadresse, einen Verzweigungsnachfolger, einen Nicht-Verzweigungsnachfolger, eine Verzweigungsausführungszählung und eine Verzweigung-eingeschlagen-Zählung enthalten, und die Verzweigungsprofilinformationen von der Interpretierereinrichtung während der Verzweigungsinstruktionsemulation protokolliert werden.
  24. Computerarchitektur-Emulationssystem nach Anspruch 21, ferner mit: einer Einrichtung zum Plazieren einer Codeflagge nach Verzweigungsinstruktionen, die einen Sprung in übersetzbare Instruktionen oder aus diesen ausführen; und einer Einrichtung zum Prüfen, ob Nachfolgerinstruktionen der entsprechenden Verzweigungsinstruktionen übersetzbar sind oder nicht, indem auf die entsprechende Codeflagge bezuggenommen wird.
  25. Computerarchitektur-Emulationssystem nach Anspruch 21, ferner mit: einer Einrichtung zum Initiieren einer Verzweigungsinstruktion, wenn eine Anzahl von Ausführungen einer Nachfolgerinstruktion der Verzweigungsinstruktion einen Schwellen wert übersteigt.
  26. Computerarchitektur-Emulationssystem nach Anspruch 21, bei welchem, wenn ein Instruktionsausführungsprozeß in bezug auf eine vorherbestimmte Rate nicht rechtzeitig ausführt, die Kompilierereinrichtung die Ausführung unter Verwendung eines Profils verfolgt, prüft, ob eine Verzweigungszählung unter einer vorherbestimmten Anzahl liegt, und ein Objekt produziert, um Verzweigungsinformationen wie den Seitenfehler zu protokollieren.
  27. Computerarchitektur-Emulationssystem nach Anspruch 21, ferner mit: einer Verzweigungsprotokolliereinrichtung zum Speichern von Profilinformationen der Verzweigungsinstruktionen im Quellen-Objektcode, der die Anzahl von Ausführungen enthält, wobei die Verzweigungsprotokolliereinrichtung einen Cache zum Speichern von Profilinformationen häufig ausgeführter Verzweigungsinstruktionen und ein Verzweigungsprotokoll zum Speichern von Profilinformationen weniger häufig ausgeführter Verzweigungsinstruktionen enthält, wobei die Profilinformationen im Cache durch das Kombinieren von Verzweigungsadresseninformationen und Verzweigungszielinformationen organisiert werden, und die im Cache organisierten Profilinformationen in einer Vielzahl von Gruppen in absteigender Reihenfolge des Eintrags in die Gruppe gespeichert werden.
  28. Computerarchitektur-Emulationssystem nach Anspruch 21, bei welchem die Kompilierereinrichtung ferner enthält: einen Blockwähler, der ein Segment des zu kompilierenden Quellen-Objektcodes auf der Basis des Startparameters und der Profilinformationen der Verzweigung auswählt, wobei der Blockwähler einen Steuerflußgraphen schafft, der die zu kompilierenden Originalinstruktionen beschreibt; eine Blockaufbaueinheit, die den Steuerflußgraphen in eine lineare Liste von Instruktionen abflacht, und eine optimierende Codegenerierungseinheit, welche die tatsächliche Kompilierung von Originalinstruktionen in übersetzte Codesegmentinstruktionen durchführt.
  29. Mehraufgaben-Computerarchitektur-Emulationssystem, welches eine Quellen-Computerarchitektur auf einer Mehraufgaben-Ziel-Computerarchitektur emuliert, mit: einer Interpretiereraufgabe zum individuellen Übersetzen eines Quellen-Objektcodes in einen entsprechenden übersetzten Objektcode und zum Bestimmen einer Anzahl von Ausführungen von Verzweigungsinstruktionen im Quellen-Objektcode; und einer Kompiliereraufgabe, die mit dem Interpretierer auf der Mehraufgaben-Ziel-Computerarchitektur operiert, zum Gruppieren von Instruktionen des Quellen-Objektcodes in ein Segment, wenn eine Anzahl von Ausführungen einer entsprechenden Verzweigungsinstruktion eine Schwellenanzahl überschreitet, und zum dynamischen Kompilieren des Segments, bei welchem die Interpretierereinrichtung und die Kompilierereinrichtung Aufgaben sind, die gleichzeitig in einem Mehraufgaben-Betriebssystem in Echtzeit operieren, und mit einer Einrichtung zum Steuern einer Kompilierungsrate von zu kompilierenden Segmenten durch die Erhöhung der Schwellenanzahl, wenn eine Warteschlage zum Speichern der zu übersetzenden Segmente eine vorherbestimmte Kapazität erreicht.
  30. Mehraufgaben-Computerarchitektur-Emulationssystem nach Anspruch 29, welches Mehraufgaben-Computerarchitektur-Emulationssystem ein dynamisches Übersetzungssystem ist, wobei das Mehraufgaben-Computerarchitektur-Emulationssystem ferner umfaßt: eine Software-Rückkopplungseinrichtung zum Ausgleichen einer Rate von Kompilierungsanforderungen, die von der Interpretiereraufgabe gesendet werden, und der Rate von Kompilierungen, die von der Kompiliereraufgabe vollendet werden, ohne daß es der Kompiliereraufgabe gestattet wird, untätig zu werden, indem die Schwellenanzahl variiert wird.
  31. Mehraufgaben-Computerarchitektur-Emulationssystem nach Anspruch 30, ferner mit: einer Warteschlange zum Speichern von Segmenten, die von der Kompiliereraufgabe zu kompilieren sind, wobei die Schwellenanzahl mit einer Mindestschwellenanzahl verglichen wird, um die Kompiliereraufgabe ein oder aus zu schalten.
DE19945992A 1998-10-21 1999-09-24 Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren Expired - Fee Related DE19945992B4 (de)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US09/176,112 US6463582B1 (en) 1998-10-21 1998-10-21 Dynamic optimizing object code translator for architecture emulation and dynamic optimizing object code translation method
US09/176112 1998-10-21

Publications (2)

Publication Number Publication Date
DE19945992A1 DE19945992A1 (de) 2000-05-04
DE19945992B4 true DE19945992B4 (de) 2004-12-09

Family

ID=22643028

Family Applications (1)

Application Number Title Priority Date Filing Date
DE19945992A Expired - Fee Related DE19945992B4 (de) 1998-10-21 1999-09-24 Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren

Country Status (4)

Country Link
US (2) US20020147969A1 (de)
JP (1) JP3553834B2 (de)
CN (1) CN1308818C (de)
DE (1) DE19945992B4 (de)

Families Citing this family (419)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPH11296381A (ja) * 1998-04-08 1999-10-29 Matsushita Electric Ind Co Ltd 仮想マシン及びコンパイラ
US6199201B1 (en) * 1998-08-03 2001-03-06 Xerox Corporation Software constructs that facilitate partial evaluation of source code
JP4573189B2 (ja) * 1998-10-10 2010-11-04 インターナショナル・ビジネス・マシーンズ・コーポレーション プログラムコード変換方法
EP0997815A3 (de) * 1998-10-29 2004-05-26 Texas Instruments Incorporated Interaktives Übersetzungssystem und -verfahren
GB9825102D0 (en) * 1998-11-16 1999-01-13 Insignia Solutions Plc Computer system
US8121828B2 (en) 1999-01-28 2012-02-21 Ati Technologies Ulc Detecting conditions for transfer of execution from one computer instruction stream to another and executing transfer on satisfaction of the conditions
US7941647B2 (en) 1999-01-28 2011-05-10 Ati Technologies Ulc Computer for executing two instruction sets and adds a macroinstruction end marker for performing iterations after loop termination
US7275246B1 (en) * 1999-01-28 2007-09-25 Ati International Srl Executing programs for a first computer architecture on a computer of a second architecture
US6954923B1 (en) 1999-01-28 2005-10-11 Ati International Srl Recording classification of instructions executed by a computer
US6826748B1 (en) * 1999-01-28 2004-11-30 Ati International Srl Profiling program execution into registers of a computer
US7111290B1 (en) 1999-01-28 2006-09-19 Ati International Srl Profiling program execution to identify frequently-executed portions and to assist binary translation
US8074055B1 (en) 1999-01-28 2011-12-06 Ati Technologies Ulc Altering data storage conventions of a processor when execution flows from first architecture code to second architecture code
US8127121B2 (en) 1999-01-28 2012-02-28 Ati Technologies Ulc Apparatus for executing programs for a first computer architechture on a computer of a second architechture
US6662354B1 (en) * 1999-01-29 2003-12-09 Unisys Corporation Determining destinations of a dynamic branch
JP4088379B2 (ja) * 1999-01-29 2008-05-21 インターナショナル・ビジネス・マシーンズ・コーポレーション コンパイル方法及び装置、並びにスタック・トレース方法及び装置
US7058932B1 (en) * 1999-04-19 2006-06-06 Unisys Corporation System, computer program product, and methods for emulation of computer programs
US6779107B1 (en) 1999-05-28 2004-08-17 Ati International Srl Computer execution by opportunistic adaptation
JP2001005675A (ja) * 1999-06-21 2001-01-12 Matsushita Electric Ind Co Ltd プログラム変換装置及びプロセッサ
JP4041248B2 (ja) * 1999-07-09 2008-01-30 松下電器産業株式会社 コンパイラ装置、コンパイルプログラムが記録されたコンピュータ読み取り可能な記録媒体及びコンパイル方法
CA2279222C (en) * 1999-07-30 2002-07-16 Ibm Canada Limited-Ibm Canada Limitee Direct call threaded code
US6629312B1 (en) * 1999-08-20 2003-09-30 Hewlett-Packard Development Company, L.P. Programmatic synthesis of a machine description for retargeting a compiler
US6772106B1 (en) * 1999-08-20 2004-08-03 Hewlett-Packard Development Company, L.P. Retargetable computer design system
WO2001022228A1 (en) 1999-09-17 2001-03-29 Nortel Networks Limited System and method for producing a verification system for verifying procedure interfaces
US6714904B1 (en) * 1999-10-13 2004-03-30 Transmeta Corporation System for using rate of exception event generation during execution of translated instructions to control optimization of the translated instructions
US6880152B1 (en) * 1999-10-13 2005-04-12 Transmeta Corporation Method of determining a mode of code generation
US7761857B1 (en) * 1999-10-13 2010-07-20 Robert Bedichek Method for switching between interpretation and dynamic translation in a processor system based upon code sequence execution counts
JP3608993B2 (ja) * 1999-11-10 2005-01-12 富士通株式会社 コンパイラ装置及びコンパイラプログラムを記録した記録媒体
JP3356742B2 (ja) * 1999-11-17 2002-12-16 インターナショナル・ビジネス・マシーンズ・コーポレーション プログラム実行方法
GB2364579A (en) * 1999-11-30 2002-01-30 Sgs Thomson Microelectronics An assembler using a descriptor file that contains information descriptive of the instruction set of a target microprocessor
US6681387B1 (en) * 1999-12-01 2004-01-20 Board Of Trustees Of The University Of Illinois Method and apparatus for instruction execution hot spot detection and monitoring in a data processing unit
DE19963832A1 (de) * 1999-12-30 2001-07-05 Ericsson Telefon Ab L M Programmprofilierung
US7100164B1 (en) * 2000-01-06 2006-08-29 Synopsys, Inc. Method and apparatus for converting a concurrent control flow graph into a sequential control flow graph
US6986128B2 (en) * 2000-01-07 2006-01-10 Sony Computer Entertainment Inc. Multiple stage program recompiler and method
US20020066081A1 (en) * 2000-02-09 2002-05-30 Evelyn Duesterwald Speculative caching scheme for fast emulation through statically predicted execution traces in a caching dynamic translator
US6594821B1 (en) 2000-03-30 2003-07-15 Transmeta Corporation Translation consistency checking for modified target instructions by comparing to original copy
US6862565B1 (en) * 2000-04-13 2005-03-01 Hewlett-Packard Development Company, L.P. Method and apparatus for validating cross-architecture ISA emulation
US6862730B1 (en) * 2000-04-26 2005-03-01 Lucent Technologies Inc. Register allocation in code translation between processors
JP2001325111A (ja) * 2000-05-16 2001-11-22 Hitachi Ltd 投機機構向けコンパイル方法
US6968542B2 (en) * 2000-06-16 2005-11-22 Hewlett-Packard Development Company, L.P. Method for dynamically identifying pseudo-invariant instructions and their most common output values on frequently executing program paths
US6615300B1 (en) * 2000-06-19 2003-09-02 Transmeta Corporation Fast look-up of indirect branch destination in a dynamic translation system
SE0002440D0 (sv) 2000-06-28 2000-06-28 Virtutech Ab Interpreter
US20020062476A1 (en) * 2000-07-14 2002-05-23 Saxe James Benjamin Case-reduced verification condition generation system and method by use of dynamic single assumption and assigning labels to variables at control join points
US6701518B1 (en) * 2000-08-03 2004-03-02 Hewlett-Packard Development Company, L.P. System and method for enabling efficient processing of a program that includes assertion instructions
US6868434B1 (en) * 2000-08-07 2005-03-15 Sun Microsystems, Inc. System and method for testing server latencies using multiple concurrent users in a computer system
US7124407B1 (en) * 2000-08-16 2006-10-17 Sun Microsystems, Inc. Method and apparatus for caching native code in a virtual machine interpreter
JP2002073345A (ja) * 2000-08-25 2002-03-12 Fujitsu Ltd 情報処理装置及び記録媒体
US6691306B1 (en) * 2000-12-22 2004-02-10 Lsi Logic Corporation Use of limited program space of general purpose processor for unlimited sequence of translated instructions
US6721943B2 (en) * 2001-03-30 2004-04-13 Intel Corporation Compile-time memory coalescing for dynamic arrays
US7099970B1 (en) * 2001-04-03 2006-08-29 Electronic Label Technology, Inc. Apparatus and method to enhance a one-wire bus
US7356673B2 (en) * 2001-04-30 2008-04-08 International Business Machines Corporation System and method including distributed instruction buffers for storing frequently executed instructions in predecoded form
CA2346762A1 (en) * 2001-05-07 2002-11-07 Ibm Canada Limited-Ibm Canada Limitee Compiler generation of instruction sequences for unresolved storage devices
US6993751B2 (en) * 2001-05-14 2006-01-31 Microsoft Corporation Placing exception throwing instructions in compiled code
US6851110B2 (en) * 2001-06-07 2005-02-01 Hewlett-Packard Development Company, L.P. Optimizing an executable computer program having address-bridging code segments
US7110525B1 (en) 2001-06-25 2006-09-19 Toby Heller Agent training sensitive call routing system
US6880154B2 (en) * 2001-06-29 2005-04-12 Intel Corporation Alias-free test for dynamic array structures
US20030033593A1 (en) * 2001-08-08 2003-02-13 Evelyn Duesterwald Dynamic execution layer interface for explicitly or transparently executing application or system binaries
US6966053B2 (en) * 2001-08-10 2005-11-15 The Boeing Company Architecture for automated analysis and design with read only structure
US7207035B2 (en) * 2001-08-23 2007-04-17 International Business Machines Corporation Apparatus and method for converting an instruction and data trace to an executable program
US6857119B1 (en) * 2001-09-25 2005-02-15 Oracle International Corporation Techniques for modifying a compiled application
CA2359862A1 (en) * 2001-10-24 2003-04-24 Ibm Canada Limited - Ibm Canada Limitee Using identifiers and counters for controlled optimization compilation
US6976249B1 (en) * 2001-11-12 2005-12-13 Apple Computer, Inc. Method for embedding object codes in source codes
US6738969B2 (en) 2001-11-14 2004-05-18 Sun Microsystems, Inc. Non-intrusive gathering of code usage information to facilitate removing unused compiled code
US20030093774A1 (en) * 2001-11-14 2003-05-15 Ronald Hilton State-specific variants of translated code under emulation
US20030101439A1 (en) * 2001-11-29 2003-05-29 Giuseppe Desoli System and method for supporting emulation of a computer system through dynamic code caching and transformation
US7251594B2 (en) * 2001-12-21 2007-07-31 Hitachi, Ltd. Execution time modification of instruction emulation parameters
DE10204345A1 (de) * 2002-02-01 2003-08-14 Systemonic Ag Verfahren zur Befehlsbearbeitung
US7331040B2 (en) * 2002-02-06 2008-02-12 Transitive Limted Condition code flag emulation for program code conversion
GB0202728D0 (en) * 2002-02-06 2002-03-27 Transitive Technologies Ltd Condition code flag emulation for program code conversion
US7134115B2 (en) * 2002-02-07 2006-11-07 Matsushita Electric Industrial Co., Ltd. Apparatus, method, and program for breakpoint setting
US20030167457A1 (en) * 2002-03-01 2003-09-04 Thompson Carol L. System and method for providing an optimizer display tool
EP1488318B1 (de) * 2002-03-20 2018-05-30 Citrix Systems International GmbH System und verfahren zur sicheren freispeichersammlung in einem mobilgeraet
US8086438B2 (en) * 2002-03-27 2011-12-27 Synopsys, Inc. Method and system for instruction-set architecture simulation using just in time compilation
US7506321B1 (en) * 2002-06-11 2009-03-17 Unisys Corporation Computer emulator employing direct execution of compiled functions
JP3956113B2 (ja) * 2002-06-13 2007-08-08 インターナショナル・ビジネス・マシーンズ・コーポレーション データ処理装置及びプログラム
JP2004021425A (ja) * 2002-06-13 2004-01-22 Hitachi Ltd コンパイラにおけるメモリ配置方式
EP1377034A1 (de) * 2002-06-27 2004-01-02 Thomson Licensing S.A. Datenverarbeitungsvorrichtung und -verfahren für interaktives Fernsehen
US7926032B2 (en) * 2002-07-18 2011-04-12 International Business Machines Corporation Two meta-level modeling approach for mapping typed data
US7107585B2 (en) * 2002-07-29 2006-09-12 Arm Limited Compilation of application code in a data processing apparatus
US7219328B2 (en) * 2002-08-28 2007-05-15 Honeywell International Inc. Model-based composable code generation
US8108843B2 (en) * 2002-09-17 2012-01-31 International Business Machines Corporation Hybrid mechanism for more efficient emulation and method therefor
US9043194B2 (en) * 2002-09-17 2015-05-26 International Business Machines Corporation Method and system for efficient emulation of multiprocessor memory consistency
US7953588B2 (en) * 2002-09-17 2011-05-31 International Business Machines Corporation Method and system for efficient emulation of multiprocessor address translation on a multiprocessor host
US7146607B2 (en) * 2002-09-17 2006-12-05 International Business Machines Corporation Method and system for transparent dynamic optimization in a multiprocessing environment
US7496494B2 (en) * 2002-09-17 2009-02-24 International Business Machines Corporation Method and system for multiprocessor emulation on a multiprocessor host system
US7124237B2 (en) * 2002-10-03 2006-10-17 Seagate Technology Llc Virtual machine emulation in the memory space of a programmable processor
US6775810B2 (en) * 2002-10-08 2004-08-10 Sun Microsystems, Inc. Boosting simulation performance by dynamically customizing segmented object codes based on stimulus coverage
US7603664B2 (en) * 2002-10-22 2009-10-13 Sun Microsystems, Inc. System and method for marking software code
US20040095348A1 (en) * 2002-11-19 2004-05-20 Bleiweiss Avi I. Shading language interface and method
US7194736B2 (en) * 2002-12-10 2007-03-20 Intel Corporation Dynamic division optimization for a just-in-time compiler
US7533012B2 (en) * 2002-12-13 2009-05-12 Sun Microsystems, Inc. Multi-user web simulator
US7143025B2 (en) * 2002-12-13 2006-11-28 Sun Microsystems, Inc. Web simulator
US20040117778A1 (en) * 2002-12-16 2004-06-17 Sehr David C. Optimization of software code using N-bit pointer conversion
US7930490B2 (en) * 2002-12-23 2011-04-19 Siemens Industry, Inc. Method for utilizing a memory device for a programmable logic controller (PLC)
US7188062B1 (en) * 2002-12-27 2007-03-06 Unisys Corporation Configuration management for an emulator operating system
US7111287B2 (en) * 2003-01-10 2006-09-19 International Business Machines Corporation Global processor resource assignment in an assembler
US7100154B2 (en) * 2003-01-16 2006-08-29 International Business Machines Corporation Dynamic compiler apparatus and method that stores and uses persistent execution statistics
US7389501B1 (en) * 2003-02-18 2008-06-17 Microsoft Corporation System and method for register allocation using SSA construction
US7310723B1 (en) 2003-04-02 2007-12-18 Transmeta Corporation Methods and systems employing a flag for deferring exception handling to a commit or rollback point
GB0307805D0 (en) * 2003-04-04 2003-05-07 Intuwave Ltd A method of enabling source code to be used to generate a first and a second software application,each compatible with a different operating system
GB0309056D0 (en) * 2003-04-22 2003-05-28 Transitive Technologies Ltd Block translation optimizations for program code conversion
US7308682B2 (en) * 2003-04-25 2007-12-11 Intel Corporation Method and apparatus for recovering data values in dynamic runtime systems
US7159122B2 (en) * 2003-05-12 2007-01-02 International Business Machines Corporation Message digest instructions
US7284100B2 (en) 2003-05-12 2007-10-16 International Business Machines Corporation Invalidating storage, clearing buffer entries, and an instruction therefor
JP4713820B2 (ja) * 2003-05-28 2011-06-29 パナソニック株式会社 プログラム実行制御装置、プログラム実行制御方法
US20040243379A1 (en) * 2003-05-29 2004-12-02 Dominic Paulraj Ideal machine simulator with infinite resources to predict processor design performance
US7219329B2 (en) * 2003-06-13 2007-05-15 Microsoft Corporation Systems and methods providing lightweight runtime code generation
US7260815B1 (en) * 2003-06-30 2007-08-21 Vmware, Inc. Method and apparatus for managing registers in a binary translator
GB0316531D0 (en) * 2003-07-15 2003-08-20 Transitive Ltd Method and apparatus for performing native binding
US20050028132A1 (en) * 2003-07-31 2005-02-03 Srinivasamurthy Venugopal K. Application specific optimization of interpreters for embedded systems
US20050028148A1 (en) * 2003-08-01 2005-02-03 Sun Microsystems, Inc. Method for dynamic recompilation of a program
US7318222B2 (en) * 2003-08-27 2008-01-08 Sun Microsystems, Inc. Methods for execution control acquistion of a program and for executing an optimized version of a program
US7207038B2 (en) * 2003-08-29 2007-04-17 Nokia Corporation Constructing control flows graphs of binary executable programs at post-link time
DE10344847A1 (de) * 2003-09-26 2005-04-14 Philips Intellectual Property & Standards Gmbh Verfahren zum Compilieren eines Quellcode-Programms in ein maschinenlesbares Zielobjekt-Programm in einer Netzwerkumgebung
US7051301B2 (en) * 2003-10-01 2006-05-23 Hewlett-Packard Development Company, L.P. System and method for building a test case including a summary of instructions
US7584455B2 (en) * 2003-10-23 2009-09-01 Microsoft Corporation Predicate-based test coverage and generation
US20050166192A1 (en) * 2003-11-06 2005-07-28 Polcha Michael P. Run time compiler system and method
US20050149913A1 (en) * 2003-12-29 2005-07-07 Yun Wang Apparatus and methods to optimize code in view of masking status of exceptions
US7747659B2 (en) * 2004-01-05 2010-06-29 International Business Machines Corporation Garbage collector with eager read barrier
US20050154573A1 (en) * 2004-01-08 2005-07-14 Maly John W. Systems and methods for initializing a lockstep mode test case simulation of a multi-core processor design
JP4701611B2 (ja) * 2004-01-15 2011-06-15 株式会社日立製作所 動的変換方式のエミュレータ向けメモリ管理方法
US7478374B2 (en) * 2004-03-22 2009-01-13 Intel Corporation Debug system having assembler correcting register allocation errors
US8689202B1 (en) 2004-03-30 2014-04-01 Synopsys, Inc. Scheduling of instructions
US8677312B1 (en) 2004-03-30 2014-03-18 Synopsys, Inc. Generation of compiler description from architecture description
US7665070B2 (en) * 2004-04-23 2010-02-16 International Business Machines Corporation Method and apparatus for a computing system using meta program representation
CN1294495C (zh) * 2004-05-20 2007-01-10 北京大学 模拟器构造方法
JP4178278B2 (ja) * 2004-05-25 2008-11-12 インターナショナル・ビジネス・マシーンズ・コーポレーション コンパイラ装置、最適化方法、コンパイラプログラム、及び記録媒体
US9280326B1 (en) 2004-05-26 2016-03-08 Synopsys, Inc. Compiler retargeting based on instruction semantic models
CN100359470C (zh) * 2004-06-30 2008-01-02 中国科学院计算技术研究所 动静结合二进制翻译中静态信息不完备的处理方法及装置
US20060037005A1 (en) * 2004-08-15 2006-02-16 Russell Paul F Method and apparatus for increasing computer security
US7747992B2 (en) * 2004-08-23 2010-06-29 Intel Corporation Methods and apparatus for creating software basic block layouts
US20060048106A1 (en) * 2004-08-27 2006-03-02 International Business Machines Corporation Link-time profile-based method for reducing run-time image of executables
US7784039B2 (en) * 2004-09-22 2010-08-24 Panasonic Corporation Compiler, compilation method, and compilation program
US20060070042A1 (en) * 2004-09-24 2006-03-30 Muratori Richard D Automatic clocking in shared-memory co-simulation
US7624384B2 (en) * 2004-11-30 2009-11-24 Intel Corporation Apparatus, system, and method of dynamic binary translation with translation reuse
US20060195732A1 (en) * 2005-02-11 2006-08-31 Joerg Deutschle Method and system for executing test cases for a device under verification
US7913239B2 (en) * 2005-03-08 2011-03-22 International Business Machines Corporation Method and apparatus for a programming framework for pattern matching and transformation of intermediate language expression trees
US7565217B2 (en) * 2005-04-01 2009-07-21 International Business Machines Corporation Traversal of empty regions in a searchable data structure
US7805708B2 (en) * 2005-05-13 2010-09-28 Texas Instruments Incorporated Automatic tool to eliminate conflict cache misses
US7770152B1 (en) * 2005-05-20 2010-08-03 Oracle America, Inc. Method and apparatus for coordinating state and execution context of interpreted languages
US8413162B1 (en) 2005-06-28 2013-04-02 Guillermo J. Rozas Multi-threading based on rollback
US20070006189A1 (en) * 2005-06-30 2007-01-04 Intel Corporation Apparatus, system, and method of detecting modification in a self modifying code
JP4778286B2 (ja) * 2005-09-28 2011-09-21 パナソニック株式会社 コンパイラ装置
US20070169012A1 (en) * 2005-11-14 2007-07-19 Microsoft Corporation Asynchronous just-in-time compilation
FR2895103B1 (fr) * 2005-12-19 2008-02-22 Dxo Labs Sa Procede et systeme de traitement de donnees numeriques
US20070150881A1 (en) * 2005-12-22 2007-06-28 Motorola, Inc. Method and system for run-time cache logging
US9830174B2 (en) * 2005-12-22 2017-11-28 Synopsys, Inc. Dynamic host code generation from architecture description for fast simulation
US7792666B2 (en) * 2006-05-03 2010-09-07 Sony Computer Entertainment Inc. Translation block invalidation prehints in emulation of a target system on a host system
US7813909B2 (en) * 2006-05-03 2010-10-12 Sony Computer Entertainment Inc. Register mapping in emulation of a target system on a host system
US7770050B2 (en) * 2006-05-03 2010-08-03 Sony Computer Entertainment Inc. Method and apparatus for resolving clock management issues in emulation involving both interpreted and translated code
US8266605B2 (en) * 2006-02-22 2012-09-11 Wind River Systems, Inc. Method and system for optimizing performance based on cache analysis
US8615743B2 (en) * 2006-02-27 2013-12-24 Microsoft Corporation Adaptive compiled code
US7873952B2 (en) * 2006-03-09 2011-01-18 Oracle America, Inc. Code transformation to optimize fragments that implement constant loading
US7904894B2 (en) * 2006-03-29 2011-03-08 Microsoft Corporation Automatically optimize performance of package execution
US8099538B2 (en) 2006-03-29 2012-01-17 Intel Corporation Increasing functionality of a reader-writer lock
US7870544B2 (en) * 2006-04-05 2011-01-11 International Business Machines Corporation Insuring maximum code motion of accesses to DMA buffers
US7568189B2 (en) * 2006-05-03 2009-07-28 Sony Computer Entertainment Inc. Code translation and pipeline optimization
JP4884297B2 (ja) * 2006-05-26 2012-02-29 パナソニック株式会社 コンパイラ装置、コンパイル方法およびコンパイラプログラム
US9658849B2 (en) * 2006-07-06 2017-05-23 Imperas Software Ltd. Processor simulation environment
GB0613409D0 (en) * 2006-07-06 2006-08-16 Imperas Inc Technique for fast simulation of multi-processor systems with transactional coherence and consistency
US8301870B2 (en) * 2006-07-27 2012-10-30 International Business Machines Corporation Method and apparatus for fast synchronization and out-of-order execution of instructions in a meta-program based computing system
JP2008097249A (ja) * 2006-10-11 2008-04-24 Internatl Business Mach Corp <Ibm> プログラム中の命令列をより高速な命令に置換する技術
US7934208B2 (en) * 2006-10-13 2011-04-26 International Business Machines Corporation Method for transparent on-line dynamic binary optimization
US7739256B2 (en) * 2006-12-07 2010-06-15 Norman Powell Method for selling custom business software and software exchange marketplace
US8799581B2 (en) * 2007-01-05 2014-08-05 International Business Machines Corporation Cache coherence monitoring and feedback
US8671248B2 (en) * 2007-01-05 2014-03-11 International Business Machines Corporation Architecture support of memory access coloring
US8214813B2 (en) 2007-01-12 2012-07-03 Microsoft Corporation Code optimization across interfaces
MX2009007876A (es) * 2007-01-24 2009-07-31 Ibm Metodo para emular eficientemente configuraciones de codigos de condiciones de arquitectura de computadora.
US7890939B2 (en) * 2007-02-13 2011-02-15 Microsoft Corporation Partial methods
US8443029B2 (en) 2007-03-01 2013-05-14 International Business Machines Corporation Round for reround mode in a decimal floating point instruction
US7934073B2 (en) * 2007-03-14 2011-04-26 Andes Technology Corporation Method for performing jump and translation state change at the same time
US8245202B2 (en) * 2007-04-18 2012-08-14 Sony Computer Entertainment Inc. Processor emulation using speculative forward translation
US8146065B2 (en) 2007-08-13 2012-03-27 International Business Machines Corporation Running time of short running applications by effectively interleaving compilation with computation in a just-in-time environment
US20090113403A1 (en) * 2007-09-27 2009-04-30 Microsoft Corporation Replacing no operations with auxiliary code
US8527976B2 (en) * 2007-11-14 2013-09-03 Nec Laboratories America, Inc. System and method for generating error traces for concurrency bugs
US7991962B2 (en) * 2007-12-10 2011-08-02 International Business Machines Corporation System and method of using threads and thread-local storage
US8108868B2 (en) * 2007-12-18 2012-01-31 Microsoft Corporation Workflow execution plans through completion condition critical path analysis
US8060356B2 (en) 2007-12-19 2011-11-15 Sony Computer Entertainment Inc. Processor emulation using fragment level translation
US8041923B2 (en) * 2008-01-11 2011-10-18 International Business Machines Corporation Load page table entry address instruction execution based on an address translation format control field
US8041922B2 (en) * 2008-01-11 2011-10-18 International Business Machines Corporation Enhanced dynamic address translation with load real address function
US8677098B2 (en) 2008-01-11 2014-03-18 International Business Machines Corporation Dynamic address translation with fetch protection
US8037278B2 (en) 2008-01-11 2011-10-11 International Business Machines Corporation Dynamic address translation with format control
US8335906B2 (en) * 2008-01-11 2012-12-18 International Business Machines Corporation Perform frame management function instruction for clearing blocks of main storage
US8417916B2 (en) 2008-01-11 2013-04-09 International Business Machines Corporation Perform frame management function instruction for setting storage keys and clearing blocks of main storage
US7739434B2 (en) 2008-01-11 2010-06-15 International Business Machines Corporation Performing a configuration virtual topology change and instruction therefore
US8103851B2 (en) 2008-01-11 2012-01-24 International Business Machines Corporation Dynamic address translation with translation table entry format control for indentifying format of the translation table entry
US8117417B2 (en) * 2008-01-11 2012-02-14 International Business Machines Corporation Dynamic address translation with change record override
US8151083B2 (en) * 2008-01-11 2012-04-03 International Business Machines Corporation Dynamic address translation with frame management
US7734900B2 (en) 2008-01-11 2010-06-08 International Business Machines Corporation Computer configuration virtual topology discovery and instruction therefore
US8082405B2 (en) * 2008-01-11 2011-12-20 International Business Machines Corporation Dynamic address translation with fetch protection
US8019964B2 (en) * 2008-01-11 2011-09-13 International Buisness Machines Corporation Dynamic address translation with DAT protection
US7895419B2 (en) 2008-01-11 2011-02-22 International Business Machines Corporation Rotate then operate on selected bits facility and instructions therefore
US8086811B2 (en) * 2008-02-25 2011-12-27 International Business Machines Corporation Optimizations of a perform frame management function issued by pageable guests
US8176279B2 (en) * 2008-02-25 2012-05-08 International Business Machines Corporation Managing use of storage by multiple pageable guests of a computing environment
US8095773B2 (en) 2008-02-26 2012-01-10 International Business Machines Corporation Dynamic address translation with translation exception qualifier
US8291397B2 (en) * 2008-04-02 2012-10-16 International Business Machines Corporation Compiler optimized function variants for use when return codes are ignored
US8453129B2 (en) * 2008-04-24 2013-05-28 International Business Machines Corporation Using hardware interrupts to drive dynamic binary code recompilation
US8407681B2 (en) * 2008-05-23 2013-03-26 International Business Machines Corporation System and method for changing variables at runtime
US8281296B2 (en) * 2008-08-12 2012-10-02 Oracle America, Inc. Cross-ISA inlining in a system virtual machine
GB2463942B (en) * 2008-10-03 2012-08-08 Icera Inc Disassembling an executable to analyse function calls to minimise cache misses
US20100125554A1 (en) * 2008-11-18 2010-05-20 Unisys Corporation Memory Recovery Across Reboots of an Emulated Operating System
US8387026B1 (en) * 2008-12-24 2013-02-26 Google Inc. Compile-time feedback-directed optimizations using estimated edge profiles from hardware-event sampling
KR20100082185A (ko) * 2009-01-08 2010-07-16 삼성전자주식회사 플래시 메모리, 캐시 메모리, 그리고 제어기를 포함하는 사용자 장치
US8308185B2 (en) * 2009-01-30 2012-11-13 Weaver Danny C Pin-engaging drawbar and lock plate assembly
US10152504B2 (en) 2009-03-11 2018-12-11 Actian Netherlands B.V. Column-store database architecture utilizing positional delta tree update system and methods
US8438558B1 (en) 2009-03-27 2013-05-07 Google Inc. System and method of updating programs and data
US8949103B2 (en) * 2009-05-01 2015-02-03 Microsoft Corporation Program code simulator
US9117071B2 (en) 2009-06-03 2015-08-25 Apple Inc. Methods and apparatuses for secure compilation
US8677329B2 (en) 2009-06-03 2014-03-18 Apple Inc. Methods and apparatuses for a compiler server
US8527969B2 (en) * 2009-07-14 2013-09-03 Unisys Corporation Systems, methods, and computer programs for dynamic binary translation in an interpreter
US8650240B2 (en) * 2009-08-17 2014-02-11 International Business Machines Corporation Complex matrix multiplication operations with data pre-conditioning in a high performance computing architecture
US8577950B2 (en) * 2009-08-17 2013-11-05 International Business Machines Corporation Matrix multiplication operations with data pre-conditioning in a high performance computing architecture
US8752008B2 (en) * 2009-09-02 2014-06-10 Advanced Micro Devices, Inc. Lightweight service based dynamic binary rewriter framework
US8428930B2 (en) * 2009-09-18 2013-04-23 International Business Machines Corporation Page mapped spatially aware emulation of a computer instruction set
US9158566B2 (en) 2009-09-18 2015-10-13 International Business Machines Corporation Page mapped spatially aware emulation of computer instruction set
US8447583B2 (en) * 2009-09-18 2013-05-21 International Business Machines Corporation Self initialized host cell spatially aware emulation of a computer instruction set
US8301434B2 (en) 2009-09-18 2012-10-30 International Buisness Machines Corporation Host cell spatially aware emulation of a guest wild branch
US8617049B2 (en) * 2009-09-18 2013-12-31 Ethicon Endo-Surgery, Inc. Symmetrical drive system for an implantable restriction device
US8949106B2 (en) * 2009-09-18 2015-02-03 International Business Machines Corporation Just in time compiler in spatially aware emulation of a guest computer instruction set
US8510511B2 (en) * 2009-12-14 2013-08-13 International Business Machines Corporation Reducing interprocessor communications pursuant to updating of a storage key
US8918601B2 (en) * 2009-12-14 2014-12-23 International Business Machines Corporation Deferred page clearing in a multiprocessor computer system
US8930635B2 (en) 2009-12-14 2015-01-06 International Business Machines Corporation Page invalidation processing with setting of storage key to predefined value
US8806179B2 (en) 2009-12-15 2014-08-12 International Business Machines Corporation Non-quiescing key setting facility
US8418156B2 (en) * 2009-12-16 2013-04-09 Intel Corporation Two-stage commit (TSC) region for dynamic binary optimization in X86
US8505034B2 (en) 2009-12-17 2013-08-06 Amazon Technologies, Inc. Automated service interface optimization
US8516230B2 (en) 2009-12-29 2013-08-20 International Business Machines Corporation SPE software instruction cache
US8850166B2 (en) * 2010-02-18 2014-09-30 International Business Machines Corporation Load pair disjoint facility and instruction therefore
US8438340B2 (en) * 2010-02-18 2013-05-07 International Business Machines Corporation Executing atomic store disjoint instructions
US8914619B2 (en) 2010-06-22 2014-12-16 International Business Machines Corporation High-word facility for extending the number of general purpose registers available to instructions
US9195623B2 (en) 2010-06-23 2015-11-24 International Business Machines Corporation Multiple address spaces per adapter with address translation
US8504754B2 (en) 2010-06-23 2013-08-06 International Business Machines Corporation Identification of types of sources of adapter interruptions
US9342352B2 (en) 2010-06-23 2016-05-17 International Business Machines Corporation Guest access to address spaces of adapter
US8468284B2 (en) 2010-06-23 2013-06-18 International Business Machines Corporation Converting a message signaled interruption into an I/O adapter event notification to a guest operating system
US9213661B2 (en) 2010-06-23 2015-12-15 International Business Machines Corporation Enable/disable adapters of a computing environment
US8621112B2 (en) 2010-06-23 2013-12-31 International Business Machines Corporation Discovery by operating system of information relating to adapter functions accessible to the operating system
US8918573B2 (en) 2010-06-23 2014-12-23 International Business Machines Corporation Input/output (I/O) expansion response processing in a peripheral component interconnect express (PCIe) environment
US8745292B2 (en) 2010-06-23 2014-06-03 International Business Machines Corporation System and method for routing I/O expansion requests and responses in a PCIE architecture
US8615645B2 (en) 2010-06-23 2013-12-24 International Business Machines Corporation Controlling the selectively setting of operational parameters for an adapter
US8645606B2 (en) 2010-06-23 2014-02-04 International Business Machines Corporation Upbound input/output expansion request and response processing in a PCIe architecture
US8572635B2 (en) 2010-06-23 2013-10-29 International Business Machines Corporation Converting a message signaled interruption into an I/O adapter event notification
US8615622B2 (en) 2010-06-23 2013-12-24 International Business Machines Corporation Non-standard I/O adapters in a standardized I/O architecture
US8510599B2 (en) 2010-06-23 2013-08-13 International Business Machines Corporation Managing processing associated with hardware events
US8626970B2 (en) 2010-06-23 2014-01-07 International Business Machines Corporation Controlling access by a configuration to an adapter function
US8635430B2 (en) 2010-06-23 2014-01-21 International Business Machines Corporation Translation of input/output addresses to memory addresses
US8650337B2 (en) 2010-06-23 2014-02-11 International Business Machines Corporation Runtime determination of translation formats for adapter functions
US8650335B2 (en) 2010-06-23 2014-02-11 International Business Machines Corporation Measurement facility for adapter functions
US8478922B2 (en) 2010-06-23 2013-07-02 International Business Machines Corporation Controlling a rate at which adapter interruption requests are processed
US8639858B2 (en) 2010-06-23 2014-01-28 International Business Machines Corporation Resizing address spaces concurrent to accessing the address spaces
US8683108B2 (en) 2010-06-23 2014-03-25 International Business Machines Corporation Connected input/output hub management
US8549182B2 (en) 2010-06-23 2013-10-01 International Business Machines Corporation Store/store block instructions for communicating with adapters
US8505032B2 (en) 2010-06-23 2013-08-06 International Business Machines Corporation Operating system notification of actions to be taken responsive to adapter events
US8566480B2 (en) 2010-06-23 2013-10-22 International Business Machines Corporation Load instruction for communicating with adapters
US8645767B2 (en) 2010-06-23 2014-02-04 International Business Machines Corporation Scalable I/O adapter function level error detection, isolation, and reporting
US8407701B2 (en) 2010-06-24 2013-03-26 International Business Machines Corporation Facilitating quiesce operations within a logically partitioned computer system
US8595469B2 (en) 2010-06-24 2013-11-26 International Business Machines Corporation Diagnose instruction for serializing processing
US9851969B2 (en) 2010-06-24 2017-12-26 International Business Machines Corporation Function virtualization facility for function query of a processor
US10521231B2 (en) 2010-06-24 2019-12-31 International Business Machines Corporation Function virtualization facility for blocking instruction function of a multi-function instruction of a virtual processor
US8522225B2 (en) 2010-06-25 2013-08-27 International Business Machines Corporation Rewriting branch instructions using branch stubs
US20110320786A1 (en) 2010-06-25 2011-12-29 International Business Machines Corporation Dynamically Rewriting Branch Instructions in Response to Cache Line Eviction
US9459851B2 (en) 2010-06-25 2016-10-04 International Business Machines Corporation Arranging binary code based on call graph partitioning
US8631225B2 (en) 2010-06-25 2014-01-14 International Business Machines Corporation Dynamically rewriting branch instructions to directly target an instruction cache location
US9600281B2 (en) 2010-07-12 2017-03-21 International Business Machines Corporation Matrix multiplication operations using pair-wise load and splat operations
US8782434B1 (en) 2010-07-15 2014-07-15 The Research Foundation For The State University Of New York System and method for validating program execution at run-time
US20120124555A1 (en) * 2010-11-11 2012-05-17 Codekko Software, Inc. Optimization of Compiled Control Objects
US9063743B2 (en) * 2010-11-23 2015-06-23 Sap Se Model-based programming, configuration, and integration of networked embedded devices
US20120198458A1 (en) * 2010-12-16 2012-08-02 Advanced Micro Devices, Inc. Methods and Systems for Synchronous Operation of a Processing Device
KR20120083803A (ko) * 2011-01-18 2012-07-26 삼성전자주식회사 가상머신을 위한 추가코드 생성장치 및 방법
EP2668565B1 (de) 2011-01-27 2019-11-06 Intel Corporation Gastinstruktion für ein mapping auf basis nativer instruktionen mithilfe eines look-aside-umwandlungspuffers auf einem prozessor
WO2012103245A2 (en) 2011-01-27 2012-08-02 Soft Machines Inc. Guest instruction block with near branching and far branching sequence construction to native instruction block
WO2012103367A2 (en) 2011-01-27 2012-08-02 Soft Machines, Inc. Guest to native block address mappings and management of native code storage
WO2012103359A2 (en) 2011-01-27 2012-08-02 Soft Machines, Inc. Hardware acceleration components for translating guest instructions to native instructions
WO2012103373A2 (en) 2011-01-27 2012-08-02 Soft Machines, Inc. Variable caching structure for managing physical storage
WO2012103253A2 (en) 2011-01-27 2012-08-02 Soft Machines, Inc. Multilevel conversion table cache for translating guest instructions to native instructions
US9495136B2 (en) * 2011-01-28 2016-11-15 International Business Machines Corporation Using aliasing information for dynamic binary optimization
WO2012143760A1 (en) * 2011-04-20 2012-10-26 Freescale Semiconductor, Inc. Method and apparatus for generating resource efficient computer program code
US8533714B2 (en) 2011-05-03 2013-09-10 International Business Machines Corporation Dynamic virtual machine domain configuration and virtual machine relocation management
US8782645B2 (en) * 2011-05-11 2014-07-15 Advanced Micro Devices, Inc. Automatic load balancing for heterogeneous cores
US9032526B2 (en) 2011-05-12 2015-05-12 Microsoft Technology Licensing, Llc Emulating mixed-code programs using a virtual machine instance
US8918797B2 (en) 2011-06-10 2014-12-23 International Business Machines Corporation Processing operator message commands
US9021180B2 (en) 2011-06-10 2015-04-28 International Business Machines Corporation Clearing blocks of storage class memory
US9323668B2 (en) 2011-06-10 2016-04-26 International Business Machines Corporation Deconfigure storage class memory command
US9037907B2 (en) 2011-06-10 2015-05-19 International Business Machines Corporation Operator message commands for testing a coupling facility
US8689240B2 (en) 2011-06-10 2014-04-01 International Business Machines Corporation Transmitting operator message commands to a coupling facility
US9021179B2 (en) 2011-06-10 2015-04-28 International Business Machines Corporation Store storage class memory information command
US8799522B2 (en) 2011-06-10 2014-08-05 International Business Machines Corporation Executing a start operator message command
US8560737B2 (en) 2011-06-10 2013-10-15 International Business Machines Corporation Managing operator message buffers in a coupling facility
US9116789B2 (en) 2011-06-10 2015-08-25 International Business Machines Corporation Chaining move specification blocks
US9058243B2 (en) 2011-06-10 2015-06-16 International Business Machines Corporation Releasing blocks of storage class memory
US9021226B2 (en) 2011-06-10 2015-04-28 International Business Machines Corporation Moving blocks of data between main memory and storage class memory
US9116788B2 (en) 2011-06-10 2015-08-25 International Business Machines Corporation Using extended asynchronous data mover indirect data address words
US9116634B2 (en) 2011-06-10 2015-08-25 International Business Machines Corporation Configure storage class memory command
US9058275B2 (en) 2011-06-10 2015-06-16 International Business Machines Corporation Data returned responsive to executing a start subchannel instruction
US8549094B2 (en) 2011-06-30 2013-10-01 International Business Machines Corporation Facilitating communication between isolated memory spaces of a communications environment
US9116685B2 (en) 2011-07-19 2015-08-25 Qualcomm Incorporated Table call instruction for frequently called functions
JP2013061810A (ja) * 2011-09-13 2013-04-04 Fujitsu Ltd 情報処理装置、情報処理装置制御方法及び中間コード命令実行プログラム
US8600727B2 (en) * 2011-10-11 2013-12-03 Unisys Corporation Streamlined execution of emulated code using block-based translation mode
US8806452B2 (en) * 2011-11-10 2014-08-12 International Business Machines Corporation Transformation of computer programs and eliminating errors
US20130132061A1 (en) * 2011-11-18 2013-05-23 Michael J. Rieschl Just-in-time static translation system for emulated computing environments
US10365900B2 (en) 2011-12-23 2019-07-30 Dataware Ventures, Llc Broadening field specialization
WO2013096894A1 (en) * 2011-12-23 2013-06-27 The Arizona Board Of Regents On Behalf Of The University Of Arizona Methods of micro-specialization in database management systems
US9329861B2 (en) 2011-12-29 2016-05-03 International Business Machines Corporation Convert to zoned format from decimal floating point format
US9335993B2 (en) 2011-12-29 2016-05-10 International Business Machines Corporation Convert from zoned format to decimal floating point format
US8850450B2 (en) 2012-01-18 2014-09-30 International Business Machines Corporation Warning track interruption facility
US9104508B2 (en) 2012-01-18 2015-08-11 International Business Machines Corporation Providing by one program to another program access to a warning track facility
US9110878B2 (en) 2012-01-18 2015-08-18 International Business Machines Corporation Use of a warning track interruption facility by a program
DE112013000453B4 (de) 2012-01-31 2023-05-17 International Business Machines Corporation Hauptverzweigungsanweisungen mit Transaktionsspeicher
RU2491615C1 (ru) 2012-02-24 2013-08-27 Закрытое акционерное общество "Лаборатория Касперского" Система и способ формирования записей для обнаружения программного обеспечения
US9459867B2 (en) 2012-03-15 2016-10-04 International Business Machines Corporation Instruction to load data up to a specified memory boundary indicated by the instruction
US9459864B2 (en) 2012-03-15 2016-10-04 International Business Machines Corporation Vector string range compare
US9454367B2 (en) 2012-03-15 2016-09-27 International Business Machines Corporation Finding the length of a set of character data having a termination character
US9710266B2 (en) 2012-03-15 2017-07-18 International Business Machines Corporation Instruction to compute the distance to a specified memory boundary
US9459868B2 (en) 2012-03-15 2016-10-04 International Business Machines Corporation Instruction to load data up to a dynamically determined memory boundary
US9715383B2 (en) 2012-03-15 2017-07-25 International Business Machines Corporation Vector find element equal instruction
US9268566B2 (en) 2012-03-15 2016-02-23 International Business Machines Corporation Character data match determination by loading registers at most up to memory block boundary and comparing
US9454366B2 (en) 2012-03-15 2016-09-27 International Business Machines Corporation Copying character data having a termination character from one memory location to another
US9280347B2 (en) 2012-03-15 2016-03-08 International Business Machines Corporation Transforming non-contiguous instruction specifiers to contiguous instruction specifiers
US9588762B2 (en) 2012-03-15 2017-03-07 International Business Machines Corporation Vector find element not equal instruction
US9922090B1 (en) 2012-03-27 2018-03-20 Actian Netherlands, B.V. System and method for automatic vertical decomposition of a table for improving input/output and memory utilization in a database
CN103365931B (zh) * 2012-04-10 2016-12-14 南京中兴新软件有限责任公司 性能分析工具中快速定位函数性能记录的方法及装置
US9367292B2 (en) * 2012-06-11 2016-06-14 Empire Technology Development Llc Modulating dynamic optimizations of a computer program
US9367323B2 (en) 2012-06-15 2016-06-14 International Business Machines Corporation Processor assist facility
US10656945B2 (en) 2012-06-15 2020-05-19 International Business Machines Corporation Next instruction access intent instruction for indicating usage of a storage operand by one or more instructions subsequent to a next sequential instruction
US9442737B2 (en) 2012-06-15 2016-09-13 International Business Machines Corporation Restricting processing within a processor to facilitate transaction completion
US9384004B2 (en) 2012-06-15 2016-07-05 International Business Machines Corporation Randomized testing within transactional execution
US9740549B2 (en) 2012-06-15 2017-08-22 International Business Machines Corporation Facilitating transaction completion subsequent to repeated aborts of the transaction
US8966324B2 (en) 2012-06-15 2015-02-24 International Business Machines Corporation Transactional execution branch indications
US8880959B2 (en) 2012-06-15 2014-11-04 International Business Machines Corporation Transaction diagnostic block
US8682877B2 (en) 2012-06-15 2014-03-25 International Business Machines Corporation Constrained transaction execution
US9348642B2 (en) 2012-06-15 2016-05-24 International Business Machines Corporation Transaction begin/end instructions
US9361115B2 (en) 2012-06-15 2016-06-07 International Business Machines Corporation Saving/restoring selected registers in transactional processing
US9436477B2 (en) 2012-06-15 2016-09-06 International Business Machines Corporation Transaction abort instruction
DE102013210839B4 (de) 2012-06-15 2023-06-07 International Business Machines Corporation Einschränken der Verarbeitung innerhalb eines Prozessors zum Erleichtern der Ausführung einer Transaktion
US10437602B2 (en) 2012-06-15 2019-10-08 International Business Machines Corporation Program interruption filtering in transactional execution
US8688661B2 (en) 2012-06-15 2014-04-01 International Business Machines Corporation Transactional processing
US9448796B2 (en) 2012-06-15 2016-09-20 International Business Machines Corporation Restricted instructions in transactional execution
DE102013210160A1 (de) 2012-06-15 2013-12-19 International Business Machines Corporation Erleichtern der Ausführung einer Transaktion nach wiederholten Abbrüchen der Transaktion
US9772854B2 (en) 2012-06-15 2017-09-26 International Business Machines Corporation Selectively controlling instruction execution in transactional processing
US9182984B2 (en) 2012-06-15 2015-11-10 International Business Machines Corporation Local clearing control
US20130339680A1 (en) 2012-06-15 2013-12-19 International Business Machines Corporation Nontransactional store instruction
US9317460B2 (en) 2012-06-15 2016-04-19 International Business Machines Corporation Program event recording within a transactional environment
US9336046B2 (en) 2012-06-15 2016-05-10 International Business Machines Corporation Transaction abort processing
US9098308B2 (en) * 2012-06-26 2015-08-04 Marvell World Trade Ltd. Method and apparatus for code performance analysis based on execution trace information
US20140047423A1 (en) * 2012-08-09 2014-02-13 Filip J. Pizlo Runtime State Based Code Re-Optimization
JP5998764B2 (ja) * 2012-09-04 2016-09-28 富士通株式会社 情報処理装置、ログ出力方法およびログ出力プログラム
US9122873B2 (en) 2012-09-14 2015-09-01 The Research Foundation For The State University Of New York Continuous run-time validation of program execution: a practical approach
US9069782B2 (en) 2012-10-01 2015-06-30 The Research Foundation For The State University Of New York System and method for security and privacy aware virtual machine checkpointing
US9471308B2 (en) 2013-01-23 2016-10-18 International Business Machines Corporation Vector floating point test data class immediate instruction
US9823924B2 (en) 2013-01-23 2017-11-21 International Business Machines Corporation Vector element rotate and insert under mask instruction
US9715385B2 (en) 2013-01-23 2017-07-25 International Business Machines Corporation Vector exception code
US9804840B2 (en) 2013-01-23 2017-10-31 International Business Machines Corporation Vector Galois Field Multiply Sum and Accumulate instruction
US9778932B2 (en) 2013-01-23 2017-10-03 International Business Machines Corporation Vector generate mask instruction
US9513906B2 (en) 2013-01-23 2016-12-06 International Business Machines Corporation Vector checksum instruction
US9047403B2 (en) * 2013-02-11 2015-06-02 International Business Machines Corporation Debugger with previous version feature
US11507574B1 (en) 2013-03-13 2022-11-22 Actian Netherlands B.V. Adaptive selection of a processing method based on observed performance for improved and robust system efficiency
US9201629B2 (en) 2013-03-14 2015-12-01 International Business Machines Corporation Instruction for performing a pseudorandom number seed operation
US8873750B2 (en) 2013-03-14 2014-10-28 International Business Machines Corporation Instruction for performing a pseudorandom number generate operation
WO2014151652A1 (en) 2013-03-15 2014-09-25 Soft Machines Inc Method and apparatus to allow early dependency resolution and data forwarding in a microprocessor
CN105122206B (zh) 2013-03-15 2018-11-09 英特尔公司 用于支持推测的访客返回地址栈仿真的方法和装置
US9582279B2 (en) 2013-03-15 2017-02-28 International Business Machines Corporation Execution of condition-based instructions
US9396097B2 (en) * 2013-03-17 2016-07-19 Typemock Ltd. Methods, circuits, devices, systems and associated computer executable code for testing software code
US10089218B2 (en) * 2013-03-17 2018-10-02 Typemock Ltd. Methods circuits apparatuses systems and associated computer executable code for generating a software unit test
US9348596B2 (en) 2013-06-28 2016-05-24 International Business Machines Corporation Forming instruction groups based on decode time instruction optimization
US9372695B2 (en) 2013-06-28 2016-06-21 Globalfoundries Inc. Optimization of instruction groups across group boundaries
US9513924B2 (en) 2013-06-28 2016-12-06 Globalfoundries Inc. Predictor data structure for use in pipelined processing
US9619230B2 (en) 2013-06-28 2017-04-11 International Business Machines Corporation Predictive fetching and decoding for selected instructions
US9361144B2 (en) 2013-06-28 2016-06-07 Globalfoundries Inc. Predictive fetching and decoding for selected return instructions
WO2015056098A2 (en) * 2013-10-18 2015-04-23 Marvell World Trade Ltd. Systems and methods for register allocation
US9600256B2 (en) * 2013-10-18 2017-03-21 Microsoft Technology Licensing, Llc Incrementally compiling software artifacts from an interactive development environment
US10318299B2 (en) 2013-10-31 2019-06-11 International Business Machines Corporation Reading a register pair by writing a wide register
US9201635B2 (en) * 2013-12-30 2015-12-01 Unisys Corporation Just-in-time dynamic translation for translation, compilation, and execution of non-native instructions
US8893294B1 (en) 2014-01-21 2014-11-18 Shape Security, Inc. Flexible caching
CN103838616B (zh) * 2014-03-05 2017-04-05 北京工业大学 基于树型程序分支的计算机程序即时编译方法
US10120681B2 (en) 2014-03-14 2018-11-06 International Business Machines Corporation Compare and delay instructions
US9454370B2 (en) 2014-03-14 2016-09-27 International Business Machines Corporation Conditional transaction end instruction
US9558032B2 (en) 2014-03-14 2017-01-31 International Business Machines Corporation Conditional instruction end operation
US9588774B2 (en) 2014-03-18 2017-03-07 International Business Machines Corporation Common boot sequence for control utility able to be initialized in multiple architectures
US9582295B2 (en) 2014-03-18 2017-02-28 International Business Machines Corporation Architectural mode configuration
US9916185B2 (en) 2014-03-18 2018-03-13 International Business Machines Corporation Managing processing associated with selected architectural facilities
US9558096B2 (en) * 2014-03-21 2017-01-31 Marvell World Trade Ltd. Method and apparatus for supporting performance analysis
US9256546B2 (en) 2014-03-31 2016-02-09 International Business Machines Corporation Transparent code patching including updating of address translation structures
US9569115B2 (en) 2014-03-31 2017-02-14 International Business Machines Corporation Transparent code patching
US9824021B2 (en) 2014-03-31 2017-11-21 International Business Machines Corporation Address translation structures to provide separate translations for instruction fetches and data accesses
US9483295B2 (en) 2014-03-31 2016-11-01 International Business Machines Corporation Transparent dynamic code optimization
US9734083B2 (en) 2014-03-31 2017-08-15 International Business Machines Corporation Separate memory address translations for instruction fetches and data accesses
US9720661B2 (en) 2014-03-31 2017-08-01 International Businesss Machines Corporation Selectively controlling use of extended mode features
US9858058B2 (en) 2014-03-31 2018-01-02 International Business Machines Corporation Partition mobility for partitions with extended code
US9715449B2 (en) 2014-03-31 2017-07-25 International Business Machines Corporation Hierarchical translation structures providing separate translations for instruction fetches and data accesses
CN104049949B (zh) * 2014-05-30 2016-10-05 南阳理工学院 一种面向bswap指令的窥孔优化方法
EP3012764A1 (de) * 2014-10-24 2016-04-27 Thomson Licensing Steuerflussdiagrammglättungsvorrichtung und -verfahren
US10897616B2 (en) * 2014-12-08 2021-01-19 Harmonic, Inc. Dynamic allocation of CPU cycles vis-a-vis virtual machines in video stream processing
US10284646B2 (en) * 2014-12-17 2019-05-07 International Business Machines Corporation Application multi-versioning in a traditional language environment
US9495303B2 (en) * 2015-02-03 2016-11-15 Intel Corporation Fine grained address remapping for virtualization
JP6559793B2 (ja) * 2015-04-10 2019-08-14 グーグル エルエルシー 共有オブジェクト・レベルにおけるバイナリ変換
JP6678185B2 (ja) * 2015-04-10 2020-04-08 グーグル エルエルシー ネイティブ・クライアントへのバイナリ変換
EP3106982B1 (de) * 2015-06-18 2021-03-10 ARM Limited Bestimmung von zweigkonvergenz in einer sequenz von programmbefehlen
US10048952B2 (en) * 2015-11-11 2018-08-14 Oracle International Corporation Compiler optimized data model evaluation
US10733099B2 (en) 2015-12-14 2020-08-04 Arizona Board Of Regents On Behalf Of The University Of Arizona Broadening field specialization
US9971581B1 (en) * 2015-12-28 2018-05-15 Wells Fargo Bank, N.A. Programming language conversion
CN107665125B (zh) * 2016-07-29 2021-03-09 北京小米移动软件有限公司 执行操作指令的方法及装置
US9965374B2 (en) * 2016-08-26 2018-05-08 Qualcomm Incorporated Profile guided indirect function call check for control flow integrity
CN106775913B (zh) * 2016-12-16 2019-07-09 华东师范大学 一种目标代码控制流图生成方法
US10114573B1 (en) * 2017-04-26 2018-10-30 International Business Machines Corporation Dynamic reduction of stack-overflow errors in a recursive data-serialization algorithm
US10089235B1 (en) 2017-07-28 2018-10-02 Citrix Systems, Inc. Dynamic trim processing with disk caching
US10474442B2 (en) * 2017-09-29 2019-11-12 Intel Corporation Methods and apparatus to perform region formation for a dynamic binary translation processor
US10491524B2 (en) 2017-11-07 2019-11-26 Advanced Micro Devices, Inc. Load balancing scheme
JP7035751B2 (ja) * 2018-04-12 2022-03-15 富士通株式会社 コード変換装置、コード変換方法、及びコード変換プログラム
US10698668B1 (en) * 2018-05-29 2020-06-30 Amazon Technologies, Inc. Custom code transformations during compilation process
JP7163697B2 (ja) * 2018-09-28 2022-11-01 富士通株式会社 生成プログラム,情報処理装置及び生成方法
US10970073B2 (en) * 2018-10-02 2021-04-06 International Business Machines Corporation Branch optimization during loading
CN109491918B (zh) * 2018-11-22 2020-05-01 中国人民解放军战略支援部队信息工程大学 一种汇编冗余指令的检测方法及装置
CN111435309A (zh) * 2019-01-11 2020-07-21 中标软件有限公司 一种寄存器分配优化实现方法
US11455153B2 (en) * 2019-03-18 2022-09-27 Advanced Micro Devices, Inc. Dynamic instances semantics
CN109918132B (zh) * 2019-03-26 2021-04-16 龙芯中科技术股份有限公司 一种指令安装方法、装置、电子设备及存储介质
CN111026398B (zh) * 2019-10-28 2023-08-11 贝壳技术有限公司 基于缓存的数据集成的构建方法与构建系统
CN112785482A (zh) 2019-11-07 2021-05-11 英特尔公司 用于将可执行对象适配到处理单元的系统和方法
US11677574B1 (en) 2020-07-02 2023-06-13 Intrado Corporation Automated conference sessions generated to manage application development
US11216257B1 (en) * 2020-07-02 2022-01-04 Intrado Corporation Automated conference sessions generated to manage application development
US11526336B2 (en) * 2021-03-15 2022-12-13 Fujitsu Limited Community-oriented, cloud-based digital annealing platform
CN113377378A (zh) * 2021-07-02 2021-09-10 北京百度网讯科技有限公司 用于小程序的处理方法、装置、设备及存储介质
US20230305992A1 (en) * 2022-03-25 2023-09-28 Nokia Solutions And Networks Oy Processor using target instructions

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5751982A (en) * 1995-03-31 1998-05-12 Apple Computer, Inc. Software emulation system with dynamic translation of emulated instructions for increased processing speed

Family Cites Families (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
GB2240861A (en) 1990-02-09 1991-08-14 Hewlett Packard Co Apparatus and method for adapting computer program from one operating environment to another
JPH06282437A (ja) 1993-03-30 1994-10-07 Hitachi Ltd オブジェクト属性のアクセス方式
US5757982A (en) * 1994-10-18 1998-05-26 Hewlett-Packard Company Quadrantal scaling of dot matrix data
US5761477A (en) * 1995-12-04 1998-06-02 Microsoft Corporation Methods for safe and efficient implementations of virtual machines
US6115809A (en) * 1998-04-30 2000-09-05 Hewlett-Packard Company Compiling strong and weak branching behavior instruction blocks to separate caches for dynamic and static prediction
US6158047A (en) * 1998-07-08 2000-12-05 Hewlett-Packard Company Client/server system for fast, user transparent and memory efficient computer language translation

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5751982A (en) * 1995-03-31 1998-05-12 Apple Computer, Inc. Software emulation system with dynamic translation of emulated instructions for increased processing speed

Also Published As

Publication number Publication date
CN1308818C (zh) 2007-04-04
CN1270348A (zh) 2000-10-18
US20020147969A1 (en) 2002-10-10
DE19945992A1 (de) 2000-05-04
JP2000132408A (ja) 2000-05-12
JP3553834B2 (ja) 2004-08-11
US6463582B1 (en) 2002-10-08

Similar Documents

Publication Publication Date Title
DE19945992B4 (de) Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren
DE69826700T2 (de) Kompilerorientiertes gerät zur parallelkompilation, simulation und ausführung von rechnerprogrammen und hardwaremodellen
DE112012000303B4 (de) Dynamische binäre Optimierung
EP0502857B1 (de) Verfahren zur dynamischen bindung von definierbaren programmelementen eines interaktiven datenverarbeitungssystems
DE69924857T2 (de) Programm-kode-umwandlung
DE69722138T2 (de) Code-Optimierer für Pipeline-Rechner
DE69909945T2 (de) Verfahren und Anordnung zur Korrelation von Profildaten dynamisch erzeugt durch ein optimiertes ausführbares Programm mit Quellcodeanweisungen
DE10297624T5 (de) Steuerung von Kompatibilitätsgraden von Binärcode-Übersetzungen zwischen Befehlssatzarchitekturen
DE69727177T2 (de) Emulation von asynchronen Signalen mit Verzweigungsmechanismus
DE19934424A1 (de) Verfahren, Vorrichtung und Computer-Programm-Produkt zur Optimierung von Registern in einem Stapel unter Verwendung eines Register-Zuordners
DE102016110195A1 (de) Erzeugen von Code in statisch typisierten Programmiersprachen für eine dynamisch typisierte array-basierte Sprache
EP1738257A1 (de) Verfahren zum vermeiden von dateninkonsistenz zwischen zugriffen verschiedener funktionen einer anwendung auf eine globale variable in einer datenverarbeitungsanlage
Launchbury et al. Monadic state: Axiomatization and type safety
Appel et al. Callee-save registers in continuation-passing style
AU773511B2 (en) Method and apparatus for producing a sparse interference graph
DE19963832A1 (de) Programmprofilierung
WO1998001805A1 (de) Verfahren zur migration von programmen mit portierbaren und nicht-portierbaren programmteilen
EP1010070B1 (de) Verfahren zum umsetzen eines objektcodes in einen programmcode
Pizka Design and implementation of the GNU INSEL-compiler gic
DE102019105418B3 (de) Verfahren zum Erzeugen einer Darstellung einer Programmlogik, Dekompiliervorrichtung, Rekompiliersystem und Computerprogrammprodukte
WO1992016894A1 (de) Verfahren zum maschinellen erstellen eines aus mehreren modulen zu bindenden programmes
Plasmeijer Clean: a programming environment based on term graph rewriting
DE19617842A1 (de) Verfahren zur Codetransformation
DE60030189T2 (de) Befehlsübersetzungsverfahren
Masinter et al. Local optimization in a compiler for stack-based Lisp machines

Legal Events

Date Code Title Description
OP8 Request for examination as to paragraph 44 patent law
8364 No opposition during term of opposition
8328 Change in the person/name/address of the agent

Representative=s name: SEEGER SEEGER LINDNER PARTNERSCHAFT PATENTANWAELTE

R119 Application deemed withdrawn, or ip right lapsed, due to non-payment of renewal fee