Skip to content

Commit

Permalink
new update
Browse files Browse the repository at this point in the history
  • Loading branch information
WeiTheShinobi committed Jul 4, 2024
1 parent 3136572 commit 7a847a8
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions note/編譯器設計engineering-a-compiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 260,52 @@ CFG 會有唯一的入口和出口,找個每個線性 IR 的程式碼區塊,
> 動態作用域:尋找在運行時最近創建的同名變量
>
> 詞法作用域已經為主要選擇,動態作用域可能產生難以理解的 bug
- 編譯器在轉換時需要一組執行時結構,activation record,把參數名、返回地址等等諸多資訊紀錄其中、創建空間、與其他過程交互,其中可能會有:
- 參數、寄存器保存區、返回值、調用者的 ar pointer 等等

- 局部儲存

透過 arp (ar 的 pointer) 訪問 ar,arp 總是指向其中一個 ar

編譯器要替 ar 分配記憶體,指標和偏移量就成了座標

- 分配 ar

stack 很適合,先進後出,也很符合過程調用時的開始與結束,

也能分配在 heap 上,因為像是閉包等等物件也許會引用到已經結束的過程,這時就不能在分配在 stack 上,否則兩者生命週期不一致。

如果一個過程不會調用其他過程(樹的葉子),那編譯器可以替葉過程進行更多優化,替葉過程靜態分配 AR,而不是在運行時分配 AR

---

- 物件導向語言的命名空間

並不是所有物件導向的程式語言都是可編譯的,物件導向的一些特性只能在運行時才能推斷,即 JIT 編譯器。

物件導向需要在 object record 中紀錄繼承、方法等等資料,查找時也要一步一步從巢狀中找到更大的作用域中

- 動態分派(dynamic dispatch):在執行時才確定調用哪個方法(舉例像是 interface 的實作)

編譯器若已知接收器總是同一個類別,那便可以改為靜態分派。若不是,可以使用 cache

### 過程之間值的傳遞

- 值傳遞
- 引用傳遞

### 可尋址性

通常,地址計算包含兩個部分,基礎基址、偏移量
基地址又能分兩種情況:靜態、運行時

---

兩種常用的機制:

- 存取鏈(access link):編譯器確保每個 AR 都有一個指標指向他的祖先,這就像一個 linked-list
- 全局陣列:global display,將 AR 存在一個 array 中,可以使非局部訪問的速度變成常數時間。

### 標準化鏈接

0 comments on commit 7a847a8

Please sign in to comment.