Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
software:deep:dev:crosscompiler:strings [2014-05-01 09:17] – graf | software:deep:dev:crosscompiler:strings [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Implementation of Strings ====== | ||
- | In Java a string like | ||
- | <code java> | ||
- | String str = new String(" | ||
- | </ | ||
- | causes the allocation of two objects. Strings in Java are // | ||
- | [{{ .: | ||
- | |||
- | Creating two objects and managing them leads to unfavorable behaviour in terms of memory and runtime. A more elegant solution would create a single object. What to do? | ||
- | - Change of the class file and replacement of the class //String// (relatively | ||
- | - Change of code generator | ||
- | We choose the second alternative. When a //new// is encountered we must check if a string is to be created. If this is the case a special string allocation method is to be called, see [[.: | ||
- | |||
- | ===== Optimized String ===== | ||
- | Damit in Java wie gewohnt mit Strings gearbeitet werden kann, wird das Erzeugen und Verarbeiten von Strings vollständig in der Klasse // | ||
- | |||
- | [{{ .strings2.png? | ||
- | |||
- | Das Feld //size// zeigt die Anzahl Bytes des ganzen Objektes an, analog zu anderen Objekten (siehe [[heap|Heap]]). Es dient der schnelleren Sweep-Phase. | ||
- | |||
- | ===== Erzeugung ===== | ||
- | Beim Erzeugen eines String steht folgender Bytecode im Classfile | ||
- | < | ||
- | new java/ | ||
- | invokespecial constructor | ||
- | </ | ||
- | Das //new// darf noch nicht ausgeführt werden, weil die Grösse des Char-Arrays nicht aus dem Typdescriptor herausgelesen werden kann. Da das Array ja fix ins Objekt zu liegen kommt, variiert die Grösse des Objektes von String zu String. Im Codegenerator wird nun geprüft, ob das new ein Objekt vom Typ String erzeugt und falls ja, wird nichts unternommen. Einzig die Referenz auf den Typdescriptor von String muss in das Resultatregister von //new// geschrieben werden. \\ | ||
- | Die nächste Bytecode-Instruktion // | ||
- | <code java> | ||
- | public static String allocateString(int ref, char value[]) { | ||
- | int len = value.length; | ||
- | String str = newstring(ref, | ||
- | str.count = len; | ||
- | for (int i = 0; i < len; i++) str.value[i] = value[i]; | ||
- | return str; | ||
- | } | ||
- | </ | ||
- | Zuerst wird die Grösse des notwendigen Arrays bestimmt und dann die Allokation auf dem Heap gemacht. Auch hier muss der Linker statt des Hilfsstubs // | ||
- | * setzt setzt den Tag des Stringsobjektes auf den Typdescriptor von //String// (wie ein newobject) | ||
- | * erzeugt aber auch die notwendige Anzahl Arrayfelder (wie ein newarray) | ||
- | * das Feld //count// wird gesetzt | ||
- | * der Konstruktor der Oberklasse wird aufgerufen. Dieser Aufruf muss direkt im Codegenerator eingefügt werden. | ||
- | * Der String wird initialisiert | ||
- | Am Schluss muss die Referenz auf den durch die Fabrikmethode erzeugten String in das Resultatregister der // | ||
- | ===== Feldzugriffe ===== | ||
- | Sobald auf Felder des Stringarrays zugegriffen werden soll, muss das im Codegenerator speziell berücksichtigt werden. Ein solcher Zugriff hat in der SSA die Form | ||
- | < | ||
- | 1: MonadicRef[sCloadFromField] {0} < | ||
- | 2: NoOpnd[sCloadLocal] (Integer) | ||
- | 3: Dyadic[sCloadFromArray] {1, 2} (Char) | ||
- | </ | ||
- | Zuerst wird also das Feld //value// geladen. //value// ist eine Referenz. Anschliessend wird über die Referenz und ein Index auf das Array zugegriffen. Im Codegenerator muss bei einer Instruktion // | ||
- | Analog muss auch das Schreiben auf die Stringzeichen angepasst werden. Hier gibt es aber noch eine Besonderheit. Weil Strings immutable sind, werden nur beim Initialisieren in den Fabrikmethoden die Arrayfelder geschrieben. Darum kann die Prüfung auf Arrayüberschreitung weggelassen werden. | ||
- | |||
- | ===== Constant String ===== | ||
- | Constant strings are stored in the constant block of a class, see [[Linker32]]. The layout there must be identical to the layout on the heap as given above. | ||
- | |||
- | ===== Special Linking ===== | ||
- | The type descriptor of the class //String// must have its field // |