-
GEBIET DER
ERFINDUNG
-
Die
Erfindung betrifft allgemein interpretierende Laufzeitumgebungen,
und spezieller betrifft sie die Erzeugung eines Codes in einer Compilersprache
zur Ausführung
in einer interpretierenden Laufzeitumgebung.
-
COPYRIGHTHINWEIS/-ERLAUBNIS
-
Ein
Teil der Offenbarung dieses Patentdokuments enthält Material, das dem Copyrightschutz
unterliegt. Der Inhaber des Copyrights hat keinen Einwand gegen
beliebige Personen hinsichtlich der Faksimilevervielfältigung
des Patentdokuments oder der Patentoffenbarung, wie sie in der Patentakte
oder Datensätzen des
Patent and Trademark Office erscheint, behält sich jedoch ansonsten alle
beliebigen Rechte aus dem Copyright vor. Der folgende Hinweis gilt
für die
Software und die Daten, wie sie unten beschrieben sind, sowie für die hier
vorliegenden Zeichnungen: Copyright © 1997,
Microsoft Corporation, alle Rechte vorbehalten.
-
HINTERGRUND
DER ERFINDUNG
-
Interpretiersprachen
werden in weitem Umfang dazu verwendet, Computerprogramme über diverse Hardwareplattformen
portierbar zu machen. Dasselbe Interpretiersprachenprogramm kann
leicht von einem Computertyp zu einem anderen verschoben werden;
es muss nur die Laufzeitumgebung, die die Interpretation ausführt, speziell
auf die zugrundeliegende Hardware zugeschnitten werden.
-
Dieser
Vorteil einer Interpretiersprache ist auch ihr größ ter Nachteil.
Ein in einer Interpretiersprache geschriebenes Programm wird deutlich
langsamer als dasselbe in einer Compilersprache geschriebene Programm
auf demselben Computer ausgeführt.
Bisherige Lösungen
für das
Problem enthalten alle wesentliche Mängel.
-
Z.
B. wurden Nativcodecompiler implementiert, die die Anweisungen der
Interpretiersprache in entsprechende Anweisungen in einer Sprache
wandeln, die für
die spezielle Hardware nativ ist. Dann wird das Nativcodeprogramm
ausgeführt.
Da jedoch das compilierte Nativcodeprogramm nicht in einer interpretierenden
Laufzeitumgebung läuft,
sind für
es keinerlei Funktionen verfügbar,
die durch die Laufzeitumgebung bereitgestellt werden. Ein derartiges
Programm ist häufig
auch viel größer als
das Interpretiersprachenprogramm, was auf minimal konfigurierten
Computern zu Ressourcenproblemen führt.
-
Es
wurde eine andere Vorgehensweise ergriffen, um ein Interpretiersprachenprogramm
insgesamt in ein Programm in einer Compilersprache zu wandeln, wobei
dieselben Funktionen bewerkstelligt werden. Derartige Bemühungen haben
sich als äußerst komplex
in der Realisierung erwiesen, und sie führen zu ineffizientem compiliertem
Code.
-
Daher
ist eine Art zum Erhöhen
des Funktionsvermögens
eines Interpretiersprachenprogramms erforderlich, während für Zugriff
auf die Funktionen der entsprechenden Laufzeitumgebung gesorgt ist,
wobei dies auf eine Weise erfolgen soll, die Systemressourcen bewahrt.
-
Das
Dokument "Harissa:
A flexible and efficient Java environment mixing bytecode and compiled
code", 16. Juni
1997, Proceedings of Object-Oriented Technologies and System, Usenix
Assoc., Berkeley, CA, USA, Seiten 1–20 von Müller G. et al. aus dem Stand
der Technik beschreibt ebenfalls Funktionsprobleme hinsichtlich
der Interpretation von Java-Programmen.
-
ZUSAMMENFASSUNG
DER ERFINDUNG
-
Die
o. g. Mängel,
Nachteile und Probleme werden durch die Erfindung berücksichtigt,
die durch Lesen und Studieren der folgenden Beschreibung verständlich werden
wird.
-
Ein
Inlinecodegenerator, der extern zu einer Laufzeitumgebung arbeitet,
reproduziert die Verarbeitung einer Innenschleife eines Interpretierers
für die
Laufzeitumgebung. Der Inlinecodegenerator verarbeitet ein Programm
in der Interpretiersprache, und er produziert ein entsprechendes
Programm in einer Compilersprache. Das Compilersprachenprogramm
wird unter Verwendung eines Standardcompilers, der für die zugrundeliegende
Hardware spezifisch ist, in ein Programm in einer nativen Sprache
compiliert. Das Programm in der nativen Sprache läuft innerhalb
der Laufzeitumgebung auf dieselbe Weise als sei es durch den Interpretierer interpretiert
worden.
-
Der
Inlinecodegenerator beseitigt den Overhead in Zusammenhang mit laufenden
Programmen in interpretiertem Code durch Exportieren der Verarbeitungszeit
für die
Innenschleife an den Codegenerator. Da der Inlinecodegenerator vorhandene
Interpretiersprachenprogramme als Eingabe akzeptiert, bleiben die
durch solche Programme erzielten Portierbarkeitsvorteile erhalten,
während
gleichzeitig die Ausführung
solcher Programme optimiert wird, wenn sie auf einem speziellen
Computer laufen. Ferner stehen, da das sich ergebende Programm in
einer nativen Sprache innerhalb des Rahmens der Laufzeitumgebung
arbeitet, Funktionen und Routinen, wie sie durch diese bereitgestellt
werden, dem Programm in einer nativen Sprache zu Verfügung.
-
Die
Erfindung beschreibt Systeme, Clients, Server, Methoden und computer-lesbare
Medien verschiedenen Umfangs. Zusätzlich zu den Gesichtspunkten
und Vorteilen der Erfindung, wie sie in dieser Zusammenfassung beschrieben
sind, werden weitere Gesichtspunkte und Vorteile der Erfindung unter
Bezugnahme auf die Zeichnungen und durch Lesen der folgenden detaillierten
Beschreibung ersichtlich.
-
KURZE BESCHREIBUNG
DER ZEICHNUNGEN
-
1 zeigt
ein Diagramm der Hardware und der Betriebsumgebung, in deren Zusammenhang
Ausführungsformen
der Erfindung realisiert werden können;
-
2A–C sind Diagramme zum Veranschaulichen eines Überblicks
einer beispielhaften Ausführungsform
der Erfindung auf Systemebene;
-
3 ist
ein Flussdiagramm eines Verfahrens, wie es von einem Client gemäß einer
beispielhaften Ausführungsform
der Erfindung auszuführen
ist;
-
4 ist
ein Diagramm einer beispielhaften Java-Ausführungsform der Erfindung auf
Systemebene; und
-
5 ist
ein Diagramm einer Methodenzustand-Datenstruktur zur Verwendung
bei einer beispielhaften Implementierung der Erfindung.
-
DETAILLIERTE
BESCHREIBUNG DER ERFINDUNG
-
In
der folgenden detaillierten Beschreibung beispielhafter Ausführungsformen
der Erfindung wird auf die beigefügten Zeichnungen Bezug genommen,
die einen zugehörigen
Teil bilden und in denen veranschaulichend spezielle beispielhafte
Ausführungsformen
dargestellt sind, durch die die Erfindung realisiert werden kann.
Diese Ausführungsformen
sind mit ausreichender Detailliertheit beschrieben, um es dem Fachmann
zu ermöglichen,
die Erfindung auszuüben,
und es ist zu beachten, dass andere Ausführungsformen verwendet werden
können
und dass logische, mechanische, elektrische und andere Änderungen
vorgenommen werden können,
ohne vom Grundgedanken oder Schutzumfang der Erfindung abzuweichen.
Die folgende detaillierte Beschreibung ist daher nicht in beschränkendem
Sinn zu verwenden, und der Schutzumfang der Erfindung ist nur durch
die beigefügten
Ansprüche
definiert.
-
Die
detaillierte Beschreibung ist in fünf Abschnitte unterteilt. Im
ersten Abschnitt werden die Hardware und die Betriebsumgebung, in
deren Zusammenhang Ausführungsformen
der Erfindung realisiert werden können, beschrieben. Im zweiten
Abschnitt wird ein Überblick über die
Erfindung auf Systemebene angegeben. Im dritten Abschnitt werden
Methoden für
eine beispielhafte Ausführungsform
der Erfindung angegeben. Im vierten Abschnitt wird eine spezielle
Java-Implementierung der Erfindung beschrieben. Schließlich erfolgt
im fünften
Abschnitt eine Schlussfolgerung zur detaillierten Beschreibung.
-
Hardware und
Betriebsumgebung
-
Die 1 ist
ein Diagramm der Hardware und der Betriebsumgebung, in deren Zusammenhang
Ausführungsformen
der Erfindung realisiert werden können. Die Beschreibung zur 1 soll
eine kurze, allgemeine Beschreibung geeigneter Computerhardware
und einer geeigneten Rechenumgebung liefern, in deren Zusammenhang
die Erfindung realisiert werden kann. Obwohl es nicht erforderlich
ist, wird die Erfindung im all gemeinen Zusammenhang computer-ausführbarer
Anweisungen, wie Programmmodulen, beschrieben, die von einem Computer,
wie einem PC, ausgeführt
werden. Im Allgemeinen beinhalten Programmmodule Routinen, Programme,
Objekte, Komponenten, Datenstrukturen usw., die spezielle Tasks
ausführen
oder spezielle abstrakte Datentypen implementieren.
-
Darüber hinaus
erkennt der Fachmann, dass die Erfindung mit anderen Computersystemkonfigurationen
realisiert werden kann, einschließlich Handgeräten, Mikroprozessorsystemen,
programmierbarer Verbraucherelektronik oder solcher auf Mikroprozessor-Basis,
Netzwerk-PCs, Minicomputern, Großrechnern und dergleichen.
Die Erfindung kann auch in verteilten Rechenumgebungen ausgeführt werden,
in denen Tasks durch Fernverarbeitungsvorrichtungen ausgeführt werden,
die über
ein Kommunikationsnetzwerk verbunden sind. In einer verteilten Rechenumgebung
können
Programmmodule sowohl in lokalen als auch in entfernten Speichern
liegen.
-
Die
beispielhafte Hardware und Betriebsumgebung der 1 zum
Realisieren der Erfindung verfügt über eine
Universal-Computervorrichtung
in Form eines Computers 20 mit einer Verarbeitungseinheit 21,
einem Systemspeicher 22 und einem Systembus 23,
der verschiedene Systemkomponenten, einschließlich des Systemsspeichers 22,
funktionsmäßig mit
der Verarbeitungseinheit 21 verbindet. Es kann nur eine
einzelne Verarbeitungseinheit 21 vorhanden sein, oder es
können
mehrere vorhanden sein, so dass der Prozessor des Computers 20 über eine
einzelne zentrale Verarbeitungseinheit (CPU) oder über mehrere
Verarbeitungseinheiten verfügt,
was allgemein als parallele Verarbeitungsumgebung bezeichnet wird.
Der Computer 20 kann ein herkömmlicher Computer, ein verteilter
Computer oder ein beliebiger anderer Typ eines Computers sein; die
Erfindung ist in dieser Weise nicht beschränkt.
-
Der
Systembus 23 kann von einem beliebigen von mehreren Typen
von Busstrukturen sein, einschließlich eines Speicherbusses
oder eines Speichercontrollers, eines Peripheriebusses und eines
lokalen Busses unter Verwendung einer beliebigen einer Anzahl von
Busarchitekturen. Der Systemspeicher kann auch einfach als Speicher
bezeichnet werden, und er verfügt über einen
Festwertspeicher (ROM) 24 und einen Direktzugriffsspeicher
(RAM) 25. Ein grundlegendes Eingabe-/Ausgabe-System (BIOS) 26,
das diejenigen Grundroutinen enthält, die dazu beitragen, Information
zwischen Elementen innerhalb des Computers 20 zu übertragen,
wie während
des Hochfahrens, ist im ROM 24 gespeichert. Der Computer 20 verfügt ferner über ein
Festplattenlaufwerk 27 zum Lesen von Daten von einer nicht
dargestellten Festplatte, und zum Schreiben auf diese, ein Magnetplatten-Laufwerk 28 zum
Lesen von einer herausnehmbaren Magnetplatte 29, oder zum Schreiben
auf diese, und ein optisches Plattenlaufwerk 30 zum Lesen
von einer herausnehmbaren optischen Platte 31 wie einer
CD-ROM oder anderen optischen Medien, oder zum Schreiben auf diesen.
-
Das
Festplattenlaufwerk 27, das Magnetplatten-Laufwerk 28 und
das optische Plattenlaufwerk 30 sind durch eine Festplattenlaufwerk-Schnittstelle 32,
eine Magnetplattenlaufwerk-Schnittstelle 33 bzw. eine Optikplattenlaufwerk-Schnittstelle 34 mit
dem Systembus 23 verbunden. Die Laufwerke und die zu ihnen
gehörenden
computerlesbaren Medien bilden einen nichtflüchtigen Speicher computer-lesbarer
Anweisungen, Datenstrukturen, Programmmodule und anderer Daten für den Computer 20.
Der Fachmann erkennt, dass in der beispielhaften Betriebsumgebung
jeder beliebige Typ computerlesbarer Medien verwendet werden kann,
die Daten speichern können,
auf die ein Computer zugreifen kann, wie Magnetkassetten, Flashspeicherkarten,
digitale Videoplatten, Bernoulli-Kassetten, Direktzugriffsspeicher
(RAMSs), Festwertspei cher (ROMs) und dergleichen.
-
Auf
der Festplatte, der Magnetplatte 29, der optischen Platte 31,
dem ROM 24 oder dem RAM 25 kann eine Anzahl von
Programmmodulen gespeichert sein, einschließlich eines Betriebssystems 35,
eines oder mehrerer Anwendungsprogramme 36, anderer Programmmodule 37 sowie
Programmdaten 38. Ein Benutzer gibt Befehle und Information über Eingabevorrichtungen
wie eine Tastatur 40 und eine Zeigevorrichtung 42 in den
PC 20 ein. Zu anderen Eingabevorrichtungen (nicht dargestellt)
können
ein Mikrofon, ein Joystick, ein Gamepad, eine Satellitenschüssel, ein
Scanner oder dergleichen gehören.
Diese und andere Eingabevorrichtungen werden häufig über eine Schnittstelle 46 mit
seriellem Port, die mit dem Systembus gekoppelt ist, mit der Verarbeitungseinheit 21 gekoppelt,
jedoch können
sie durch andere Schnittstellen angeschlossen werden, wie einen
Parallelport, einen Gameport oder einen universal serial bus (USB).
Mit dem Systembus 23 ist auch ein Monitor 47 oder
eine andere Art einer Anzeigevorrichtung über eine Schnittstelle, wie
einen Videoadapter 48, verbunden. Zusätzlich zum Monitor verfügen Computer
typischerweise über
andere periphere Ausgabevorrichtungen (nicht dargestellt), wie Lautsprecher
und Drucker.
-
Der
Computer 20 kann in einer Netzwerkumgebung unter Verwendung
logischer Verbindungen zu einem oder mehreren Ferncomputern, wie
einem Ferncomputer 49 arbeiten. Diese logischen Verbindungen
erfolgen durch eine Kommunikationsvorrichtung, die mit dem Computer
oder einem Teil desselben verbunden ist; die Erfindung ist nicht
auf eine spezielle Art von Kommunikationsvorrichtung beschränkt. Der
Ferncomputer 49 kann ein anderer Computer, ein Server,
ein Router, ein Netzwerk-PC,
ein Client, einer Peervorrichtung oder ein anderer üblicher
Netzwerkknoten sein, und typischerweise enthält er viele oder alle der Elemente,
die oben hinsichtlich des Compu ters 20 beschrieben wurden,
obwohl in der 1 nur ein Speicher 50 dargestellt
ist. Zu den in der 1 dargestellten logischen Verbindungen
gehören
ein lokales Netzwerk (LAN) 51 sowie ein Fernbereichs-Netzwerk
(WAN) 52. Derartige Netzwerkumgebungen sind in Büros, unternehmensweiten
Computernetzwerken, Intranets und dem Internet üblich.
-
Wenn
der Computer 20 in einer LAN-Netzwerkumgebung verwendet
wird, ist er über
eine Netzwerkschnittstelle oder einen Adapter 53, wobei
es um einen Typ einer Kommunikationsvorrichtung handelt, mit dem lokalen
Netzwerk 51 verbunden. Wenn der Computer 20 in
einer WAN-Netzwerkumgebung verwendet wird, enthält er typischerweise ein Modem 54,
einen Typ einer Kommunikationsvorrichtung, oder irgendeinen anderen
Typ einer Kommunikationsvorrichtung zum Errichten einer Verbindung über das
Fernbereichs-Netzwerk, wie das Internet. Das Modem 54,
das intern oder extern sein kann, ist über die Schnittstelle 46 mit
seriellem Port mit dem Systembus 23 verbunden. In einer
Netzwerkumgebung können
Programmmodule, wie sie hinsichtlich des PC 20 oder Teilen
desselben dargestellt sind, in einem Fernspeicher gespeichert werden.
Es ist zu beachten, dass die dargestellten Netzwerkverbindungen
beispielhaft sind und dass andere Einrichtungen von Kommunikationsvorrichtungen
zum Erstellen einer Kommunikationsverbindung zwischen den Computern, sowie
derartige Kommunikationsvorrichtungen, verwendet werden können.
-
Es
wurden die Hardware und die Betriebsumgebung beschrieben, in deren
Zusammenhang Ausführungsformen
der Erfindung realisiert werden können. Der Computer, in dessen
Zusammenhang Ausführungsformen
der Erfindung realisiert werden können, kann ein herkömmlicher
Computer, ein verteilter Computer oder ein beliebiger anderer Typ
eines Computers sein; die Erfindung ist in dieser Weise nicht beschränkt.
-
Ein
derartiger Computer enthält
typischerweise eine oder mehrere Verarbeitungseinheiten als Prozessor
sowie ein computerlesbares Medium als Speicher. Der Computer kann
auch über
eine Kommunikationsvorrichtung wie einen Netzwerkadapter oder ein
Modem verfügen,
so dass er kommunizierend an andere Computer angeschlossen werden
kann.
-
Überblick
auf Systemebene
-
Unter
Bezugnahme auf die 2A–C wird
nun ein Überblick über den
Betrieb einer beispielhaften Ausführungsform der Erfindung auf
Systemebene gegeben.
-
Die 2A zeigt
die Logikblöcke
eines Interpretierers 200 für eine allgemeine Computersprache,
der in einer Laufzeitumgebung in einem Computer wie dem Computer 20 in
der 1 arbeitet. Der Interpretierer 200 sorgt
dafür,
dass Anweisungen in der Interpretiersprache, die allgemein als "Bytecodes" bezeichnet werden,
als Anweisungen in einer Sprache ausgeführt werden, die für die Laufzeitumgebung
nativ ist. Im Allgemeinen werden der Bytecode und der Code in der
Interpretiersprache als "lauffähiger" Code bezeichnet,
da sie vom Computer ausgeführt
werden, ohne dass sie compiliert werden müssten. In ähnlicher Weise bildet auch Code
in der nativen Sprache, wie ein Maschinensprachecode, lauffähigen Code.
-
Wenn
ein in der Interpretiersprache geschriebenes Programm in der Laufzeitumgebung
läuft,
liest der Interpretierer 200 jeden Bytecode im Programm,
und er verzweigt auf eine Routine, die für den Typ des Bytecodes spezifisch
ist (Logikblock 201). Dann führt der Interpretierer eine
Anweisung, oder eine Gruppe von Anweisungen, in der nativen Sprache
aus, wobei die durch den Bytecode spezifizierte Operation ausgeführt wird (Logikblock 202).
Der Prozess wird wiederholt, bis alle Bytecodes im Programm abgearbeitet
sind.
-
In
der 2B ist ein anderer Typ eines Interpretierers dargestellt,
der als "just-in-time" (JIT)-Compiler 210 bezeichnet
wird. Anstatt dass der JIT-Compiler 210 jeden Bytecode
interpretieren würde
und die zugehörige
Operation sofort ausführen
würde,
wandelt er alle Bytecodes im Programm in äquivalente Anweisungen in einer
nativen Sprache (Logikblöcke 211 und 212).
Diese Anweisungen werden dann in einem Programm in der nativen Sprache
gesammelt (Logikblock 213) und ausgeführt (Logikblock 214).
Die Logikblöcke 211 und 212 werden
gemeinsam als "Innenschleife" des JIT-Compilers
bezeichnet.
-
Die 2C veranschaulicht
eine Ausführungsform
eines Inlinecodegenerators 220, der extern zu einer Laufzeitumgebung 221 arbeitet
und die Verarbeitung der Innenschleife des JIT-Compilers 210 reproduziert.
In den Inlinecodegenerator 220 wird ein Bytecodeprogramm 222 eingegeben,
um ein entsprechendes Programm in einer Compilersprache 223 zu
erzeugen. Das Programm 223 in der Compilersprache wird
dann unter Verwendung eines Compilers 224 in ein Programm 225 in
der nativen Sprache compiliert. Wenn das Programm 225 in
der nativen Sprache durch die Laufzeitumgebung 221 ausgeführt wird,
erscheint es so, als sei es durch einen JIT-Compiler erzeugt worden.
Da das Programm 225 in der nativen Sprache innerhalb des
Ausführungsrahmens
der Laufzeitumgebung 221 arbeitet, stehen durch diese bereitgestellten
Funktionen und Routinen dem Programm 225 in der nativen
Sprache zu Verfügung,
wie es durch die gestrichelte Verbindung zwischen dem Inlinecodegenerator 220 und
der Laufzeitumgebung 221 dargestellt ist. Darüber hinaus
kann der Compiler 224, da er für den Computer spezifisch ist,
den erzeugten Code optimieren, um redundante Anweisungen zu beseitigen
und eine zusätzliche
Codeoptimierung für
die Hardware auszuführen.
-
Bei
einer beispielhaften Ausführungsform
gibt der Inlinecodegenerator 220 Quellcode-Anweisungen für eine Compilerhochsprache,
wie C, aus, und der Compiler 224 ist für diese Sprache spezifisch.
-
Bei
einer anderen beispielhaften Ausführungsform gibt der Inlinecodegenerator 220 Anweisungen
in einer Compiler-Zwischensprache aus. Eine Compiler-Zwischensprache
wird dazu verwendet, für
Kommunikation zwischen sprachspezifischer Compilerlogik und hardwarespezifischer
Compilerlogik zu sorgen. Die durch den Inlinecodegenerator erzeugten
Anweisungen in der Zwischensprache werden an die geeignete hardwarespezifische
Compilerlogik, d. h. den Compiler 224, weitergegeben, um
das Programm in der nativen Sprache zu erzeugen.
-
In
diesem Abschnitt der detaillierten Beschreibung wurde ein Überblick über den
Betrieb einer beispielhaften Ausführungsform der Erfindung auf
Systemebene beschrieben. Ein Inlinecodegenerator implementiert die
Innenschleife eines extern zu einer Laufzeitumgebung vorhandenen
JIT-Compilers, um den Overhead in Zusammenhang mit laufenden Programmen
in interpretiertem Code zu beseitigen. Da der Inlinecodegenerator existierende
Interpretiersprachenprogramme als Eingang akzeptiert, bleiben die
durch diese Programme erzielten Portierbarkeitsvorteile erhalten,
während
gleichzeitig die Ausführung
dieser Programme optimiert wird, wenn sie auf einem speziellen Computer
laufen. Ferner erzeugt der Inlinecodegeneratorcode, der jede beliebige
Funktion nutzt, wie sie von der Laufzeitumgebung exportiert wird.
Während
die Erfindung nicht auf irgendeine spezielle Ausführungsform
einer interpretierenden Innenschleife beschränkt ist, wurden der Deutlichkeit
halber die auf hoher Ebene liegenden Funktionen der Innenschleife
eines JIT-Compilers beschrieben.
-
Methoden beispielhafter
Ausführungsformen
der Erfindung
-
Im
vorigen Abschnitt wurde ein Überblick
der Operationen beispielhafter Ausführungsformen der Erfindung
auf Systemebene beschrieben. In diesem Abschnitt werden die speziellen
Methoden, wie sie von einem derartige beispielhafte Ausführungsformen
ausführenden
Computer verwendet werden, unter Bezugnahme auf eine Reihe von Flussdiagrammen
beschrieben. Die auszuführenden
Methoden bilden Computerprogramme aus computer-ausführbaren
Anweisungen. Das Beschreiben der Methoden unter Bezugnahme auf ein
Flussdiagramm ermöglicht
es dem Fachmann, derartige Programme, die derartige Anweisungen
enthalten, zu entwickeln, um die Methoden auf einem geeigneten Computer
auszuführen
(wobei der Prozessor der Computer die Anweisungen von computerlesbaren
Medien ausführt).
-
Als
Erstes wird auf die 3 Bezug genommen, in der Vorgänge dargestellt
sind, wie sie von einem den Inlinecodegenerator 220 realisierenden
Computer auszuführen
sind. Beginnend mit einem Block 301 wird der erste Bytecode
im Programm eingelesen. Wie es unten detaillierter erläutert wird,
wird eine eindeutige Marke für
den Bytecode erzeugt (Block 302). Es wird der Typ des Bytecodes
bestimmt (Block 303), und der Bytecode wird in die ihm
entsprechende Anweisung in der Compilersprache oder einen Satz von
Anweisungen gewandelt (Block 304). Der Inlinecodegenerator 300 fährt mit
der Verarbeitung jedes Bytecodes im Programm fort, bis alle Bytecodes
gewandelt sind (Block 305). Wie es der Fachmann unmittelbar
erkennt, hängt
der im Block 304 erzeugte Anweisungstyp davon ab, ob der
Inlinecodegenerator Quellcode in einer Compilersprache oder Compilerzwischencode
ausgibt.
-
In
den meisten Bytecodeprogrammen wird, wenn es erforderlich ist, dass
die Logik auf einen Bytecode außerhalb
der Sequenz springt, eine Verzweigungsanweisung verwendet, die einen Versatz
für den
Ziel-Bytecode relativ zur Verzweigungsanweisung spezifiziert. Da
der Inlinecodegenerator 300 für jeden Bytecode eine Marke
erzeugt, wandelt der Block 304 den Versatzwert in der Verzweigungsanweisung
in die Marke für
den Ziel-Bytecode. Bei einer Ausführungsform enthält jede
im Block 302 erzeugte Marke ihren relativen Versatz zum
Anfang des Programms. Der Inlinecodegenerator subtrahiert den in
der Verzweigungsanweisung spezifizierten Relativversatz vom Versatz
in der Marke der Verzweigungsanweisung, um die Marke für den Ziel-Bytecode
zu berechnen. Dem Fachmann sind leicht alternative Wege erkennbar,
gemäß denen
die ursprünglichen Bytecodes
mit für
die äquivalenten
Anweisungen erzeugten Marken gleichgesetzt werden, wie die Verwendung
eines Arrays zum Verwalten aller Marken. Bei einer alternativen
beispielhaften Ausführungsform,
die gestrichelt in der 3 dargestellt ist, führt der
Codegenerator ein "Zusammenstreichen" der Marken aus,
die unbenutzt sind, nachdem alle Bytecodes gewandelt wurden (Block 306),
so dass nur Marken vorhanden sind, auf die durch die abschließend erzeugten
Anweisungen Bezug genommen wird.
-
Wie
es im vorigen Abschnitt erläutert
ist, hat der im Block 304 erzeugte Code Zugriff auf alle
globalen variablen und/oder Funktionen, die durch die Laufzeitumgebung
exportiert werden.
-
Es
wurden spezielle Methoden beschrieben, wie sie von einem Computer
ausgeführt
werden, der eine beispielhafte Ausführungsform der Erfindung ausführt. Die
Methoden wurden unter Bezugnahme auf ein Flussdiagramm veranschaulicht,
das alle der Schritte von 301 bis 306 enthält.
-
Implementierung
der Java Virtual Machine
-
In
diesem Abschnitt der detaillierten Beschreibung wird eine spezielle
Implementierung der Erfindung beschrieben, wie sie für die Implementierung
der Java Virtual Machine (JVM) durch Microsoft Corporation spezifisch
ist.
-
Die 4 veranschaulicht
eine beispielhafte Ausführungsform
des erfindungsgemäßen Inlinecodegenerators 401 in
Verbindung mit einer JVM 402. Die JVM 402 besteht
aus drei Hauptkomponenten: einem Java-Interpretierer 403,
einem Java-JIT-Compiler 404 und
einem Laufzeitsystem 405. Da die JVM ein System auf Stapelspeicherbasis
ist, werden alle vom im Laufzeitsystem 402 ausgeführten Programmen
geschaffenen Objekte in einem Stapelspeicher 406 gespeichert.
Ein Konstantenpool 407 sorgt für Variable für die Programme.
Sowohl der Stapelspeicher 406 als auch der Konstantenpool 407 werden
vom Laufzeitsystem 405 verwaltet. Das Laufzeitsystem 405 sorgt
auch für
Spezialfunktion 408, wie die Sammlung von Datenmüll zu Objekten, die
nicht länger
in Gebrauch sind, im Hintergrund.
-
Ein
Java-Programmierer erzeugt Objekte und Methoden, die auf die Objekte
im Java-Quellcode ("Java"-Datei) 409 einwirken,
und er gibt die Java-Datei 409 an einer Java-Compiler 410 weiter,
der die Java-Bytecodes ("Klassen"datei) 411 erzeugt.
Wenn der Inlinecodegenerator 401 verwendet wird, werden
die Klassendatei 411 und jegliche Java-Bibliotheken 412,
die Methodenbezüge
auf die Klassendatei 411 enthalten, an den Codegenerator 402 weitergegeben.
Code in Compilersprache wird vom Codegenerator 402 erzeugt
und an einen hardwarespezifischen Compiler 413 weitergegeben,
der eine ausführbare
Datei (DLL) 414 erzeugt.
-
Wenn
von einem im Laufzeitsystem 405 laufenden Programm eine
externe Methode aufgerufen wird, ermittelt die JVM 402,
ob die Methode in einer Bytecode-Klassendatei oder einer ausführbaren
DLL-Datei vorliegt, wie es unten detaillierter erläutert wird.
Wenn die Methode eine Klassendatei ist, leitet die JVM 402 die Klassendatei 411 gemeinsam
mit den erforderlichen Klassenbibliotheken 412 entweder
an den Java-Interpretierer 403 oder
den Java-JIT-Compiler 404 zur Wandlung in ausführbaren
Code weiter. Der ausführbare
Code wird dann zur Ausführung
an das Laufzeitsystem 405 weitergeleitet. Andererseits
leitet die JVM 402, wenn die Methode in einer durch den
Inlinecodegenerator 401 erzeugten DLL-Datei vorliegt, einfach
die DLL-Datei 414 zur Ausführung an das Laufzeitsystem 405 weiter.
-
Die
JVM 402 exportiert auch bestimmte Laufzeitsystemvariable
und Methoden an den Codegenerator 401, damit der ausführbare Code
in der DLL-Datei 414 erhalten werden kann und den Zustand
der JVM 402 manipulieren kann.
-
Die
unten angegebene Tabelle 1 veranschaulicht Anweisungen in der Sprache
C, wie sie durch die Innenschleife des JIT-Compilers 404 für eine Untergruppe
von Java-Bytecodes erzeugt werden. Die Anweisungen in der Sprache
C enthalten Zeigen auf den Stapelspeicher 406, den Konstantenpool 407,
Methoden 408 sowie lokale Variable im Laufzeitsystem 405,
die von der JVM 402 exportiert wurden. Die Innenschleife wird
wie folgt codiert:
while (pCode++)
switch (*pCode)
...
case
LDC
[entsprechend C-Anweisungen, wie in der Tabelle 1 dargestellt]
...
case
BEQ
[entsprechend C-Anweisungen, wie in der Tabelle 1 dargestellt]
...
case
IADD
[entsprechend C-Anweisungen, wie in der Tabelle 1 dargestellt]
...
break
-
-
Unter
Verwendung des folgenden Java-Bytecodeprogramms als Beispiel
LDC <index1>
LDC <index2>
IADD
BEQ-3
-
Erzeugt
der Codegenerator 401 das folgende Programm in der Sprache
C:
label_1:
*pStack++ = m_pMethod->m_pClass->m_ConstantPool[1];
label_2:
*pStack++
= m_pMethod->m_pClass->m_pConstantPool[2];
label_3:
*(pStack-1)
+= *(pStack);
pStack-;
label_4:
if (*pStack) goto
label_1;
-
Da
der ausführbare
Code 414 außerhalb
der JVM 402 erzeugt wird, muss diese zur Laufzeit keine Schleife
durch die Innenschleife des JIT-Compilers 404 ausführen, wodurch
das Funktionsvermögen
gegenüber
einem identischen Bytecodeprogramm wesentlich erhöht wird,
das den JIT-Compiler 404 durchläuft. Ferner werden Bezugnahmen
auf den Konstantenpool 407 durch den Codegenerator 401 speziell
codiert, so dass der Compiler 413 für diesen Teil des Programms
in der Sprache C effizienter Code als der JIT-Compiler 404 erzeugt,
der Code ausgibt, der der Art nach allgemein ist. Bei einer alternativen
beispielhaften Ausführungsform,
bei der der Compiler 413 ein optimierender C-Compiler ist,
ist die Anzahl der einem Bytecode entsprechenden Anweisungen auf
einen mi nimalen Satz compilierter Anweisungen reduziert.
-
Bestimmte
Java-Bytecodes müssen
in die JVM 402 zurückgerufen
werden, und so können
sie nicht alleine durch Anweisungen in der Sprache C repräsentiert
werden. Der sich ergebende erzeugte Code ist in der Tabelle 1 durch
den Bytecode INVOKESTATIC <index> veranschaulicht, der
einen Aufruf auf eine andere Java-Methode ausführt. Der erzeugte Code muss
als Erstes FindMethod aufrufen, um einen Zeiger auf die Methode
(pMethod) zu erhalten, die durch die JVM 402 freigelegt
wurde. Dann muss der erzeugte Code die exportierte Methode, ExecuteStaticMethod,
aufrufen, um die aufgerufene Methode auszuführen, und er muss LookUpException
aufrufen, um jegliche Ausnahmen zu handhaben, die sich aus der Ausführung ergeben.
Bei einer alternativen beispielhaften Ausführungsform werden die Anweisungen
sowohl für
ExecuteStaticMethod als auch LookUpException inline mit dem C-Sprache-Code
für INVOKESTATIC
erzeugt.
-
Bei
der beispielhaften Ausführungsform
der JVM 402 zeigen zwei Flags, ein Flag 501 für native
Methoden sowie ein JIT-Flag 502,
für jede
Methode den "Zustand" der Methode an.
Die Flags 501, 502 können in einer internen, im
Speicher vorhandenen Repräsentation
der Klasse gespeichert werden, oder sie können in einer Datei dauerhaft
gespeichert sein. Eine die Flags enthaltende beispielhafte Datenstruktur
ist in der 5 dargestellt. Die JVM 402 verwendet
die Flags 501, 502 zum Bestimmen, wie eine Methode
zu laden ist, die innerhalb des Laufzeitsystems 405 aufgerufen
wird.
-
Wenn
keines der Flags gesetzt ist, lädt
die JVM 402 die Bytecodes für die Methode, und sie ruft
entweder den Interpretierer 403 oder den JIT-Compiler 404 auf,
um die Codes zu verarbeiten. Dieser Fall repräsentiert einen Java-Nach-Java-Aufruf. Wenn nur
das Flag zur nativen Methode gesetzt ist, lädt die JVM 402 die
entsprechende DLL, sie durchsucht dieselbe nach dem Eintrittspunkt
für die
aufgerufene Methode, und sie ruft die Methode über eine Schnittstelle für nativen
Methoden, wie JNI oder RNI, auf. Dieser Fall wird als Aufruf eines "importierten" Codes gehandhabt.
-
Wenn
nur das JIT-Flag gesetzt ist, erkennt die JVM 404, dass
die Methode bereits in Maschinencode compiliert ist, sie springt
direkt zum Eintrittspunkt der Methode in der entsprechenden DLL-Datei,
und sie führt den
geeigneten Code aus. Auf diese Weise wird ausführbarer Code gehandhabt, der
gemäß der Erfindung
erzeugt und compiliert wird.
-
Der
Fachmann erkennt leicht andere Stellen, die dazu verwendet werden
können,
den Zustand jeder Methode zu speichern. Z. B. wird bei einer alternativen
beispielhaften Ausführungsform
der Zustand jeder Methode innerhalb der entsprechenden Klassendatei
selbst gespeichert. Bei einer anderen alternativen beispielhaften
Ausführungsform
wird die Erweiterung J/Direct verwendet, die einen privaten Datensatz
speichert, um auf den Eintrittspunkt einer Methode zu zeigen.
-
In
diesem Abschnitt wurde ein Inlinecodegenerator beschrieben, der
Java-Bytecodes in äquivalente Anweisungen
in einer Compilersprache wandelt. Die Anweisungen in der Compilersprache
werden dann an einer Compiler weitergegeben, der ausführbaren
Maschinensprachecode erzeugt. Der ausführbare Code kann dann direkt
vom aktuellen Java-Laufzeitsystem aufgerufen werden, und daher allen
Stapeloperationen des interpretierten Bytecodes genügt, arbeiten
der vorhandene Datenmüllsammler
und andere Laufzeitmerkmale normal. Der ausführbare Code muss nur die Information
der JVM dahingehend aktualisieren, welcher äquivalente Bytecode gerade
ausgeführt
wird, wenn ein Funktionsaufruf erfolgt oder wenn eine Ausnahme ausgegeben
wird. Daher, und aufgrund der Tatsache, dass grundlegende Stapeloperationen
durch den Compiler so optimiert werden können, dass Register genutzt
werden, beschleunigt der Inlinecodegenerator die Ausführung von
Java-Bytecode deutlich
gegenüber
einem Interpretierer oder einem JIT-Compiler.
-
Schlussfolgerung
-
Es
wurde ein Inlinecodegenerator beschrieben. Obwohl hier spezielle
Ausführungsformen
veranschaulicht und beschrieben wurden, erkennt es der Fachmann,
dass jede Anordnung, die es darauf abgesehen hat, denselben Zweck
zu erfüllen,
die dargestellten speziellen Ausführungsformen ersetzen kann.
Diese Anwendung soll alle Anpassungen oder Variationen der Erfindung
abdecken.
-
Z.
B. erkennt es der Fachmann, dass zwar alle Java Virtual Machines
auf Stapelbasis arbeiten, dass jedoch nicht alle JVMs über einen
Konstantenpool verfügen,
wie er im vorigen Abschnitt beschrieben ist. Da der Begriff "Konstantenpool" auf jede Ansammlung
verfügbarer
Variablen, die Konstanten enthalten, angewandt werden kann, gehören zu Strukturen,
die einem Konstantenpool äquivalent
sind, Variablenspeicher, die innerhalb von Klassendateien implementiert
sind und zum Ladezeitpunkt zu einer Hashtabelle decodiert werden.
-
Ferner
erkennt es der Fachmann, dass verschiedene Laufzeitumgebungen verschiedene
Methoden, d. h. Ausnahmehandling, Aufruf von Methoden und/oder Speicherzuordnung,
exportieren, die vom erzeugten Code genutzt werden können. Daher
ist der erzeugte Code spezifisch für die Laufzeitumgebung, wie
dies für Code
gilt, der durch einen Interpretierer oder einen JIT-Compiler erzeugt
wird, und es besteht keine Beschränkung nur durch die charakteristischen
Beschränkungen
der Laufzeitumgebung, in der der Inlinecodegenerator implementiert ist.
-
Die
diesbezüglich
in dieser Anmeldung verwendete Terminologie soll alle Laufzeitumgebungen
beinhalten, sowohl vergangene als auch aktuelle und zukünftige.
Daher ist es ausdrücklich
beabsichtigt, dass die Erfindung nur durch die folgenden Ansprüche und
deren Äquivalente
beschränkt
ist.