Unix archaeology: Από τις μαγνητικές ταινίες στους linear allocators
Η ανακάλυψη μιας χαμένης μαγνητικής ταινίας του Unix v4 από τα Bell Labs προσφέρει μια σπάνια ευκαιρία για Unix archaeology στις απαρχές της γλώσσης C. Κοιτάζοντας τον πηγαίο κώδικα εκείνης της εποχής, συναντάμε μια απίστευτα απλή προσέγγιση στη διαχείριση μνήμης. Στον compiler της v4, η συνάρτηση alloc() λειτουργούσε ως ένας πρωτόγονος linear allocator: ευθυγράμμιζε το μέγεθος, έλεγχε τα όρια και επεξέτεινε το heap μέσω sbrk(). Σε περίπτωση αποτυχίας, εκτελούσε άμεσο cold-exit.
Η αρχιτεκτονική αυτή είχε μια σημαντική ιδιότητα: οι δείκτες (pointers) δεν ακυρώνονταν ποτέ κατά την επέκταση και δεν υπήρχε καμία ανάγκη για explicit free(). Τα δεδομένα ζούσαν για ολόκληρο τον κύκλο ζωής του προγράμματος, απλοποιώντας δραματικά την υλοποίηση των εργαλείων της εποχής.
Explicit memory regions και το αρχικό API της malloc()
Ίσως το πιο εντυπωσιακό εύρημα στις εσωτερικές δομές του Dennis Ritchie (dmr/malloc.c) είναι η υπογραφή των συναρτήσεων:
malloc(mp, size)
mfree(mp, size, aa)
Αντίθετα με το σύγχρονο global malloc(), οι συναρτήσεις αυτές δέχονταν ως πρώτο όρισμα έναν δείκτη σε χάρτη μνήμης (coremap ή swapmap). Αυτό επέτρεπε τον διαμερισμό της μνήμης σε explicit memory regions, προσφέροντας αρχιτεκτονικά πλεονεκτήματα που σήμερα συναντάμε σε προηγμένα systems programming frameworks (όπως τα arenas). Η μετάβαση αργότερα σε ένα καθολικό API έγινε πιθανότατα λόγω hardware περιορισμών, έλλειψης virtual memory και της επιθυμίας απλοποίησης των κλήσεων.
Η εξέλιξη των macros και οι ρίζες της C++ new
Καθώς το Unix προχωρούσε προς τις εκδόσεις v7 και v8, οι μηχανικοί αντιμετώπισαν τα ίδια επαναλαμβανόμενα boilerplate σημεία στους υπολογισμούς μεγεθών (sizeof). Η λύση δόθηκε με τη χρήση macros που θυμίζουν έντονα τον τελεστή new της C++:
#define new(type) ((type *) alloc (sizeof (type)))
Είναι γνωστό ότι ο Bjarne Stroustrup εμπνεύστηκε το new και το delete από τη γλώσσα προγραμματισμού Simula για να αποφύγει τα λάθη και την πολυπλοκότητα των manual κλήσεων malloc/init. Ωστόσο, η ύπαρξη παρόμοιων macros στον κώδικα του Unix υποδηλώνει μια παράλληλη εσωτερική αναζήτηση ασφαλέστερων αφαιρέσεων στη διαχείριση μνήμης.
Το κυνήγι του Garbage Collection
Ένα λιγότερο γνωστό ιστορικό στοιχείο είναι ότι οι δημιουργοι του Unix δεν έμειναν ικανοποιημένοι αποκλειστικά με τη manual διαχείριση. Στις επόμενες εκδόσεις (όπως η v9), εισήχθησαν συναρτήσεις όπως η galloc() και αντίστοιχα macros (gcnew), προσφέροντας heap storage allocation με αυτόνομη συλλογή απορριμμάτων (garbage collection). Αυτό επιβεβαιώνει πως η ανάγκη για αυτοματοποιημένη διαχείριση μνήμης υπήρχε από τα πρώτα στάδια εξέλιξης των γλωσσών συστήματος, πολύ πριν την καθιέρωση σύγχρονων runtimes.