DE19959758A1 - Bestimmung der Art und der Genauigkeit von lokalen Variablen bei vorhandenen Subroutinen - Google Patents

Bestimmung der Art und der Genauigkeit von lokalen Variablen bei vorhandenen Subroutinen

Info

Publication number
DE19959758A1
DE19959758A1 DE19959758A DE19959758A DE19959758A1 DE 19959758 A1 DE19959758 A1 DE 19959758A1 DE 19959758 A DE19959758 A DE 19959758A DE 19959758 A DE19959758 A DE 19959758A DE 19959758 A1 DE19959758 A1 DE 19959758A1
Authority
DE
Germany
Prior art keywords
subroutine
delta
local variables
map
types
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.)
Ceased
Application number
DE19959758A
Other languages
English (en)
Inventor
Anthony Cocchi
Janice Cynthia Shepherd
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
International Business Machines Corp
Original Assignee
International Business Machines Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by International Business Machines Corp filed Critical International Business Machines Corp
Publication of DE19959758A1 publication Critical patent/DE19959758A1/de
Ceased legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • G06F11/3636Software debugging by tracing the execution of the program
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/436Semantic checking
    • G06F8/437Type checking
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y10TECHNICAL SUBJECTS COVERED BY FORMER USPC
    • Y10STECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y10S707/00Data processing: database and file management or data structures
    • Y10S707/99951File or database maintenance
    • Y10S707/99952Coherency, e.g. same view to multiple users
    • Y10S707/99953Recoverability
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y10TECHNICAL SUBJECTS COVERED BY FORMER USPC
    • Y10STECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y10S707/00Data processing: database and file management or data structures
    • Y10S707/99951File or database maintenance
    • Y10S707/99956File allocation

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computational Linguistics (AREA)
  • Software Systems (AREA)
  • Computer Hardware Design (AREA)
  • Quality & Reliability (AREA)
  • Debugging And Monitoring (AREA)
  • Devices For Executing Special Programs (AREA)

Abstract

Ein Verfahren wird bereitgestellt, um die Art wenigstens einer lokalen Variablen nach Aufrufen einer Subroutine zu verfolgen. Das Verfahren verbindet jeden aus einer Vielzahl von Sprungbefehlen, die die Subroutine aufrufen, mit einer ersten Information, die die Art des Werts angibt, der in der lokalen Variablen gespeichert ist. Das Verfahren verbindet wenigstens einen Interessenpunkt der Ausführung innerhalb der Subroutine mit einer zweiten Information und einer Rücksprungadresse für die Subroutine. Wenn eine Abfrage empfangen wird, erhält das Verfahren mittels des Interessenpunkts der Ausführung eine zweite Abbildung von der zweiten Information. Die erste Abbildung gibt die Art des Werts an, der in der lokalen Variablen gespeichert wird, wenn einer der Sprungbefehle ausgeführt wird. Anhand der ersten und zweiten Abbildung mischt das exemplarische Verfahren die erste Abbildung mit der zweiten Abbildung, um eine aktuelle Art für die lokale Variable anzugeben.

Description

Die vorliegende Erfindung bezieht sich im allgemeinen auf die Verfolgung von Variablen und insbesondere auf die Verfolgung von lokalen Variablen beim Aufruf von Subroutinen. Im folgenden sind ein Verfahren und eine Vorrichtung zur Verfolgung von lokalen Variablenarten im Anschluß an den Aufruf einer Subroutine beschrieben.
In den meisten Sprachimplementierungen wird ein Stapel be­ nutzt, um Verfahrensaufrufe und -Rücksprünge von Verfahren zu verfolgen und die Werte von lokalen Variablen und Zwischenergebnissen zu speichern. Für Sprachen, die mehrere Threads unterstützen, wird für jeden Thread, die erstellt wurde, ein Stapel erzeugt. Die Stapel werden in Datenübertragungsblöcke aufgeteilt, wobei jeder Datenübertragungsblock beim Aufruf eines Verfahrens in den Stapel eingespeichert und bei Rücksprung des Verfahrens aus dem Stapel ausgespeichert wird. Jeder Datenübertragungsblock, mit Ausnahme des aktuellen Datenübertragungsblocks, enthält die Speicherstelle des nächsten Befehls, der auszuführen ist, wenn die normale Steuerung zu diesem Datenübertragungsblock zurückkehrt. Was den aktuellen Datenübertragungsblock angeht (der Datenübertragungsblock für das Verfahren, das gerade ausgeführt wird), so wird die Speicherstelle des aktuellen, in Ausführung befindlichen Befehls im Datenübertragungsblock oder in einer maschinenabhängigen Speicherstelle (beispielsweise ein Maschinenregister) gehalten. Jeder Datenübertragungsblock zeigt somit den Befehl auf, der gerade von dem Verfahren, das von dem Datenübertragungsblock dargestellt wird, ausgeführt wird (nachstehend Ausführungspunkt genannt). Lokale Variablen eines Verfahrens werden innerhalb des Datenübertragungsblocks, der bei Ausführung des Verfahrens erstellt wurde, verschiedenen Plätzen zugeordnet. Eine ausführlichere Beschreibung der StapelDatenübertragungsblock, wie diese in einer Java™ Virtual Machine benutzt werden, ist in der "The Java™ Virtual Machine Specification", Lindholm, Yellin, Section 3.6, 1996, beschrieben, auf deren kompletten Umfang hier Bezug genommen wird.
Die Java™ Virtual Machine (JVM) unterscheidet sich von anderen Ausführungsmodellen dadurch, dass eine lokale Variable, während bestimmter Ausführungsteile eines Verfahrens Werte verschiedener Arten speichern kann. Eine lokale Variable kann beispielweise, während ein Teil eines Verfahrens ausgeführt wird, einen Ganzzahlwert (int.) beinhalten. In einem anderen Teil der Ausführung desselben Verfahrens kann jedoch dieselbe lokale Variable eine Referenz (Zeiger) zu einem, einer Registergruppe zugewiesenen Objekt beinhalten.
Während der Ausführung eines Programms kann es vorteilhaft sein, die Arten von Werten, die in jeder der lokalen Variablen gespeichert sind, zu verfolgen und genau zu bestimmen. Zwei beispielhafte Anwendungen für diese Art der Verfolgung sind die dynamische Speicherreklamation (Speicherbereinigung (garbage collection)) und das Debugging. Für die dynamische Speicherreklamation ist es wünschenswert, genau festzulegen, welche lokalen Variablen Referenzen zu Objekten enthalten, die einer Registergruppe zugewiesen wurden.
Beim Debugging ist es wünschenswert, genau die Arten der Werte zu identifizieren, die in lokalen Variablen gespeichert sind, wenn die in den lokalen Variablen gespeicherten Werte dem Benutzer angezeigt werden. Anhand der Art von Daten, die in einer gegebenen lokalen Variablen gespeichert sind, kann der Debugger diese Daten dem Benutzer dann korrekt anzeigen. Anhand eines Werts, der in einer lokalen Variablen gespeichert ist und ohne die Art des Werts zu kennen, der in der Variablen gespeichert ist, wird der Debugger insbesondere nicht wissen, ob dieser Wert ein Zeiger auf den Wert oder der eigentliche Wert selbst ist. Selbst wenn der Wert als Nichtzeiger oder einfacher Wert bekannt ist, muß der Debugger außerdem die spezifische Datenart kennen, um den Wert dem Benutzer korrekt anzeigen zu können. So werden beispielsweise Ganzzahlendaten, Gleitkommadaten und Zeichendaten mittels unterschiedlichen internen Darstellungen gespeichert. Anhand des Werts allein, der im internen Format dargestellt ist, muß der Debugger die Art des Werts kennen, um diesen Wert übersetzen und dem Benutzer korrekt anzeigen zu können. Die Anzeige der in den lokalen Variablen gespeicherten Werte und Arten ermöglicht es dem Benutzer, seine/ihre Debugging-Strategie dementsprechend zu definieren. Im Zusammenhang mit dieser Anwendung bezieht sich der Begriff "Grundelement" auf eine Nichtzeiger-Datenart einschließlich aber nicht begrenzt auf Zeichen, Ganzzahl, lang, kurz, Gleitkommazahl und Bit oder Flag.
Die Java™ Virtual Machine Specification, auf die oben Bezug genommen wurde, nennt die Regeln, denen der Bytecode einer Datei der Java™ Klasse entsprechen muß, um als gültig berücksichtigt zu werden. Ein Lochprüfer kann vor Ausführung benutzt werden, um sicherzustellen, dass eine Datei der Java™ Klasse diesen Regeln entspricht. Eine Java™ Regel besagt, dass an irgendeinem gegebenen Punkt innerhalb eines Verfahrens, ungeachtet des Codepfades, der zu diesem Punkt führt, auf eine lokale Variable nur zugegriffen werden kann, wenn bekannt ist, dass sie einen Wert von der Art enthält, der von der Entität erwartet wird, die auf die lokale Variable zugreift. Wenn beispielsweise an einem Punkt in einem Verfahren auf eine lokale Variable als Referenz zugegriffen wird, dann müssen alle Codepfade zu diesem Punkt dieser Variablen eine Referenz oder eine Null zuweisen. Ebenso müssen, wenn auf eine lokale Variable als Gleitkommazahl zugegriffen wird, alle Codepfade, die zu diesem Zugriff führen, dieser lokalen Variablen eine Gleitkommazahl zuweisen. Diese Regel bedeutet, dass für viele Dateien der Java™ Klasse eine einfache statische Analyse des Bytecodes für jedes Java™ Verfahren den Artenstatus für alle lokalen Variablen in allen Speicherstellen, die innerhalb des Verfahrens von Interesse sind, identifizieren wird. Die Analyse wird als "statisch" bezeichnet, da sie nicht den spezifischen Steuerflußpfad berücksichtigt, der von dem Verfahren während der Ausführung genommen wird.
Eine statische Analyse des Bytecodes kann möglicherweise nicht funktionieren, wenn der Bytecode JSR-(jump subroutine) Befehle enthält. Die JSR-Befehle, die von Java™ unterstützt werden, sind anders als Aufrufbefehle von Subroutinen, die von anderen Sprachen unterstützt werden, da der JSR-Befehl keinen neuen Datenübertragungsblock im Stapel plaziert. Dadurch erzeugt der JSR-Befehl keine neuen "Kopien" von lokalen Variablen. Statt dessen greift die Subroutine, die durch den JSR-Befehl angesteuert wird (nachstehend "Ziel- Subroutine" oder "JSR-Subroutine" genannt) auf dieselben lokalen Variablen in den gleichen Speicherstellen wie das aufrufende Programm zu. Die JSR-Subroutine kann außerdem neue Werte in der lokalen Variablen speichern oder die Art des Werts ändern, der in der lokalen Variablen gespeichert ist. Je nachdem, von welchem JSR-Befehl die JSR-Subroutine aufgerufen wurde, könnte demgemäß eine gegebene lokale Variable Daten unterschiedlicher Arten speichern. Andere Sprachen und das Java™ Verfahren zum Aufrufen erstellen einen neuen Satz lokaler Variablen in einem neuen Stapeldatenübertragungsblock. Daher ist in diesen anderen Sprachen die Artenbestimmung eine einfache Art und Weise, die Kopie der lokalen Variablen, wie sie im Speicher vorhanden sind, zu analysieren.
In einer JSR-Subroutine kann die Artenbestimmung von dem Ausführungsfluß durch das Verfahren abhängig sein. Ein JSR- Befehl wird benutzt, um zu einer Subroutine (eine Codesektion innerhalb des Verfahrens) zu springen. Bei Ausführung eines JSR-Befehls wird die Befehlsadresse, die direkt im Anschluss an den JSR-Befehl erscheint, oben auf dem Stapel plaziert. Dies ist die Rücksprungstelle für die JSR-Subroutine. Während der Ausführung der JSR-Subroutine wird die Rücksprungstelle in einer lokalen Variablen gespeichert. Die Ausführung der Subroutine endet mit der Ausführung eines "ret" Befehls, der die lokale Variable mit der Rücksprungstelle nennt. Eine JSR-Subroutine kann auch abrupt beendet werden, wie dies unten beschrieben ist.
Mehrere verschiedene Punkte im Bytecode können JSR-Befehle enthalten, die die gleiche Ziel-JSR-Subroutine nennen. Nach Ausführung der Subroutine fährt die Ausführung mit dem Befehl fort, der sich an den JSR-Befehl anschließt, der in die Subroutine - wie in der lokalen Variablen gespeichert - gesprungen ist. Lokale Variablen des Verfahrens sind in der JSR-Subroutine definierbar und zugänglich und unterliegen denselben Regeln bei der Benutzung von lokalen Variablen wie der Rest des Verfahrens.
Die JVM Regeln ermöglichen es einer lokalen Variablen, Werte von unterschiedlichen Arten zu behalten, wenn verschiedene JSR-Befehle ausgeführt werden, die zur selben JSR-Subroutine führen. Nach dieser Regel kann auf die lokale Variable innerhalb der JSR-Subroutine nicht zugegriffen werden, aber ihre Existenz kommt zur Komplexität hinzu, die Arten der Werte genau zu bestimmen, die in den lokalen Variablen für Ausführungspunkte innerhalb der JSR-Subroutine gespeichert sind. Eine einfache statische Analyse berücksichtigt nicht oder bestimmt nicht, welcher JSR-Befehl ausgeführt wurde, um zur JSR-Subroutine zu springen und verfolgt daher nicht die Art des Werts, der aktuell in den lokalen Variablen gespeichert ist, bevor zur JSR-Subroutine gesprungen wird.
Es ist zu bemerken, dass eine JSR-Subroutine auch abrupt beendet werden kann, wenn während ihrer Ausführung eine Ausnahme auftritt. In dem Fall wird die Ausführungssteuerung an eine geeignete Ausnahmebehandlungsroutine übertragen, beispielsweise an einen Java™ "catch" Block. Dieser abrupte Abschluß wird nur der Vollständigkeit halber erwähnt. Die Erfindung betrifft die Bestimmung von Wertarten, die während der Ausführung der JSR-Subroutine in den lokalen Variablen gespeichert werden. Ob die Subroutine normal oder abrupt beendet wird, ist für die Erfindung nicht relevant.
Eine JSR-Subroutine kann ihrerseits einen JSR-Befehl enthal­ ten, der zu einer anderen JSR-Subroutine springt. Diese Ver­ schachtelung von JSR-Befehlen innerhalb von JSR-Subroutinen bedeutet, dass für einen gegebenen Ausführungspunkt innerhalb einer JSR-Subroutine die Wertarten, die von den lokalen Variablen gespeichert werden, davon abhängig sein können, welcher Satz von JSR-Befehlen ausgeführt wurden, um diesen Punkt zu erreichen. Es ist weder eine direkte noch indirekte Rekursion zulässig.
Eine Lösung, um die Arten von lokalen Variablen an den ver­ schiedenen Ausführungspunkten innerhalb der JSR-Subroutinen zu bestimmen, bestehen darin, den Bytecode vor Ausführung neu zu schreiben, um zu verhindern, dass eine gegebene lokale Variable verschiedene Wertarten speichert, wenn verschiedene JSR-Befehle, die zur selben JSR-Subroutine verzweigen, ausgeführt werden. Das Neuschreiben des Bytecodes kann das Duplizieren der JSR-Subroutinen beinhalten, so dass es eine Version der JSR-Subroutine für jede Wertart gibt, die in einer gegebenen lokalen Variablen zum Zeitpunkt der verschiedenen JSR-Befehle gespeichert ist. Ein Nachteil bei dieser Lösung ist, dass sie die Größe des Bytecodes erhöht. Desweiteren kann, wenn die JSR-Befehle verschachtelt werden, die Anzahl der Kopien der einzelnen JSR-Subroutinen exponentiell anwachsen, was den Bytecode ebenfalls anschwellen läßt.
Eine weitere Lösung zum Neuschreiben des Bytecodes enthält die Aufteilung einer lokalen Variablen in mehrere lokale Variablen, wenn diese dazu bestimmt wurde, verschiedene Arten zu dem Zeitpunkt zu speichern, wenn die verschiedenen JSR-Befehle dieselbe JSR-Subroutine aufrufen. Während der Speicherbereinigung können lokale Variablen, die Werte von irgendeiner Nichtreferenzart speichern, als eine Art gruppiert werden, wodurch die lokale Variable nur in zweierlei Weise geteilt werden kann. Diese Gruppierung zur Speicherbereinigung reduziert zwar die Teilung der lokalen Variablen, hebt sie jedoch nicht auf. Während des Debugging ist jedoch die Referenz-/Nichtreferenz-Dichotomie nicht verfügbar, und die lokale Variable muß einmal für jede unterschiedliche Wertart geteilt werden, die sie vor einem gegebenen Interessenpunkt gespeichert haben kann. Agesen et al. schlugen diese Teilungslösung 1998 vor.
Die Lösung der Variablenteilung enthält die Einführung von neuen lokalen Variablen in den Bytecode. Im Java™ Bytecode werden die lokalen Variablen mit Nummern bezeichnet. Die lokale Variable 1 ist eine separate lokale Variable der lokalen Variablen 5. Der Bytecode wird platzsparend angepaßt, so dass Referenzen auf lokale Variablen mit sehr niedrigen Nummern weniger Platz brauchen als Referenzen auf lokale Variablen, die durch größere Nummern dargestellt sind. Die Lösung der Variablenteilung bedeutet, dass die Bytecodes, die sich u. U. auf die lokale Variable X bezogen haben, sich jetzt auf die lokale Variable Y beziehen müssen. Dementsprechend kann durch die Variablenteilung die Größe des resultierenden Bytecodes zunehmen.
Somit kann durch beide Lösungen des Neuschreibens die Größe des resultierenden Bytecodes zunehmen. Da die JVM eine Ober­ grenze bei der Größe des Bytecodes für ein Verfahren verlangt, können bei einigen großen Verfahren beide Lösungen des Neuschreibens versagen. Da die JVM ebenfalls eine Obergrenze bei der Anzahl von eindeutigen lokalen Variablen verlangt, die von einem Verfahren definiert werden, hat die Lösung der Variablenteilung einen weiteren Nachteil.
In einem Computerprogramm, dessen Subroutine nach einem Sub­ routinenaufruf ausgeführt wird, werden die Arten der lokalen Variablen verfolgt. Eine Basisabbildung, die die Arten der lokalen Variablen angibt, wird für den Subroutinenaufruf außerhalb der Subroutine erzeugt. Für einen interessierenden Punkt innerhalb der Subroutine, wird eine Deltaabbildung erzeugt, die Änderungen in irgendeiner der lokalen Variablen angibt. Ein Ausführungspfad zum Ausführungspunkt wird bestimmt, um die Basisabbildung als dem Subroutinenaufruf entsprechend zu identifizieren. Die Basisabbildung wird mit der aktuellen Deltaabbildung zusammengeführt, die von der Deltaabbildung gemäß dem Ausführungspfad erhalten wird, um Arten der lokalen Variablen zu bestimmen.
Fig. 1 zeigt ein Blockdiagramm mit beispielhaften Datenstrukturen für Referenzabbildungen;
Fig. 2 (a) und Fig. 2 (b) zeigen Blockdiagramme, die die Abbildungsarten darstellen;
Fig. 3 zeigt ein Flußdiagramm eines beispielhaften Ausfüh­ rungsbeispiels der Erfindung, das einen Überblick von einer Stack-Walking-Prozedur bei der Speicherbe­ reinigung gibt
Fig. 4 zeigt ein Flussdiagramm von der Verarbeitung, die in den Datenübertragungsblock durchgeführt wird, die den JSR-Subroutinen entsprechend bestimmt wurden;
Fig. 5 zeigt ein Flußdiagramm von der Verarbeitung, die durchgeführt wurde, um Abbildungen für die JSR- Subroutinen zu erzeugen;
Fig. 6(a)-Fig. 6(c) zeigen beispielhafte Abbildungen, die zur Illustration der Zusammenführungsoperation nützlich sind.
Die Erfindung stellt ein Verfahren bereit, um die Art wenigstens einer lokalen Variablen nach Aufrufen einer Subroutine zu verfolgen. Die Erfindung wird insbesondere im Zusammenhang mit Programmiersprachen benutzt, die es lokalen Variablen ermöglichen, verschiedene Wertarten während der Programmausführung an unterschiedlichen Stellen zu speichern, und die keinen neuen Stapeldatenübertragungsblock beim Aufrufen einer Subroutine erstellen. Dementsprechend kann die aufgerufene Subroutine auf dieselbe Kopie der lokalen Variablen zugreifen und diese ändern wie es die aufrufende Subroutine kann. Diese beiden Eigenschaften verkomplizieren das Problem der Verfolgung von lokalen Variablenarten. Java™ ist eine beispielhafte Sprache, die diese beiden Eigenschaften hat, aber die Erfindung wird ebenfalls auf andere Sprachen mit diesen beiden Eigenschaften angewendet.
In einem beispielhaften Ausführungsbeispiel stellt die Erfindung ein Verfahren bereit, um eine Art von wenigstens einer lokalen Variablen an einem gegebenen Punkt innerhalb einer Subroutine mit einem beispielhaften Verfahren zu verfolgen, das die folgenden Schritte enthält. Das Verfahren erzeugt zuerst Informationen, die eine Adresse von einem Verzweigungsbefehl darstellen, der die Subroutine, die eine Art der lokalen Variablen im Verzweigungsbefehl darstellt, aufruft und Änderungen in der Art der lokalen Variablen darstellt, die innerhalb der Subroutine nach dem Sprungbefehl und bis zu dem gegebenen Punkt gemacht wurden. Das Verfahren identifiziert dann die Art der lokalen Variablen an dem gegebenen Punkt innerhalb der Subroutine, aufgrund der Information, die in dem ersten Schritt des Verfahrens erzeugt wurde.
Bei der weiteren Verarbeitung verbindet das beispielhafte Verfahren jeden aus einer Vielzahl von Verzweigungsbefehlen, die die Subroutine aufrufen, mit einer ersten Information. Die erste Information ist eine Datenstruktur, die die Art des Werts angibt, der in der lokalen Variablen gespeichert ist, wenn jeder aus der Vielzahl von Verzweigungsbefehlen ausgeführt wird. Aus praktischen Gründen ist die erste Information eine lokale Variablenabbildung, die die Arten von jeder lokalen Variablen definiert, wenn die Subroutine aufgerufen wird.
Das beispielhafte Verfahren verbindet mindestens einen Ausführungspunkt innerhalb der Subroutine mit einer zweiten Information. Der Interessenpunkt der Ausführung ist irgendein Punkt innerhalb der Subroutine, an dem es erforderlich sein kann, die Art von jeder lokalen Variablen zu ermitteln. Die zweite Information ist eine Datenstruktur, die irgendwelche Änderungen (sofern erfolgt) in der Art angibt, die an der lokalen Variablen nach Eintritt in die Subroutine und vor dem Ausführungspunkt durchgeführt wurden. Aus praktischen Gründen ist die zweite Information eine Deltaabbildung, die irgendwelche Änderungen angibt, die an den lokalen Variablen nach dem Verzweigen zu der Subroutine und vor dem Ausführungspunkt durchgeführt wurden.
Das beispielhafte Verfahren verbindet den Ausführungspunkt mit einer Rücksprungadresse für die Subroutine. Diese Rücksprungadresse ermöglicht es dem Verfahren, den Punkt in dem aufrufenden Programm zu identifizieren, von dem aus die aktuelle Subroutine aufgerufen wurde. Mittels dieser Rück­ sprungadresse geht das Verfahren über die Kette der Subrou­ tinenaufrufe zurück, wobei sie jeden aufrufenden Punkt identifiziert, und die Änderungen verfolgt, die an den lokalen Variablen bis zu jedem aufrufenden Punkt durchgeführt wurden.
Wenn eine Abfrage empfangen wird, um die Art der lokalen Variablen an dem Ausführungspunkt in der Subroutine zu identifizieren, erhält das beispielhafte Verfahren mittels des Ausführungspunkt eine zweite Abbildung von der zweiten Information. Die zweite Abbildung gibt die Änderung in der Art der lokalen Variablen an, die innerhalb der Subroutine durchgeführt wurde. Das beispielhafte Verfahren erhält auch die Rücksprungadresse, die zu dem Ausführungspunkt gehört und erhält mittels der Rücksprungadresse eine erste Abbildung von der ersten Information. Die erste Abbildung gibt die Art des Werts an, der in der lokalen Variablen gespeichert wird, wenn einer der Verzweigungsbefehle ausgeführt wird, um die Subroutine aufzurufen.
In dem Fall, wo die Subroutinenaufrufe "verschachtelt" werden (eine Subroutine ruft eine andere Subroutine auf), wird die zweite Abbildung, die der "aufgerufenen" Subroutine entspricht, mit der zweiten Abbildung verbunden oder kombiniert. Dieser Verbindungs- oder Kombinationsschritt wird für jede Ebene der Verschachtelung in der Subroutinenaufrufkette wiederholt, d. h. für jede Subroutine, die eine andere Subroutine aufruft. Dieser Schritt wird wiederholt, bis ein Aufrufpunkt erreicht ist, der nicht innerhalb einer Subroutine liegt.
Anhand der ersten und kombinierten zweiten Abbildungen wird die erste Abbildung mit der zweiten Abbildung verbunden, um eine aktuelle Art für die lokale Variable anzugeben. Bei Durchführung dieser Verbindung kombiniert das beispielhafte Verfahren die Art des Status der lokalen Variablen, wie diese von den Subroutinen geändert wurde, mit der Art des Status der lokalen Variablen, wie diese vor dem Aufruf der Subroutinen existierte.
Der Vorteil der beispielhaften Verfahren gegenüber den Alternativlösungen, die als Hintergrund der Erfindung beschrieben wurden, und zu denen das Neuschreiben des Bytecodes gehört, ist, dass die beispielhaften Verfahren für alle gültigen Bytecodes benutzt werden können. Anders als bei den Lösungen des Neuschreibens, die versagen können, falls das Neuschreiben zu viele neue lokale Variablen oder zu viele neue Bytecodebefehle erstellt, verletzen die beispielhaften Verfahren keine der festen Grenzen, die für eine JVM definiert wurden. Die Erstellung der Extra- Deltaabbildungen erfordert nur wenig zusätzliche Zeit zusätzlichen Platz gegenüber der Erstellung von lokalen Variablenabbildungen für Ausführungspunkte, die nicht innerhalb von JSR-Subroutinen liegen. Demgemäß erlaubt das beispielhafte Verfahren die genaue Verfolgung der lokalen Variablenarten, ohne irgendwelche JVM Regeln zu brechen und ohne die Größe des Bytecodes oder die Anzahl von lokalen Variablen zu erhöhen.
Ein beispielhaftes Verfahren der Erfindung stellt einen Prozeß bereit, durch den die Arten von lokalen Variablen während der Stapelanalyse bestimmt werden können. Das Verfahren benutzt eine "JSR-Subroutinen"-Aufrufkette, eine lokale Variablenbasisabbildung, die zum Zeitpunkt eines JSR- Anfangsbefehls definiert wurde und eine weitere Abbildung einer lokalen Variablen, nachstehend "Deltaabbildung" genannt, die Änderungen widerspiegelt, die an lokalen Variablen nach dem Sprung zur JSR-Subroutine durchgeführt wurden.
Die "JSR-Subroutinen" Aufrufkette ist die Folge von JSR- Subroutinenaufrufen, die innerhalb eines Verfahrens zum Erreichen des aktuellen Ausführungspunkts in diesem Verfahren ausgeführt wurden. Die statische Datenflußanalyse des Bytecodes erkennt die Ausführungspunkte innerhalb eines Verfahrens, die innerhalb einer JSR-Subroutine liegen. Wie bereits vorher erörtert, plaziert die Ausführung eines JSR- Befehls eine Rücksprungadresse (die Adresse des Befehls, der auf die Adresse des JSR-Befehls folgt) in einen Operandenstapel. Nach dem Sprung zur JSR-Subroutine und während der Ausführung der JSR-Subroutine wird diese Rücksprungadresse in einer lokalen Variablen gespeichert. Mittels der statischen Datenflußanalyse kann die Position der Rücksprungsadresse (ihre Position in dem Operandenstapel oder in einer lokalen Variablen) für jeden Ausführungspunkt in einer JSR-Subroutine bestimmt werden.
Die lokale Variablenbasisabbildung ist eine Struktur, die für jede lokale Variable, die Art des Werts, falls vorhanden, identifiziert, die in der lokalen Variablen gespeichert ist. Bei der Speicherbereinigung muß die lokale Variablenabbildung nur angeben, ob der gespeicherte Wert eine Referenz- oder Nichtreferenzart ist, d. h. ob der Wert ein Zeiger zum Heap ist oder nicht. Für andere Zwecke, beispielsweise für das Debugging, sollte die lokale Variablenabbildung mehr spezifische Arteninformationen speichern, einschließlich aber nicht beschränkt auf lange Festkommazahlen, Gleitkommazahlen, Ganzzahlen usw.. Mittels der statischen Datenflußanalyse des Bytecodes können die lokalen Variablenabbildungen für alle Ausführungspunkte definiert werden, die außerhalb von JSR-Subroutinen liegen.
Die Deltaabbildung ist eine Struktur, die, für jede lokale Variable, die Art der Werte, sofern vorhanden, kennzeichnet, die als letzte der lokalen Variablen seit Eingabe der JSR- Subroutine zugeordnet wurden. Mittels der einfachen statischen Datenflußanalyse des Bytecodes kann die Deltaabbildung für die Ausführungspunkte innerhalb einer JSR-Subroutine bestimmt werden. Es ist zu beachten, dass die lokale Variablenbasisabbildung die Art des Status jeder lokalen Variablen an einem Punkt vor dem Einstieg in die JSR-Subroutine speichert, während die Deltaabbildung irgendwelche Änderungen verfolgt, die an der Art des Status von der lokalen Variablen nach Eingabe der JSR-Subroutine durchgeführt wurden.
Das beispielhafte Verfahren der Erfindung benutzt zwei zusätzliche logische Strukturen: einen "Abbildungs- Positionsanzeiger" (map locator) und einen "Rücksprungadreß- Positionsanzeiger" (return address locator). Der Abbildungs- Positionsanzeiger verbindet einen Ausführungspunkt mit seiner passenden Abbildung (lokale Variablenbasisabbildung oder Deltaabbildung). Der Rücksprungadress-Positionsanzeiger wird benutzt, um jeden Ausführungspunkt innerhalb einer JSR- Subroutine mit der Speicherstelle seiner entsprechenden Rücksprungadresse zu verbinden. Ein Ausführungspunkt ist ein Punkt innerhalb einer Subroutine, an den es notwendig sein kann, die Art von einer oder mehreren lokalen Variablen zu bestimmen. Ein Ausführungspunkt kann einem potentiellen Speicherbereinigungsort entsprechen.
Die Schritte eines beispielhaften Verfahrens sind:
  • 1. Für jeden JSR-Befehl, der nicht innerhalb einer JSR- Subroutine liegt, ist die lokale Variablenbasisabbildung im JSR-Befehl mittels der einfachen statischen Datenflußanalyse zu definieren (siehe zum Beispiel Compilers, Principles, Techniques, and Tools - Aho, Sethi, Ulman 1986). Für jeden JSR- Befehl ist im Abbildungs-Positionsanzeiger, der den JSR-Befehl mit seiner lokalen Variablenbasisabbildung verbindet, ein Eintrag vorzunehmen.
  • 2. Für jeden Ausführungspunkt innerhalb einer JSR- Subroutine sind die Änderungen, sofern erfolgt, zu identifizieren, die an der Art des Werts, der in jeder der lokalen Variablen gespeichert ist, nachdem der Eintritt in die JSR-Subroutine vorgenommen wurde und den gegebenen Ausführungspunkt enthält. Für jeden Ausführungspunkt ist jede dieser Änderungen an den lokalen Variablen in einer Deltaabbildung für diesen - Ausführungspunkt zu speichern. Für jeden Ausführungspunkt ist in dem Abbildungs-Posi­ tionsanzeiger, der den Ausführungspunkt mit seiner entsprechenden Deltaabbildung verbindet, eine Eingabe zu machen.
    Wenn eine Deltaabbildung für den Eintrittspunkt in die JSR-Subroutine erstellt würde (der Punkt, bevor der erste Befehl der JSR-Subroutine ausgeführt wird), würde diese Deltaabbildung angeben, dass keine lokalen Variablen geändert wurden. Zwei unterschiedliche Ausführungspunkte innerhalb einer JSR-Subroutine werden unterschiedliche Deltaabbildungen haben, wenn irgendeine der lokalen Variablen zwischen zwei Ausführungspunkten einer anderen Art zugeordnet wird.
  • 3. Für jeden Ausführungspunkt innerhalb einer JSR- Subroutine ist die Position des Wertes der Rücksprungadresse zu bestimmen. Wenn der JSR-Befehl ausgeführt wird, wird die Rücksprungadresse auf den Operandenstapel gesetzt und während der JSR-Subroutine wird die Rücksprungadresse in einer lokalen Variablen gespeichert. Für jeden Ausführungspunkt ist in dem Rücksprungadress-Positionsanzeiger, der die Rücksprung­ adresse angibt, die diesem Ausführungspunkt entspricht, eine Eingabe zu machen. Es ist zu beachten, dass die Schritte 1-3, die hier beschrieben werden, während der Speicherbereinigung oder während eines Vorverar­ beitungsschritts vor der Speicherbereinigung ausgeführt werden können.
  • 4. Während der Ausführung der Speicherbereinigung ist zu bestimmen, ob der Stapeldatenübertragungsblock zeigt, dass die Ausführung innerhalb einer JSR-Subroutine erfolgt. Wie oben beschrieben, kann dies über eine statische Datenflußanalyse erfolgen. Wenn der Ausführungspunkt innerhalb einer JSR-Subroutine liegt, ist dieser Ausführungspunkt als aktueller Ausführungspunkt und die JSR-Subroutine als aktuelle JSR-Subroutine zu betrachten und wie folgt zu verarbeiten:
    • a) Indem der aktuelle Ausführungspunkt als Index in der Struktur des Abbildungs-Positionsanzeigers benutzt wird, ist der Ausführungspunkt in der Deltaabbildung abzubilden, die diesem Ausführungspunkt entspricht. Mit der lokalisierten Deltaabbildung ist der aktuelle Status der Art jeder lokalen Variablen im aktuellen Ausführungspunkt zu bestimmen. Diese Deltaabbildung wird nachstehend als "erste" Deltaabbildung bezeichnet.
    • b) Indem der aktuelle Ausführungspunkt als Index in der Struktur des Rücksprungadreß-Positionsanzeigers benutzt wird, sind der aktuelle Ausführungspunkt und der Wert der Rücksprungadresse, die diesem aktuellen Ausführungspunkt entsprechen, abzubilden.
    • c) Der Wert der Rücksprungadresse ist zu benutzen, um die Adresse des "aufrufenden" JSR-Befehls zu bestimmen, der ausgeführt wurde, um zur aktuellen JSR-Subroutine zu springen. Wie oben beschrieben, ist der JSR-Befehl der Befehl, der dem vorausgeht, auf den die Rücksprungadresse zeigt.
    • d) Falls der aufrufende JSR-Befehl nicht innerhalb einer JSR-Subroutine liegt, ist mit Schritt 5 fortzufahren.
    • e) Indem die Adresse der "aufrufenden" JSR-Subroutine als Index zum Abbildungs-Positionsanzeiger benutzt wird, ist diese Adresse in ihrer entsprechenden Deltaabbildung abzubilden. Diese Deltaabbildung ist zu benutzen, um den Status der Art jeder der lokalen Variablen im Ausführungspunkt des "aufrufenden" JSR- Befehls zu identifizieren. Diese Deltaabbildung wird nachstehend als "zweite" (oder weitere) Deltaabbildung bezeichnet.
    • f) Die erste Deltaabbildung ist mit der zweiten Deltaabbildung zu verbinden, wobei der ersten Deltaabbildung Vorrang zu geben ist, um eine zusammengesetzte Deltaabbildung zu erstellen. Wenn die erste Deltaabbildung angibt, dass die Art einer lokalen Variablen geändert wurde, dann wird die Änderung für diese Variable in der zusammengesetzten Deltaabbildung benutzt. Ansonsten wird der Wert von der zweiten Deltaabbildung für diese Variable benutzt. Werden die Deltaabbildungen auf diese Art und Weise verbunden, bleibt die Reihenfolge, in der die Änderungen während der Ausführung durchgeführt wurden, erhalten, indem sichergestellt wird, dass die zuletzt durchgeführte Änderung in der zusammengesetzten Deltaabbildung reflektiert wird. Die zusammengesetzte Deltaabbildung wird dann zur aktuellen Deltaabbildung.
    • g) Die "aufrufende" JSR-Subroutine, die den aktuellen JSR-Befehl enthält, wird die aktuelle JSR- Subroutine, und der Ausführungspunkt wird zum "auf­ rufenden" JSR-Befehl.
    • h) Es ist mit Schritt b) fortzufahren. Tatsächlich wird diese Schleife für jeden "aufrufenden" JSR-Befehl wiederholt, der innerhalb einer anderen JSR- Subroutine liegt. Indem diese Schleife auf diese Art und Weise wiederholt wird, verarbeitet das beispielhafte Verfahren die "verschachtelten" JSR- Befehle.
  • 5. Indem die Adresse des JSR-Befehls als Index in die Struktur des Abbildungs-Positionsanzeigers benutzt wird, ist diese Adresse in ihrer entsprechenden lokalen Variablenbasisabbildung abzubilden. Da diese Adresse des JSR-Befehls nicht innerhalb einer JSR-Subroutine liegt, wird die Struktur des Abbildungs- Positionsanzeigers für diese Adresse eher eine lokale Variablenbasisabbildung als eine Deltaabbildung bereitstellen.
  • 6. Die lokale Variablenbasisabbildung des JSR-Befehls ist mit der aktuellen Deltaabbildung (von 4(a) oder 4(f) oben) zu mischen, wobei der Deltaabbildung Vorrang zu geben ist, um eine verbundene Abbildung zu erstellen. Wenn die aktuelle Deltaabbildung zeigt, dass die Art einer lokalen Variablen geändert wurde, dann wird diese Änderung in der verbundenen Abbildung reflektiert. Ansonsten wird der Wert von der lokalen Variablenbasisabbildung in der verbundenen Abbildung reflektiert. Die Eintragungen in die verbundene Abbildung zeigen die Art jeder der lokalen Variablen im Originalausführungspunkt (Schritt 4).
    Es ist zu beachten, dass die vorgenannten Schritte 1 bis 3 vor Ausführung des Programms als eine Art der Vorverarbeitung durchgeführt werden könnten. Alternativ können diese Schritte ausgeführt werden, wenn das Programm einen Ausführungspunkt erreicht hat, wo es notwendig ist, die Arten der lokalen Variablen festzulegen. Das beschriebene Verfahren zur Erstellung der lokalen Variablenbasisabbildungen und der Deltaabbildungen ist von der tatsächlichen Zeit, zu der das Verfahren ausgeführt wird, unabhängig.
Beispielhafte Implementierung I. Überblick
In einer beispielhaften Implementierung wird das definierte Verfahren als Speicherbereinigung für eine Java™ Virtual Machine beschrieben. Es sollte jedoch klar sein, dass die Konzepte und Verfahren, die hier beschrieben werden, ohne weiteres auf Debugging oder auf andere Anwendungen angewendet werden können, wo es erforderlich ist, die Art genau zu ermitteln, die jeder lokalen Variablen an gegebenen Punkten in der Ausführung von Subroutinen, beispielsweise JSR-Subroutinen, aktuell zugewiesen wurde. Wo es im folgenden angebracht ist, wird die Erörterung beispielhafte Ausführungsbeispiele der vorliegenden Erfindung enthalten, die sich auf das Debugging oder andere Anwendungen beziehen. Ein beispielhaftes Ausführungsbeispiel der vorliegenden Erfindung identifiziert genau alle Ursachen der Entstehung und benutzt diese, um die lebenden Objekte zu bestimmen. Die verbleibenden Objekte sind tot und werden speicherbereinigt.
Im Zusammenhang mit dem Debugging wird die Art von jeder lokalen Variablen genau zu dem Augenblick bestimmt, in dem die Debugging-Sitzung aufgerufen wird. Auf diese Art und Weise kann jede lokale Variable dem Benutzer im korrekten Format angezeigt werden, wodurch das Debugging erleichtert wird.
Die Ursachen der Entstehung sind entweder in statischen Daten oder Stapeldatenübertragungsblock vorhanden. Die Verarbeitung der statischen Daten enthält nicht das beispielhafte Verfahren der Erfindung und wird nicht weiter erörtert. Die Bestimmung der Ursachen der Entstehung in den Stapeldatenübertragungsblock erfordert ein Abtasten aller Stapeldatenübertragungsblock und die Kenntnis des Formats jedes Datenübertragungsblocks. Es ist zu beachten, dass bei jedem Verfahrensaufruf ein Datenübertragungsblock auf den Stapel gelegt wird. Ein beispielhaftes Ausführungsbeispiel der vorliegenden Erfindung verarbeitet diese Stapeldatenübertragungsblöcke, die JSR-Subroutinenaufrufe enthalten.
Ein beispielhaftes Ausführungsbeispiel der vorliegenden Erfindung basiert auf der Übersetzung oder Kompilierung von Java™ Bytecodes in Maschinencode. Ein weiteres beispielhaftes Ausführungsbeispiel der vorliegenden Erfindung erstreckt sich jedoch auf eine Bytecode- Interpretation. In einem beispielhaften Ausführungsbeispiel der vorliegenden Erfindung ist der virtuelle Rechner selbst in Java™ geschrieben. Dementsprechend ist alles ein Java™ Objekt, das den Maschinencode eines Verfahrens enthält.
Die Speicherbereinigung wird jedesmal aufgerufen, wenn eine Speicheranforderung nicht von dem verfügbaren Speicher erfüllt werden kann. Die Speicherbereinigung sucht alle lebenden Objekte in dem System und beginnt, indem der Satz der "root" (Wurzel) Zeiger bestimmt wird. Der Satz mit den Ursachen der Entstehung enthält alle lokalen variablen Zeiger, die Zeiger im Operandenstapel für jeden Stapeldatenübertragungsblock, und die statischen Variablen, die auf die Objekte zeigen. Der "lebende" Satz von Objekten enthält außerdem die Objekte, auf die von dem Wurzelsatz gezeigt wird sowie den transitiven Abschluß von Objekten, auf die von diesen Objekten gezeigt wird. Alle anderen Objekte sind "tot" und können speicherbereinigt werden. (Siehe Garbage Collection, Algorithms for Automatic Dynamic Memory Management", Jones, Lins, 1996, section 2.5.) Die Zuordnung des dynamisch zugewiesenen Speichers, der diesen toten Objekten zugewiesen wurde, wird aufgehoben, wodurch mehr dynamischer Speicher frei wird, der von anderen Anwendungen genutzt werden kann. Im Zusammenhang mit der Speicherbereinigung bezieht sich der Begriff "Objekt" auf Datenstrukturen, für die der Speicher vom Systemspeicherbereich dynamisch zugeordnet wird.
Während die Speicherbereinigung die Stapeldatenübertragungsblock abtastet, trifft sie gelegentlich auf Datenübertragungsblock, bei denen der Ausführungspunkt innerhalb einer JSR-Subroutine liegt. An diesen Punkten wird das oben beschriebene Verfahren benutzt, um die Wurzeln innerhalb dieses Stapeldatenübertragungsblocks zu lokalisieren. Ein beispielhafter Speicherbereinigungsprozeß ist unten beschrieben.
  • 1. Eine Liste mit allen Objekten, die aktuell dem Speichersystem zugeordnet sind, ist aufzubewahren. Eine Liste von den nicht zugeordneten Plätzen im Speichersystem ist aufzubewahren.
  • 2. Kann die Speicheranforderung von dem nicht zugeordneten Speicher erfüllt werden?
  • 3. Falls nicht, dann
    ist der Satz mit "lebenden" Objekten zu identifizie­ ren, die aktuell im System gespeichert sind, indem der Satz mit "root" Zeigern bestimmt wird, der den bzw. die lokalen Variablenzeiger im Operandenstapel für alle Stapeldatenübertragungsblöcke und
    die statischen Variablen, die auf diese Objekte zei­ gen, enthält;
    sind alle Objekte zu identifizieren, auf die von dem Satz Wurzelzeiger gezeigt wird;
    und es ist der Satz mit Objekten zu identifizieren, auf die von diesen Objekten gezeigt wird.
  • 4. Alle Objekte, die aktuell im Speichersystem gespei­ chert und nicht Teil des Satzes mit "lebenden" Objekten sind, wie diese in Schritt 3 identifiziert wurden. Ein nicht "lebendes" Objekt ist "tot". Es ist eine Liste mit allen aktuell zugewiesenen Objekten und eine Liste mit "lebenden" Objekten, auf die aktuell gezeigt wird, auszugeben, denn die "toten" Objekten werden identifiziert, indem die letztgenannte Liste von der vorherigen Liste "subtrahiert" wird. Der Platz, der diesen "toten" Objekten zugeordnet wurde, ist zur Liste des nicht zugeordneten Speichers hinzuzufügen, wodurch die Zuordnung der "toten" Objekte aufgehoben wird.
  • 5. Kann die Speicheranforderung von dem Platz in der nicht zugeordneten Liste erfüllt werden? Falls nicht, dann ist vom Betriebssystem mehr Speicher anzufordern, oder der Benutzer ist zu informieren, dass für die Anwendung nicht genug Platz zur Verfügung steht.
    Der Prozeß kann zusätzliche Speicherzuordnungsoptimierungen durchführen, wie beispielsweise die Objektverschiebung, um die Fragmentierung des Speichers zu minimieren. Weitere Einzelheiten finden Sie in Garbage Collection, Algorithms for Automatic Dynamic Memory Management, Jones, Lins, 1996, section 2.5, auf das hier insgesamt Bezug genommen wird.
    Ein beispielhaftes Ausführungsbeispiel der Erfindung wird in Schritt 3 oben benutzt, um die Stapeldatenübertragungsblöcke abzutasten und den Satz von lokalen Variablenzeiger im Stapeldatenübertragungsblock zu bestimmen.
Informationen bezüglich der Speicherstelle von Wurzeln im Stapel sind in Referenzabbildungen enthalten. Ein Satz Abbildungen ist mit jedem Verfahren verbunden und zwar eine Abbildung für jede Stelle, wobei die Art von jeder lokalen Variablen identifiziert werden muß, zum Beispiel, wo eine Speicherbereinigung, eine Debugging-Sitzung oder eine ähnliche Operation auftreten kann.
Fig. 1 zeigt ein Blockdiagramm, das Objektstrukturen dar­ stellt, die zum Verweis auf die Referenzabbildungen benutzt werden. Die Fig. 2(a) und die Fig. 2(b) zeigen verschiedene Arten von Referenzabbildungen. Die Referenzabbildungen können entweder statisch vor Ablauf der Anwendung oder dynamisch während der Speicherbereinigung oder dem Debugging erstellt werden. Die Abbildungen werden auf die gleiche Weise erzeugt, wobei es keine Rolle spielt, wann die Abbildungen erzeugt wurden.
Der MCSites Bereich 100 ist ein Bereich mit Ganzzahl- Offsets, eine für jeden Ausführungspunkt im Bytecode, wo eine Speicherbereinigung oder eine Debugging-Sitzung angefordert werden kann. Der Offset ist der Offset des Interessenpunkts vom Anfang des Verfahrenscodes. Das bedeutet, durch Eingabe eines Offsets in den Bytecode, wird der MCSites Bereich 100 durchsucht, um den Eintrag zu finden, der dem gegebenen Offset entspricht. Wenn der richtige Eintrag in den MCSites Bereich 100 gefunden ist, wird dieser richtige Eintrag zum Mapid, der den Interessenpunkt in den Referenzabbildungen 101 lokalisiert.
Das ReferenceMaps Objekt 101 ist ein Bereich mit Referenzab­ bildungen, die auf einer Eins-zu-Eins-Basis den Stellen ent­ sprechen, d. h. für jeden Interessenpunkt gibt es einen Eintrag in der ReferenceMaps Struktur. Das höchstwertigste Bit 210 von jeder Abb. 200 identifiziert, welche der beiden Arten des Eintrags vorhanden sind. Für die Stellen von Interessen, die nicht innerhalb der JSR-Subroutinen liegen, besteht der Rest des Eintrags aus der Bitabbildung 201, mit einem Bit pro lokaler Variablen und einem Bit für jedes mögliche Wort im Java™ Stapel. Für Stellen von Interesse innerhalb einer JSR-Subroutine enthält der Eintrag einen Index 202 (die UnusualMaps id) im UnusualMaps Bereich 102, wobei die Informationen über die Stelle behalten werden.
Der UnusualMap Bereich 102 ist ein Bereich mit Referenzen in UnusualMap Objekten, der einen Eintrag pro Stelle innerhalb einer JSR-Subroutine enthält. Der ReferenceMaps Bereich 101 stellt in diesem Bereich einen Index bereit, wenn der Interessenpunkt innerhalb einer JSR-Subroutine liegt. Jeder Eintrag im UnusualMaps Bereich 102 zeigt auf ein UnusualMap Objekt 103, wo die Informationen über diesen Interessenpunkt gespeichert sind.
Jedes UnusualMap Objekt 103 enthält die Abbildungsinformation für eine Stelle mit Informationen innerhalb einer JSR-Subroutine. Diese Abbildungsinformation enthält den Offset in der Rahmenstelle, die entweder die lokale Variable oder den Operandenstapeleintrag enthält, der die Rücksprungadresse von der JSR-Subroutine enthält. Diese Abbildungsinformation enthält auch andere Informationen, was davon abhängt, ob das Verfahren der Erfindung die Speicherbereinigung oder das Debugging ausführt.
Bei der Speicherbereinigung wird das UnusualMap Objekt (103) als Positionsanzeiger zur Lokalisierung der set-to-ref- (oder set-to-reference), set-to-nonref- (set-to-non­ reference) und der Rücksprungadreßbereiche konfiguriert. Diese Bereiche enthalten zusammen eine Deltaabbildung. Diese Positionsanzeiger (oder Indizes) lokalisieren jeden der drei Bereiche, die in dem UnusualReferenceMaps Objekt 104 gespeichert sind. Der set-to-ref-Bereich identifiziert alle lokalen Variablen, in der die Subroutine Referenzen in Objekten (Zeiger) zu einem Zeitpunkt zwischen der Eingabe der Subroutine und der Ausführung des gegebenen Interessenpunkts innerhalb der Subroutine speicherte. Ebenso identifiziert der set-to-nonref-Bereich alle lokale Variablen, in denen die Subroutine Nichreferenzarten zu einem Zeitpunkt zwischen der Eingabe der Subroutine und der Ausführung des gegebenen Interessenpunkts innerhalb der Sub­ routine speicherte. Wenn die Subroutine nacheinander sowohl eine Referenz- als auch eine Nichtreferenzart in derselben lokalen Variablen gespeichert hat, dann zeigen diese beiden Bereiche nur die Ergebnisse von der letzten Speicherung, die vor dem Interessenpunkt ausgeführt wurde. Wenn an einem gegebenen Punkt in der Subroutine eine Variable über die verschiedenen Ausführungspfade auf verschiedene Arten gesetzt wird, dann wird die Variable als "set to non reference" betrachtet. Der Rücksprungadreßbereich identifiziert die lokalen Variablen und Operandenstapeleinträge, die die Rücksprungadressen von der JSR-Subroutine enthalten (eine für jede Subroutine, wenn diese verschachtelt ist).
Das UnusualReferenceMaps Objekt 104 enthält die Bitabbildungen für die set-to-ref-, die set-to-nonref- und die Rücksprungadreßbereiche mit einem Bit für jede lokale Variable. Eine "1" gibt an, dass eine oder mehrere Aktionen unternommen wurden, und eine "0" gibt an, dass keine Aktion durchgeführt wurde, oder dass eine vorherige Aktion abgelöst wurde. So gibt beispielsweise eine "1" an, die an der Stelle des set-to-ref-Bereichs gespeichert ist und einer gegebenen lokalen Variablen entspricht, dass die Subroutine eine Referenz in der lokalen Variablen gespeichert hat. Ebenso gibt eine "1" an, die an einer Stelle des set-to-nonref- Bereichs gespeichert ist, dass die Subroutine die entsprechende lokale Variable als Nichtreferenz oder einfache Art setzt, oder dass die Variable entlang der Ersatzausführungspfade innerhalb der Subroutine auf ver­ schiedene Arten gesetzt wurde. Es ist zu beachten, dass eine "0" in den set-to-ref- oder den set-to-nonref-Bereichen der Deltaabbildung angibt, dass die lokale Variable nicht auf diesen Punkt in der Subroutine gesetzt wurde, oder dass die gesetzt Aktion abgelöst wurde.
Im Zusammenhang mit dem Debugging oder anderen Anwendungen sind die UnusualMap Objekte und die UnusualReferenceMaps Ob­ jekte 104 konfiguriert, um die Art des in jeder lokalen Variablen gespeicherten Werts anzugeben, anstatt anzugeben, ob es sich bei der Art um eine Referenz oder Nichtreferenz handelt, wie dies oben erörtert wurde. Die Objekte 103 und 104 könnten, anstatt einen set-of-ref-Bereich und einen set- to-nonref-Bereich bereitzustellen, einen separaten Bereich für jede Wertart bereitstellen, die einer lokalen Variablen zugeordnet werden könnte. So könnte beispielsweise ein set- to-int-Bereich ein Bit speichern, das jede lokale Variable identifiziert, die auf eine Ganzzahlart gesetzt ist. Ein set-to-float-Bereich könnte ein Bit speichern, das jede lokale Variable identifiziert, die auf eine Gleitkommazahlenart gesetzt und so weiter für jede mögliche Wertart. Alternativ dazu könnten die Objekte 103 und 104 einen einzelnen Bereich mit einem Eintrag für jede lokale Variable bereitstellen, wobei jeder Eintrag konfiguriert ist, um einen Code zu speichern. Ein einzigartiger Code, beispielsweise ein Multi-Bit-Code, könnte zu jeder Wertart gehören, so dass das Speichern eines der Codes in dem Bereich darauf hinweist, dass die Subroutine eine gegebene lokale Variable auf die Art setzt, die diesem Code entspricht. Ein einzigartiger Code ist für den Fall erforderlich, wenn Ersatzpfade an einer Stelle unterschiedliche Arten derselben Variablen zuordnen.
II. Abbildungserstellung
Die Erstellung der Abbildungen wird wie folgt vorgenommen.
  • 1. Für jedes Verfahren werden die Bytecodes analysiert. Bei der Speicherbereinigung erinnert sich jeder Be­ fehl, der in einer lokalen Variablen Ergebnisse im Analyseprogramm speichert, ob die Speicherung eine Referenz war oder nicht. Beim Debugging erinnert sich das Analyseprogramm daran, ob die Datenart in der lokalen Variablen gespeichert war. Es ist zu beachten, dass die Bytecode-Erstellungsregeln, die die Datenart anfordern, der in den lokalen Variablen in einem Bytecode gespeichert ist, unabhängig von dem Ausführungspfad sind, mit Ausnahme in einer JSR- Subroutine.
  • 2. Bei einem Bytecodebefehl, bei dem die Speicherbereinigung oder ein Debugging-Vorgang auftreten können, wird eine Abbildung erstellt und gespeichert. Bei den Abbildungen unterscheidet man zwei Arten: eine lokale Variablenbasisabbildung oder eine Deltaabbildung. Die Abbildungen der Deltaabbildung werden an potentiellen Speicherbereinigungs- oder Debuggingpunkten innerhalb einer JSR-Subroutine erstellt. An allen übrigen potentiellen Speicherbereinigungs- oder Debuggingpunkten wird eine Abbildung der lokalen Variablenbasisabbildungsart erzeugt.
    Im Zusammenhang mit der Speicherbereinigung kann die lokale Variablenbasisabbildung eine "reference" Abbildung sein, die genaue Informationen enthält, zum Beispiel, ob jede lokale Variable eine Objektreferenz enthält oder nicht. In diesem Zusammenhang enthält eine "delta" Abbildung, die einem gegebenen Punkt in der JSR-Subroutine entspricht, nur Informationen, die den Endeffekt der Änderungen enthält, die eventuell in der JSR- Subroutine im Referenzstatus der lokalen Variablen bis zu diesem gegebenen Punkt durchgeführt wurden.
    Im Zusammenhang mit dem Debugging kann die lokale Variablenbasisabbildung die genaue Art des in jeder lokalen Variablen gespeicherten Werts speichern. In diesem Zusammenhang enthält eine "delta" Abbildung, die einem gegebenen Punkt in der JSR-Subroutine ent­ spricht, nur Informationen, die den Endeffekt von Änderungen angeben, die eventuell in der JSR- Subroutine im Artenstatus der lokalen Variablen bis zu diesem Punkt durchgeführt wurden.
    Die Abbildungen werden entweder erstellt, wenn die Bytecodes in Maschinencodes konvertiert werden oder während der Speicherbereinigung oder dem Debugging, während der Rahmen für jedes Verfahren im Stapel abgetastet wird. Das Verfahren zur Erstellung dieser Abbildungen bleibt gleich, wobei es keine Rolle spielt, wann die Abbildungen erstellt wurden.
  • 3. Die Abbildungen enthalten folgende Informationen:
    • a) Im Zusammenhang mit der Speicherbereinigung kann die lokale Variablenbasisabbildung eine "reference" Abbildung sein, die eine Vielzahl von Bits enthält, wobei jedes Bit entweder eine lokale Variable oder ein Wort im Java™ Stapel darstellt. In bezug auf das hier beschriebene Verfahren sind die Java™ Stapelwörter und die entsprechenden Bits irrelevant. Wenn ein Bit Eins ist, bedeutet dies, dass das entsprechende Wort eine Referenz ist. Eine Null bedeutet, dass das Wort keine Referenz ist, d. h. eine andere Art, z. B. Ganzzahl (int.), Gleitkommazahl usw. oder keine Art. Im Zusammenhang mit dem Debugging gibt die lokale Variablenbasisabbil­ dung die Art des Werts an, der in jeder lokalen Variablen gespeichert ist und benutzt die oben erörterten Schemata.
    • b) Eine Deltaabbildung ist mit jedem gegebenen Interessenpunkt in der JSR-Subroutine verbunden und identifiziert alle Änderungen, die während der Ausführung der JSR-Subroutine vom Eintrag bis zum gegebenen Interessenpunkt durchgeführt wurden. Im Zusammenhang mit der Speicherbereinigung benutzt eine beispielhafte Implementierung eine Deltaabbildung, die drei Bereiche enthält, um folgendes anzugeben:
      die lokalen Variablen, die "set-to-reference" wurden,
      die lokalen Variablen, die "set-to-nonreference" wurden, und
      die lokalen Variablen oder Java™ Stapelwörter, die Subroutine-Rücksprungadressen enthalten.
Im set-to-reference-Bereich bedeutet es, wenn ein Bit Eins ist, dass das entsprechende Wort während einer JSR- Subroutine als letztes auf eine Referenz gesetzt wurde. Eine Null bedeutet, dass das Wort in der aktuellen JSR-Subroutine nicht auf eine Referenz gesetzt wurde oder von einer set-to- nonrefererice-Aktion abgelöst wurde. Es ist zu beachten, dass eine Null bedeutet, dass das Wort entweder eine Referenz oder Nichtreferenz enthalten könnte. So könnte beispielsweise ein zuvor aufgerufenes Verfahren oder eine zuvor aufgerufene JSR-Subroutine die lokale Variable auf eine Referenz gesetzt haben.
Im set-to-nonreference-Bereich bedeutet es, wenn ein Bit Eins ist, dass das entsprechende Wort während der JSR- Subroutine auf eine Nichtreferenz gesetzt wurde, oder dass alternative Ausführungen innerhalb der Subroutine vorhanden sind, die das entsprechende Wort auf verschiedene Arten setzen. Eine Null bedeutet, dass das Wort in der aktuellen JSR-Subroutine nicht auf eine Nichtreferenzart gesetzt wurde oder von einer set-to-reference-Aktion abgelöst wurde.
Was den Rücksprungadreßbereich angeht, so bedeutet es, wenn ein Bit Eins ist, dass das entsprechende Wort eine JSR-Rück­ sprungadresse enthält. Der Grund für diesen Bereich ist, dass in einem beispielhaften Ausführungsbeispiel der vorliegenden Erfindung jedes Verfahren (der Maschinencode) ein Objekt ist. JSR-Rücksprungadressen, die in lokalen Variablen gespeichert sind, sind deshalb interne Zeiger auf diese Objekte. Da durch eine Kopierspeicherbereinigung diese Objekte verschoben werden können, ist es wünschenswert, ihre Stelle zu verfolgen und diese internen Zeiger zu verschieben, um die Kontinuität vor und nach der Speicherbereinigung zu erhalten.
III. Stack Walking während der Speicherbereinigung
Fig. 3 zeigt anhand eines Flußdiagramms, wie das Stack Walking verarbeitet wird. Ausgehend von dem letzten Datenübertragungsblock wird beim Stack Walking der Stapel nach oben verarbeitet, wobei jeder Datenübertragungsblock in der Reihenfolge seines Auftretens verarbeitet wird. Wenn ein Datenübertragungsblock angibt, dass das Verfahren sich nicht in einer JSR-Subroutine befand, als die Steuerung übertragen wurde, dann wird die normale Datenübertragungsblockverarbeitung durchgeführt, d. h. der Datenübertragungsblock wird abgetastet, und seine Wurzeln werden der Speicherbereinigung gemeldet. Das Verfahren der Erfindung wird ausgeführt, um die Datenübertragungsblöcke zu verarbeiten, wobei die Steuerung während einer JSR- Subroutine übertragen wurde. Die Verarbeitung von JSR- SubroutinenDatenübertragungsblöcken wird nicht erörtert.
Der letzte Datenübertragungsblock wird bei Schritt 300 erreicht. Die Erkennung, ob der Datenübertragungsblock in einer JSR-Subroutine war, als die Steuerung an das nächste Verfahren übertragen wurde, wird in Schritt 301 durchgeführt:
  • 1. Der Offset des Verfahrenaufrufbefehls im Aufrufcodeobjekt wird wie folgt bestimmt:
    Rufen Sie die Rücksprungadresse im Aufrufcodeobjekt auf, zu dem die Steuerung zurückkehrt, wenn das Ver­ fahren abgeschlossen ist. In einem beispielhaften Ausführungsbeispiel sind die Rücksprungadresse und eine Verfahrens-ID, die das Verfahren identifizieren, Teil der Verfahrensaufrufbedingung, und ihre Stelle im Stapeldatenübertragungsblock ist somit bekannt.
    Die Verfahrens-ID wird benutzt, um den Ursprung des aufrufenden Codeobjekts zu lokalisieren, und die Rücksprungadresse minus des Codeursprungs ergibt den Offset des Verfahrensaufrufbefehls im aufrufenden Codeobjekt.
  • 2. Die Abbildung für den Offset, der in Schritt 1 festgelegt wurde, wird wie folgt bestimmt:
    Der MCSite Bereich 100 ist mittels des Offsets zu durchsuchen, um den Eintrag zu finden, der dem in Schritt 1 festgelegten Offset entspricht. Der MCSites Bereich 100 ist ein Bereich mit Offsets, bei denen jeder Eintrag einer gegebenen Speicherbereinigungs- oder Debuggingstelle entspricht. Der Index der entsprechenden Eintragsnummer im Bereich wird die Mapid für die gegebene Stelle.
    Das im ReferenceMaps-Eintrag für diese gegebene Stelle höchstwertigste Bit ist zu prüfen, indem das Mapid als Index benutzt wird, um festzustellen, ob die gegebene Stelle innerhalb einer JSR-Subroutine liegt.
    Wenn die Stelle keine JSR-Subroutine ist, ist der Rest des Eintrags im ReferenceMaps Bereich 101 die Referenzabbildung für die gegebene Stelle.
    Wenn die Stelle innerhalb einer JSR-Subroutine liegt, dann enthält der ReferenceMaps Eintrag einen Index im UnusualMaps Bereich 102. Dieser Index wird nachstehend UnusualMapid genannt.
    Wenn der Datenübertragungsblock nicht in einer JSR- Subroutine war, dann wird der Datenübertragungsblock normal verarbeitet (Schritt 305). Andernfalls wird die JSR-Datenübertragungsblockverarbeitung durchge­ führt (Schritt 304), wie dies nachstehend beschrieben ist. Nachdem der Datenübertragungsblock verarbeitet wurde, wird der vorherige Datenübertragungsblock (sofern vorhanden) erreicht (Schritt 302), auf Gültigkeit geprüft (Schritt 303) und entsprechend unter Vorbehalt bewertet (Schritt 301).
IV. Datenübertragungsblockverarbeitung in der JSR- Subroutine
Fig. 4 und Fig. 5 zeigen im Detail die Operationen bei der Datenübertragungsblockverarbeitung in der JSR- Subroutine (Schritt 304). Nachdem die UnusualMapid angegeben wurde wie in Abschnitt III-2 beschrieben ist, wird die Verarbeitung wie folgt durchgeführt:
  • 1. In Schritt 401 wird die JSR-Subroutinenabbildung für die Stelle bestimmt. Dies geschieht entsprechend der Abbildung in Fig. 5.
    • a) Mit der UnusualMapid als Index ist das UnusualMap Objekt im UnusualMaps Bereich (Schritt 500) zu lokalisieren. Jedes UnusualMap Objekt enthält alle Informationen über eine potentielle Speicherbereinigungs- oder Debugging-Stelle innerhalb einer JSR-Subroutine.
    • b) Die "delta" Abbildungen, die zu den Stellen gehören, werden extrahiert und gespeichert, wobei sie mit anderen Deltaabbildungen gemischt werden können, falls diese in einer JSR- Situation (Schritt 501) verschachtelt sind.
    • c) Derjenige, der diese JSR-Subroutine (Schritt 502) aufgerufen hat, ist zu identifizieren. Um dies durchführen zu können, erhalten wir den Rücksprungadreß-Offset für die JSR-Subroutine. Diese Information ist in dem UnusualMap Objekt enthalten. Mittels dieses Rücksprungadreß- Offsets erhält man die Rücksprungadresse der JSR-Subroutine, d. h. die Adresse des aufrufenden JSR-Befehls. Mittels der Anfangsadresse des Codeobjekts wird der Offset desjenigen berechnet, der die JSR-Subroutine aufgerufen hat.
    • d) Der Status in der JSR-Befehlsstelle (Schritt 503) ist zu identifizieren, d. h. es ist festzustellen, ob sich der Aufrufende selbst innerhalb einer JSR-Subroutine (verschachtelte JSR-Subroutinen) befindet oder nicht. Dies geschieht, indem der MCSites Bereich mittels des Offsets vom Aufrufenden (ähnlich Schritt III-2 oben) durchsucht und die entsprechende Abbildung überprüft wird.
    • e) Wenn sich die aufrufende JSR-Stelle innerhalb einer anderen JSR-Subroutine befindet, ist diese Situation ein "verschachtelter" JSR- Subroutinenaufruf. In diesem Fall ist das UnusualMap Objekt zu benutzen, das Informationen über die zweite oder "aufrufende" JSR-Subroutine enthält, um ihre Abbildungen (Schritt 504), wie in den Schritten a) und b) durchgeführt, zu erhalten. Die Deltaabbildungen von dieser "aufrufenden" JSR-Subroutine werden mit den zuvor gespeicherten Deltaabbildungen gemischt.
      Es ist zu beachten, dass die erste JSR- Subroutine, auf die getroffen wird, die letzte JSR-Subroutine ist, um die Aktualisierungen auf die lokalen Variablen anzulegen. Dementsprechend haben ihre Aktualisierungen gegenüber lokalen Variablen Vorrang, so dass, wenn die Deltaabbildungen gemischt werden, Änderungen, die von der letzten JSR-Subroutine gemacht wurden, in der gemischten Abbildung reflektiert werden. Wenn beispielsweise eine "aufrufende" Subroutine eine "aufgerufene" Subroutine aufruft, und beide Subroutinen die Art einer gegebenen lokalen Variablen geändert haben, haben die Änderungen, die von der "aufgerufenen" Subroutine durchgeführt wurden, Vorrang und werden in der gemischten Deltaabbildung reflektiert. Nach erfolgter Mischung kehrt das Verfahren zu Schritt c) (Schritt 505) zurück und greift auf sich selbst zurück, bis es zu Schritt f) unten gelangt.
      Um zu Schritt f) zu gelangen, muß das Verfahren seinen Weg nach oben fortsetzen, wobei die Ver­ schachtelung von JSR-Aufrufen aufgehoben wird, und die Deltaabbildungen, die dem JSR- Subroutinenaufruf entsprechen, gemischt werden, bis ein JSR-Aufruf von einer Nicht-JSR- Subroutine erzielt wird. Wenn das Verfahren einen solchen Aufruf findet, verarbeitet es Schritt f) unten.
    • f) Wenn die aufrufende JSR-Stelle NICHT selbst innerhalb einer JSR-Subroutine liegt, wird die Abbildung an dieser Stelle erhalten und mit der Information in der gespeicherten Deltaabbildung (Schritte 506, 507) gemischt. Die Referenzabbildung listet für jede lokale Variable auf, ob die lokale Variable, die zum Zeitpunkt des JSR-Befehls an der aufrufenden JSR-Stelle auf eine Referenz gesetzt war, ausgeführt wurde. In dieser Mischung haben die Änderungen, die in der Deltaabbildung aufgezeichnet wurden, Priorität, so dass Änderungen, die in "aufgerufenen" JSR- Subroutinen gemacht wurden, in der neuen, gemischten Abbildung reflektiert werden. Diese neue Abbildung wird benutzt, um den Status der lokalen Variablen für die Speicherbereinigung zu bestimmen. Im Zusammenhang mit dem Debugging, würde die Referenzabbildung angeben, welche Datenarten in jeder lokalen Variablen in der Nicht-JSR-Subroutine gespeichert wurden, und die endgültige gemischte Abbildung würde die Art von Daten reflektieren, die in jeder lokalen Variablen zu dem Zeitpunkt gespeichert waren, als die Debugging-Sitzung aufgerufen wurde.
  • 2. Wieder zurück zu Fig. 4. Die erste Referenz im Datenübertragungsblock wird erzielt (Schritt 402). Dies geschieht, indem die kombinierte Abbildung für das erste Bit, das auf "1" gesetzt ist, abgetastet wird. Das Wort, das diesem Bit entspricht, wird lokalisiert, und sein Offset vom Datenübertragungsblockzeiger wird bestimmt. Die Entsprechung ist, dass Bit 1 Wort 1 darstellt, Bit 2 Wort 2 darstellt und so weiter. Jedes Wort, dessen entsprechendes Bit gesetzt ist, ist eine Referenz (anders ausgedrückt, ein Zeiger im Speicherbereich) und stellt einen "lebenden" Zeiger dar, dessen Integrität durch die Speicherbereinigung erhalten bleiben muß. Die Wörter beginnen mit einem bekannten Offset von dem Datenübertragungsblockzeiger. Von jeder Referenz wird dieser Offset zur Verarbeitung (Schritt 403) an die Speicherbereinigung zurückgeschickt.
  • 3. Wenn die Speicherbereinigung die nächste Referenz (Schritt 404) anfordert, fährt das Verfahren von dem zuvor lokalisierten, gesetzten Bit mit der Vorwärtsabtastung fort, bis das nächste gesetzt Bit lokalisiert ist. Wenn keine weiteren Referenzen mehr vorhanden sind, wie dies durch die gesetzten Bits angegeben ist, kehrt das Verfahren zu einer Anzeige von dieser Situation zurück (Schritt 405).
  • 4. Die Speicherbereinigung folgt dann einer ähnlichen Prozedur, um die Rücksprungadressen für alle JSR- Subroutinen-Rücksprungadressen, die im Datenübertragungsblock sind, (Schritte 406-409) zu bestimmen. Diese Rücksprungadressen sind interne Zeiger auf Codeobjekte und müssen verschoben werden, wenn wir eine Speicherbereinigung durch Kopieren benutzen, bei der Codeobjekte verschoben werden. Bei einer Speicherbereinigung, die nicht durch Kopieren erfolgt, müssen diese Zeiger nicht verschoben werden.
Die Fig. 6(a)-Fig. 6(c) sind beispielhafte Abbildungen, die hilfreich sind, um die Mischoperation zu illustrieren. Fig. 6(a) ist ein Beispiel von einer Basisabbildung. Die Einsen und Nullen, die sich in der Basisabbildung befinden, geben an, ob es sich bei den entsprechenden Variablen um eine Zeigerart handelt. Eine beispielhafte Deltaabbildung ist in Fig. 6(b) dargestellt. Wie zuvor erörtert, enthält die Deltaabbildung einen set-to-ref-Bereich und einen set- to-non-ref-Bereich. Wenn vom Zeitpunkt der Eingabe einer JSR-Subroutine bis zum Erreichen des Interessenpunkts eine Variable in eine Zeigerart geändert wird, kann somit die entsprechende Stelle im set-to-ref-Bereich zum Beispiel auf 1 gesetzt werden. Ebenso kann, wenn vom Zeitpunkt der Eingabe der JSR-Subroutine bis zum Erreichen des Interessenpunkts eine Variable geändert wird, so dass sie nicht länger eine Zeigerart ist, der entsprechende Teil des set-to-non-ref-Bereichs zum Beispiel auf 1 gesetzt werden. Wenn bei einer Variablen die Deltaabbildung keine Änderungen angibt, dann erscheint die Variablenart, die in der Basisabbildung erscheint, auch in der gemischten Abbildung. Ungeachtet der Variablenart in der Basisabbildung wird, wenn der set-to-ref-Bereich angibt, dass die Variablenart in einen Zeiger geändert wurde, die Art dieser Variablen in der gemischten Abbildung ebenfalls als Zeiger angegeben. Ungeachtet davon, ob die Basisabbildung angibt, dass eine Variable ein Zeiger ist, wird, wenn der set-to-non-ref- Bereich angibt, dass die Art der Variablen geändert wurde, so dass sie kein Zeiger ist, die gemischte Abbildung auch angeben, dass die Variablenart für diese Variable kein Zeiger ist.
Obwohl hier mit Bezug auf bestimmte spezifische Ausführungs­ beispiele abgebildet und beschrieben, ist die vorliegende Erfindung trotzdem nicht auf die abgebildeten Einzelheiten begrenzt. Statt dessen können verschiedene Änderungen an den Details innerhalb des Anwendungsbereichs und des Äquivalenzbereichs der Ansprüche und ohne von dem Sinn der Erfindung abzuweichen, durchgeführt werden.

Claims (21)

1. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen in einem Computerprogramm, das eine Vielzahl von Subroutinen enthält, die nach dem jeweiligen Subroutinenaufruf ausgeführt werden, wobei das Verfahren Schritte enthält, um
  • a) für jeden Subroutinenaufruf außerhalb dieser Vielzahl von Subroutinen, die jeweiligen Basisabbildungen zu erstellen, die die Arten der jeweiligen lokalen Variablen nennen;
  • b) für jeden Ausführungspunkt innerhalb irgendeiner Vielzahl von Subroutinen, die jeweiligen Deltaabbildungen zu erzeugen, die die Änderungen in den jeweiligen lokalen Variablen angeben;
  • c) Ausführungspfade zu jedem Ausführungspunkt zu bestimmen, um zu identifizieren, welche Basisabbildungen dem jeweiligen Subroutinenaufruf entsprechen; und
  • d) a) jede der Basisabbildungen mit b) einer jeweiligen aktuellen Deltaabbildung zu verbinden, wovon jede aus einer der Deltaabbildungen stammt, die auf diesen Ausführungspfaden basieren, um die Arten der lokalen Variablen zu bestimmen.
2. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei zum Zeitpunkt des jeweiligen Subroutinenaufrufs die jeweiligen Rücksprungadressen gespeichert und mit Hilfe der Rücksprungadressen in Schritt c) die Ausführungspfade bestimmt werden.
3. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei jede dieser Subroutinen von entsprechenden weiteren Subroutinen aufgerufen wird, wobei weiterhin Deltaabbildungen, die Änderungen an einzelnen der lokalen Variablen für jede der weiteren Subroutinen erstellt werden, wobei die weiteren Deltaabbildungen jeweils mit einer der entsprechenden der Deltaabbildungen kombiniert werden, um die aktuellen Abbildungen zu erhalten.
4. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei das Verfahren außerdem den Schritt zur Durchführung der Speicherbereinigung auf der Grundlage der Ergebnisse von Schritt d) enthält.
5. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 4, wobei wenigstens eine dieser Variablen als Zeiger festgelegt ist, und dass während der Speicherbereinigung dieser Zeiger und ein Objekt, auf das dieser Zeiger zeigt, erhalten bleiben, während die Zuordnung anderer Speicherstellen aufgehoben wird.
6. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, das außerdem den Schritt enthält, einzelne dieser lokalen Variablen anzuzeigen um den Debugging-Vorgang dieses Computerprogramms durchzuführen.
7. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei das Computerprogramm Java™ Virtual Machinen-Befehle enthält.
8. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei jede Basisabbildung, jede Deltaabbildung und die aktuelle Abbildung angeben, ob es sich bei der lokalen Variablen um einen Zeiger oder ein Grundelement handelt.
9. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei diese Basisabbildung mittels der statischen Datenflußanalyse erstellt wird.
10. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei jede Basisabbildung und jede Deltaabbildung mit einem Abbildungs- Positionsanzeiger registriert werden, und wobei dieser Abbildungs-Positionsanzeiger abgefragt wird, um diese Deltaabbildung dahingehend zu identifizieren, dass sie zum Verbinden in Schritt d) benutzt wird.
11. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei, wenn die aktuelle Abbildung erstellt wird, das Verbinden so durchgeführt wird, dass die Deltaabbildung gegenüber der weiteren Deltaabbildung Vorrang hat.
12. Ein Verfahren zur Verfolgung der Arten von lokalen Variablen gemäß Anspruch 1, wobei in Schritt d) das Verbinden so durchgeführt wird, dass die aktuelle Deltaabbildung gegenüber der Basisabbildung Vorrang hat.
13. Vorrichtung zur Verfolgung der Arten von lokalen Varia­ blen in einem Computerprogramm, das eine Subroutine enthält, die nach einem Subroutinenaufruf ausgeführt wird, wobei die Vorrichtung enthält,
Basisabbildungs-Erzeugungsmittel, um eine Basisabbildung zu erzeugen, die Arten dieser lokalen Variablen für den Subroutinenaufruf außerhalb der Subroutine anzeigt;
Deltaabbildungs-Erzeugungsmittel, um eine Deltaabbildung zu erzeugen, die Änderungen in einer der lokalen Variablen für einen Ausführungspunkt innerhalb dieser Subroutine anzeigt;
Bestimmungsmittel, um einen Ausführungspfad zu diesem Ausführungspunkt festzulegen, um die Basisabbildung dahingehend zu identifizieren, dass sie dem Subroutinenaufruf entspricht; und
Verbindungsmittel, um die Basisabbildung mit einer aktuellen Deltaabbildung zu verbinden, die von der Deltaabbildung gemäß dem Ausführungspfad erzielt wird, um die Arten dieser lokalen Variablen zu bestimmen.
14. Vorrichtung zur Verfolgung der Arten von lokalen Varia­ blen gemäß Anspruch 13, wobei zum Zeitpunkt des jeweiligen Subroutinenaufrufs eine Rücksprungadresse gespeichert wird, und diese Rücksprungadresse durch die Bestimmungsmittel zur Bestimmung des Ausführungspfads verwendet wird.
15. Vorrichtung zur Verfolgung der Arten von lokalen Varia­ blen gemäß Anspruch 13, wobei die Subroutine von einer weiteren Subroutine aufgerufen wird, und die Deltaabbildungs-Erzeugungsmittel außerdem verwendet werden, um eine weitere Deltaabbildung zu erstellen, die Änderungen in den lokalen Variablen für die weitere Subroutine angibt, wobei die Verbindungsmittel außerdem dazu verwendet werden, um die weitere Deltaabbildung mit der Deltaabbildung zu verbinden, um die aktuelle Abbildung zu erhalten.
16. Gegenstand, umfassend ein computernutzbares Medium mit darin enthaltenen computerlesbaren Programmcodemitteln, um die Arten von lokalen Variablen in einem Computerprogramm zu verfolgen, das eine Subroutine aufweist, die nach einem Subroutinenaufruf ausgeführt wird, wobei die computerlesbaren Programmcodemittel in diesem Produktionsartikel computerlesbare Programmcodemittel enthalten, um einen Computer zu veranlassen,
Für den Subroutinenaufruf außerhalb dieser Subroutine, eine Basisabbildung zu erstellen, die die Arten der lokalen Variablen nennt;
bei einem Ausführungspunkt innerhalb der Subroutine eine Deltaabbildung zu erstellen, die Änderungen in irgendeiner dieser lokalen Variablen angibt;
einen Ausführungspfad zu diesem Ausführungspunkt zu bestimmen, um die Basisabbildung dahingehend zu identifizieren, dass sie dem Subroutinenaufruf entspricht; und
die Basisabbildung a) mit einer aktuellen Deltaabbil­ dung b) zu verbinden, die von dieser Deltaabbildung gemäß des Ausführungspfads erzielt wird, um die Arten von diesen lokalen Variablen zu bestimmen.
17. Gegenstand wie in Anspruch 16 aufgeführt, wobei diese Subroutine von einer weiteren Subroutine aufgerufen wird, und die computerlesbaren Programmcodemittel, die in diesem Gegenstand enthalten sind, außerdem computerlesbare Programmcodemittel enthalten, um einen Computer zu veranlassen,
für die weitere Subroutine eine weitere Deltaabbildung zu erstellen, die Änderungen in einer der lokalen Variablen angibt, wobei die weitere Deltaabbildung mit der Deltaabbildung verbunden wird, um die aktuelle Abbildung zu erhalten.
18. Gegenstand wie in Anspruch 16 aufgeführt, wobei eine Rücksprungadresse zum Zeitpunkt des Subroutinenaufrufs gespeichert wird, und die Rücksprungadresse zur Bestimmung des Ausführungspfades benutzt wird.
19. Ein Computerprogrammprodukt, das ein computernutzbares Medium mit darin enthaltenen computerlesbaren Programmcodemitteln aufweist, um die Arten von lokalen Variablen in einem Computerprogramm zu verfolgen, das eine Subroutine hat, die nach einem Subroutinenaufruf ausgeführt wird, wobei die computerlesbaren Programmcodemittel in diesem Computerprogrammprodukt computerlesbare Programmcodemittel enthalten, um einen Computer zu veranlassen,
für den Subroutinenaufruf außerhalb dieser Subroutine eine Basisabbildung zu erstellen, die die Arten der lokalen Variablen nennt;
bei einem Ausführungspunkt innerhalb der Subroutine eine Deltaabbildung zu erstellen, die Änderungen in einer dieser lokalen Variablen angibt;
einen Ausführungspfad zu diesem Ausführungspunkt zu bestimmen, um die Basisabbildung dahingehend zu identifizieren, dass sie dem Subroutinenaufruf entspricht; und
die Basisabbildung a) mit einer aktuellen Deltaabbil­ dung b) zu verbinden, die von dieser Deltaabbildung gemäß des Ausführungspfads erhalten wird, um Arten dieser lokalen Variablen zu bestimmen.
20. Ein Computerprogrammprodukt wie in Anspruch 19 aufge­ führt, wobei eine Rücksprungadresse zum Zeitpunkt des Subroutinenaufrufs gespeichert wird, wobei die Rücksprungadresse zur Bestimmung des Ausführungspfades benutzt wird.
21. Ein Computerprogrammprodukt wie in Anspruch 19 aufge­ führt, wobei diese Subroutine von einer weiteren Subroutine aufgerufen wird, eine weitere Deltaabbildung, die Änderungen in diesen lokalen Variablen angibt, für die weitere Subroutine erstellt wird, und wobei die weitere Deltaabbildung mit dieser Deltaabbildung kombiniert wird, um die aktuelle Abbildung zu erhalten.
DE19959758A 1998-12-14 1999-12-11 Bestimmung der Art und der Genauigkeit von lokalen Variablen bei vorhandenen Subroutinen Ceased DE19959758A1 (de)

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
US09/211,388 US6442751B1 (en) 1998-12-14 1998-12-14 Determination of local variable type and precision in the presence of subroutines

Publications (1)

Publication Number Publication Date
DE19959758A1 true DE19959758A1 (de) 2000-06-21

Family

ID=22786735

Family Applications (1)

Application Number Title Priority Date Filing Date
DE19959758A Ceased DE19959758A1 (de) 1998-12-14 1999-12-11 Bestimmung der Art und der Genauigkeit von lokalen Variablen bei vorhandenen Subroutinen

Country Status (2)

Country Link
US (1) US6442751B1 (de)
DE (1) DE19959758A1 (de)

Families Citing this family (38)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6295640B1 (en) * 1998-05-08 2001-09-25 Apple Computer, Inc. Method and apparatus for distinguishing reference values from non-reference values in a runtime environment
US6675378B1 (en) * 2000-01-06 2004-01-06 International Business Machines Corporation Object oriented apparatus and method for allocating array objects on an invocation stack
US7103877B1 (en) * 2000-11-01 2006-09-05 International Business Machines Corporation System and method for characterizing program behavior by sampling at selected program points
US7065747B2 (en) * 2001-05-08 2006-06-20 Sun Microsystems, Inc. Identifying references to objects during bytecode verification
US7178132B2 (en) * 2002-10-23 2007-02-13 Microsoft Corporation Forward walking through binary code to determine offsets for stack walking
US7103723B2 (en) * 2003-02-25 2006-09-05 Intel Corporation Priority-based code cache management
GB2399897B (en) * 2003-03-26 2006-02-01 Advanced Risc Mach Ltd Memory recycling in computer systems
US7340493B2 (en) * 2003-07-02 2008-03-04 International Business Machines Corporation System and method for reducing memory leaks in virtual machine programs
US7426716B2 (en) * 2003-07-11 2008-09-16 Board Of Regents, The University Of Texas System Recovery and representation of object interaction in an object oriented program
US7313789B1 (en) * 2004-02-27 2007-12-25 Sun Microsystems, Inc. Methods and systems for reducing a program size
US7712081B2 (en) * 2005-01-19 2010-05-04 International Business Machines Corporation Using code motion and write and read delays to increase the probability of bug detection in concurrent systems
US7574702B2 (en) * 2005-03-18 2009-08-11 Microsoft Corporation Method and apparatus for hybrid stack walking
US20070157030A1 (en) * 2005-12-30 2007-07-05 Feghali Wajdi K Cryptographic system component
GB0601566D0 (en) * 2006-01-26 2006-03-08 Codeplay Software Ltd A parallelization system and compiler for use in such a system
US20080178149A1 (en) * 2007-01-24 2008-07-24 Peterson James G Inferencing types of variables in a dynamically typed language
JP5186802B2 (ja) * 2007-05-08 2013-04-24 富士通セミコンダクター株式会社 マイクロプロセッサ
US8560938B2 (en) * 2008-02-12 2013-10-15 Oracle International Corporation Multi-layer XML customization
US8191074B2 (en) * 2007-11-15 2012-05-29 Ericsson Ab Method and apparatus for automatic debugging technique
US20090132666A1 (en) * 2007-11-15 2009-05-21 Shahriar Rahman Method and apparatus for implementing a network based debugging protocol
US8788542B2 (en) 2008-02-12 2014-07-22 Oracle International Corporation Customization syntax for multi-layer XML customization
US8538998B2 (en) * 2008-02-12 2013-09-17 Oracle International Corporation Caching and memory optimizations for multi-layer XML customization
US8875306B2 (en) 2008-02-12 2014-10-28 Oracle International Corporation Customization restrictions for multi-layer XML customization
US8966465B2 (en) 2008-02-12 2015-02-24 Oracle International Corporation Customization creation and update for multi-layer XML customization
US8782604B2 (en) 2008-04-11 2014-07-15 Oracle International Corporation Sandbox support for metadata in running applications
US20090307669A1 (en) * 2008-06-06 2009-12-10 Garst Jr Gerald Blaine Memory management for closures
US8667031B2 (en) 2008-06-13 2014-03-04 Oracle International Corporation Reuse of shared metadata across applications via URL protocol
US8996658B2 (en) 2008-09-03 2015-03-31 Oracle International Corporation System and method for integration of browser-based thin client applications within desktop rich client architecture
US8799319B2 (en) 2008-09-19 2014-08-05 Oracle International Corporation System and method for meta-data driven, semi-automated generation of web services based on existing applications
US9122520B2 (en) 2008-09-17 2015-09-01 Oracle International Corporation Generic wait service: pausing a BPEL process
US8875115B2 (en) * 2008-11-29 2014-10-28 International Business Machines Corporation Type merging technique to reduce class loading during Java verification
US8856737B2 (en) * 2009-11-18 2014-10-07 Oracle International Corporation Techniques for displaying customizations for composite applications
US8667153B2 (en) * 2010-07-07 2014-03-04 Red Hat Israel, Ltd. Using a virtual network interface to obtain access to resources
US8954942B2 (en) 2011-09-30 2015-02-10 Oracle International Corporation Optimizations using a BPEL compiler
US9027006B2 (en) 2012-08-09 2015-05-05 Apple Inc. Value profiling for code optimization
US10261764B2 (en) * 2014-05-13 2019-04-16 Oracle International Corporation Handling value types
US9749409B2 (en) * 2015-02-04 2017-08-29 International Business Machines Corporation Predictive data replication and acceleration
US10503787B2 (en) 2015-09-30 2019-12-10 Oracle International Corporation Sharing common metadata in multi-tenant environment
CN111737166B (zh) * 2020-05-15 2023-04-07 完美世界(北京)软件科技发展有限公司 数据对象的处理方法、装置及设备

Family Cites Families (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CA2098459A1 (en) 1992-06-15 1993-12-16 James L. Adcock Computer method and system for conservative-stack and generational heap garbage collection
US6047125A (en) * 1997-10-01 2000-04-04 Sun Microsystems, Inc. Garbage collection system for improved use of memory by removal of reference conflicts
US6260190B1 (en) * 1998-08-11 2001-07-10 Hewlett-Packard Company Unified compiler framework for control and data speculation with recovery code
US6327701B2 (en) * 1998-09-15 2001-12-04 Sun Microsystems, Inc. Method and apparatus for finding bugs related to garbage collection in a virtual machine

Also Published As

Publication number Publication date
US6442751B1 (en) 2002-08-27

Similar Documents

Publication Publication Date Title
DE19959758A1 (de) Bestimmung der Art und der Genauigkeit von lokalen Variablen bei vorhandenen Subroutinen
DE69738101T2 (de) Verwaltung des Zugangs zu Objekten mit Hilfe von Referenzen mit drei Zuständen
DE69836796T2 (de) Datenverarbeiter mit lokalisierter gedächtnisreklamierung
DE60002295T2 (de) Aufwandslose ausnahmebehandlung
DE69309486T2 (de) Mehrsprachiges computerprogramm
DE3853981T2 (de) Veränderliche Bereiche anwendendes Verfahren und Gerät zum Stützen der symbolischen Fehlersuche von optimierten Kodes.
DE69909945T2 (de) Verfahren und Anordnung zur Korrelation von Profildaten dynamisch erzeugt durch ein optimiertes ausführbares Programm mit Quellcodeanweisungen
DE68921775T2 (de) Prozessorssimulation.
DE69909021T2 (de) Dynamische Speicherrückforderung ohne Compiler- oder Programmverbinderunterstützung
DE60130840T2 (de) Vorrichtung und Verfahren zur Katalogisierung von symbolischen Daten zur Verwendung bei der Leistungsanalyse von Computerprogrammen
DE69932371T2 (de) Verschiebbare Instrumentationskennzeichen für die Prüfung und die Fehlerbeseitigung eines Computerprogramms
DE60032685T2 (de) Speicherrückforderungsverfahren
DE69924857T2 (de) Programm-kode-umwandlung
DE69533530T2 (de) Verfahren und System zur dynamischen Aggregation von Objekten
DE69031538T2 (de) System und Verfahren zur Sammlung von Softwareanwendungsereignissen
DE60006410T2 (de) Verfahren und system zum verteilen von objektorientierten rechnerprogrammen
DE3842289C2 (de) Verfahren zur Entwicklung von Programmen für ein verteiltes Datenverarbeitungssystem
DE10358834A1 (de) Verfahren, Einrichtung und Computer-Produkt zum Analysieren von Binärdaten
DE19922796A1 (de) Bestimmen der tatsächlichen Klasse eines Objekts zur Laufzeit
DE69932964T2 (de) Verfahren, System und Rechnerprogrammprodukt zur Initialisierung einer Datenstruktur beim ersten Gebrauch
DE60103521T2 (de) Vorladen von klassen in einer datenverarbeitungseinrichtung ohne virtueller speicherverwalter
DE10300545A1 (de) Vorrichtung, Verfahren, Speichermedium und Datenstruktur zur Kennzeichnung und Speicherung von Daten
DE69905776T2 (de) Sprachenverarbeitungsverfahren mit geringem Aufwand und Speicherbedarf bei der Profildatensammlung
DE19600428C2 (de) Vorrichtung und Verfahren zum Reduzieren eines durch einen Prozeß verwendeten tatsächlichen Arbeitssatzes eines Prozesses in einem Computersystem mit virtuellem Speicher
DE69931685T2 (de) Verfahren und Gerät zum Implementieren von schnellen Subclass- und Subtyp-Überprüfungen

Legal Events

Date Code Title Description
OP8 Request for examination as to paragraph 44 patent law
8131 Rejection