DE19928980A1 - Codeerzeugung für einen Bytecode-Compiler - Google Patents
Codeerzeugung für einen Bytecode-CompilerInfo
- Publication number
- DE19928980A1 DE19928980A1 DE19928980A DE19928980A DE19928980A1 DE 19928980 A1 DE19928980 A1 DE 19928980A1 DE 19928980 A DE19928980 A DE 19928980A DE 19928980 A DE19928980 A DE 19928980A DE 19928980 A1 DE19928980 A1 DE 19928980A1
- Authority
- DE
- Germany
- Prior art keywords
- code
- class
- fragment
- target
- bytecodes
- 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.)
- Withdrawn
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/447—Target code generation
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements 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/44—Arrangements for executing specific programs
- G06F9/448—Execution paradigms, e.g. implementations of programming paradigms
- G06F9/4488—Object-oriented
- G06F9/449—Object-oriented method invocation or resolution
- G06F9/4491—Optimising based on receiver type
Abstract
Es werden ein Verfahren, ein System und eine Vorrichtung zur Erzeugung und Optimierung von Maschinencode in einem Laufzeit-Compiler aus einer Gruppe von Bytecodes beschrieben, die dem Compiler angeboten werden. Der Compiler greift auf Information zu, welche die Wahrscheinlichkeit kennzeichnet, daß eine Klasse einen speziellen Typ besitzt, wenn auf sie vom laufenden Programm zugegriffen wird. Unter Verwendung der erfaßten Information wählt der Compiler ein Code-Erzeugungsverfahren aus einer Vielzahl von Code-Erzeugungsverfahren aus. Ein Code-Generator erzeugt einen optimierten Maschinencode entsprechend dem ausgewählten Code-Erzeugungsverfahren und speichert den optimierten Maschinencode in einem Code-Zwischenspeicher für eine erneute Verwendung.
Description
Die vorliegende Erfindung betrifft im allgemeinen Compiler und insbesondere ein Codeer
zeugungs-Verfahren zur Optimierung der Ausführung von Programmen, die als Bytecode
dargestellt sind.
Bytecode-Programmiersprachen, wie z. B. die Java™-Programmiersprache (Warenzeichen
von Sun Microsystems, Inc.) stellen Computerprogramme als Satz von Bytecodes dar. Je
der Bytecode ist ein numerischer Maschinencode für eine "virtuelle Maschine", die nur in der
Software auf einem Client-Computer existiert. Die virtuelle Maschine ist im wesentlichen ein
Interpreter, der die Bytecodes versteht, die Bytecodes in einen Maschinencode übersetzt
und dann den Maschinencode auf der eigentlichen (native) Maschine ablaufen läßt.
Bytecode-Programmiersprachen, wie die Java-Programmiersprache gewinnen bei den Ent
wicklern von Softwareanwendungen an Popularität, weil sie einfach zu verwenden und au
ßerordentlich handlich bzw. transportabel sind. Programme, die in Form von Bytecodes dar
gestellt sind, können ohne weiteres auf jeden Rechner übertragen werden, der eine virtuelle
Maschine besitzt, die in der Lage ist, die Bytecodes korrekt zu interpretieren und zu über
setzen. Da jedoch Bytecode-Programmiersprachen während der Laufzeit auf dem
Client-Computer übersetzt werden müssen, weisen sie den Nachteil auf, daß sie nicht in der Lage
sind, mit einer Geschwindigkeit zu arbeiten, die mit der von herkömmlich kompilierten Spra
chen, wie z. B. C oder C++ konkurrieren kann.
Die Geschwindigkeitsbeschränkungen von Bytecode-Sprachen stehen hauptsächlich mit
dem Compilierungsprozeß in Verbindung. Compilierung ist der Vorgang, durch den Pro
gramme, die in einer höheren Programmiersprache (das heißt in einer vom Menschen les
baren Sprache) geschrieben worden sind, in einen maschinenlesbaren Code übersetzt wer
den. Beim Kompilierungsvorgang gibt es vier grundlegende Schritte: Tokenisierung, Par
sing, Codeerzeugung und Optimierung. Bei herkömmlichen kompilierten Programmen wer
den alle diese Schritte vor der Laufzeit ausgeführt, während bei Sprachen, die von einem
Interpreter übersetzt werden, wie z. B. BASIC, alle Kompilierungsschritte während der Lauf
zeit Befehl für Befehl ausgeführt werden. Befehlsshells, wie z. B. CSH sind Beispiele für In
terpreter, die eine begrenzte Anzahl von Befehlen erkennen. Mit einem Interpreter über
setzte Sprachen führen zur Ineffizienz, weil es keine Möglichkeit gibt, den resultierenden
Code zu optimieren.
Bei einer Bytecode-Programmiersprache werden die Tokenisierung und das Parsing vor der
Laufzeit durchgeführt. Nach dem Parsing wird das Programm in Bytecodes übersetzt, die
von einer virtuellen Maschine verstanden bzw. übersetzt werden können. In Folge hiervon
ist ein Bytecodeinterpreter schneller als ein Sprachinterpreter, wie z. B. in einigen der ur
sprünglichen BASIC-Programmiersprachen-Realisierungen. Auch sind die sich ergebenden
Programme dann, wenn sie im Bytecodeformat dargestellt sind, kompakter als ein vollstän
dig kompiliertes Programm. Aufgrund dieser Eigenschaften sind Bytecode-Sprachen ein
nützlicher Kompromiß in Rechner-Netzwerkumgebungen, in denen Software von einer Ma
schine zur Ausführung auf eine andere Maschine übertragen wird.
In der Java-Programmierumgebung heißt das Programm, das die Übersetzung in Bytecodes
ausführt, "javac" und wird manchmal als Java-Compiler bezeichnet (obwohl es nur einen
Teil des oben beschriebenen Compilierungsprozeßes ausführt). Das Programm, das die
Bytecodes auf dem Client-Computer übersetzt, wird als virtuelle Java-Maschine (JVM) be
zeichnet. Wie andere Interpreter läuft die virtuelle Java-Maschine in einer Schleife, die jeden
Bytecode ausführt, den sie empfängt. Es tritt jedoch immer noch ein zeitraubender Überset
zungsschritt auf der virtuellen Maschine auf, wenn die Bytecodes übersetzt werden. Für je
den Bytecode identifiziert der Interpreter die entsprechende Reihe von Maschineninstruktio
nen und führt sie dann aus. Der zusätzliche Aufwand, der für jede einzelne Übersetzung
erforderlich ist, ist minimal, doch akkumuliert sich der zusätzliche Aufwand für jeden Befehl,
der ausgeführt wird. Bei einem großen Programm wird der zusätzliche Aufwand im Ver
gleich mit der einfachen Durchführung einer Reihe von vollständig kompilierten Befehlen
beträchtlich. In Folge hiervon haben große Anwendungen, die in der Java-Programmier
sprache geschrieben sind, die Tendenz, langsamer zu sein als die äquivalente Anwendung
in einer vollständig kompilierten Form.
Um den Ablauf zu beschleunigen, wurden virtuelle Maschinen mit einem Just-in-Time-Com
piler, der im folgenden als JIT bezeichnet wird, verbunden oder umfassen einen solchen JIT.
Der JIT verbessert das Laufzeitverhalten von Bytecodeinterpretern dadurch, daß er die
Bytecodes in echten bzw. ursprünglichen (native) Maschinencode kompiliert, bevor er sie
ausführt. Der JIT übersetzt eine Reihe von Bytecodes in Maschinenbefehle dann, wenn er
sie zum ersten Mal sieht, und führt dann bei nachfolgenden Aufrufen die Maschinenbefehle
aus, statt die Bytecodes zu übersetzen. Die Maschinenbefehle werden nur im Arbeitsspei
cher gespeichert und daher beginnt der JIT den Compilierungsprozeß von neuem, wenn das
Programm das nächste Mal läuft.
Das Ergebnis ist, daß die Bytecodes weiterhin übertragbar sind und in vielen Fällen wesent
lich schneller laufen, als dies bei einem normalen Interpreter der Fall wäre. Eine
Just-In-Time-Compilierung ist insbesondere dann nützlich, wenn Codesegmente wiederholte Male
ausgeführt werden, wie dies bei vielen Berechnungsprogrammen der Fall ist. Eine
Just-in-Time-Compilierung führt jedoch bei kleinen Codeabschnitten, die nur einmal oder einige
wenige Male ausgeführt und dann nicht nochmals verwendet werden, nur zu einer geringen
Verbesserung des Verhaltens (performance) und kann das Verhalten sogar verlangsamen.
Eine Einschränkung der JIT-Technologie besteht darin, daß die Compilierung während der
Laufzeit stattfindet, und somit stellt jede Rechenzeit, die für den Versuch verwendet wird,
den Maschinencode zu optimieren, einen zusätzlichen Aufwand dar, der die Ausführung des
Programms verlangsamen kann. Somit können viele Optimierungsverfahren bei dem Stand
der Technik entsprechenden JIT-Compilern nicht verwendet werden. Auch sieht ein
JIT-Compiler nur sehr wenige Befehle gleichzeitig und kann somit keine Optimierung über viele
Befehle hinweg durchführen. Eine Folge hiervon ist, daß der Compiler nicht mit Sicherheit
den Satz von Klassen bestimmen kann, der von einem Programm verwendet wird. Darüber
hinaus kann sich der Satz von Klassen bei jeder Ausführung eines gegebenen Programms
ändern, so daß der Compiler der virtuellen Maschine niemals annehmen kann, daß der Satz
von Klassen immer zweifelsfrei bekannt ist.
Wegen dieser Unbestimmtheit ist es schwierig, einen wirklich optimalen Maschinen- bzw.
Ursprungscode (native code) während der Laufzeit zu erzeugen. Versuche, eine Optimie
rung mit einer unvollständigen Kenntnis des Klassensatzes durchzuführen, können ineffzi
ent sein oder die Funktionalität des Programms ändern. Die Unsicherheit hinsichtlich des
Klassensatzes führt zu einem großen Bereich einer potentiellen Ineffizienz bei einem
Java-Ablauf. Der Klassensatz ist ein Satz aller Klassen, die verwendet werden, um einen spezi
ellen Abschnitt eines Programms in Java-Sprache auszuführen. Bei einem in herkömmlicher
Weise stapel-compilierten Programm ist die Gesamtheit von Klassen, die vom Programm
verwendet werden, zum Zeitpunkt der Compilierung bekannt, wodurch die Aufgabe der Op
timierung in starkem Maße vereinfacht wird.
Es kommt in Programmen häufig vor, daß eine erste Methode (die Aufrufmethode) eine
zweite Methode (die Zielmethode) in einem Vorgang aufruft, der als "Methodenaufruf" be
zeichnet wird. Dieser Methodenaufrufvorgang ist vom Programmierer her gesehen vorteil
haft, doch erfordert er viele Taktzyklen. Eine wesentliche Optimierung bei der Kompilierung
von objektorientiertem Programmcode wird als "Inlining" bezeichnet. Bei vollständig kompi
lierten Programmen macht das Inlining diese Zielmethoden-Aufrufe dadurch effizienter, daß
der Code der Zielmethode in die aufrufende Methode hinein kopiert wird.
Wegen der Semantik der Java-Plattform kann der Compiler jedoch nicht immer den voll
ständigen Klassensatz feststellen. Weil bei Java die Klassen erweiterbar sind und dyna
misch geladen werden können, können Methoden durch nachfolgende Erweiterungen auf
eine Klasse außer Kraft gesetzt werden und der Compiler kann nicht mit Sicherheit davon
ausgehen, daß ein virtueller Methodenaufruf irgend eine spezielle Methode erreichen wird.
Bei der Java-Programmiersprache kann eine Methode durch das Fehlen einer Angabe (de
fault) außer Kraft gesetzt werden (overridden), außer sie ist ausdrücklich als "final" definiert.
Von allen "nicht-finalen" Methoden wird angenommen, daß sie außer Kraft gesetzt werden
können.
Somit müssen alle Aufrufe, die sich auf nicht-finale Blattmethoden (leaf methods) beziehen,
annehmen, daß die Zielmethode zur irgend einem Zeitpunkt in der Zukunft außer Kraft ge
setzt werden kann. Somit wurden in der Vergangenheit nur zeitraubende virtuelle Methoden-Aufruf
sequenzen verwendet, um sie aufzurufen. Je kleiner die Methode ist, um so größer ist
der durch Inlining erzielbare Vorteil. Eine nur eine Zeile umfassende Methode würde typi
scherweise weit mehr Zeit mit dem Ein- und Austreten in die bzw. aus der Routine verbrau
chen, als mit der Durchführung ihres Inhalts. Tests haben gezeigt, daß häufig bis zu 85%
dieser nicht-finalen Blattmethoden-Aufrufe aufgelöst werden könnten, wenn es möglich
wäre, sicher zu wissen, daß keine weiteren Klassen diese Methoden überlasten bzw. außer
Kraft setzen werden.
Somit besteht ein Bedarf für ein Verfahren und eine Vorrichtung zur Erzeugung von optima
lerem Ursprungscode (native code) in einer Umgebung, in welcher der Satz von Klassen für
ein Programm nicht zweifelsfrei bekannt ist. Auch besteht ein Bedarf für ein Verfahren und
eine Vorrichtung, das bzw. die die Klassen mit einem tolerierbaren Einfluß auf das Pro
gramm-Ausführungsverhalten behandelt, wenn die Kenntnis des Klassensatzes unvollstän
dig ist.
Kurz zusammengefaßt umfaßt die vorliegende Erfindung ein Verfahren, ein System und
eine Vorrichtung zur Erzeugung und Optimierung von Ursprungscode in einem Laufzeitcom
piler aus einer Gruppe von Bytecodes, die dem Compiler dargeboten werden. Der Compiler
greift auf Information zu, welche die Wahrscheinlichkeit kennzeichnet, daß eine Klasse
einen speziellen Typ besitzt, wenn auf sie vom laufenden Programm zugegriffen wird. Unter
Verwendung der durch den Zugriff erhaltenen Information wählt der Compiler ein
Code-Erzeugungsverfahren aus einer Vielzahl von Code-Erzeugungsverfahren aus. Ein
Codegenerator erzeugt gemäß dem ausgewählten Code-Erzeugungsverfahren einen opti
mierten Ursprungscode und speichert den optimierten Ursprungscode in einem
Code-Pufferspeicher für eine erneute Verwendung.
Fig. 1 zeigt eine Netzwerk-Rechner-Umgebung, bei der das Verfahren und das Sy
stem gemäß der vorliegenden Erfindung Verwendung finden,
Fig. 2 zeigt eine Programmierumgebung gemäß dem System und den Verfahren
der vorliegenden Erfindung,
Fig. 3 zeigt ein Ausführungsbeispiel der vorliegenden Erfindung,
Fig. 4 zeigt eine andere Ausführungsform gemäß der vorliegenden Erfindung, und
Fig. 5 zeigt eine weitere Ausführungsform gemäß der vorliegenden Erfindung.
Die vorliegende Erfindung geht von der Erkenntnis aus, daß ein System, das dazu verwen
det wird, wiederholte Male die gleichen Programme in einer Bytecode-Sprache ablaufen
zulassen, mit Hilfe eines Prozesses, der als "Profiling" bezeichnet wird, eine hinreichend
genaue Kenntnis des Klassensatzes aufbauen kann, der in diesen Programmen verwendet
wird. Das Profiling kann über einen einzigen Ablauf des Programms oder über eine Reihe
von Programmabläufen hinweg erfolgen, die in verschiedenen Sitzungen auftreten. Es ist
dieses Ansammeln von Kenntnis, die während der Laufzeit abgeleitet wird, das eine Ein
schränkung bekannter Systeme, nämlich das Fehlen eines laufzeit-spezifischen Wissens, in
einen Vorteil verwandelt. Dieser Vorteil ergibt sich, weil das angesammelte Wissen für die
spezielle Laufzeitumgebung spezifisch ist und inhärent jeder charakteristischen Eigenart der
Laufzeitumgebung Rechnung trägt, wenn die laufenden Programme profiliert werden. Im
Gegensatz hierzu optimieren herkömmliche Kompilierungsverfahren auf der Basis einer
verallgemeinerten Kenntnis des typischen Programmverhaltens in typischen Laufzeitumge
bungen.
Das System gemäß der vorliegenden Erfindung erzeugt einen effizienten Ursprungscode
aus einem Bytecode-Programm, wenn es "weiß" oder in vernünftiger Weise annehmen
kann, daß der bei früheren Durchläufen verwendete Klassensatz nicht erweitert wird. Die
Ausdrücke "weiß" und "Kenntnis" bzw. Wissen", wie sie hier verwendet werden, bedeuten,
daß Datenstrukturen im System und/oder der Software Daten enthalten, welche die "ge
wußte" oder "gekannte" Informationen darstellen. In ähnlicher Weise bedeutet eine "ver
nünftige Annahme", daß das System und/oder die Software Information enthält, die einem
Zustand bzw. einer Bedingung eine Wahrscheinlichkeit größer Null zuordnet, obwohl dieser
Zustand bzw. Bedingung nicht mit Sicherheit bekannt ist.
Die vorliegende Erfindung erzeugt während der Laufzeit Code unter Verwendung eines dy
namischen Compilers, der auf die bezüglich des laufenden Programms bekannte oder in
vernünftiger Weise angenommene Information reagiert. Bei einem speziellen Beispiel um
faßt der dynamische Compiler eine Vielzahl von Code-Erzeugungsverfahren, aus der er für
jede spezielle Gruppe von Bytecodes, die er kompiliert, eine auswählen kann. Die Auswahl,
welches Verfahren in einem speziellen Fall verwendet wird, basiert auf dem Wissen, das
momentan dadurch gewonnen werden kann, daß der Code selbst zusammen mit der
Kenntnis bzw. dem Wissen erprobt wird, die bzw. das über die Zeit hinweg aus der Überwa
chung der Durchführung des Codes gewonnen wurde.
Obwohl die vorliegende Erfindung in Bezug auf ein System beschrieben wird, das alle Byte
codes in einem Programm in Maschinencode kompiliert, sei darauf hingewiesen, daß die
Erfindung in vorteilhafter Weise auch in einem System verwendet werden kann, das nur
ausgewählte Gruppen von Bytecodes kompiliert. Beispielsweise kann die virtuelle Maschine
gemäß der vorliegenden Erfindung einen herkömmlichen Bytecode-Interpreter umfassen,
der parallel zum dynamischen Compiler arbeitet. Bei einer solchen Realisierung ist es mög
lich, nur ausgewählte Gruppen von Bytecodes auf der Basis der Häufigkeit ihrer Durchfüh
rung bzw. des relativen Nutzens, der durch die Kompilierung der Bytecodes erzielt werden
kann, oder anderer das Verhalten betreffender Kriterien zu kompilieren. Somit sind diese
Ausführungsformen äquivalent zu den speziellen Ausführungsformen, die hier für die
Zwecke der vorliegenden Erfindung beschrieben werden.
Die vorliegende Erfindung betrifft speziell die Optimierung von Ursprungscode durch die in
tensive Verwendung von Inlining-Verfahren, wenn der Code Zielmethoden-Aufrufe umfaßt.
Somit ist die vorliegende Erfindung insbesondere nützlich für die Optimierung von objektori
entierten Programmen, die viele kleine Objekte und Methoden verwenden, die häufig Me
thoden von anderen Objekten aufrufen, sowie die Klassen, die diese Methoden beschrei
ben. Die Java-Programmiersprache ist ein Beispiel einer stark objektorientierten Sprache,
die zu engen Objektdefinitionen unter Verwendung von kleinen begrenzten Zweckmethoden
ermutigt.
In einer stark objektorientierten Sprache ist die Erweiterbarkeit von Klassen ein Schlüssel
merkmal, das die Programmierung erleichtert und die Funktionalität verbessert. Eine Klasse
wird erweitert, wenn sie in Unterklassen unterteilt wird, so daß Methoden, die von der
Klasse beschrieben werden, außer Kraft gesetzt werden. Sobald sie außer Kraft gesetzt
worden sind, verwenden alle nachfolgenden Aufrufe einer außer Kraft gesetzten Methode
die neue Methode und nicht die, welche ursprünglich in der Ausgangsklasse oder abstrakten
Klasse beschrieben wurde, wenn der Empfänger des Methodenaufrufs die erweiterte Klasse
ist. Ein besonderer Nutzen der vorliegenden Erfindung besteht darin, daß sie ein System
und ein Verfahren zum Handhaben der Komplexitäten schafft, die durch eine Aufteilung in
Unterklassen in einem laufenden System verursacht werden.
Fig. 1 zeigt ein Computersystem 100, das so konfiguriert ist, daß es das Verfahren und die
Vorrichtung gemäß der vorliegenden Erfindung realisiert. Ein Client-Rechner 102 lädt ein
Programm herunter, das sich auf einem Server-Rechner 104 befindet. Der Client-Rechner
hat einen Prozessor 106 zur Ausführung der Programmbefehle, der über einen Systembus
mit einer Benutzerschnittstelle 108 verbunden ist. Die Benutzerschnittstelle 108 umfaßt
verfügbare Einrichtungen, um einem Benutzer Information anzuzeigen (beispielsweise einen
Kathodenstrahl-Monitor oder eine Flüssigkristall-Anzeige) sowie Einrichtungen, die dazu
dienen, vom Benutzer Information entgegenzunehmen (beispielsweise eine Tastatur, eine
Maus und dergleichen). Eine Speichereinheit 110 (beispielsweise ein Speicher mit wahl
freiem Zugriff, ein Festwertspeicher, ein programmierbarer Festwertspeicher und derglei
chen) speichert Daten und Befehle für die Durchführung des Programms. Die Speicherein
heit 112 umfaßt eine Massenspeichereinrichtung (beispielsweise Festplatten, ein
CD-LAUFWERK, Netzwerk-Laufwerke und dergleichen). Ein Modem 114 konvertiert Daten vom
Systembus in ein oder aus einem Format, das für eine Übertragung über das Netzwerk 105
geeignet ist. Das Modem 114 kann in äquivalenter Weise durch einen Netzwerkadapter oder
einen anderen rein digitalen oder gemischt analog/digitalen Adapter für ein Kommunikati
onsnetzwerk ersetzt werden.
Der Server 104 umfaßt typischerweise eine ähnliche Gruppe von Komponenten einschließ
lich einem Prozessor 116, einer Benutzerschnittstelle 118 und einem Server-Speicher 120.
Der Server-Speicher 122 speichert in einem speziellen Beispiel Programme, die in einem
Bytecode dargestellt sind und über das Modern 114 durch das Netzwerk 105 an den
Client-Rechner 104 übertragen werden. Es sei darauf hingewiesen, daß die vorliegende Erfindung
auch auf einem einzelnen Rechner statt in der in Fig. 1 gezeigten Netzwerk-Rechnerumge
bung dadurch ausgeführt werden kann, daß einfach das Bytecode-Programm in der
Client-Speichereinheit 112 gespeichert wird.
In der Beschreibung der vorliegenden Erfindung bezieht sich der Ausdruck "Klassentyp" auf
eine Eigenschaft, welche eine spezielle Klasse identifiziert und eine Klasse von jeder ande
ren Klasse oder jeder Unterklasse der Klasse selbst unterscheidet. Wenn eine Klasse in
Unterklassen aufgeteilt wird, ergibt sich ein neuer Klassentyp. Der Klassentyp eines spezi
ellen Objekts kann aus den Daten ermittelt werden, die in der Klassenbeschreibung gespei
chert sind. Eine Klasse kann durch die Verwendung des Schlüsselworts "final" definiert wer
den, wobei sie in diesem Fall nicht in Unterklassen aufgeteilt werden kann; andernfalls kann
sie in Unterklassen unterteilt werden. Die objektorientierte Programmierung fördert die Un
terteilung in Unterklassen, so daß üblicherweise eine Klasse in Unterklassen aufteilbar ist (in
der Java-Programmsprache ist dies tatsächlich der Fall, der eintritt, wenn keine speziellen
Vorgaben erfolgen). Wenn eine Klasse in Unterklassen unterteilt werden kann, kann sie be
liebig oft in Unterklassen aufgeteilt werden, was zu einem Satz von Klassentypen führt, der
über den gesamte Programmablauf hinweg erzeugt wird. Zur Laufzeit ist dann, wenn eine
Methode durch einen Methodenaufruf aufgerufen wird, nur ein spezieller Typ dieses Typen
satzes korrekt.
Fig. 2 zeigt eine beispielhafte Java-Programmierumgebung, die eine "Kompilierzeit-Umge
bung" 201 und eine "Laufzeit-Umgebung" 202 umfaßt. Das Entwickeln und der Ablauf eines
Programms in Java-Sprache umfassen zwei Schritte. Ein Programmierer gibt den
Java-Quellencode ein, der von einem Java-Compiler, wie z. B. dem in Fig. 2 gezeigten Javac in
eine Form konvertiert wird, die als Java- Bytecode bezeichnet wird. Wie oben beschrieben,
sind die Java-Bytecodes kompakt und transportierbar, was sie zu einer für die Speicherung
und Übertragung eines Programms in einem Netzwerk-Computersystem idealen Form
macht.
Der Bytecode wird dann in die Laufzeit-Umgebung 202 übertragen, um von einem Pro
gramm ausgeführt zu werden, das als Virtuelle Java-Maschine (JVM) bekannt ist. Alle Virtu
ellen Java-Maschinen verstehen die gleichen Bytecodes, so daß die Bytecode-Form eines
Java-Programms auf jeder Plattform mit einer Virtuellen Java-Maschine ablaufen kann. Auf
diese Weise ist eine Virtuelle Java-Maschine eine echte Ausführungs-Engine für
Java-Bytecodes; die Virtuelle Java-Maschine kann für eine gegebene Plattform einmal geschrie
ben werden und ist dann in der Lage, jedes Bytecode-Programm ablaufen zu lassen. Wie
bei herkömmlichen Virtuellen Java-Maschinen umfaßt die bevorzugte Ausführungsform ei
nen Bytecode-Interpreter 206, zu dem parallel ein dynamischer Compiler 208 läuft, wobei
ersterer einen übersetzten Ursprungscode in herkömmlicher Weise erzeugt, während der
Compiler 208 Zeit aufwendet, um optimierten Ursprungscode zu erzeugen.
Der dynamische Compiler 208 gemäß der vorliegenden Erfindung beschleunigt die Durch
führung des Java-Codes durch eine optimierte Kompilierung wie oben beschrieben. Der
Compiler 208 übernimmt den Java-Bytecode und konvertiert in Antwort auf das Wissen und
die Verhaltensinformation, die vom Profiler 210 erhalten werden, die Bytecodes in einen Ur
sprungscode für die verwenderspezifische Arten von Hardware 102 und Betriebssystem
203. Die vorliegende Erfindung verwendet eine Optimierungs-Compiler-Technologie um ein
hochwertiges Verhalten der maschinenausführbaren Form des Programms zu erzielen. Im
Gegensatz zu dem vom Interpreter 206 übersetzten Code wird der vom Compiler 208 opti
mierte Code für eine spätere Wiederverwendung im Code-Zwischenspeicher 212 gespei
chert.
Der Profiler 210 ist angeschlossen, um die Ausführung des Codes über die Zeit hinweg und
insbesondere das Verhalten des speziellen, ablaufenden Programms hinsichtlich der Auftei
lung in Unterklassen und der Überlastung zu überwachen. Für die vorliegende Erfindung ist
es von Bedeutung, daß der Profiler 210 Wissen darüber ansammelt, welche Klassen vom
Programm tatsächlich verwendet werden. Der Profiler 210 erzeugt Profildaten, die Klasse
für Klasse oder Methode für Methode in einer Profildaten-Struktur (nicht dargestellt) gespei
chert werden. Somit kann, obwohl der dynamische Compiler 208 zunächst keinerlei Wissen
bezüglich des Klassensatzes besitzt, eine sitzungsspezifische Kenntnis des Klassensatzes
und des Klassenverhaltens durch den Profiler 210 erhalten werden. In einer beispielhaften
Ausführungsform umfaßt der Profiler 210 Datenstrukturen, wie z. B. eine Tabelle, die einen
Eintrag für jede Klasse aufweisen, von der er wahrnimmt, daß sie durchgeführt wird.
In dem Maß, in dem die Ausführung fortschreitet, speichert der Profiler 210 Daten in der
Datenstruktur, die anzeigen, ob eine spezielle Klasse in Unterklassen aufgeteilt worden ist,
und die bei jedem einzelnen Methodenaufruf anzeigen, ob es sehr wahrscheinlich ist, daß
der Klassentyp einer speziellen Klasse der richtige Klassentyp ist. Die gespeicherten Daten
sind somit nützlicher als eine einfache "feste" Anzeige, die direkt aus der Klassenbeschrei
bung entnommen werden kann. Darüber hinaus kann zwar die Datenstruktur im Profiler 210
beim Start auf einen bekannten Status initialisiert werden, doch ändert sie sich dynamisch
um das momentane Verhalten des Programms in der Umgebung wiederzuspiegeln, in der
es verwendet wird.
Es ist zweckmäßig, die vorliegende Erfindung in Bezug auf vier Kategorien von Methoden
aufrufen zu verstehen, bei denen die Erfindung besonders nützlich ist. Der erste Fall ist ein
Methodenaufruf, bei dem die Klasse des Empfängerobjekts (das heißt die Klasse, die die
Zielmethode definiert) eindeutig bzw. zweifelsfrei bekannt ist. Dies kann sich ergeben, wenn
die Methode als "final" bezeichnet ist (das heißt das Schlüsselwort "final" in ihrer Beschrei
bung enthält) oder wenn eine Festcode-Analyse ergeben hat, daß die Methode de facto final
ist, obwohl sie nicht ausdrücklich als final deklariert wurde. Im zweiten Fall ist bekannt, daß
die Empfängerklasse variabel ist. Ein Aufruf einer Methode, die in einer abstrakten Klasse
definiert ist, oder einer Klasse, von der bekannt ist, daß sie in Unterklassen aufgeteilt wurde,
ist ein Beispiel für diesen Fall. Die ersten beiden Fälle stellen Extreme dar, in denen entwe
der eine Klasse in unzweifelhafter Weise als fest bekannt ist oder die Klasse in hohem Maß
dahingehend unbestimmt ist, welchen Typ sie bei einem speziellen Durchlauf aufweisen
wird.
Die beiden verbleibenden Fälle umschließen Grauzonen, bei denen eine gewisse Laufzeit-Kenntnis
hinsichtlich der Klasse erarbeitet werden kann, um die Erzeugung eines effiziente
ren Codes zu ermöglichen. In dritten Fall wird die Empfängerklasse als eine Klasse identifi
ziert, die mit einer gewissen Wahrscheinlichkeit einen speziellen Typ besitzt. Gemäß der
vorliegenden Erfindung kann dieser Fall aus einer auf dem Profiler basierenden Rückmel
dung identifiziert werden. In einem vierten Fall ist es sehr wahrscheinlich, daß die Empfän
gerklasse einen speziellen Typ besitzt, weil die auf dem Profiler basierende Rückmeldung
anzeigt, daß die Klasse bei keinem vorausgehenden Durchlauf in Unterklassen aufgeteilt
worden ist.
Gemäß der vorliegenden Erfindung ist im ersten Fall bekannt, daß die Klasse durch nach
folgende Methodenaufrufe nicht außer Kraft gesetzt werden kann. In diesem Fall können
Methodenaufrufe immer direkt aufgerufen oder in den Code hinein kopiert werden, der für
die aufrufende Methode erzeugt worden ist. Diese beiden Arten von Optimierungen (direktes
Aufrufen und Inlining) sind verschiedene aber analoge Vorgänge. Ein direktes Aufrufen kann
schneller ausgeführt werden, als ein virtueller Methodenaufruf. Eine noch schnellere Opti
mierung besteht darin, tatsächlich den Code der Zielmethode in den Code der aufrufenden
Methode hinein zu kopieren (Inlining). Das Inlining bewirkt jedoch, daß die Codegröße wäh
rend der Laufzeit anwächst und stellt somit größere Anforderungen an den Befehls-Zwi
schenspeicher des Rechners. Wenn nicht anders spezifiziert, ist die Auswahl zwischen die
sen beiden Optimierungsverfahren eine Sache der geeigneten Codeerzeugung, um die Be
dürfnisse einer speziellen Anwendung zu erfüllen.
Im zweiten Fall würde eine einfache Umsetzung der vorliegenden Erfindung einen Code er
zeugen, der einen herkömmlichen virtuellen Funktionsaufruf realisiert. Dies ist vertretbar,
weil eine Optimierung in einem solchen Fall einen größeren zusätzlichen Aufwand erfordert
und dazu führen kann, daß sehr viel Code für jeden Aufruf der Methode erzeugt wird. Alter
nativ werden alle möglichen Klassen als Fälle in einem "Schalter-Statement" identifiziert, so
daß der Code der Zielmethode aus jeder möglichen Klasse in den Code der aufrufenden
Methode hinein kopiert wird. Der Schalter wird beim Ausführen der aufrufenden Methode
dadurch selektiert, daß der momentane Klassentyp getestet und der Schalter auf der Basis
des Testergebnisses ausgewählt wird.
Im dritten Fall können Aufrufe direkt für die Methode durchgeführt werden, die die größte
Wahrscheinlichkeit besitzt, daß sie die richtige ist, wobei ein kleiner Test im Code der Ziel
methode durchgeführt wird. Wenn die Klasse für die Methode nicht die richtige ist, kann ein
virtueller Funktionsaufruf durchgeführt werden. Alternativ können Methoden des dritten Falls
in den Code der aufrufenden Methode hineinkopiert werden, jedoch mit einem Test unmit
telbar vor dem ersten Befehl des hineinkopierten Codes, der überprüft, ob der Klassentyp
korrekt ist, und der ersatzweise einen virtuellen Methodenaufruf durchführt, wenn dies nicht
der Fall ist.
Im vierten Fall können Methodenaufrufe dadurch effizient ausgeführt werden, daß die Me
thode direkt aufgerufen wird. Gemäß der vorliegenden Erfindung nimmt der zunächst er
zeugte Code an, daß die Klasse niemals in Unterklassen aufgeteilt wird. Wenn sie jedoch
nachfolgend in Unterklassen aufgeteilt wird, dann wird der erste Befehl der Methode an ein
kleines Codefragment angeheftet bzw. in diese eingeflickt (patched), das den Empfänger te
stet und einen virtuellen Funktionsaufruf durchführt, wenn dieser nicht korrekt ist. Wenn er
korrekt ist, wird der eingeflickte Befehl ausgeführt und es wird zum Hauptmethoden-Code
zurück verzweigt.
Je kürzer die Zielmethode ist, desto wichtiger ist es, daß sie in den Code der aufrufenden
Methode hineinkopiert wird. Um eine erneute Kompilierung der aufrufenden Methoden zu
vermeiden, ist ein Test der empfangenden Klasse (das heißt der Klasse der Zielmethode)
erforderlich. Wünschenswerter Weise erfordert dieser Test wenig zusätzlichen Aufwand und
ist relativ schnell. Ein Beispiel für einen ungünstigsten Fall eines Methodenaufrufs einer
Zielmethode mit nur einem einzigen Befehl wird durch eine einfache Zugriffsmethode erläu
tert. Nimmt man beispielsweise an, daß eine Klasse Y die Beschreibung
Das Ursprungscodesegment, das für die aufrufende Methode erzeugt wird, kann folgend er
maßen aussehen:
In dem obigen Maschinencode realisiert der erste Befehl einen Klassentypentest, der einen
von der Klassenbeschreibung im Speicher ausgelesenen Klassentyp mit einer vordefinier
ten Konstanten für die erwartete Klasse vergleicht. Diese vorbestimmte Konstante wird fest
gelegt, wenn der Code erzeugt wird, und kann immer dann auf den neuesten Stand ge
bracht werden, wenn der Code erneut erzeugt wird. Wenn die beiden Werte gleich sind, wird
der für die Ungleichheit vorgesehene Verzweigungsbefehl übersprungen und es wird der
Maschinencode, der das Inline-Verfahren realisiert, ausgeführt. Der Fall, daß ein durchge
hender Aufruf (call-through) der virtuellen Funktionstabelle auftritt, wird durch den Befehl
vfCall behandelt und führt zu einer gewissen Verschlechterung des Ablaufverhaltens. Da je
doch erwartet werden kann, daß es sich hierbei um einen unüblichen Fall handelt, spielt das
Verhalten keine Rolle.
Es wird davon ausgegangen, daß der Code so organisiert werden kann, daß Ergebnisse
dieses Klassentypentests für eine Vielzahl von Methodenaufrufen wiederverwendet werden
können. Zu Zeitpunkten, in denen mehrere Aufrufe Methoden der gleichen Klasse betreffen
und die Klasse der Zielmethoden zwischen zwei aufeinanderfolgenden Aufrufen nicht in
Unterklassen unterteilt worden sein kann, kann ein einziger Klassentypentest durchgeführt
und von allen Zielmethoden-Aufrufen verwendet werden. Diese Ausführungsform verteilt
den zusätzlichen Aufwand, der mit der Durchführung des Klassentypentests verbunden ist,
über eine Vielzahl von Methodenaufrufen und verbessert dadurch die Effizienz.
Ein Weg, eine weitere Verbesserung des Inlining zu erzielen, besteht darin, den Klassentest
(d. h. die CMP- und BNE-Befehle in dem obigen Beispiel) völlig zu entfernen. Der sich erge
bende Code umfaßt nur den Code der Zielmethode und ist somit äußerst effizient. Der durch
das Inlining erzeugte Code wird jedoch nicht genau sein, wenn die Zielmethode jemals au
ßer Kraft gesetzt worden ist. Somit muß sich die JVM immer dann, wenn dies durchgeführt
wird, daran erinnern, daß dann, wenn die Klasse der Zielmethode jemals durch eine Klasse
in Unterklassen aufgeteilt worden ist, welche die Methode außer Kraft setzt, das durch Inli
ning erzeugte Codesegment durch eine virtuelle Aufrufsequenz ersetzt werden muß.
Die virtuelle Aufrufsequenz könnte größer sein als alles, was sie ersetzt, und um dieses
Problem zu lösen kann der erste Befehl des ursprünglich durch Inlining erzeugten Codes in
einen Befehl geändert werden, der die Ausführung des Programms an eine Stelle zurück
verweist, an der sich die Befehle für die Ausführung der virtuellen Aufrufsequenz befinden.
Beispiele umfassen einen Verzweigungsbefehl, einen Aufrufbefehl, einen Unterbrechungs
punkt-Befehl und dergleichen. Die Auswahl, auf welche Weise dieses Merkmal realisiert
wird, basiert auf der Überlegung, welche Vorgehensweise zu einer geeignet effizienten und
flexiblen Realisierung für eine spezielle Maschine führt.
Bei der in Fig. 3 gezeigten Verzweigungs-Realisierung wird der erste Befehl des Inline-Codes
durch einen Verzweigungsbefehl (beispielsweise BR X, wobei X die Stelle ist, an der
sich der den virtuellen Funktionsaufruf realisierende Code befindet) ersetzt. Bei nachfolgen
den Ausführungen wird nicht der durch Inlining eingefügte Code sondern statt dessen der
Code an der Stelle X ausgeführt. Der Code, der den virtuellen Funktionsaufruf realisiert,
muß mit einem Verzweigungsbefehl enden, damit zum Ende der durch Inlining eingefügten
Codesequenz zurückgekehrt wird.
Bei der in Fig. 4 gezeigten "Aufruf"-Realisierung wird der erste Befehl des Inline-Codes
durch einen Aufrufbefehl ersetzt, der Befehle an einer Stelle X aufruft, die den virtuellen
Funktionsaufruf realisieren. Am Ende der aufgerufenen Sequenz läßt ein Rückkehrbefehl
(RTN in Fig. 4) die Befehlsausführung an die Stelle zurückkehren, die unmittelbar hinter
dem Aufrufbefehl in dem eingeflickten Code liegt. In den zweiten Befehl des Inline-Codes
wird ein Verzweigungsbefehl eingeflickt (patched), der auf das Ende des Inline-Codeseg
ments zeigt.
Eine in Fig. 4 gezeigte Aufruf-Realisierung kann in manchen Prozessoren, wie z. B. in Pro
zessoren mit einer SPARC-Architektur äußerst effizient und flexibel sein, da diese Prozes
soren Aufrufbefehle in einer Weise realisieren, die es der aufgerufenen Befehlssequenz
ermöglicht, sich irgendwo im virtuellen Speicherraum des Rechners (beispielsweise in ei
nem 4-Gigabyte-Adressenraum im Fall einer SPARC-Architektur) zu befinden. Im Gegen
satz hierzu kann ein typischer Verzweigungsbefehl nur an eine Stelle innerhalb eines be
grenzten Bereiches von Adressenplätzen um den Verzweigungsbefehl herum verzweigen.
Dies kann ein signifikanter Vorteil in den Fällen sein, in denen der eingeflickte Code (patch
code) tatsächlich während der Laufzeit kompiliert wird. Wenn beispielsweise der Code an
der Stelle X in Fig. 3 und 4 erst kompiliert würde, nachdem festgestellt wurde, daß er benö
tigt wird (d. h. nachdem die Methode, von der der durch Inlining eingefügte Code stammte,
außer Kraft gesetzt worden ist) kann es sein, daß in der Nähe kein freier Speicherplatz zur
Aufnahme des Einflickcodes vorhanden ist. Somit kann es erforderlich sein, den Einflick
code außerhalb des Adressenbereiches unterzubringen, der über einen Verzweigungsbefehl
zugänglich ist. Alternativ kann das Programm mit leeren Speicherplätzen gefüllt werden, die
erforderlichenfalls für die Aufnahme von Einflickcode verwendet werden können, doch ist
dies eine ziemlich ineffiziente Verwendung der Speicherressourcen, die das' Programm auf
blähen und das Organisieren des Befehls-Zwischenspeichers komplizieren kann.
Fig. 5 zeigt eine Realisierung, die den Unterbrechungspunkt-Handler des Betriebssystems
verwendet, um den Einflickcode zu realisieren. Wie in Fig. 5 gezeigt, wird der erste Befehl
des durch Inlining eingefügten Codes mit einem Unterbrechungspunkt-Befehl eingeflickt, der
bei Ausführung eine Ausnahme schaltet. Der Unterbrechungspunkt-Befehl wird vom Unter
brechungspunkt-Handler abgefangen, der auf eine Datenstruktur, wie z. B. eine Unterbre
chungspunkt-Tabelle 601 Bezug nimmt. Für jeden Unterbrechungspunkt-Befehl "A" verweist
die Tabelle 601 auf einen Satz "B" von Befehlen zur Handhabung des Unterbrechungs
punkts. Die Befehle bei B können ihrerseits den virtuellen Funktionsaufruf realisieren. Es sei
darauf hingewiesen, daß diese Prozedur eine ziemlich langsame Sequenz ist, doch wird in
Anwendungsumgebungen, in denen dieser Fall selten auftritt, eine Nettoverbesserung des
Verhaltens erzielt. Diese Ineffizienzen können im Profil aufgezeichnet und korrigiert werden,
wenn die Task das nächste Mal abläuft.
Um dieses Merkmal dann zu ermöglichen, wenn der Compiler die Methode erzeugt, muß er
sowohl ein Codefragment erzeugen, das den virtuellen Funktionsaufruf realisiert, als auch
ein Codefragment, das den durch Inlining eingefügten Code selbst realisiert. Dieses Code
fragment für den virtuellen Funktionsaufruf wird vom Unterbrechungspunkt-Handler aufge
rufen und muß als Inkrement die gespeicherte Rückkehradresse enthalten, um den Code
ablauf zu veranlassen, zum Ende des jetzt ungültigen, durch Inlining eingefügten Codes zu
springen und dann von der Interruptsequenz zurückzukehren. Die Adresse des Speicher
platzes, der eingeflickt werden soll, und die Adresse des Speicherplatzes, der das Code
fragment enthält, werden in einer Datenstruktur angeordnet, die der Methode zugeordnet ist,
die durch Inlining eingefügt werden soll. Immer dann, wenn diese Methode in Unterklassen
aufgeteilt wird, wird die Einflickzuordnung zu den Befehlen in der Befehlsdatenstruktur her
gestellt, und der Unterbrechungspunkt-Handler wird über die Zuordnung informiert.
Ein attraktives Merkmal des Systems und des Verfahrens gemäß der vorliegenden Erfin
dung besteht darin, daß der Code, wenn er erzeugt worden ist, niemals neu kompiliert wer
den muß, und daß keine schwierigen Stapel-Einflick-Verfahren erforderlich sind. Obwohl die
Compiler-Komplexität und die Größe der Datenstruktur etwas anwachsen, ergibt sich in of
fenkundiger Weise eine Verbesserung hinsichtlich der Effizienz der Codeausführung.
Obwohl die Erfindung mit einem gewissen Ausmaß von Einzelangaben beschrieben und
erläutert wurde, sei darauf hingewiesen, daß die vorliegende Beschreibung lediglich bei
spielhaft ist und daß vorn Fachmann viele Änderungen hinsichtlich der Kombination und der
Anordnung von Teilen vorgenommen werden können, ohne daß von Geist und Umfang der
Erfindung abgewichen wird.
Claims (20)
1. Verfahren zur Erzeugung eines Codes aus einem durch Bytecodes dargestellten
Programm, das folgende Schritte umfaßt:
Empfangen einer Gruppe der Bytecodes, die eine auszuführende Methode darstel len,
dann, wenn die empfangenen Bytecodes eine Aufrufmethode darstellen, die eine andere Methode aufruft, Bestimmen, ob die Klasse der Zielmethode in eindeutiger Weise bekannt ist,
dann, wenn die Klasse der Zielmethode in eindeutiger Weise bekannt ist, Erzeugen eines Codes für die empfangenen Bytecodes, der Code aus der Zielmethode in den Code für die aufrufende Methode, die ausgeführt werden soll, durch Inlining einfügt, und
Speichern des erzeugten Codes für nachfolgende Ausführungen der aufrufenden Methode.
Empfangen einer Gruppe der Bytecodes, die eine auszuführende Methode darstel len,
dann, wenn die empfangenen Bytecodes eine Aufrufmethode darstellen, die eine andere Methode aufruft, Bestimmen, ob die Klasse der Zielmethode in eindeutiger Weise bekannt ist,
dann, wenn die Klasse der Zielmethode in eindeutiger Weise bekannt ist, Erzeugen eines Codes für die empfangenen Bytecodes, der Code aus der Zielmethode in den Code für die aufrufende Methode, die ausgeführt werden soll, durch Inlining einfügt, und
Speichern des erzeugten Codes für nachfolgende Ausführungen der aufrufenden Methode.
2. Verfahren nach Anspruch 1, bei dem dann, wenn die Klasse der Zielmethode nicht
eindeutig bekannt ist, das Verfahren weiterhin folgende Schritte umfaßt:
Bestimmen, ob von der Klasse der Zielmethode bekannt ist, daß sie in Unterklassen aufgeteilt ist, und
dann, wenn bekannt ist, daß die Klasse der Zielmethode in Unterklassen aufgeteilt ist, Erzeugen eines Codes für die empfangenen Bytecodes, der einen virtuellen Funktionsaufruf für die Methode ausführt.
Bestimmen, ob von der Klasse der Zielmethode bekannt ist, daß sie in Unterklassen aufgeteilt ist, und
dann, wenn bekannt ist, daß die Klasse der Zielmethode in Unterklassen aufgeteilt ist, Erzeugen eines Codes für die empfangenen Bytecodes, der einen virtuellen Funktionsaufruf für die Methode ausführt.
3. Verfahren nach Anspruch 1, bei dem dann, wenn die Klasse der Zielmethode nicht
eindeutig bekannt ist, das Verfahren weiterhin folgende Schritte umfaßt:
Bestimmen, ob von der Klasse der Zielmethode bekannt ist, daß sie in Unterklassen unterteilt ist,
dann, wenn von der Klasse der Zielmethode bekannt ist, daß sie in Unterklassen unterteilt ist, Ermitteln, ob alle möglichen Unterklassen für die Klasse der Zielme thode bekannt sind,
wobei dann, wenn alle möglichen Unterklassen für die Klasse der Zielmethode be kannt sind, das Verfahren weiterhin folgende Schritte umfaßt:
Erzeugen eines Codefragments für jede mögliche Unterklasse, wobei jedes Code fragment Code aus der Zielmethode, wie sie durch die zugehörige Unterklasse defi niert wird, durch Inlining verarbeitet,
Erzeugen von Code für die empfangenen Bytecodes, der einen Schalter realisiert, für den jedes Codefragment einen Fall darstellt, und
Erzeugen von Code für die empfangenen Bytecodes, der auf der Basis des mo mentanen Unterklassen-Status der Klasse der Zielmethode zum Zeitpunkt, zu dem die aufrufende Methode ausgeführt wird, den Schalter auf den entsprechenden Fall setzt.
Bestimmen, ob von der Klasse der Zielmethode bekannt ist, daß sie in Unterklassen unterteilt ist,
dann, wenn von der Klasse der Zielmethode bekannt ist, daß sie in Unterklassen unterteilt ist, Ermitteln, ob alle möglichen Unterklassen für die Klasse der Zielme thode bekannt sind,
wobei dann, wenn alle möglichen Unterklassen für die Klasse der Zielmethode be kannt sind, das Verfahren weiterhin folgende Schritte umfaßt:
Erzeugen eines Codefragments für jede mögliche Unterklasse, wobei jedes Code fragment Code aus der Zielmethode, wie sie durch die zugehörige Unterklasse defi niert wird, durch Inlining verarbeitet,
Erzeugen von Code für die empfangenen Bytecodes, der einen Schalter realisiert, für den jedes Codefragment einen Fall darstellt, und
Erzeugen von Code für die empfangenen Bytecodes, der auf der Basis des mo mentanen Unterklassen-Status der Klasse der Zielmethode zum Zeitpunkt, zu dem die aufrufende Methode ausgeführt wird, den Schalter auf den entsprechenden Fall setzt.
4. Verfahren nach Anspruch 1, bei dem dann, wenn die Klasse der Zielmethode nicht
eindeutig bekannt ist, das Verfahren weiterhin folgende Schritte umfaßt:
Identifizieren eines Satzes von Klassen, die möglicherweise für die Klasse der Ziel methode korrekt sind,
Auswählen einer Klasse aus dem Satz von möglichen Klassen auf der Basis des Wissens, daß die ausgewählte Klasse mit einer Wahrscheinlichkeit, die größer ist als Null, für jede Durchführung der aufrufenden Klasse korrekt ist,
Erzeugen eines ersten Codefragments, das Code aus der ausgewählten Klasse in den Code für die auszuführende Aufrufmethode durch Inlining einfügt,
Erzeugen eines zweiten Codefragments, das einen virtuellen Funktionsaufruf ohne Inlining-Code ausführt,
Erzeugen eines Testcodes, der vor dem ersten und zweiten Codefragment, die ge testet werden sollen, während jeder Ausführung der aufrufenden Methode überprüft, ob die ausgewählte Klasse die richtige Klasse ist,
Erzeugen eines Verzweigungscodes, der die Codeausführung veranlaßt, entweder das erste Codefragment oder das zweite Codefragment in Abhängigkeit vom Test code auszuwählen, und
Kombinieren des ersten Codefragments, des zweiten Codefragments, des Test codes und des Verzweigungscodes zur Bildung des erzeugten Codes für die emp fangenen Bytecodes.
Identifizieren eines Satzes von Klassen, die möglicherweise für die Klasse der Ziel methode korrekt sind,
Auswählen einer Klasse aus dem Satz von möglichen Klassen auf der Basis des Wissens, daß die ausgewählte Klasse mit einer Wahrscheinlichkeit, die größer ist als Null, für jede Durchführung der aufrufenden Klasse korrekt ist,
Erzeugen eines ersten Codefragments, das Code aus der ausgewählten Klasse in den Code für die auszuführende Aufrufmethode durch Inlining einfügt,
Erzeugen eines zweiten Codefragments, das einen virtuellen Funktionsaufruf ohne Inlining-Code ausführt,
Erzeugen eines Testcodes, der vor dem ersten und zweiten Codefragment, die ge testet werden sollen, während jeder Ausführung der aufrufenden Methode überprüft, ob die ausgewählte Klasse die richtige Klasse ist,
Erzeugen eines Verzweigungscodes, der die Codeausführung veranlaßt, entweder das erste Codefragment oder das zweite Codefragment in Abhängigkeit vom Test code auszuwählen, und
Kombinieren des ersten Codefragments, des zweiten Codefragments, des Test codes und des Verzweigungscodes zur Bildung des erzeugten Codes für die emp fangenen Bytecodes.
5. Verfahren nach Anspruch 1, bei dem dann, wenn die Klasse der Zielmethode zwei
felhaft ist, das Verfahren weiterhin folgende Schritte umfaßt:
Erzeugen eines ersten Codefragments für die empfangenen Bytecodes, das Code aus der Klasse der Zielmethode so im Inlining-Verfahren behandelt, als ob die Klasse der Zielmethode fest wäre,
Erzeugen eines zweiten Codefragments, das einen virtuellen Funktionsaufruf für die Zielmethode realisiert und den Programmablauf zum ersten Codefragment zurück kehren läßt,
Erzeugen einer Datenstruktur, die einen Eintrag für die Zielmethode umfaßt, wobei der Eintrag eine erste Adresse eines ersten Befehls im ersten Codefragment sowie eine zweite Adresse eines ersten Befehls im zweiten Codefragment speichert,
Einflicken des ersten Befehls des ersten Codefragments mit einem dritten Code fragment, das den Programmablauf zum zweiten Codefragment immer dann über trägt, wenn die Zielmethode außer Kraft gesetzt worden ist.
Erzeugen eines ersten Codefragments für die empfangenen Bytecodes, das Code aus der Klasse der Zielmethode so im Inlining-Verfahren behandelt, als ob die Klasse der Zielmethode fest wäre,
Erzeugen eines zweiten Codefragments, das einen virtuellen Funktionsaufruf für die Zielmethode realisiert und den Programmablauf zum ersten Codefragment zurück kehren läßt,
Erzeugen einer Datenstruktur, die einen Eintrag für die Zielmethode umfaßt, wobei der Eintrag eine erste Adresse eines ersten Befehls im ersten Codefragment sowie eine zweite Adresse eines ersten Befehls im zweiten Codefragment speichert,
Einflicken des ersten Befehls des ersten Codefragments mit einem dritten Code fragment, das den Programmablauf zum zweiten Codefragment immer dann über trägt, wenn die Zielmethode außer Kraft gesetzt worden ist.
6. Verfahren nach Anspruch 5, bei dem das dritte Codefragment einen Verzweigungs
befehl umfaßt und das zweite Codefragment einen Verzweigungsbefehl umfaßt, der
dem Programmablauf zum Ende des ersten Codefragments zurückkehren läßt.
7. Verfahren nach Anspruch 5, bei dem das dritte Codefragment einen Aufrufbefehl
umfaßt und das Einflicken weiterhin ein Ersetzen eines zweiten Befehls im ersten
Codefragment durch einen Verzweigungsbefehl umfaßt, der den Programmablauf
zum Ende des ersten Codefragments zurückkehren läßt.
8. Verfahren nach Anspruch 5, bei dem das dritte Codefragment einen Unterbre
chungspunkt-Befehl umfaßt, der eine Unterbrechungspunkt-Handler-Routine aufruft.
9. Verfahren nach Anspruch 8, bei dem die Unterbrechungspunkt-Handler-Routine
Code umfaßt, der den Programmablauf zum Ende des ersten Codefragments zu
rückkehren läßt.
10. Verfahren nach Anspruch 1, bei den der Schritt des Ermittelns, ob von der Klasse
der Zielmethode bekannt ist, daß sie in Unterklassen unterteilt ist, eine Überprüfung
der Geschichte früherer Durchläufe der auszuführenden Methode umfaßt.
11. Vorrichtung zur Erzeugung von Code aus empfangenen Bytecodes, die folgende
Bestandteile umfaßt:
einen Compiler, der die Bytecodes empfängt,
eine Datenstruktur im Compiler, die eine Vielzahl von Einträgen aufweist, wobei je der Eintrag einer objektorientierten Programmklasse entspricht, auf die sich jeweils eine spezielle Gruppe der Bytecodes bezieht,
eine Datenaufzeichnung in jedem Eintrag der Datenstruktur, die anzeigt, ob es wahrscheinlich ist, daß die entsprechende Klasse in Unterklassen aufgeteilt worden ist,
einen Codegenerator im Compiler, der so angeschlossen ist, daß er auf die Daten aufzeichnungen zugreift, wobei der Codegenerator für jede Gruppe von Bytecodes aus einer Vielzahl von Codeerzeugungsoptionen auf der Basis eines momentanen Werts der Datenaufzeichnung, die der Klasse entspricht, auf die sich die Gruppe von Bytecodes bezieht, eine Auswahl trifft, und
einen Ursprungscode-Zwischenspeicher, der eine Vielzahl von Einträgen aufweist, wobei jeder Eintrag einer speziellen Gruppe von Bytecodes entspricht und jeder Eintrag den erzeugten Ursprungscode enthält, der der speziellen Gruppe von Byte codes zugeordnet ist, wobei jedes Mal dann, wenn eine spezielle Gruppe von Byte codes zum ersten Mal vom Compiler empfangen wird, die Gruppe von Bytecodes zum Codegenerator weitergeleitet wird, und jedesmal dann, wenn die spezielle Gruppe von Bytecodes vom Compiler empfangen wird, die Bytecodes in einen aus dem Ursprungscode-Zwischenspeicher ausgewählten Code übersetzt werden.
einen Compiler, der die Bytecodes empfängt,
eine Datenstruktur im Compiler, die eine Vielzahl von Einträgen aufweist, wobei je der Eintrag einer objektorientierten Programmklasse entspricht, auf die sich jeweils eine spezielle Gruppe der Bytecodes bezieht,
eine Datenaufzeichnung in jedem Eintrag der Datenstruktur, die anzeigt, ob es wahrscheinlich ist, daß die entsprechende Klasse in Unterklassen aufgeteilt worden ist,
einen Codegenerator im Compiler, der so angeschlossen ist, daß er auf die Daten aufzeichnungen zugreift, wobei der Codegenerator für jede Gruppe von Bytecodes aus einer Vielzahl von Codeerzeugungsoptionen auf der Basis eines momentanen Werts der Datenaufzeichnung, die der Klasse entspricht, auf die sich die Gruppe von Bytecodes bezieht, eine Auswahl trifft, und
einen Ursprungscode-Zwischenspeicher, der eine Vielzahl von Einträgen aufweist, wobei jeder Eintrag einer speziellen Gruppe von Bytecodes entspricht und jeder Eintrag den erzeugten Ursprungscode enthält, der der speziellen Gruppe von Byte codes zugeordnet ist, wobei jedes Mal dann, wenn eine spezielle Gruppe von Byte codes zum ersten Mal vom Compiler empfangen wird, die Gruppe von Bytecodes zum Codegenerator weitergeleitet wird, und jedesmal dann, wenn die spezielle Gruppe von Bytecodes vom Compiler empfangen wird, die Bytecodes in einen aus dem Ursprungscode-Zwischenspeicher ausgewählten Code übersetzt werden.
12. Vorrichtung nach Anspruch 11, die weiterhin einen Profiler umfaßt, der angeschlos
sen ist, um den Compiler über einen Zeitraum hinweg zu überwachen, um Kenntnis
über die aktuellen Klassen und Unterklassen anzusammeln, die während der Pro
grammdurchführung aufgerufen werden.
13. System für die Laufzeit-Kompilierung von objektorientiertem Programmcode, wobei
der Programmcode Code umfaßt, der eine Vielzahl von objektorientierten Klassen
definiert, wobei das System folgendes umfaßt:
einen Laufzeitcompiler, der den Programmcode empfängt, die aufrufenden Metho den, die eine Zielmethode aufrufen, identifiziert und feststellt, ob die Klasse der Zielmethode in unzweifelhafter Weise bekannt ist,
einen Codegenerator im Compiler, der Code aus der Zielmethode in den Code der aufrufenden Methode, die ausgeführt werden soll, im Inlining-Verfahren einfügt, und
einen Code-Zwischenspeicher, der Datenstrukturen enthält, die den erzeugten Code für nachfolgende Durchführungen der aufrufenden Methode speichert.
einen Laufzeitcompiler, der den Programmcode empfängt, die aufrufenden Metho den, die eine Zielmethode aufrufen, identifiziert und feststellt, ob die Klasse der Zielmethode in unzweifelhafter Weise bekannt ist,
einen Codegenerator im Compiler, der Code aus der Zielmethode in den Code der aufrufenden Methode, die ausgeführt werden soll, im Inlining-Verfahren einfügt, und
einen Code-Zwischenspeicher, der Datenstrukturen enthält, die den erzeugten Code für nachfolgende Durchführungen der aufrufenden Methode speichert.
14. Computersystem, das folgende Bestandteile umfaßt:
einen Speicher zum Speichern eines Bytecode-Programms, wobei das Byte code-Programm eine Sequenz von Bytecodes umfaßt, wobei Gruppen der Bytecodes auszuführende Methoden einschließlich einer aufrufenden Methode und einer Ziel methode umfassen, wobei die aufrufende Methode einen Vorgang umfaßt, der die Zielmethode aufruft,
eine Datenverarbeitungseinheit zum Ausführen von Ursprungscode,
einen Code-Zwischenspeicher zum Speichern von Ursprungscode-Darstellungen zumindest einiger der Methoden,
einen Compiler, der dann, wenn eine spezielle Gruppe von Bytecodes das erste Mal empfangen wird, so arbeitet, daß er die empfangenen Gruppe von Bytecodes in eine Ursprungscode-Darstellung der Bytecodes übersetzt und die Ursprungs code-Darstellung im Code-Zwischenspeicher speichert,
einen Profiler, der mit der Datenverarbeitungseinheit verbunden ist, wobei der Pro filer Datenstrukturen aufweist, die Information über die Klasse einer jeden Methode speichern, welche eine Wahrscheinlichkeit dafür anzeigt, daß die Klasse der Me thode in Unterklassen aufgeteilt worden ist,
Optimierungscode im Compiler, der mit den Datenstrukturen des Profilers gekoppelt ist, um ein Code-Erzeugungsverfahren auf der Basis der gespeicherten Information auszuwählen.
einen Speicher zum Speichern eines Bytecode-Programms, wobei das Byte code-Programm eine Sequenz von Bytecodes umfaßt, wobei Gruppen der Bytecodes auszuführende Methoden einschließlich einer aufrufenden Methode und einer Ziel methode umfassen, wobei die aufrufende Methode einen Vorgang umfaßt, der die Zielmethode aufruft,
eine Datenverarbeitungseinheit zum Ausführen von Ursprungscode,
einen Code-Zwischenspeicher zum Speichern von Ursprungscode-Darstellungen zumindest einiger der Methoden,
einen Compiler, der dann, wenn eine spezielle Gruppe von Bytecodes das erste Mal empfangen wird, so arbeitet, daß er die empfangenen Gruppe von Bytecodes in eine Ursprungscode-Darstellung der Bytecodes übersetzt und die Ursprungs code-Darstellung im Code-Zwischenspeicher speichert,
einen Profiler, der mit der Datenverarbeitungseinheit verbunden ist, wobei der Pro filer Datenstrukturen aufweist, die Information über die Klasse einer jeden Methode speichern, welche eine Wahrscheinlichkeit dafür anzeigt, daß die Klasse der Me thode in Unterklassen aufgeteilt worden ist,
Optimierungscode im Compiler, der mit den Datenstrukturen des Profilers gekoppelt ist, um ein Code-Erzeugungsverfahren auf der Basis der gespeicherten Information auszuwählen.
15. Computersystem nach Anspruch 14, bei dem der Profiler weiterhin eine Überwa
chungsanordnung umfaßt, die die Durchführung einer jeden Methode überwacht
und aufzeichnet, wenn die Klasse einer jeden Methode in Unterklassen unterteilt
wird, und
einen Geschichts-Akkumulator, der die gespeicherte Information in der Datenstruk tur des Profilers modifiziert, um die aufgezeichnete Information der Überwachungs anordnung anzuzeigen.
einen Geschichts-Akkumulator, der die gespeicherte Information in der Datenstruk tur des Profilers modifiziert, um die aufgezeichnete Information der Überwachungs anordnung anzuzeigen.
16. Computersystem nach Anspruch 14, bei dem der Optimierungscode weiterhin fol
gendes umfaßt:
Code, der mit den Datenstrukturen des Profilers gekoppelt ist und anzeigt, daß die Klasse einer Methode zweifelsfrei bekannt ist,
Code, der mit den Datenstrukturen des Profilers gekoppelt ist und anzeigt, daß die Klasse einer Methode einen dynamischen Typ besitzt und eine von Null verschie dene Wahrscheinlichkeit besteht, daß sie von einem speziellen Typ ist,
Code, der mit den Datenstrukturen des Profilers verbunden ist und anzeigt, daß die Klasse einer Methode dynamisch ist aber bei keiner aufgezeichneten Durchführung in Unterklassen unterteilt worden ist, und
Code, der mit den Datenstrukturen des Profilers verbunden ist und anzeigt, daß die Klasse einer Methode dynamisch ist und wahrscheinlich irgend einen aus einer Vielzahl von Typen bei irgend einer speziellen Durchführung besitzt.
Code, der mit den Datenstrukturen des Profilers gekoppelt ist und anzeigt, daß die Klasse einer Methode zweifelsfrei bekannt ist,
Code, der mit den Datenstrukturen des Profilers gekoppelt ist und anzeigt, daß die Klasse einer Methode einen dynamischen Typ besitzt und eine von Null verschie dene Wahrscheinlichkeit besteht, daß sie von einem speziellen Typ ist,
Code, der mit den Datenstrukturen des Profilers verbunden ist und anzeigt, daß die Klasse einer Methode dynamisch ist aber bei keiner aufgezeichneten Durchführung in Unterklassen unterteilt worden ist, und
Code, der mit den Datenstrukturen des Profilers verbunden ist und anzeigt, daß die Klasse einer Methode dynamisch ist und wahrscheinlich irgend einen aus einer Vielzahl von Typen bei irgend einer speziellen Durchführung besitzt.
17. Computersystem nach Anspruch 16, bei den der Compiler weiterhin ein Kompilie
rungsverfahren umfaßt, das auf die Feststellung, daß die Klasse einer Methode
zweifelsfrei bekannt ist, in der Weise reagiert, daß Ursprungscode, der die Methode
darstellt, in den Ursprungscode für irgend eine aufrufende Methode durch Inlining
eingefügt wird, wenn Code für die aufrufende Methode erzeugt wird.
18. Computersystem nach Anspruch 16, bei den der Compiler weiterhin ein Kompilie
rungsverfahren umfaßt, das auf die Feststellung, daß die Klasse einer Methode ei
nen dynamischen Typ besitzt, jedoch mit einer von Null verschiedenen Wahr
scheinlichkeit einen speziellen Typ besitzt, mit der Erzeugung von Code reagiert,
der
Ursprungscode, der die Methode von der Klasse mit dem speziellen Typ, von dem
festgestellt wurde, daß er mit einer von Null verschiedenen Wahrscheinlichkeit kor
rekt ist, durch Inlining einfügt,
einen virtuellen Funktionsaufruf für einen momentanen Typ der Klasse der Methode realisiert,
testet, ob die Klasse des speziellen Typs, der mit einer von Null verschiedenen Wahrscheinlichkeit identifiziert wurde, tatsächlich korrekt ist, und auf der Basis des Testergebnisses entweder auf den durch Inlining eingefügten Ur sprungscode oder den virtuellen Funktionsaufruf-Code verzweigt.
einen virtuellen Funktionsaufruf für einen momentanen Typ der Klasse der Methode realisiert,
testet, ob die Klasse des speziellen Typs, der mit einer von Null verschiedenen Wahrscheinlichkeit identifiziert wurde, tatsächlich korrekt ist, und auf der Basis des Testergebnisses entweder auf den durch Inlining eingefügten Ur sprungscode oder den virtuellen Funktionsaufruf-Code verzweigt.
19. Computersystem nach Anspruch 16, bei dem der Compiler weiterhin folgendes
umfaßt:
ein Kompilierungsverfahren, das auf die Feststellung, daß die Klasse einer Methode vom dynamischen Typ ist aber in keiner aufgezeichneten Durchführung in Unter klassen unterteilt worden ist, mit der Erzeugung eines ersten Codefragments, das den Ursprungscode, der die Zielmethode aus der Klasse der Zielmethode darstellt, durch Inlining einfügt, und eines zweiten Codefragments reagiert, das einen virtuel len Funktionsaufruf für die Klasse der Zielmethode realisiert,
einen ersten Bereich im Code-Zwischenspeicher, der das erste Codefragment ent hält,
einen zweiten Bereich im Code-Zwischenspeicher, der das zweite Codefragment enthält,
eine Datenstruktur, die eine Adresse des ersten Bereichs und eine Adresse des zweiten Bereichs enthält,
Code, der dazu dient, festzustellen, ob die Klasse der Zielmethode in Unterklassen unterteilt worden ist,
Code zum Einflicken eines Unterbrechungspunkt-Befehls in die Adresse des ersten Bereichs im Code-Zwischenspeicher in Antwort auf die Feststellung, daß die Klasse der Zielmethode in Unterklassen unterteilt worden ist, und
eine Unterbrechungspunkt-Handhabungs-Routine, die den Code im zweiten Bereich im Code-Zwischenspeicher ausführt und zu einer Adresse am Ende des ersten Be reichs im Code-Zwischenspeicher zurückkehrt.
ein Kompilierungsverfahren, das auf die Feststellung, daß die Klasse einer Methode vom dynamischen Typ ist aber in keiner aufgezeichneten Durchführung in Unter klassen unterteilt worden ist, mit der Erzeugung eines ersten Codefragments, das den Ursprungscode, der die Zielmethode aus der Klasse der Zielmethode darstellt, durch Inlining einfügt, und eines zweiten Codefragments reagiert, das einen virtuel len Funktionsaufruf für die Klasse der Zielmethode realisiert,
einen ersten Bereich im Code-Zwischenspeicher, der das erste Codefragment ent hält,
einen zweiten Bereich im Code-Zwischenspeicher, der das zweite Codefragment enthält,
eine Datenstruktur, die eine Adresse des ersten Bereichs und eine Adresse des zweiten Bereichs enthält,
Code, der dazu dient, festzustellen, ob die Klasse der Zielmethode in Unterklassen unterteilt worden ist,
Code zum Einflicken eines Unterbrechungspunkt-Befehls in die Adresse des ersten Bereichs im Code-Zwischenspeicher in Antwort auf die Feststellung, daß die Klasse der Zielmethode in Unterklassen unterteilt worden ist, und
eine Unterbrechungspunkt-Handhabungs-Routine, die den Code im zweiten Bereich im Code-Zwischenspeicher ausführt und zu einer Adresse am Ende des ersten Be reichs im Code-Zwischenspeicher zurückkehrt.
20. Ein Computer-Datensignal, das durch eine Trägerwelle realisiert ist, die einem
Computer zugeführt wird, um Code im Computer für ein Programm zu erzeugen,
das in Form von Bytecodes dargestellt ist, wobei das Signal folgendes umfaßt:
einen ersten Codeteil, der Code umfaßt, der so konfiguriert ist, daß er den Compu ter veranlaßt, eine Gruppe von Bytecodes zu empfangen, die eine auszuführende Methode darstellen,
einen zweiten Codeteil, der Code umfaßt, der konfiguriert ist, um den Computer zu veranlassen, festzustellen, ob es wahrscheinlich ist, daß die Klasse der Zielmethode einen speziellen Typ bei jeder Durchführung der Zielmethode besitzt,
einen dritten Codeteil, der mit den zweiten Codeteil verbunden ist und Code umfaßt, der konfiguriert ist, um den Computer zu veranlassen, eine Code-Erzeugungsstra tegie auf der Basis der vom zweiten Codeteil getroffenen Feststellung auszuwählen, und
einen vierten Codeteil, der mit dem dritten Codeteil verbunden ist, um Code zu er zeugen, der die Gruppe von Bytecodes gemäß der ausgewählten Code-Erzeu gungsstrategie realisiert.
einen ersten Codeteil, der Code umfaßt, der so konfiguriert ist, daß er den Compu ter veranlaßt, eine Gruppe von Bytecodes zu empfangen, die eine auszuführende Methode darstellen,
einen zweiten Codeteil, der Code umfaßt, der konfiguriert ist, um den Computer zu veranlassen, festzustellen, ob es wahrscheinlich ist, daß die Klasse der Zielmethode einen speziellen Typ bei jeder Durchführung der Zielmethode besitzt,
einen dritten Codeteil, der mit den zweiten Codeteil verbunden ist und Code umfaßt, der konfiguriert ist, um den Computer zu veranlassen, eine Code-Erzeugungsstra tegie auf der Basis der vom zweiten Codeteil getroffenen Feststellung auszuwählen, und
einen vierten Codeteil, der mit dem dritten Codeteil verbunden ist, um Code zu er zeugen, der die Gruppe von Bytecodes gemäß der ausgewählten Code-Erzeu gungsstrategie realisiert.
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US09/108,061 US6760907B2 (en) | 1998-06-30 | 1998-06-30 | Code generation for a bytecode compiler |
Publications (1)
Publication Number | Publication Date |
---|---|
DE19928980A1 true DE19928980A1 (de) | 2000-01-13 |
Family
ID=22320067
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
DE19928980A Withdrawn DE19928980A1 (de) | 1998-06-30 | 1999-06-24 | Codeerzeugung für einen Bytecode-Compiler |
Country Status (5)
Country | Link |
---|---|
US (1) | US6760907B2 (de) |
JP (1) | JP2000040007A (de) |
CA (1) | CA2274210A1 (de) |
DE (1) | DE19928980A1 (de) |
GB (1) | GB2342473B (de) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
WO2007098724A1 (de) | 2006-02-28 | 2007-09-07 | Siemens Aktiengesellschaft | System und verfahren zur analyse eines fertigungsprozesses |
Families Citing this family (78)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6968549B1 (en) | 1999-07-02 | 2005-11-22 | Beryl Technical Assays Llc | Method and system for dynamically loading data structures into memory with global constant pool |
US7150005B2 (en) * | 1999-07-02 | 2006-12-12 | Beryl Technical Assays, Llc | Method and system for global constant management for memory |
GB9921720D0 (en) * | 1999-09-14 | 1999-11-17 | Tao Group Ltd | Loading object-oriented computer programs |
US20020112078A1 (en) * | 1999-12-03 | 2002-08-15 | David Yach | Virtual machine web browser |
US20010042138A1 (en) * | 1999-12-23 | 2001-11-15 | Reinhard Buendgen | Method and system for parallel and procedural computing |
US6865730B1 (en) * | 2000-03-08 | 2005-03-08 | International Business Machines Corporation | Interprocedural analysis and optimization of an object oriented program in the presence of dynamic class loading |
US7150011B2 (en) * | 2000-06-20 | 2006-12-12 | Interuniversitair Microelektronica Centrum (Imec) | Virtual hardware machine, methods, and devices |
US7124407B1 (en) * | 2000-08-16 | 2006-10-17 | Sun Microsystems, Inc. | Method and apparatus for caching native code in a virtual machine interpreter |
US6658656B1 (en) * | 2000-10-31 | 2003-12-02 | Hewlett-Packard Development Company, L.P. | Method and apparatus for creating alternative versions of code segments and dynamically substituting execution of the alternative code versions |
US6964039B2 (en) * | 2000-12-13 | 2005-11-08 | Esmertec Ag | Method to create optimized machine code through combined verification and translation of JAVA™ bytecode |
JP2002259135A (ja) * | 2001-02-28 | 2002-09-13 | Internatl Business Mach Corp <Ibm> | プログラムの最適化方法及びこれを用いたコンパイラ |
US7055146B1 (en) * | 2001-03-08 | 2006-05-30 | Microsoft Corporation | Method and system for dynamically inserting modifications for identified programs |
US6931627B2 (en) * | 2001-05-16 | 2005-08-16 | Sun Microsystems, Inc. | System and method for combinatorial test generation in a compatibility testing environment |
US6898785B2 (en) * | 2001-08-16 | 2005-05-24 | Hewlett-Packard Development Company, L.P. | Handling calls from relocated instrumented functions to functions that expect a return pointer value in an original address space |
EP1442361A1 (de) * | 2001-10-25 | 2004-08-04 | Koninklijke Philips Electronics N.V. | Geringe ausnahmekontrolle |
EP1313011B1 (de) * | 2001-10-31 | 2007-12-12 | Aplix Corporation | System zum Ausführen von Zwischenkode, Methode zum Ausführen von Zwischenkode, und Computerprogrammprodukt zum Ausführen von Zwischenkode |
EP1308838A3 (de) * | 2001-10-31 | 2007-12-19 | Aplix Corporation | Apparat zur Vorverarbeitung von Zwischenkode, Apparat zur Ausführung von Zwischenkode, System zur Ausführung von Zwischenkode und Computerprogrammprodukt zur Vorverarbeitung und zur Ausführung von Zwischenkode |
JP3808755B2 (ja) * | 2001-11-07 | 2006-08-16 | 富士通株式会社 | Jitコンパイラを備えた仮想計算機 |
US20030103080A1 (en) * | 2001-12-05 | 2003-06-05 | Bahman Radjabi | System and method for developing a code generator for object-oriented communication protocol |
US7103608B1 (en) * | 2002-05-10 | 2006-09-05 | Oracle International Corporation | Method and mechanism for storing and accessing data |
EP1378832A1 (de) * | 2002-07-04 | 2004-01-07 | Sap Ag | Verfahren und System zur einfachen Fehlerbeseitigung von Softwareprogrammen |
EP1378833A1 (de) * | 2002-07-04 | 2004-01-07 | Sap Ag | Dynamische Kodehaltepunkte für Computerprogramme |
US7107585B2 (en) * | 2002-07-29 | 2006-09-12 | Arm Limited | Compilation of application code in a data processing apparatus |
US7058783B2 (en) * | 2002-09-18 | 2006-06-06 | Oracle International Corporation | Method and mechanism for on-line data compression and in-place updates |
US7150012B2 (en) * | 2002-10-15 | 2006-12-12 | Nokia Corporation | Method and apparatus for accelerating program execution in platform-independent virtual machines |
US7243333B2 (en) * | 2002-10-24 | 2007-07-10 | International Business Machines Corporation | Method and apparatus for creating and executing integrated executables in a heterogeneous architecture |
US7213123B2 (en) * | 2002-10-24 | 2007-05-01 | International Business Machines Corporation | Method and apparatus for mapping debugging information when debugging integrated executables in a heterogeneous architecture |
US7200840B2 (en) * | 2002-10-24 | 2007-04-03 | International Business Machines Corporation | Method and apparatus for enabling access to global data by a plurality of codes in an integrated executable for a heterogeneous architecture |
US7222332B2 (en) * | 2002-10-24 | 2007-05-22 | International Business Machines Corporation | Method and apparatus for overlay management within an integrated executable for a heterogeneous architecture |
US7225431B2 (en) * | 2002-10-24 | 2007-05-29 | International Business Machines Corporation | Method and apparatus for setting breakpoints when debugging integrated executables in a heterogeneous architecture |
US7100154B2 (en) * | 2003-01-16 | 2006-08-29 | International Business Machines Corporation | Dynamic compiler apparatus and method that stores and uses persistent execution statistics |
CN100346297C (zh) * | 2003-02-18 | 2007-10-31 | 株式会社爱可信 | 本地编译方法、本地编译预处理方法、服务器和通信系统 |
JP4713820B2 (ja) * | 2003-05-28 | 2011-06-29 | パナソニック株式会社 | プログラム実行制御装置、プログラム実行制御方法 |
US7266813B2 (en) * | 2003-09-30 | 2007-09-04 | International Business Machines Corporation | Determining how many class-type checks to inline |
US8423471B1 (en) * | 2004-02-04 | 2013-04-16 | Radix Holdings, Llc | Protected document elements |
US20050240914A1 (en) * | 2004-04-21 | 2005-10-27 | Intel Corporation | Portable just-in-time compilation in managed runtime environments |
JP2006146613A (ja) * | 2004-11-19 | 2006-06-08 | Matsushita Electric Ind Co Ltd | プログラム変換方法 |
US7530059B2 (en) * | 2005-02-18 | 2009-05-05 | International Business Machines Corporation | Method for inlining native functions into compiled java code |
US20060200811A1 (en) * | 2005-03-07 | 2006-09-07 | Cheng Stephen M | Method of generating optimised stack code |
KR100678912B1 (ko) * | 2005-10-18 | 2007-02-05 | 삼성전자주식회사 | 메소드 바이트코드 해석 방법 및 상기 방법에 의해동작하는 시스템 |
US20070169012A1 (en) * | 2005-11-14 | 2007-07-19 | Microsoft Corporation | Asynchronous just-in-time compilation |
EP1960934B1 (de) * | 2005-12-13 | 2012-03-21 | Gemalto SA | Verfahren zur sicherung der ausführung eines vermittelnden sprachsoftwarecodes bei einer tragbaren anwendung |
WO2007076629A1 (en) * | 2005-12-30 | 2007-07-12 | Intel Corporation | Type checking for object-oriented programming languages |
US7975263B2 (en) * | 2006-01-10 | 2011-07-05 | Intel Corporation | Method and apparatus for generating run time profiles for program compilation |
WO2007104158A1 (en) | 2006-03-14 | 2007-09-20 | Transgaming Technologies Inc. | General purpose software parallel task engine |
US7793275B2 (en) * | 2006-03-31 | 2010-09-07 | Intel Corporation | Methods and apparatus to tune intermediate representations in a managed runtime environment |
US8381202B2 (en) * | 2006-06-20 | 2013-02-19 | Google Inc. | Runtime system for executing an application in a parallel-processing computer system |
US8136104B2 (en) | 2006-06-20 | 2012-03-13 | Google Inc. | Systems and methods for determining compute kernels for an application in a parallel-processing computer system |
US8024708B2 (en) | 2006-06-20 | 2011-09-20 | Google Inc. | Systems and methods for debugging an application running on a parallel-processing computer system |
US8375368B2 (en) * | 2006-06-20 | 2013-02-12 | Google Inc. | Systems and methods for profiling an application running on a parallel-processing computer system |
WO2008002173A1 (en) * | 2006-06-20 | 2008-01-03 | Intel Corporation | Method and apparatus to call native code from a managed code application |
US8136102B2 (en) | 2006-06-20 | 2012-03-13 | Google Inc. | Systems and methods for compiling an application for a parallel-processing computer system |
US8261270B2 (en) * | 2006-06-20 | 2012-09-04 | Google Inc. | Systems and methods for generating reference results using a parallel-processing computer system |
US8443348B2 (en) | 2006-06-20 | 2013-05-14 | Google Inc. | Application program interface of a parallel-processing computer system that supports multiple programming languages |
US8108844B2 (en) | 2006-06-20 | 2012-01-31 | Google Inc. | Systems and methods for dynamically choosing a processing element for a compute kernel |
US7814486B2 (en) * | 2006-06-20 | 2010-10-12 | Google Inc. | Multi-thread runtime system |
US8146066B2 (en) | 2006-06-20 | 2012-03-27 | Google Inc. | Systems and methods for caching compute kernels for an application running on a parallel-processing computer system |
US7895569B2 (en) * | 2006-08-30 | 2011-02-22 | Research In Motion Limited | System and method for implementing software breakpoints in an interpreter |
US8296742B2 (en) * | 2006-10-10 | 2012-10-23 | Microsoft Corporation | Automatic native generation |
US20090024986A1 (en) * | 2007-07-19 | 2009-01-22 | Microsoft Corporation | Runtime code modification |
US7971032B2 (en) * | 2007-11-14 | 2011-06-28 | Vns Portfolio Llc | System for native code execution |
JP2009211190A (ja) * | 2008-02-29 | 2009-09-17 | Hitachi Ltd | 情報処理装置 |
US8479178B2 (en) * | 2008-06-27 | 2013-07-02 | Microsoft Corporation | Compiler in a managed application context |
US8281296B2 (en) * | 2008-08-12 | 2012-10-02 | Oracle America, Inc. | Cross-ISA inlining in a system virtual machine |
US8438558B1 (en) | 2009-03-27 | 2013-05-07 | Google Inc. | System and method of updating programs and data |
JP5496849B2 (ja) * | 2010-10-15 | 2014-05-21 | インターナショナル・ビジネス・マシーンズ・コーポレーション | プロファイル計装方法、プログラム及びコンパイラ |
KR101171667B1 (ko) | 2010-12-16 | 2012-08-06 | 한국과학기술연구원 | 프로파일을 이용한 부분 인라이닝 최적화 방법 |
US8819649B2 (en) * | 2011-09-09 | 2014-08-26 | Microsoft Corporation | Profile guided just-in-time (JIT) compiler and byte code generation |
JP2013061810A (ja) * | 2011-09-13 | 2013-04-04 | Fujitsu Ltd | 情報処理装置、情報処理装置制御方法及び中間コード命令実行プログラム |
KR20130068630A (ko) * | 2011-12-15 | 2013-06-26 | 한국전자통신연구원 | 임베디드 디바이스의 초기화 방법 및 장치 |
US9367292B2 (en) * | 2012-06-11 | 2016-06-14 | Empire Technology Development Llc | Modulating dynamic optimizations of a computer program |
US20150186168A1 (en) * | 2013-12-30 | 2015-07-02 | Unisys Corporation | Dedicating processing resources to just-in-time compilers and instruction processors in a dynamic translator |
US10565014B2 (en) * | 2017-12-05 | 2020-02-18 | Western Digital Technologies, Inc. | Data processing offload using in-storage code execution |
US10691433B2 (en) | 2018-08-31 | 2020-06-23 | Databricks Inc. | Split front end for flexible back end cluster processing |
US11934518B2 (en) | 2019-01-09 | 2024-03-19 | Nec Corporation | Verification apparatus, multiparty computation verification system, and method and program for verifying multiparty computation executable code |
US11194612B2 (en) * | 2019-07-30 | 2021-12-07 | International Business Machines Corporation | Selective code segment compilation in virtual machine environments |
US10783082B2 (en) * | 2019-08-30 | 2020-09-22 | Alibaba Group Holding Limited | Deploying a smart contract |
CN113326046B (zh) * | 2021-05-26 | 2023-09-26 | 网易(杭州)网络有限公司 | 获取编译时长的方法和装置 |
Family Cites Families (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5748964A (en) | 1994-12-20 | 1998-05-05 | Sun Microsystems, Inc. | Bytecode program interpreter apparatus and method with pre-verification of data type restrictions |
US5835771A (en) * | 1995-06-07 | 1998-11-10 | Rogue Wave Software, Inc. | Method and apparatus for generating inline code using template metaprograms |
US5857105A (en) * | 1997-02-05 | 1999-01-05 | Hewlett-Packard Company | Compiler for reducing number of indirect calls in an executable code |
US5995754A (en) * | 1997-10-06 | 1999-11-30 | Sun Microsystems, Inc. | Method and apparatus for dynamically optimizing byte-coded programs |
US6170083B1 (en) * | 1997-11-12 | 2001-01-02 | Intel Corporation | Method for performing dynamic optimization of computer code |
US6110226A (en) * | 1998-02-19 | 2000-08-29 | Cygnus Solutions | Java development environment using optimizing ahead-of-time compiler |
EP0943990A3 (de) * | 1998-02-27 | 2004-12-22 | Texas Instruments Incorporated | Verfahren und System zum Darbieten dynamischer Optimierungsinformation in einer Kodeinterpretierlaufzeitumgebung |
US5983021A (en) * | 1998-05-27 | 1999-11-09 | Sun Microsystems | Dynamically switching statically bound function calls to dynamically bound function calls without recompilation |
-
1998
- 1998-06-30 US US09/108,061 patent/US6760907B2/en not_active Expired - Lifetime
-
1999
- 1999-06-11 CA CA002274210A patent/CA2274210A1/en not_active Abandoned
- 1999-06-22 GB GB9914411A patent/GB2342473B/en not_active Expired - Fee Related
- 1999-06-24 DE DE19928980A patent/DE19928980A1/de not_active Withdrawn
- 1999-06-30 JP JP11184857A patent/JP2000040007A/ja active Pending
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
WO2007098724A1 (de) | 2006-02-28 | 2007-09-07 | Siemens Aktiengesellschaft | System und verfahren zur analyse eines fertigungsprozesses |
US7933678B2 (en) | 2006-02-28 | 2011-04-26 | Siemens Aktiengesellschaft | System and method for analyzing a production process |
Also Published As
Publication number | Publication date |
---|---|
US6760907B2 (en) | 2004-07-06 |
GB9914411D0 (en) | 1999-08-18 |
JP2000040007A (ja) | 2000-02-08 |
GB2342473A (en) | 2000-04-12 |
US20020104076A1 (en) | 2002-08-01 |
GB2342473B (en) | 2003-08-27 |
CA2274210A1 (en) | 1999-12-30 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
DE19928980A1 (de) | Codeerzeugung für einen Bytecode-Compiler | |
DE69924857T2 (de) | Programm-kode-umwandlung | |
DE60208710T2 (de) | Plattformunabhängige im-voraus-kompilierung | |
DE69909945T2 (de) | Verfahren und Anordnung zur Korrelation von Profildaten dynamisch erzeugt durch ein optimiertes ausführbares Programm mit Quellcodeanweisungen | |
DE69926602T2 (de) | Hybrider Rechtzeitkompiler der minimale Betriebsmittel verwendet | |
DE69938218T2 (de) | Vorrichtung und Verfahren zum Laden eines Java Anwendungsprogramms | |
DE60035745T2 (de) | Verfahren zum bei Bedarf Laden und Ausführen einer Netzwerkanwendung | |
DE69727381T2 (de) | Verfahren zum transportieren von in einer schnittstellendefinitionssprache definierten datenstrukturen zwischen heterogenen systemen | |
DE60001916T2 (de) | Plattformunabhängige speicherabbild analysearchitektur zur programmfehlerbeseitigung | |
DE69730276T2 (de) | Vorrichtung und Verfahren zur Erleichterung der Vermeidung von exzeptionellen bestimmten Zuständen während des Ablaufs eines Programmes | |
DE69922015T2 (de) | Verfahren und vorrichtung zum übersetzen und ausführen von arteigenem code in einer umgebung mit virtuellen maschinen | |
DE69727933T2 (de) | Verfahren und gerät zum beschreiben einer definierten schnittstelle, einer operation und eines datentyps in einer schnittstellendefinitionssprache | |
DE69733739T2 (de) | Rechnersystem und Verfahren zum Testen eines Netzwerkmanagement-Agenten (TMN-Agenten) | |
DE69628965T2 (de) | Verfahren und Gerät zum Verwalten von Beziehungen zwischen Objekten in einer verteilten Objektumgebung | |
DE19945992B4 (de) | Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren | |
EP0604431B1 (de) | Verfahren zur adaption einer objektorientierten applikation | |
EP0502857B1 (de) | Verfahren zur dynamischen bindung von definierbaren programmelementen eines interaktiven datenverarbeitungssystems | |
DE69919384T2 (de) | Verfahren und vorrichtung zur automatischen optimierung der ausführung eines rechnerprogramms | |
US4949255A (en) | Message interface and method for recursive calling between interpretive and compiled computer processes | |
DE60006410T2 (de) | Verfahren und system zum verteilen von objektorientierten rechnerprogrammen | |
DE60313652T2 (de) | Verfahren und gerät zur kontrolle der umwandlung von programm-kodes | |
EP0989488A2 (de) | Verfahren und Gerät zur Auflösung von Datenreferenzen in erzeugtem Kode | |
DE60002327T2 (de) | Ableitung von operandtypen innerhalb einer zwischensprache | |
DE69905776T2 (de) | Sprachenverarbeitungsverfahren mit geringem Aufwand und Speicherbedarf bei der Profildatensammlung | |
EP1034475A1 (de) | Verfahren zum testen von systemkomponenten eines objektorientierten programms |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
8110 | Request for examination paragraph 44 | ||
8139 | Disposal/non-payment of the annual fee |