Table Of ContentMichael Gloger
Implementierung funktionaler Programmiersprachen
Michael Gloger
Implementierung
funktiona er
Programmier.
sprachen
Codegenerierung, Speicherverwaltung und
Testsysteme für Sprachen mit verzögerter
Auswertung
r[)il DeutscherUniversitätsVerlag
!:\{J
~
GABLER ·VIEWEG ·WESTDEUTSCHER VERLAG
Die Deutsche Bibliothek - ClP-Einheitsaufnahme
Gloger, Michael:
Implementierung funktionaler Programmiersprachen:
Codegenerierung, Speicherverwaltung und Testsysteme für
Sprachen mit verzögerter Auswertung / Michael Gloger. -
Wiesbaden: Dt. Univ.-Verl., 1993
(DUV : Informatik)
Zug I. : Darmstadt, Te chn. Hochsch., Diss. 1992
ISBN 978-3-8244-2037-7 ISBN 978-3-322-91022-6 (eBook)
DOI 10.1007/978-3-322-91022-6
017
Der Deutsche Universitäts-Verlag ist ein Untemehmen der
Verlagsgruppe Bertelsmann Intemational.
© Deutscher Universitäts-Verlag GmbH, Wiesbaden 1993
Das Werk einschließlich aller seiner Teile ist urheberrechtlich ge
schützt. Jede Verwertung außerhalb der engen Grenzen .des Ur
heberrechtsgesetzes ist ohne Zustimmung des Verlags unzulässig
und strafbar. Das gilt insbesondere für Vervielfältigungen, Über
setzungen, Mikroverfilmungen und die Einspeicherung und Verar
beitung in elektronischen Systemen.
Gedruckt auf chlorarm gebleichtem und säurefreiem Papier
ISBN 978-3-8244-2037-7
Kurzfassung
In den letzten Jahren war die Entwicklung neuer funktionaler Programmierspra
chen das Ziel vieler Forschungsprojekte. Aufgrund der vielfältigen Abstrakti
onsmöglichkeiten, sind Programme in funktionalen Sprachen leichter zu schrei
ben, leichter zu verstehen und leichter zu ändern als Programme in prozeduralen
Sprachen. In Sprachen mit verzögerter Auswertung (lazy evaluation, normalor
der reduction) wird ein Ausdruck erst ausgewertet, wenn sicher ist, daß der Wert
des Ausdrucks zur Berechnung des Programmergebnisses benötigt wird. Diese
Auswertungsstrategie erweitert die Ausdrucksmöglichkeiten einer funktionalen
Sprache erheblich: Sie ermöglicht neue Programmier-und Strukturierungstech
niken und verbessert die Wiederverwendbarkeit von Software. Die hinzuge
wonnene Flexibilität bei der Programmierung erschwert jedoch die effiziente
Implementierung solcher Sprachen, da für einen großen Teil der Ausdrücke ei
nes Programms erst zur Laufzeit festgestellt werden kann, ob sie zur Berechnung
des Gesamtergebnisses ausgewertet werden müssen. Eine weitere Schwierigkeit
ergibt sich aus der verzögerten Auswertung bei der Entwicklung von Testsyste
men, da dem Programmierer die erst zur Laufzeit festgelegte Reihenfolge der
Auswertung von Teilausdrücken nachvollziehbar dargestellt werden muß.
Das SAMPAE-System ist die Implementierung der an der TH-Darmstadt neu
entwickelten gleichnamigen Sprache. SAMPAE ist eine moderne funktionale
Sprache mit nicht strikten Funktionen und Datenkonstruktoren, einem einfa
chen Modulkonzept und einem mächtigen polymorphen Typsystem, das sowohl
rekursive Typen als auch benutzerdefinierbare Überladungen erlaubt. Für diese
Sprache wurde eine komfortable Programmierumgebung entwickelt. Die vor
liegende Arbeit beschreibt die bei der Implementierung der Ausführungskom
ponente des SAMPAE-Entwicklungssystems gewonnenen Erkenntnisse anhand
eines Entwurfs einer Implementierung einer funktionalen Mini-Sprache.
Der erste Teil 4er Arbeit, befaßt sich mit der Entwicklung eines Übersetzers
für diese Mini-Sprache. Im Gegensatz zu den sonst üblichen abstrakten Maschi
nen, die auf einem Laufzeitkeller basieren, wird in dieser Arbeit eine abstrakte
Registermaschine mit einer "tagged" Speicherarchitektur als Zwischensprache
benutzt. Ausgangspunkt für diese Entwicklung waren die Erfahrungen mit der
SAM PA E-Implementierung, die wie die meisten anderen Übersetzer für funk
tionale Sprachen, auf einer virtuellen Kellermaschine beruht. Da die Architek-
vi
tur dieser Maschine sehr von der Architektur moderner Prozessoren abweicht,
kann effizienter Code mit Hilfe dieses Maschinenmodells nur mit großem Auf
wand generiert werden. Insbesondere ist dieses Maschinenmodell ungeeignet,
um die in dieser Arbeit beschriebenen Optimierungstechniken zu spezifizieren
und implementieren, da dazu sowohl die Kenntnis der Quellsprache als auch der
Zielarchitektur notwendig ist.
Anhand der Übersetzung des Codes der virtuellen Registermaschine in
die Maschinensprache eines weitverbreiteten modernen RISC-Prozessors, dem
SPARC-Prozessor, wird gezeigt, daß auch prozessorspezifische Optimierungen
durch Transformationen des virtuellen Maschinencodes ausgedrückt werden
können. Daraus folgt, daß selbst zur Spezifikation maschinenabhängiger Op
timierungen, kein weiterer Wechsel der Abstraktionsebenen notwendig ist.
Die Hauptursache der Ineffizienz von Sprachen mit verzögerter Auswertung
gegenüber strikten Sprachen ist in der hohen Anzahl der zusätzlichen Spei
cherzugriffe begründet, die durch die verzögerte Auswertung verursacht wer
den. Es werden Techniken vorgestellt, die den Speicherplatzbedarf zur Dar
stellung unausgewerteter Teilausdrücke und die Anzahl der Speicherzugriffe zur
dynamischen Überprüfung des Auswertungszustands und zur Auswertung dieser
Ausdrücke minimiert.
Ein einfacher generationsbasierter Algorithmus zur Speicher bereinigung
wird im zweiten Teil der Arbeit entwickelt. Es wird gezeigt, daß trotz der
großen Zahl von Überschreibungen von Haldenobjekten, die durch die verzögerte
Auswertung verursacht werden, die besonders effizienten generationsbasierten
Algorithmen zur Speicherbereinigung verwendet werden können. Der in dieser
Arbeit vorgestellte Algorithmus verwendet eine neue Methode zur Verwaltung
von überschreibbaren Haldenobjekten, die überhaupt erst eine sinnvolle An
wendung des Generationenprinzips für die Speicherfreigabe bei Sprachen mit
verzögerter Auswertung zuläßt. Es wird empirisch nachgewiesen, daß der gene
rationsbasierte Algorithmus in vielen Fällen wesentlich effizienter als ein einfa
cher Two-Space-Copy-Collector arbeitet.
Der letzte Teil der Arbeit ist dem Testen gewidmet. Das Testen nicht strikter
funktionaler Programme wird erschwert durch die (praktisch) nicht vorhersag
bare Reihenfolge von Reduktionsschritten, da diese zum großen Teile erst zur
Laufzeit abhängig von den Eingabedaten bestimmt wird. Zur Verfolgung von
Auswertungsschritten wird für über Patterns definierte Funktionen ein Box
Modell vorgeschlagen und eine auf diesem Modell basierende Implementierung
eines Testsystems skizziert.
Inhaltsverzeichnis
1 Projekt geschichte und Überblick 1
1.1 Das SAMP>.E Projekt ..... . 1
l.2 Die funktionale Sprache SAM P> .E . 2
l.3 Die SAMP>.E Programmierumgebung . 2
1.4 Die Ausführung von SAMP>.E Programmen 3
l.5 Übersetzer-Architektur und Maschinenmodelle 4
l.6 Aufbau dieser Arbeit .............. . 6
2 Einiührung 9
2.1 MS - Eine einfache funktionale Sprache 9
2.2 Verzögerte Auswertung und Striktheitsanalyse . 14
2.3 Eigenschaften moderner RISC Rechner . . . . . 17
2.4 Prinzipielle Techniken der MS Implementierung. 20
2.4.1 Polymorphismus ............. . 21
2.4.2 Automatische Speicherverwaltung und Struktur von Spei-
cherzellen . . . . . . . . 23
2.4.3 Verzögerte Auswertung ... 29
2.4.4 Funktionen höherer Ordnung 40
3 Übersetzung von Sprachen mit verzögerter Auswertung 47
3.1 Phaseneinteilung des Übersetzers . . 47
3.2 Die abstrakte Registermaschine RM 49
3.3 Die abstrakte Syntax von MS 59
3.4 Suspensionsanalyse 62
3.5 RM-Übersetzer . . 70
3.5.1 RM-Codegeneratoren -die Basis der Übersetzerspezifikation 70
3.5.2 Codegenerator-Kombinatoren................ 72
Vlll INHALTSVERZEICHNIS
3.5.3 Signatur der Übersetzerfunktionen 76
3.5.4 Übersetzen der globalen Definitionen. 78
3.5.5 Übersetzen von Ausdrücken . . . . . . 82
3.5.6 Codegenerierung für verzögerte Ausdrücke. 95
3.6 Optimierung der Repräsentation verzögerter Ausdrücke 99
3.6.1 Motivation ...... . . . . . . . . . . . . . . 99
3.6.2 Die optimale Repräsentation von Suspensionen 104
3.6.3 Komplexität des Optimierungsproblems Optimale Sus-
pensions-Repräsentation . . . . . . . . . . . . . . . 106
3.6.4 Eine Näherungslösung des Optimierungsproblems . 114
3.6.5 Suspensionsanalyse für Multisuspensionen 120
3.6.6 Anpassung des Übersetzers .... . . . . 124
3.6 Generierung von Objektcode am Beispiel des SPARC-Prozessors 99
3.6.1 Aktivieren des Garbage-Collectors und Optimierung von
Speicherallokierungen .................... 107
3.6.2 Verminderung der Anzahl der gleichzeitig lebendigen vir-
tuellen Register. 111
3.6.3 Registerzuteilung 113
4 Speicherverwaltung 157
4.1 Speicherfreigabe für Multisuspensionen . ....... 157
4.1.1 Einzelheiten des Two-Space-Copy-Collectors 157
4.1.2 Problematik der Speicherfreigabe für Multisuspensionen 158
4.1.3 Effiziente Speicherfreigabe für Multisuspensionen 159
4.2 Generationenbasierte Speicherbereinigung ........ 166
4.2.1 Gründe und Voraussetzungen für die Anwendung genera-
tionsbasierter Techniken ................... 166
4.2.2 Speicherallokierungsverhalten bei Sprachen mit verzöger-
ter Auswertung ........................ 168
4.2.3 Ein einfacher generationsbasierter Garbage-Collector für
Sprachen mit verzögerter Auswertung ........... 171
INHALTSVERZEICHNIS ix
4.2.4 Evaluierung der Garbage-Collector-Algorithmen . 182
5 Testen bei verzögerter Auswertung 189
5.1 Einführung in die Problematik und Diskussion bisheriger Techniken 189
5.2 Das Boxmodell . . . . . . . . . . . 192
5.3 Implementierung des Testsystems . 195
6 Zusammenfassung und Ausblick 199
6.1 Codegenerierung .. 199
6.2 Speicherverwaltung . 200
6.3 Testen ..... 201
Literaturverzeichnis 202
A Die funktionale Sprache SAMPAE 215
A.1 Lexikalische Konventionen 215
A.2 Operatoren 216
A.3 Ausdrücke. 216
A.4 Definition von Werten 220
A.5 Module 223
A.6 Typen 224
A.6.1 Basistypen 226
A.6.2 Vordefinierte strukturierte Typen 228
A.6.3 Typsynonyme . 232
A.6.4 Summentypen 233
A.7 I terator-Ausdrücke .. 234
B Standard SAMPAE-Funktionen 239
C Befehle des SPARC-Prozessors 245
Tabellenverzeichnis
3.1 Übersetzungsschablonen 104
3.2 Übersetzungsschablonen 105
4.1 Merkmale der Testprogramme 169
4.2 Anteil des Speicherplatzes in Prozent, der bei der n-ten Speicher-
bereinigung nach der Speicheranforderung freigegeben wird. 170
4.3 Anteil des Speicherplatzes in Prozent, der bei der n-ten Speicher-
bereinigung noch nicht freigegeben wurde ............. 171
4.4 Speicherbereinigungen mit generationenbasiertem Garbage-
Collector ........................ 175
4.5 Speicherbereinigungen mit Two-Space-Copy-Collector 176
4.6 Speicherbereinigungen mit Collector2 182
4.7 Evaluierung Two-Space-Copy-Collector 183
4.8 Evaluierung Collectorl 183
4.9 Evaluierung Collector2 184
4.10 Relative Effizienz von Collector1 und Collector2 . 184
A.1 Prioritäten der vor definierten Operatoren 217
C.l SPARC-Befehle 247
C.2 SPARC-Befehle 248
Abbild ungsverzeichnis
1.1 Übersetzer-Architektur mit zwei Maschinenmodellen 5
1.2 Übersetzer-Architektur mit einem Maschinenmodell 6
2.1 MS-Syntax: Definitionen 10
2.2 MS-Syntax: Vordefinierte Typen und zugehörige Notationen 11
2.3 MS-Syntax: Ausdrücke 12
2.4 MS-Syntax: Vor definierte Funktionen 13
2.5 SPARC Registerfenster 20
2.6 To-Space-Copy-Collector 25
2.7 S- und L-Repräsentationen 35
2.8 SPARC-Code für den isevaluated-Test 36
2.9 Ergebnis der Applikation einer dreisteIligen Funktion auf zwei
Argumente .............................. 42
3.1 RM-Maschinenzustand 50
3.2 RM-Hauptfunktionen 51
3.3 RM-Befehle ..... . 52
3.4 RM-Zustandsübergänge, Teil 1 54
3.5 RM-Zustandsübergänge, Teil 2 55
3.6 RM-Hilfsdefinitionen 57
3.7 SAMPAE-Datentyp zur Repräsentation der MS-Grammatik 59
3.8 SAMPAE-Repräsentation der MS-Grammatik 60
3.9 Hilfsfunktionen zur MS-Grammatik 62
3.10 Suspensionsanalyse: Datentypen und Hilfsfunktionen 63
3.11 Suspensionsanalyse: Funktionsdefinitionen 64
3.12 Suspensionsanalyse: Wortbelegung 66
3.13 Das Prädikat terminate ... . . . 69
Description:2.1 MS -Eine einfache funktionale Sprache Zur Beschreibung der Übersetzung funktionaler Sprachen wird in diesem Ab schnitt eine einfache Sprache definiert, die als gemeinsamer Kern der meisten modernen funktionalen Sprachen angesehen werden kann. Diese Sprache enthält keine Listen-oder Mengenabs