-
Die
Erfindung betrifft allgemein das technische Gebiet der Speicherverwaltung
bei der Ausführung
eines Programms durch einen tragbaren Datenträger, der einen Prozessor aufweist.
Ein derartiger tragbarer Datenträger
kann insbesondere eine Chipkarte in unterschiedlichen Bauformen
oder ein Chipmodul sein. Spezieller betrifft die Erfindung die Nutzung
zweier unterschiedlicher Speicherbereiche des Datenträgers, um
während
der Programmausführung erzeugte
Objekte zu speichern.
-
Bei
tragbaren Datenträgern
sind generell mehrere Speicherbereiche vorgesehen, die in unterschiedlichen
Speichertechnologien ausgeführt
sind. Typischerweise ist der Speicher in einen flüchtigen Schreib-/Lesespeicher
(RAM), einen nicht-flüchtigen beschreibbaren
Speicher (EEPROM) sowie einen maskenprogrammierten Festwertspeicher
(ROM) unterteilt. Ein Schreibvorgang in das RAM benötigt erheblich
weniger Zeit – z.B.
um den Faktor 30 weniger – als
ein Schreibvorgang in das EEPROM. Andererseits nimmt ein Bit im
RAM deutlich mehr Fläche
auf einem Halbleiterchip des Datenträgers ein als ein Bit im EEPROM,
so daß in
der Regel nur relativ wenig RAM vorgesehen ist. Es besteht daher
das Problem, das schnelle, aber knappe RAM möglichst gut und flexibel zu
nutzen.
-
Tragbare
Datenträger
mit komplexen Speicherverwaltungsfunktionen sind z.B. unter der
Marke Java CardTM bekannt. Das Dokument "Java CardTM 2.2 Runtime Environment (JCRE) Specification", Juni 2002, herausgegeben
von der Firma Sun Microsystems, Inc., Palo Alto, USA, im Internet
verfügbar
unter http://java.sun.com/products/javacard, beschreibt die in einer
Java Card bereitgestellte Umgebung zur Ausführung von Programmen (Java
Card Applets). In Kapitel 5 ist dargestellt, daß persistente Objekte typischerweise
im EEPROM des Datenträgers
gespeichert werden, während
transiente Objekte typischer weise im RAM angelegt werden. Aus Sicherheitsgründen ist
die Speicherung transienter Objekte im EEPROM nicht zulässig.
-
Bei
der gerade beschriebenen Speicherverwaltung einer Java Card werden
zur Erzeugung transienter Objekte spezielle Systemaufrufe verwendet, wie
sie z.B. auf den Seiten 81 – 85
des Dokuments "Java
CardTM 2.2 Application Programming Interface", Juni 2002, herausgegeben von der Firma
Sun Microsystems, Inc., Palo Alto, USA, verfügbar im Internet unter der
oben genannten Adresse, beschrieben sind. Dies schränkt den
Umfang ein, in dem transiente Objekte in der Praxis benutzt werden. Überdies
haben transiente Objekte als solche eine potenziell unbeschränkte Lebensdauer;
die Bezeichnung "transient" bezieht sich lediglich
auf die in den Objekten gespeicherten Daten. Die Nutzung transienter Objekte
bewirkt daher nur eine geringe Steigerung der Flexibilität bei der
Speicherverwaltung.
-
Die übliche und
empfohlene Praxis bei der Programmierung einer Java Card ist es,
alle Objekte, die während
der gesamten Lebensdauer eines Programms (Applet) benötigt werden,
bei der Installation des Programms statisch anzulegen. Dies geschieht in
einer Methode mit dem vorgegebenen Namen "install". Die genannte Praxis hat jedoch eine
wenig flexible und damit nicht optimale Speicherverwaltung zur Folge.
Wenn beispielsweise in einem Programm ein transientes Feld angelegt
wird, um temporäre
Daten für
kryptographische Operationen zu speichern, so ist der hierfür im RAM
statisch reservierte Speicherplatz für andere Programme in der Regel
verloren. Innerhalb des Programms hängt es von der Geschicklichkeit
des Programmierers ab, inwieweit solcher reservierter Speicherplatz
auch für
andere Aufgaben herangezogen wird. Es wäre deshalb wünschenswert,
die Nutzung des knappen Speicherplatzes im RAM zu verbessern und
die Speicherverwaltung zu automatisieren.
-
Die
Erfindung hat demgemäß die Aufgabe, die
Probleme des Standes der Technik zumindest zum Teil zu vermeiden
und eine Technik zur Speicherverwaltung bei einem tragbaren Datenträger bereitzustellen,
durch die die Nutzung eines effizient beschreibbaren Speicherbereichs – typischerweise
eines RAM-Speichers – verbessert
wird. Insbesondere soll durch die Erfindung eine flexible Nutzung
des RAM-Speichers ohne Aufwand für
den Programmierer ermöglicht
werden.
-
Erfindungsgemäß wird diese
Aufgabe ganz oder zum Teil gelöst
durch ein Verfahren gemäß Anspruch
1 zur Speicherverwaltung bei der Ausführung eines Programms, ein
Verfahren gemäß Anspruch
7 zum Umsetzen eines Quellprogramms, einen tragbaren Datenträger gemäß Anspruch
12 und ein Computerprogrammprodukt gemäß Anspruch 13. Die abhängigen Ansprüche betreffen
bevorzugte Ausgestaltungen der Erfindung.
-
Die
Erfindung beruht auf der Grundidee, bestimmte Objekte, die bei der
Ausführung
des Programms durch den tragbaren Datenträger erzeugt werden, automatisch
in einem effizient beschreibbaren Speicherbereich – z.B. im
RAM – anzulegen. Hierfür kommen
insbesondere solche Objekte in Frage, die nur eine kurze Lebenszeit
besitzen. Derartige Objekte werden im vorliegenden Dokument als "lokale Objekte" bezeichnet. Lokale
Objekte im Sinne der Erfindung können
z.B. exception-Objekte sein, wie sie beim Auftreten von Ausnahmen
(exceptions) erzeugt werden. Die Lebenszeit eines exception-Objekts endet, sobald
die entsprechende Ausnahme gefangen worden ist.
-
Durch
die Erfindung kann temporär
benötigter
Speicherplatz kurzzeitig und dynamisch – nämlich in Form eines lokalen
Objekts – zur
Verfügung
gestellt werden. Das lokale Objekt wird zum Teil oder vollständig im
RAM oder einem anderen effizient beschreibbaren Speicher angelegt.
Durch die automatische und dynamische Speicherverwaltung der Erfindung
wird dieser Speicher besonders gut genutzt. Dies erhöht die Leistungsfähigkeit
des Datenträgers sowohl
im Hinblick auf die Verarbeitungsgeschwindigkeit als auch im Hinblick
auf den für
die ausgeführten
Programme effektiv zur Verfügung
stehenden Speicherplatz.
-
Allgemein
ist die Lebenszeit eines Objekts dann beendet, wenn keine Referenzen
auf das Objekt mehr existieren, weil dann kein Zugriff auf das Objekt
mehr möglich
ist. Ein lokales Objekt kann insbesondere dadurch definiert sein,
daß keine
persistente Referenz auf das Objekt existiert. Als "persistente Referenz" soll hierbei eine
Referenz auf das Objekt verstanden werden, die persistent, z.B.
in einem Feld eines Objekts, einem statischen Feld oder einem Feld
eines Array, gespeichert ist. Sobald eine Referenz auf ein Objekt
in eines der genannten Felder eingeschrieben wird, kann das Objekt
kein lokales Objekt mehr sein. Nicht-persistente Referenzen auf
ein Objekt, die z.B. im Operandenstapel oder in einer lokalen Variablen
enthalten sind, beeinflussen die Einordnung eines Objekts als lokales
oder nicht-lokales Objekt dagegen nicht.
-
Die
Unterscheidung, ob ein Objekt als lokales oder als nicht-lokales
Objekt zu behandeln ist, kann zur Compilezeit des Programms oder
zur Laufzeit oder teils zur Compilezeit und teils zur Laufzeit erfolgen.
Bei einer Unterscheidung zur Laufzeit werden zumindest manche neu
erzeugten Objekte zunächst
im zweiten, effizient beschreibbaren Speicherbereich angelegt. Während der
weiteren Programmausführung
wird überwacht,
ob eine persistente Referenz auf das Objekt angelegt wird. Sobald
dies der Fall ist, kann das Objekt nicht länger als lokales Objekt behandelt
werden. Es wird dann in den ersten, nicht-flüchtigen Speicherbereich übertragen.
-
Bei
einer Unterscheidung zur Compilezeit analysiert der Compiler einen
Abschnitt des Quellprogramms, der die Erzeugung des Objekts beinhaltet,
daraufhin, ob eine persistente Referenz auf das Objekt angelegt
wird. In Abhängigkeit
vom Ergebnis der Analyse erzeugt der Compiler dann Programmcode,
der das Objekt im ersten oder – ganz
oder teilweise – im
zweiten Speicherbereich anlegt. Der Begriff "Compiler" soll in der Wortwahl des vorliegenden Dokuments
alle Programme umfassen, die automatische Umsetzvorgänge ausführen. So
sollen neben dem Java-Compiler im engeren Sinne z.B. auch Konverter
zur Erzeugung von CAP-Dateien (Card Application Files) und Optimierungsprogramme
als "Compiler" bezeichnet werden.
-
Eine
Quellprogrammanalyse zur Compilezeit kann in der Regel nur ein ungefähres Ergebnis
liefern. Darunter ist zu verstehen, daß zumindest eine der beiden
Klassifizierungen eines Objekts als lokal bzw. nicht-lokal mit einer
gewissen Unsicherheit behaftet ist. Es kann deshalb vorgesehen sein,
daß nur sicher
als lokal erkannte Objekte im zweiten Speicherbereich angelegt werden,
während
alle anderen Objekte im ersten Speicherbereich angelegt werden.
In einer Ausführungsalternative
werden dagegen nur die sicher als nicht-lokal erkannten Objekte
im ersten Speicherbereich angelegt, während alle anderen Objekte
im zweiten Speicherbereich angelegt werden. Zumindest für Objekte,
die nicht sicher als lokal klassifiziert werden konnten, wird dann
zusätzlich
die oben beschriebene Laufzeitüberwachung durchgeführt. In
manchen Ausführungsformen
sind Compilerdirektiven (pragmas) vorgesehen, mit denen Objekte
als lokal oder nicht-lokal gekennzeichnet werden können.
-
In
bevorzugten Ausgestaltungen werden – wahlweise zur Laufzeit oder
zur Compilezeit – einfache
Kriterien angewendet, um zu bestimmen, ob Objekte im ersten oder
zunächst
im zweiten Speicherbereich angelegt werden sollen. So kann z.B.
vorgesehen sein, daß Objekte,
die durch die install-Methode des Programms erzeugt werden, im ersten
Speicherbereich angelegt werden. In unterschiedlichen Ausführungsformen
können
entweder alle anderen Objekte zunächst im zweiten Speicherbereich
angelegt werden oder nur einzelne Arten von Objekten. Solche Objektarten
können
z.B. exception-Objekte oder Objekte sein, die nur temporär für kryptographische Operationen
benötigt
werden.
-
Die
Lebensdauer eines lokalen Objekts endet in der Regel mit der Beendigung – entweder durch
einen Rücksprung
(return) oder durch eine Ausnahme (exception) – der Methode, in der das lokale
Objekt erzeugt worden ist, weil zu diesem Zeitpunkt die möglicherweise
existierenden lokalen Referenzen auf das Objekt gelöscht werden.
Der gegebenenfalls im zweiten Speicherbereich für das Objekt noch benötigte Speicherplatz
kann dann freigegeben werden. Eine Ausnahme von der gerade genannten Regel
gilt dann, wenn das Objekt als Rückgabeparameter
der Methode, die das Objekt erzeugt hat, verwendet wird. Die aufrufende
Methode erhält
in diesem Fall eine Referenz auf das Objekt, so daß das Objekt
zumindest bis zur Beendigung dieser Methode nicht gelöscht werden
darf.
-
Umfreigegebenen
Speicherplatz im zweiten Speicherbereich zur Anlage neuer Objekte
nutzen zu können,
ist in manchen Ausführungsformen
eine Speicherbereinigung (garbage collection) vorgesehen. Diese
verursacht jedoch Zeitaufwand während der
Programmausführung
und erhöht
die Komplexität der
Laufzeitumgebung. Bevorzugt wird daher ein besonders einfaches Verfahren
eingesetzt, bei dem ein Füllstandszeiger
die Belegung des zweiten Speicherbereichs angibt. Bei der Beendigung
einer Methode wird der Füllstandszeiger
in der Regel auf den Stand zurückgesetzt,
den er beim Aufruf dieser Methode hatte. Eine Ausnahme von dieser
Regel wird in bevorzugten Ausführungsformen
lediglich dann gemacht, wenn der durch die Rücksetzung freigegebene Abschnitt
des zweiten Speicherbereichs ein Objekt enthält, das als Rückgabeparameter
der Methode verwendet wird.
-
Um
zu gewährleisten,
daß ein
Objekt bei Bedarf vom zweiten in den ersten Speicherbereich übertragen
werden kann, wird vorzugsweise schon beim Anlegen des Objekts im
zweiten Speicherbereich überprüft, ob auch
im ersten Speicherbereich genügend
Platz für
das Objekt vorhanden ist. Bevorzugt wird auch während der weiteren Programmausführung beim
Anlegen neuer Objekte sichergestellt, daß im ersten Speicherbereich
stets genügend
Platz für eine
eventuell erforderliche Übertragung
von Objekten ist.
-
Der
erste Speicherbereich befindet sich in bevorzugten Ausgestaltungen
in einem EEPROM oder einem sonstigen nicht-flüchtigen beschreibbaren Speicher
des Datenträgers,
während
der zweite Speicherbereich in einem RAM oder einem sonstigen effizient
beschreibbaren Speicher angeordnet ist. Der zweite Speicherbereich
kann insbesondere als lokaler Heap und/oder in einem Stapelspeicher
ausgebildet sein. Die Speicherung in einem Stapelspeicher ist insbesondere
für Objekte
vorteilhaft, die schon zur Compilezeit als lokale Objekte identifiziert
wurden.
-
Das
erfindungsgemäße Computerprogrammprodukt
weist Programmbefehle auf, um das erfindungsgemäße Umsetzungsverfahren zu implementieren.
Ein derartiges Computerprogrammprodukt kann ein körperliches
Medium sein, beispielsweise ein Halbleiterspeicher oder eine Diskette
oder eine CD-ROM, auf dem ein Programm zur Ausführung eines erfindungsgemäßen Verfahrens
gespeichert ist. Das Computerprogrammprodukt kann jedoch auch ein
nicht-körperliches
Medium sein, beispielsweise ein über
ein Computernetzwerk übermitteltes
Signal. Bevorzugt ist das Computerprogrammprodukt ein Compiler,
der zur Ausführung
durch einen üblichen
Arbeitsplatzrechner vorgesehen ist, um Programme für tragbare
Datenträger
zu erzeugen.
-
In
bevorzugten Ausgestaltungen weisen der Datenträger und/oder das Computerprogrammprodukt
Merkmale auf, die den oben beschriebenen und/oder den in den abhängigen Verfahrensansprüchen genannten
Merkmalen entsprechen.
-
Weitere
Merkmale, Vorteile und Aufgaben der Erfindung gehen aus der folgenden
genauen Beschreibung eines Ausführungsbeispiels
und mehrerer Ausführungsalternativen
hervor. Es wird auf die schematischen Zeichnungen verwiesen, in
denen zeigen:
-
1 ein Blockdiagramm eines
tragbaren Datenträgers
nach einem Ausführungsbeispiel
der Erfindung,
-
2 ein Flußdiagramm
eines beim Anlegen eines neuen Objekts ausgeführten Verfahrens,
-
3 eine beispielhafte Darstellung
der Speicherbelegung in einem Stapelspeicher und einem lokalen Heap
während
der Programmausführung,
-
4 ein Flußdiagramm
eines bei der Beendigung einer Methode ausgeführten Verfahrens, und
-
5 eine schematische Darstellung
der Umsetzung eines Quellprogramms in ein ausführbares Programm.
-
Der
in 1 dargestellte Datenträger 10 ist im
vorliegenden Ausführungsbeispiel
als Chipkarte gemäß dem Java-Card-Standard
ausgestaltet. Der Datenträger 10 weist
auf einem einzigen Halbleiterchip einen Prozessor 12, mehrere
in unterschiedlichen Technologien ausgestaltete Speicherfelder und eine
Schnittstellenschaltung 14 zur kontaktlosen oder kontaktgebundenen
Kommunikation auf. Im vorliegenden Ausführungsbeispiel sind als Speicherfelder
ein Festwertspeicher 16, ein nicht-flüchtiger beschreibbarer Speicher 18 und
ein Schreib-/Lese-Speicher 20 vorgesehen. Der Festwertspeicher 16 ist
als maskenprogrammiertes ROM, der nicht-flüchtige Speicher 18 als
elektrisch lösch-
und programmierbares EEPROM und der Schreib-/Lese-Speicher 20 als
RAM ausgestaltet. Schreibvorgänge
in den nicht-flüchtigen
Speicher 18 sind relativ aufwendig und benötigen beispielsweise
die dreißigfache
Zeit von Schreibvorgängen
in den Schreib-/Lese-Speicher 20.
-
Im
Festwertspeicher 16 – und
zum Teil auch im nicht-flüchtigen
Speicher 18 – sind
Systemprogramme 22 enthalten, die zum Betrieb des Datenträgers 10 benötigt werden.
In an sich bekannter Weise umfassen die Systemprogramme 22 ein
Betriebssystem 24 sowie Programmcode 26 zur Implementierung
einer virtuellen Maschine 26, die im vorliegenden Ausführungsbeispiel
als JCVM (Java Card Virtual Machine) ausgestaltet ist. Ferner ist
eine Klassenbibliothek 28 vorgesehen, die Anwendungsprogrammierschnittstellen
bereitstellt. Ein Programm 30, das als Java Card Applet
ausgebildet ist, wurde bei der Initialisierung des Datenträgers 10 in
den nicht-flüchtigen
Speicher 18 geladen; in Ausführungsalternativen kann sich
das Programm 30 ganz oder teilweise im Festwertspeicher 16 befinden.
Während
in 1 nur ein einziges
Programm 30 gezeigt ist, können weitere Programme zur
Ausführung
durch den Prozessor 12 des tragbaren Datenträgers 10 vorgesehen
sein.
-
Das
Programm 30 weist mehrere Methoden 30.1, 30.2, 30.3, 30.4 auf,
die im folgenden zusammenfassend mit 30.x bezeichnet werden.
In an sich bekannter Weise umfassen die Methoden 30.x eine mit "install" bezeichnete Methode
zur Installation des Programms 30, eine mit "process" bezeichnete Methode
zur Bearbeitung eingehender Datenpakete und gegebenenfalls Methoden "select" und "deselect", die bei einem Wechsel
zwischen mehreren Programmen des Datenträgers 10 aufgerufen
werden.
-
Ein
im Schreib-/Lese-Speicher 20 befindlicher Stapelspeicher 32 nimmt
während
der Programmausführung
Operanden, Rücksprungadressen,
lokale Variablen und sonstige Datenwerte auf. Der freie Bereich
des Stapelspeichers 32 ist in 1 durch eine Schraffur veranschaulicht.
-
Im
nicht-flüchtigen
Speicher 18 ist ein erster Speicherbereich 34 reserviert,
der in an sich bekannter Weise als persistenter Heap (Haufen oder
Halde) ausgebildet ist. Gemäß der üblichen
Java-Card-Architektur würden
in diesem persistenten Heap alle Objekte, statischen Datenfelder
und nicht-transienten Arrays angelegt werden. Im vorliegenden Ausführungsbeispiel
wird dagegen der persistente Heap nur selektiv eingesetzt. Lokale
Objekte, die voraussichtlich nur eine kurze Lebensdauer besitzen
und auf die keine persistenten Referenzen verweisen, werden nicht
im ersten Speicherbereich 34, sondern in einem zweiten
Speicherbereich 36 im Schreib-/Lese-Speicher 20 angelegt.
Der zweite Speicherbereich 36 wird auch als lokaler Heap
bezeichnet, weil er ähnlich
wie der persistente Heap zur Speicherung von Objekten dient.
-
Zur
Veranschaulichung der gerade beschriebenen Verhältnisse zeigt 1 beispielhaft zwei im ersten Speicherbereich 34 angelegte
Objekte 38, 40, die jeweils mehrere Datenfelder
aufweisen. Eines der Datenfelder des ersten Objekts 38 enthält eine
Referenz 42 auf das zweite Objekt 40. Die Referenz 42 wird,
da sie in einem persistent gespeicherten Datenfeld enthalten ist,
auch als "persistente
Referenz" bezeichnet.
Das zweite Objekt 40 ist kein lokales, sondern ein persistentes
Objekt, da die persistente Referenz 42 darauf verweist.
Im zweiten Speicherbereich 36 ist beispielhaft ein lokales
Objekt 44 gezeigt. Eine lokale Referenz 46, die
beispielsweise in einer im Stapelspeicher 32 angelegten
lokalen Variablen enthalten ist, verweist auf das lokale Objekt 44.
Ein weiterer Wert im Stapelspeicher 32 gibt als Füllstandszeiger 48 den
Beginn des freien Speichers im zweiten Speicherbereich 36 an;
dieser freie Speicher ist in 1 schraffiert
dargestellt.
-
Wenn
bei der Programmausführung
durch den Datenträger 10 die
Anlage eines neuen Objekts durch den Befehl "NEW" angefordert
wird, wird der in 2 dargestellte
Ablauf ausgeführt.
In Schritt 50 wird zunächst
geprüft,
ob im ersten Speicherbereich 34 genügend Speicherplatz zur Anlage
des neuen Objekts frei ist. Ist zu wenig Speicherplatz vorhanden,
so wird die Objekterzeugung mit einer Fehlermeldung abgebrochen.
Die Überprüfung in
Schritt 50 findet im vorliegenden Ausführungsbeispiel unabhängig von
der Art des anzulegenden Objekts statt, um sicherzustellen, daß auch ein
zunächst
im zweiten Speicherbereich 36 angelegtes Objekt jederzeit in
den ersten Speicherbereich 34 übertragen werden kann.
-
Im
vorliegenden Ausführungsbeispiel
ist vorgesehen, daß Objekte,
die durch die Installationsmethode "install" des Programms 30 angelegt
werden, stets als persistente Objekte betrachtet und daher in den
ersten Speicherbereich 34 aufgenommen werden. In Schritt 52 wird
daher abgefragt, ob gerade die Programminstallation stattfindet.
Ist dies der Fall, so wird das neue Objekt in Schritt 54 als
persistentes Objekt im ersten Speicherbereich 34 erzeugt.
Der in Schritt 54 ausgeführte Erzeugungsvorgang entspricht
der bei einer üblichen
Java Card ausgeführten Anlage
eines Objekts im persistenten Heap.
-
Wenn
in Schritt 52 festgestellt wurde, daß sich die Programmausführung außerhalb
der Installationsmethode befindet, wird das neu anzulegende Objekt
im vorliegenden Ausführungsbeispiel
zunächst
als lokales Objekt angesehen. Es wird dann im zweiten Speicherbereich 36 – dem lokalen
Heap – angelegt,
sofern dort genügend
Speicherplatz frei ist. Letzteres wird in Schritt 56 überprüft. Ist
genügend Speicherplatz
im lokalen Heap vorhanden, wird das Objekt dort in Schritt 58 an
der nächsten
freien Stelle – unmittelbar
anschließend
an den bisher genutzten Bereich – angelegt, und der Füllstandszeiger 48 wird entsprechend
aktualisiert. Ist der lokale Heap dagegen bereits zu voll, so erfolgt
in Schritt 54 der übliche Objektanlagevorgang
im ersten Speicherbereich 34, in dem ja – wie in
Schritt 50 überprüft – noch genügend freier
Speicherplatz verfügbar
ist.
-
Während der
weiteren Ausführung
des Programms 30 durch den Datenträger 10 wird bei jeder Erzeugung
oder Änderung
einer persistenten Referenz überprüft, ob die
Referenz auf ein im zweiten Speicherbereich 36 befindliches
Objekt verweist. Ist dies der Fall, so wird das Objekt aus dem zweiten Speicherbereich 36 in
den ersten Speicherbereich 34 übertragen. Wegen der Abfrage
in Schritt 50 ist sichergestellt, daß dies jederzeit möglich ist.
-
Im
vorliegenden Ausführungsbeispiel
ist der zweite Speicherbereich 36 ähnlich wie ein Stapelspeicher
organisiert, um nach Beendigung einer Methode 30.x den
Speicherplatz, der durch die in dieser Methode 30.x erzeugten
lokalen Objekte belegt wird, auf einfache Weise freigeben zu können. Zur
Erläuterung
dieses Vorgangs zeigt 3 eine
beispielhafte Belegung des Stapelspeichers 32 mit mehreren
Stapelrahmen (stack frames) 60.1, 60.2, 60.3.
In an sich bekannter Weise wird beim Aufruf jeder Methode 30.x ein
neuer Stapelrahmen 60.x angelegt, der bei Beendigung der
Methode 30.x wieder gelöscht wird. Der
Stapelrahmen 60.x enthält
eine Rücksprungadresse
zur aufrufenden Methode, Verwaltungs- und Sicherungsdaten sowie
gegebenenfalls lokale Variablen der aufgerufenen Methode.
-
Im
vorliegenden Ausführungsbeispiel
weist jeder Stapelrahmen 60.x ferner ein Füllstandsfeld 62.x auf,
das während
der Ausführung
der entsprechenden Methode 30.x den Füllstandszeiger 48 enthält. In der
beispielhaften Darstellung von 3 enthält also
das Füllstandsfeld 62.3 den
aktuellen Füllstandszeiger 48,
und das Füllstandsfeld 62.2 enthält denjenigen
Füllstand,
der beim Aufruf der dem Stapelrahmen 60.3 entsprechenden
Methode gegolten hat. Der Abschnitt 64.3 bezeichnet denjenigen
Abschnitt im lokalen Heap, der von der aktuell ausgeführten Methode
seit ihrem Aufruf neu belegt wurde. Die Abschnitte 64.1 und 64.2 im
lokalen Heap wurden von denjenigen Methoden, bei deren Aufruf die Speicherrahmen 60.1 bzw. 60.2 angelegt
wurden, gefüllt.
-
Im
vorliegend beschriebenen Ausführungsbeispiel
ist vorgesehen, daß bei
der Beendigung einer Methode der durch diese Methode belegte Platz im
zweiten Speicherbereich 36 in der Regel vollständig freigegeben
wird. Dies geschieht ohne weiteres Zutun dadurch, daß bei der
Beendigung einer Methode der entsprechende Stapelrahmen 60.x – einschließlich des
darin enthaltenen Füllstandsfeldes 62.x – verworfen
wird, und daß das
Füllstandsfeld 62.(x – 1) des
nächstälteren Stapelrahmens 62.(x – 1) mit
seiner dort gespeicherten Belegung als neuer Füllstandszeiger 48 verwendet
wird. So wird beispielsweise nach der Beendigung derjenigen Methode,
bei deren Aufruf der Stapelrahmen 60.3 angelegt wurde,
der Inhalt des Füllstandsfeldes 62.2 als
neuer Füllstandszeiger 48 verwendet,
so daß der
gesamte Speicherabschnitt 64.3 freigegeben wird.
-
Eine
Ausnahme von der im vorherigen Absatz genannten Regel ergibt sich
dann, wenn die gerade beendete Methode eine Referenz auf ein von
ihr im zweiten Speicherbereich 36 angelegtes lokales Objekt
an die aufrufende Methode zurückgibt.
In diesem Fall wird der Inhalt des aktuellen Füllstandsfeldes 62.x in
den nächstälteren Stapelrahmen 60.(x – 1) kopiert,
um ein Überschreiben
des lokalen Objekts zu verhindern. Wenn beispielsweise bei der Speicherbelegung
von 3 die Methode, die
den Speicherrahmen 60.3 angelegt hat, einen Verweis auf
ein im Speicherbereich 64.3 befindliches Objekt zurückgibt,
wird der Wert des Füllstandsfeldes 62.3 in das
Füllstandsfeld 62.2 des
vorhergehenden Stapelrahmens 60.2 kopiert.
-
Das
gerade geschilderte Verfahren bei der Beendigung einer Methode ist
in 4 nochmals veranschaulicht.
In Abhängigkeit
vom Ergebnis des Schrittes 70 wird entweder das Füllstandsfeld 62.(x – 1) des
vorhergehenden Stapelrahmens 60.(x – 1) reaktiviert (Schritt 72),
oder es wird der Wert des aktuellen Füllstandszeigers 48 in
den vorhergehenden Stapelrahmen 60.(x – 1) übernommen.
-
In 5 ist der an sich bekannte Übersetzungsvorgang
eines Java-Quellprogramms 80 durch einen Compiler 82 in
eine CAP-Datei (Card Application File) 84 dargestellt.
Die CAP-Datei 84 wird ihrerseits von einem Ladeprogramm 86 – z.B. bei
der Initialisierung des Datenträgers 10 – als Programm 30 in
den Datenträger 10 geladen.
Der Compiler 82 weist im hier beschriebenen Ausführungsbeispiel
neben dem eigentlichen Compiliermodul zur Übersetzung des Quellprogramms 80 in
Bytecode ferner einen Konverter auf, der diverse Korrektheitsüberprüfungen vornimmt
und der auch als "Off-Card
Virtual Machine" bezeichnet
wird.
-
Bei
dem bislang beschriebenen Verfahren wurde zur Entscheidung, ob ein
neu anzulegendes Objekt im ersten oder im zweiten Speicherbereich 34, 36 erzeugt
werden sollte, zur Laufzeit in Schritt 52 eine einfache
Abfrage durchgeführt.
Weitere Laufzeitüberprüfungen erfolgten
bei der Anlage und bei Aktualisierungen von persistenten Referenzen.
In Ausführungsalternativen
ist dagegen vorgesehen, die genannten Überprüfungen ganz oder zum Teil auf
die Ebene des Compilers 82 vorzuverlagern.
-
Durch
abstrakte Analyse des Quellprogramms 80 oder eines Zwischencodes
kann der Compiler 82 Informationen gewinnen, ob ein während der
späteren
Programmausführung
neu anzulegendes Objekt als lokales oder als nicht-lokales Objekt betrachtet
werden soll. Je nach dem Ergebnis dieser Analyse erzeugt der Compiler 82 dann
Programmcode, der entweder die Anlage des Objekts im ersten Speicherbereich 34 oder
im zweiten Speicherbereich 36 bewirkt. In Ausführungsalternativen
werden Objekte, die zur Compilezeit sicher als lokal erkannt wurden,
wie lokale Variablen im Stapelspeicher 32 angelegt. Je
nachdem, ob zusätzlich
ein lokaler Heap im Schreib-/Lese-Speicher 20 vorgesehen
ist, bildet in diesen Ausgestaltungen der Stapelspeicher 32 den
gesamten zweiten Speicherbereich 36 oder einen Teil des
zweiten Speicherbereichs 36.
-
In
der Regel wird das Quellprogramm 80 Befehle zur Erzeugung
von Objekten erhalten, die zur Compilezeit nicht eindeutig als lokale
oder nicht-lokale Objekte klassifiziert werden können. Solche Objekte können entweder
sogleich im ersten Speicherbereich 34 angelegt werden,
oder sie können
auf die oben beschriebene Weise zunächst als lokale Objekte im
zweiten Speicherbereich 36 angelegt und nur bei Bedarf
in den ersten Speicherbereich 34 übertragen werden.