High-level Overview of the Native-Code Generation Process

Representation of Pointers

Kod bir nesne dosyasına yayımlandığında, işaretçiler yer değiştirmeler olarak yayımlanacaktır. Serileştirme sonrası kod, bu sabitlerden birine işaret eden herhangi bir nesnenin yeniden oluşturulmasını ve doğru çalışma zamanı işaretçisini içermesini sağlayacaktır.

Aksi takdirde, bunlar sabit sabitler olarak yayımlanacaktır.

Bu nesnelerden birini yaymak için literal_pointer_val çağrısını yapın. Bu, Julia değerini ve LLVM globalini izlemeyi sağlayacak, bunların hem mevcut çalışma zamanı için hem de serileştirmeden sonra geçerli olmasını sağlayacaktır.

Nesne dosyasına yayıldığında, bu global değişkenler büyük bir gvals tablosunda referanslar olarak saklanır. Bu, ayrıştırıcının bunlara indeksle referans vermesine ve onları geri yüklemek için Global Ofset Tablosu (GOT) benzeri özel bir manuel mekanizma uygulamasına olanak tanır.

Fonksiyon işaretçileri benzer şekilde işlenir. Büyük bir fvals tablosunda değerler olarak saklanırlar. Global değişkenler gibi, bu durum serileştiricinin bunlara indeksle referans vermesine olanak tanır.

extern fonksiyonlarının, isimler aracılığıyla, bağlayıcıdaki olağan sembol çözümleme mekanizması ile ayrı olarak ele alındığını unutmayın.

Not edin ki ccall fonksiyonları da ayrı bir şekilde, manuel GOT ve Prosedür Bağlantı Tablosu (PLT) aracılığıyla işlenir.

Representation of Intermediate Values

Değerler, bir jl_cgval_t yapısında dolaşımda. Bu, bir R-değeri temsil eder ve onu bir yere atamak veya geçirmek için gerekli bilgileri içerir.

Onlar genellikle mark_julia_type (anlık değerler için) ve mark_julia_slot (değerlere işaretçiler için) yardımcı yapıcılarından biri aracılığıyla oluşturulurlar.

convert_julia_type fonksiyonu, iki tür arasında dönüşüm yapabilir. cgval.typ'i typ olarak ayarlanan bir R-değeri döndürür. İstenilen temsile nesneyi dönüştürmek için gerektiğinde yığın kutuları oluşturur, yığın kopyaları ayırır ve temsili değiştirmek için etiketli birleşimleri hesaplar.

Buna karşılık update_julia_type, cgval.typ'i yalnızca sıfır maliyetle (yani herhangi bir kod yaymadan) yapılabiliyorsa typ olarak değiştirecektir.

Union representation

İçsel birleştirilmiş türler, etiketli tür temsili aracılığıyla yığın üzerinde tahsis edilebilir.

Etiketli birleşimleri işleyebilmesi gereken ilkel rutinler şunlardır:

  • mark-type
  • yerel-yükle
  • store-local
  • isa
  • is
  • emit_typeof
  • emit_sizeof
  • kutulu
  • açmak
  • özel cc-ret

Her şeyin, bu ilkelere dayanarak birleşim ayırma uygulamak için çıkarımda işlenebilir olması gerekir.

Tagged-union'un temsili < void* union, byte selector > çiftidir. Seçici, byte & 0x7f olarak sabit boyutludur ve ilk 126 isbitini birleştirir. İçindeki isbit nesnelerinin tür birliğine derinlik öncelikli bir sayım kaydeder. Sıfır indeksi, union*'un aslında etiketli bir yığın tahsisli jl_value_t* olduğunu ve etiketli bir birim olarak değil, normal bir kutulu nesne olarak ele alınması gerektiğini gösterir.

Seçicinin yüksek biti (byte & 0x80), void*'ın gerçekten bir yığın tahsisli (jl_value_t*) kutu olup olmadığını belirlemek için test edilebilir, böylece bir kutunun yeniden tahsis edilmesi maliyetinden kaçınılırken, düşük bitlere dayalı olarak birliğin bölünmesini verimli bir şekilde ele alma yeteneği korunur.

byte & 0x7f tür için kesin bir test olduğu garanti edilmiştir, eğer değer bir etiketle temsil edilebiliyorsa - asla byte = 0x80 olarak işaretlenmeyecektir. isa test edilirken tür-etiketini de test etmek gerekli değildir.

union* bellek bölgesi herhangi bir boyutta tahsis edilebilir. Tek kısıtlama, selector tarafından şu anda belirtilen verileri içerecek kadar büyük olmasıdır. İlgili Union türü alanına göre orada saklanabilecek tüm türlerin birleşimini içerecek kadar büyük olmayabilir. Kopyalama yaparken uygun dikkat gösterin.

Specialized Calling Convention Signature Representation

Bir jl_returninfo_t nesnesi, herhangi bir çağrılabilirin çağrı konvansiyonu ayrıntılarını tanımlar.

Eğer bir metodun argümanlarından veya dönüş türünden herhangi biri kutusuz olarak temsil edilebiliyorsa ve metod varargs değilse, specTypes ve rettype alanlarına dayalı olarak optimize edilmiş bir çağrı sözleşmesi imzası verilecektir.

Genel ilkeler şunlardır:

  • Temel türler int/yüzer kayıtlarında geçer.
  • Vektör kayıtlarında VecElement türlerinin demetleri geçilir.
  • Yapılar yığın üzerinde geçer.
  • Dönüş değerleri, bir gizli sret argümanı aracılığıyla döndürülecekleri bir boyut kesim noktasında, argümanlarla benzer şekilde işlenir.

Bu, get_specsig_function ve deserves_sret tarafından uygulanan toplam mantıktır.

Ayrıca, eğer dönüş tipi bir birleşimse, bir çift değer (bir işaretçi ve bir etiket) olarak döndürülebilir. Eğer birleşim değerleri yığın üzerinde tahsis edilebiliyorsa, bunları depolamak için yeterli alan da gizli bir ilk argüman olarak geçilecektir. Döndürülen işaretçinin bu alana, bir kutulu nesneye veya hatta başka bir sabit belleğe işaret edip etmeyeceği, çağrılan fonksiyona bağlıdır.