Press "Enter" to skip to content

GOTO 2016 • Exploring Swift Memory Layout • Mike Ash


quindi parleremo della memoria
layout in Swift come sono sicuro che tu sappia
Swift è la nuova fantasia magica di Apple
linguaggio di programmazione e io vado
tuffati un po ‘ e parla di
i bit e i byte e come è tutto messo
insieme e che aspetto ha dentro
memoria quando si esegue effettivamente il codice
un vero breve informatico su di me sono attivo
line at my cache comm Ho un blog
dove faccio tutti i tipi di cose pazze come
questo mi piace prendere le cose a parte
e vedere come funzionano e io ho un
un mucchio di pazzi progetti github che tu
probabilmente non dovrebbe mai usare nulla
ma sono molto divertenti da giocare con I’m on
Twitter se hai voglia di seguirmi
c’è una foto del mio gatto perché tu
sapere che Internet è tutto sui gatti e
siamo fondamentalmente tutti sul
Internet in questi giorni volo solo alianti
il punto di informazioni è molto divertente
e la freccia è puntata sopra
qui così sono io
sai che metto sempre una foto di me stesso
su queste diapositive e poi risate parole
e come le persone possono semplicemente guardarmi così io
ho deciso di smettere di farlo, quindi ecco
il piano prima voglio solo dare un
rapida panoramica di che memoria sono
certo sapete tutti che cos’è la memoria ma
può aiutare a ottenere un po ‘di
prospettiva e basta strappartelo
ora vai a rivisitare la fondazione il
roba fondamentale quindi ho scritto un programma
che fondamentalmente è dove ho generato tutto
questa informazione va davvero
attraverso la scansione del programma a partire da
un valore particolare e scarica tutto
fuori che sono in quei valori in memoria
e poi finalmente mi tufferò davvero
in quanto rapido espone roba in memoria
come sai in realtà quel programma
produce e alcuni contrastano con come vedono
lo fa e come lo fa C ++, quindi cos’è
la memoria e fondamentalmente la memoria è ciò che
ferma che ciò accada in modo da sapere
devi tenere traccia di dove sei
essenzialmente hai una computazione
processo e sei in qualche stato all’interno
quel processo in ogni momento e se tu
non posso tenerne traccia, allora lo farai
non andare mai da nessuna parte così non vogliamo
solo ripetendo all’infinito che vogliamo
in realtà fare progressi
e questo è ciò che riguarda tutto questo
capire come effettivamente costruire
hardware che può ricordare cose e
conosci le informazioni del negozio e scava
fuori più tardi era una specie di uno dei
problemi fondamentali in informatica e
ci sono molte tecnologie lungo il
modo iniziato con tubi a vuoto voi
potete immaginare queste cose sono come questo
grande e sono essenzialmente come un
lampadina ad incandescenza e ciascuno
tiene un po ‘ così se vuoi davvero
memorizzare una quantità ragionevole di dati
stai parlando di una stanza piena di
attrezzature incredibilmente calde più tardi lì
erano linee di ritardo del mercurio questo è un po ‘
una bella tecnologia di un tubo tu
in pratica riempilo di mercurio che hai
un oratore o qualcosa del genere su uno
fine e qualcosa come un microfono acceso
l’altra estremità e tu pulsi i tuoi dati
attraverso di essa e ci vuole tempo per viaggiare
e per questo potresti adattarti alle cose
in e memorizzare le informazioni in questo modo
e c’era una piccola proposta divertente
qualcuno ha deciso che il gin avrebbe fatto un
buon mezzo per questo ha avuto tutto il diritto
proprietà chimiche e qualsiasi altra cosa
come posso dire che nessuno l’ha mai costruito ma
divertente da parte la memoria del nucleo magnetico
era un avanzamento di questa roba che era
tecnologia molto pulita ottiene piccoli anelli di
tazza di ferro e tu fai scorrere i fili
loro e secondo l’ elettrico
la corrente che invii attraverso di loro è possibile
memorizzare i dati o recuperare i dati memorizzando
nel campo magnetico in quello dentro
quegli anelli e quindi quello era un anello per
un po ‘ e lo stato dell’arte di questo in
gli anni ’60 o ’70 erano fondamentalmente un cubo
su questo grande potrebbe contenere 32 mila
bit di informazioni e quindi è possibile
immagina di sapere questa cosa che ho dentro
la mia mano può contenere molti gigabyte di
miliardi di bit di memoria e così via
sono avanzato molto da allora
quindi RAM dinamica DRAM fondamentalmente silicio
i chip sono lo stato dell’arte oggi
che dovremmo essere tutti incredibilmente
grazie per perché rende davvero nostro
vive molto più facilmente il fatto che possiamo
avere questi sai che questo ci permette di
memorizzare miliardi e miliardi di bit di
informazioni tutte in una volta e il mio telefono è
malcontento se mi puoi perdonare
solo un momento qui non andiamo d’accordo
quindi questa è la visione hardware delle cose
non mi interessa davvero tanto
Hardware la maggior parte del tempo
programmazione perché tutto il
lavori analoghi lo ignoriamo , quindi come funziona
lo sguardo per un programmatore quindi abbiamo ottenuto la
l’ unità fondamentale di informazione è
il bit che è un uno o uno zero
tradizionalmente organizziamo bit e
gruppi di otto quelli sono byte e ciascuno
la memoria è essenzialmente solo lunga
sequenza di byte uno dopo l’altro
stai solo vagando per sapere dove andare
la nebbia e sono disposti in a
certo ordine ogni boccone ottiene un numero
questo è chiamato il suo indirizzo così iniziamo
zero e poi uno e poi due e poi
tre e un sistema da otto miliardi di byte
ti abbiamo fatto conoscere miliardi nel
distanza puoi essere tu sai che puoi vedere
queste cose in direzioni diverse
spesso lo vediamo come questo organizzato da
parola invece di byte, quindi una parola è a
termine vago dell’arte nel computer
scienza ma di solito significa un’unità
questa è la dimensione di un puntatore così via
dispositivi moderni a 64 bit o 8 byte e
si dirige all’infinito così qui
Ho i byte indirizzati da 8 e
ci piacerebbe che esadecimale esadecimale sia
dove hai invece l’indirizzo di base 16
di base 8 quindi da 0 a 9 quindi un passaggio
F è un bel multiplo di 2 così
tutto si combina bene è il
tipo di linguaggio nativo di calcolo
quindi è il linguaggio naturale da usare qui
e così ho finito gli indirizzi
esadecimale invece 0 816 è 1024 e
tutto questo e questo è solo il grande
immagine di ciò che sembra tutta questa cosa
come se tu fossi uno zoom out, questo è un Mac
in esecuzione su x86 64 tutto è un po ‘
un po ‘diverso in questo tutto molto piattaforma
specifico ma essenzialmente hai un
divario di cose che non esiste il
i primi 4 gigabyte di memoria non lo sono
mappato questo è tutto ciò non occupa
qualsiasi spazio fisico è solo un an
affrontare il trucco allora hai il
usa il tuo programma essenzialmente il tuo
la memoria è la roba verde
così ottieni un pezzo che è per te e
allora hai un bel grande spazio vuoto
dopo quello e poi finalmente il kernel
è giù in fondo quindi hai questo
2 al 64 ° byte di potenza che ottengono
affettato e organizzato in questo modo e
questo è essenzialmente come sembra se tu
ingrandisci leggermente, quindi è lo stesso
foto come prima tranne che è di più
realistico perché invece di partire da
0 iniziamo con 4 miliardi di dollari
puntatori nella memoria sono sicuro che tu sei tutto
familiare con il puntatore del termine
fa riferimento a un puntatore a questo livello
solo un numero ed è un numero che
capita solo di corrispondere al
indirizzo di qualcos’altro in memoria così
qui abbiamo questa cosa lassù
questo è il negozio l’indirizzo di questo
un po ‘ laggiù e io lo indico
con una freccia la freccia non esiste in
la realtà è solo un numero che trattiamo
come se fosse una freccia e un’altra ancora
dettaglio su tutto questo whoops
siamo andati troppo lontano nel più moderno
i sistemi immagazzinano cose in little-endian
ordine che è essenzialmente il minimo
una parte significativa del numero arriva
prima è come se fossi fuori da te
conosci 234 come 4 3 2 tutto è indietro
solo una di quelle cose che ti piacciono
di dover imparare a conviverci e
leggerlo in questo modo
quindi la memoria è organizzata fino a noi
vederlo è organizzato in tre
parti fondamentali che abbiamo al
livello hardware è solo una grande lista di
roba ma come il modo in cui trattiamo effettivamente
le parti di esso sono più specifiche
scopi quindi abbiamo la pila che è
dove tutte le tue variabili locali vanno quando
scrivi le variabili che stai utilizzando
i tuoi calcoli in una funzione
va in pila e si chiama a
impilare perché ogni volta che fai un
chiamata di funzione aggiunge quelle funzioni
variabili locali ad esso e quando lo fai
un’altra chiamata sale e un’altra chiamata
sale e poi quando torni da a
funzione che torna indietro giù
di nuovo in basso quindi è come una pila di cose
hai anche dati globali nel tuo
programma quelli sono essenzialmente cose
che è arrivato come parte del programma
quando è stato caricato così il bagliore
le variabili fanno parte della tua stringa
costante i tuoi metadati di tipo in rapido
in altre lingue viene semplicemente caricato come
parte di quello e poi hai il
heap e l’heap sono dinamicamente
roba assegnata quando ne crei una nuova
oggetto che alloca un po ‘di memoria
questo è sul mucchio e queste sono cose
dove fondamentalmente non lo sono loro
vivono in modo permanente ne hanno un po ‘
vita ma non sono legati ad a
funzione non sono legati al tuo
programma loro loro prendono vita e vanno
via tipo di arbitrariamente e questo è
essenzialmente tutto il resto quando tu
crea un nuovo oggetto quando assegni
memoria manualmente quando si concatena
stringhe qualunque sia tutto in pila
quindi è una specie di panoramica che conosci
ti ricordo quale memoria è ciò che il tutto
affare è che stiamo parlando di qui
entriamo nella memoria di dumping in realtà
andando a immergersi nell’ispezionare il contenuto
vedere cosa c’è realmente lì così sono
andando ad esplorare questo programma che io
ha scritto come funziona che effettivamente va dentro
e traccia tutte queste cose se qualcuno
vuole dare un’occhiata ho capito
su github l’indirizzo github è lì
o c’è un piccolo URL qui sotto o se qualcuno
Mi piacciono gli URL davvero enormi che puoi usare
uno in fondo ma non aspetterò
per te da digitare
solo molto velocemente questo facilita Xcode otto
e Swift tre se qualcuno lo fa
qualsiasi cosa con Swift finora si sa che
ci sono stati un sacco di versioni di esso
e a loro piace rompere la compatibilità così
l’anno scorso è stato Swift ad avviare una coppia
di settimane fa abbiamo Swift tre ora
e questo è diverso, quindi se si vuole
utilizzare quel codice avete bisogno di questo in modo da tornare a
questo il tipo di unità fondamentale di
questo programma è una funzione che sembra
come questo e questa è una funzione
funziona su un tipo arbitrario prende un
valore e restituirà un array
di interi o byte a 8 bit senza segno e
lo useremo solo come nella demo sopra
crei una variabile contenente
qualcosa qualsiasi cosa arbitraria e poi
lo chiami e ti consegnerà
indietro i byte che lo compongono e
questo servirà da base
per questo intero programma e la domanda
è come scrivere questo in
in particolare questo è un vero veloce
panoramica di una possibile implementazione
che non è ciò che il programma in realtà
usa ma in qualche modo ottiene il tutto
la palla che rotola fino a come questo
funziona così l’idea è che ottieni il valore
ottieni le sue dimensioni perché conosciamo il
tipo del valore questo è un generico
funzione in Swift in modo che funzioni su qualsiasi
scrivi ma sa di che tipo si tratta
chiamato con in qualsiasi momento questo
tipo di layout di memoria ci consente di ottenere il
dimensione reale in modo che ci dice quanti
byte è così sappiamo per quanto tempo è dentro
memoria e poi c’è questo built-in
funzione in Swift chiamata con non sicuro
puntatore quindi chiami che gli dai un
variabile e torna indietro e ti dà
un puntatore a quella variabile e una volta noi
avere un puntatore possiamo fare cose come
guarda quel puntatore come se fosse a
puntatore di un tipo diverso quindi noi
immagina di avere un puntatore a un int e
lo facciamo con la chiamata di rimbalzo della memoria qui
che dice che va bene far finta che non sia così
un puntatore a un intero lo finge
questo è un puntatore ai byte e funziona
con me su questo sai che è lo stesso
cosa ma è un tipo diverso ora vai
attraverso e leggerlo così che cosa fa
questo richiede un puntatore a qualsiasi cosa
cosa arbitraria hai e dice tutto
giusto fingere che siano byte non elaborati
interpretalo così
e poi una volta che possiamo andare
attraverso e basta leggere uno per uno e
è un po ‘una scorciatoia qui, giusto
dire al sistema di leggerlo per me
non c’è nessun anello o qualcosa di simile
il puntatore buffer non sicuro mi consente fondamentalmente
dì che è un contenitore e poi posso
crea un array da quello e io lo farò
tipo di accaduto, Swift, lasciati fare a te
scrivere cose brevi come quelle così reali
demo rapida di ciò che produce io
creato una variabile che contiene 1 2 3 4
5 6 7 8 e poi ho appena scaricato 42
e se stampo queste cose, allora ottengo
questi risultati qui in modo da poter vedere il
il primo stampa esattamente ciò che abbiamo visto
tranne che è indietro perché ricorda
i sistemi moderni tendono a fare cose
all’indietro, quindi stampa otto sette
sei cinque quattro tre due uno zero e
poi 42 esce come 42 con un gruppo di
zeri dopo perché è un 64 byte
prima bit bit e solo molto veloce
non hai bisogno di seguirlo davvero
questo è solo che conosci un codice che ho scritto
che volevo sistemare molto velocemente
esadecimale è di nuovo il naturale
linguaggio di calcolo di basso livello, quindi questo
prende solo una serie di byte e dump
invece come una stringa esadecimale
come una sequenza di numeri decimali
come abbiamo visto prima, quindi se lo usiamo
allora otteniamo questo invece lo stesso di base
cosa eccetto invece di stampare decimale
otteniamo hex così uno due tre quattro cinque
le sei e sette otto escono come ha fatto
prima e poi 42 esce come 2a da allora
questo è ciò che 42 è esadecimale
seguito da un gruppo di zeri, quindi questo
ci permette di scaricare la roba in una forma
che possiamo capire ma è ancora
vicino a ciò che il computer ha tutto bene
quindi abbiamo capito dove possiamo prendere un valore
e vedere cosa c’è dentro, ma programmi reali
sono più complicati dei singoli valori
hanno molto di più in corso
i programmi reali hanno un aspetto più simile a questo
hai un valore che contiene a
un sacco di byte e quei byte possono alcuni
di quei byte sono in realtà puntatori
quale punto altre cose e quei punti
ad altre cose e sai che ottieni
tutta questa cosa dell’albero in corso così noi
voglio essere in grado di inseguire effettivamente tutto
questa roba giù in modo automatico
il programma ha bisogno di essere in grado di realtà
trova tutte queste cose così come facciamo
che iniziamo con la consapevolezza che
i puntatori sono solo interi tutti a
puntatore è solo un indirizzo è solo un
numero che interpretiamo come un altro
posizione in memoria, così ho scritto un rapido
struct che viene utilizzato nel programma
tutto ciò che è è solo contiene un indirizzo
che è un puntatore intero senza segno
numero intero e avvolgendolo in a
struct mi aiuta a tenere le cose a parte così tu
non confondere quali parametri sono
in realtà interi e quali parametri
sono interi che stiamo trattando come
i puntatori hanno appena creato un nuovo tipo così
che il sistema di tipi ci aiuta a scrivere
programma correttamente e quindi questo bit di
il codice richiede essenzialmente una matrice di byte
che sappiamo già come ottenerlo
ho appena scritto quella funzione e ci vuole
quella matrice di byte e prova a scansionare
per i puntatori in esso così di nuovo un puntatore è
un numero intero che ti capita di trattare come
un indirizzo e non possiamo sapere come fare
vengono trattati a questo livello perché
prendiamo solo un po ‘ di luci e noi
non so cosa significano quindi siamo solo
andando a tipo di andare ottimista
attraverso e tagliarlo in pezzi di
8-bit otto byte e li estrarre
e fai finta di dire che sai cosa succede se questi
erano i puntatori che cosa significherebbe così
questo è ciò che prendiamo questo array
di byte e diciamo invece di prendere
trattandolo come una matrice di byte
dammi un puntatore al suo contenuto e
trattalo come un puntatore ai puntatori okay
il che significa che possiamo essenzialmente andare
attraverso e dire leggere il primo puntatore
pezzo di dimensioni leggere il secondo puntatore
pezzo di dimensioni leggere il terzo puntatore di dimensioni
pezzo e poi prendiamo tutto questo e
restituiscilo come array in modo da avere questo codice
essenzialmente lo farò
vasta gamma di byte che otteniamo dal
cosa prima e dividerlo che piace
questo quindi questa è un’indicazione visiva di
cosa sta succedendo con quel codice così noi
dargli un valore che ritorna un mucchio
di byte e lo attraversiamo affettandolo
e prendi i singoli pezzi e poi
possiamo iniziare a inseguirli così noi
può leggere un valore afferrare tutti i suoi byte
allora possiamo prendere tutti i puntatori che
quei byte potrebbero indicare e poi noi
può prendere quei suggerimenti e ripetere il
processo e in sostanza che ti dà
l’albero che hai baciato in un ciclo continua
fino a quando hai i puntatori
per esplorare leggi i loro contenuti e
poi gli sputi il problema con
questo approccio non sappiamo che
i puntatori sono in realtà dei puntatori e quali
puntatori sono solo numeri interi che tu lo sai
potrebbe essere il punteggio più alto dei giocatori che potrebbe
sii a conoscenza del numero di persone che
non ti piaccio o qualcosa del genere e
non sappiamo cosa significano e
normalmente in un programma quando si tenta di
leggi da un puntatore che in realtà non è
un puntatore è solo un pezzo illegale
di memoria rispetto al tuo programma si blocca
che è buono nel codice normale perché tu
non voglio procedere quando il tuo programma
è confuso che lo vuoi solo
fermarsi e produrre un registro di arresto anomalo o
qualcosa del genere ma in questo codice noi
vogliono essere in grado di andare avanti in modo che possiamo
esplorare questa roba, quindi vogliamo essere in grado
leggere da puntatori senza crash
se sono così male sul Mac e su iOS
abbiamo questa bella funzione di basso livello
Le piattaforme Apple usano un finto kernel
altamente modificato e aggiunto su roba ma
le chiamate simulate di basso livello sono ancora lì
e c’è una chiamata finta chiamata mach vm
leggere sovrascrivere e in sostanza è a
chiamata di sistema dove le dai due
puntatori e tu dici che voglio copiare questo
molti byte da quel puntatore a questo
puntatore se si ha familiarità con il mem
funzione di copia dallo standard C.
libreria è esattamente come quella tranne
che se dai alla copia copia un punto negativo o
il tuo programma si blocca e se lo dai
mach vm legge / scrive un puntatore cattivo è
okay restituisce un errore perché è un
chiamata di sistema succede che il kernel
livello il livello del kernel può fare tutto questo
controllando in sicurezza e così può tornare indietro
e dire che non potrei farlo perché tu
sappi che non è un vero puntatore che è stato
solo un mucchio di spazzatura e non te
sapere l’ indirizzo lì non esiste e
così basato su quello che possiamo attraversare e
seguire fedelmente questo albero senza
schiantarsi perché possiamo essenzialmente
provare ottimisticamente ogni puntatore passarlo
a questa funzione e poi se arriva
indietro e dice c’è stato un errore che è
bene diciamo che okay non potrebbe seguire
continuare così è molto veloce
questa è solo la funzione prototipo di cosa
sembra che abbia un compito che è
come un processo se hai ragione
le autorizzazioni sul Mac puoi effettivamente
leggi da altri processi non tuoi
che è una sorta di fondamento di come
puoi creare un debugger che richiede
indirizzo ci vuole una lunghezza ci vuole un
indirizzo di destinazione e ci vuole un
puntatore a qualcosa dove lo dirà
quanti byte ha effettivamente letto così
All’inizio ho mostrato un
funzione che leggerebbe da un puntatore
ma era che potrebbe andare in crash se avete dato
un cattivo puntatore che leggerà da a
puntatore sicuro così essenzialmente è solo
un involucro attorno a quella finta chiamata che ci vuole
il puntatore che gli dai lo fa un po ‘
un po ‘di casting per farlo entrare nel modulo
che il sistema vuole e poi solo
fa quella chiamata se ci riesce
ritorna e dice hey ce l’ abbiamo fatta e se lo è
non restituisce quindi false il chiamante
può sapere che non ha funzionato e in modo che
in base alla quale possiamo costruire questo
totale
sistema di scansione ricorsiva vediamo
ci andiamo bene, quindi possiamo leggere
questa roba in modo sicuro, ma abbiamo bisogno di sapere
quanto leggere il primo valore che leggiamo
possiamo ottenere la dimensione del tipo perché
sappiamo che il tipo al momento della compilazione è a
funzione generica otteniamo che i metadati
dal compilatore ma dopo che iniziamo
inseguendo i puntatori non possiamo farlo
più perché abbiamo a che fare con
sacchi arbitrari di byte che non conosciamo
cos’è questa roba, quindi dobbiamo conoscerci
bisogno di essere in grado di indovinare almeno come
molti byte da leggere in qualsiasi momento e
quando insegui questi puntatori
per cose che sono in pila
c’è la funzione di dimensione malloc a
meno sul Mac e su iOS dove tu
dargli un puntatore e torna indietro e
dice che in realtà sapevi che 32
byte assegnati sul mucchio qui così noi
può chiamarlo e torna indietro e
ci dice esattamente quanto possiamo leggere
che è fantastico e anche meglio questo
la funzione è tollerante di dati errati quindi se
gli dai qualcosa che non è un
puntatore o dargli due puntatori a
qualcosa che è legittimo ma non
allocato sullo heap o tu lo dai a
puntatore a qualcosa nel mezzo di
un’altra cosa qualunque essa non si preoccupa
ti restituirà zero quindi non è così
incidente che è davvero conveniente per il nostro
scopi e finalmente abbiamo globale
le variabili codificano cose come quelle
sono i simboli nella tua app c’è il DL
funzione di adder dove tu la dai un
indirizzo e ritorna e ti dice
quale simbolo si trova nelle vicinanze e quindi possiamo usarlo
per controllare se c’è qualcosa
in realtà un simbolo e possiamo anche usarlo
per tipo di estrarre la dimensione di
essenzialmente la scansione ti dà il
simbolo che viene immediatamente prima del
puntatore si dà in modo da iniziare
qui e tu dici dammi il simbolo
informazioni e se ritorna e
dice di sì ho informazioni sui simboli allora
avanzare da un byte e dire che ne dite
qui che ne dici di qui e di qui e
continua a farlo finché non ti dà
una risposta diversa e poi sai
esattamente per quanto tempo quella cosa era e come a
bonus ti dà anche i nomi così
la tua funzione nomina la tua variabile globale
nomi come quelli che compaiono tutti
di questa API e quindi possiamo usarli per
annota la nostra scansione e aiutaci a capire
cosa sta succedendo a quei nomi in Swift e
anche in C ++ tendono a venire storpiati
perché il compilatore tenta di incorporare
informazioni su cosa sia il tipo
inoltre solo il nome così in C per
esempio se hai una funzione chiamata
convocare saprai che sarà il nome del simbolo
che sputa solo dice evocazione e
in Swift se hai una funzione chiamata
convocare il nome del simbolo ne esce di più
come questo dove ne hai un mucchio
roba extra su di esso perché non lo farà
includi solo quel nome ma lo farà anche
includere il fatto che ne occorrono due
numeri interi e restituisce una stringa o
qualunque cosa sia effettivamente così per
aiuto con quello c’è il Swift D
comando di manipolazione fornito con Xcode I
immagina che sia disponibile in Swift
strumenti open-source e tu dai anche a
simbolo mutilato e ritorna con
qualcosa come questo che è di più
leggibile così nel mio codice che scarico
tutto attraverso quella Swift d mangle
è un programma molto carino perché se tu
dagli qualcosa che non capisce
lo restituisce semplicemente non modificato
quindi potrei semplicemente dare da mangiare a tutto
senza dover temere che lo sarebbe
esplodere o schiantarsi o qualcosa del genere
su dati che non sono stati effettivamente stravolti
I simboli Swift e poi C ++ ha lo stesso
cosa c’è uno strumento chiamato C ++ filt
che fa lo stesso lavoro per i nomi C ++
e ha la stessa semantica o se tu
dagli qualcosa che non capisce
te lo restituisce senza cambiare
così ho potuto solo passare ogni altro nome che
Mi sono imbattuto in questi due strumenti a
molti di questi dati in cui ci imbattiamo
ricordi in realtà stringhe
scrivi informazioni testuali come metodo
nomi come input dell’utente ed è utile per
essere in grado di trovare questi e il problema è
di nuovo stiamo lavorando con questi sacchetti di
byte non sappiamo cosa sta succedendo con
loro sono solo una sequenza di dati e
vogliamo essere in grado di indovinare almeno
quali sequenze di dati effettivamente
rappresentare il testo e quali no e
non c’è modo di farlo in modo affidabile ma a
euristica decente è cercare ASCII
caratteri e cerca ASCII stampabile
caratteri da 0 a 31 in ASCII
controlla i personaggi che noi non abbiamo
aspettarsi di trovare come parte del testo in a
programma
almeno non il testo che siamo
interessato e poi roba oltre 126
è il carattere di cancellazione e ASCII
o i suoi caratteri non ASCII quindi guardiamo
per caratteri ASCII stampabili e noi
cercare sequenze di almeno quattro così
l’idea è che se ne hai uno o
due o tre, allora è probabile che sia così
solo alcuni altri dati che solo
per coincidenza è successo ad assomigliare
testo e una volta arrivati ​​fino a quattro c’è
una buona possibilità che sia qualcosa
Texturalmente interessante e non è un
garanzia ma è decente
euristico ti dà buoni risultati e
questo è il codice che passa e
implementa quella euristica qui che dai
è una matrice di byte e passa attraverso
le sue fessure che si allineano in blocchi di
caratteri ASCII contigui stampabili
e quindi filtra tutti quelli brevi
e ti restituisce due lunghi così noi
può eseguire questo sugli array di byte che noi
uscire dallo scanner per vedere cosa c’è
continuando a stare bene, così è
questo è essenzialmente quelli sono i
fondamenti del programma c’è a
un mucchio di contabilità che continua in esso
se sei interessato a quella parte
su Github ma quelli quelli sono i
pezzi fondamentali e ora sappiamo come
per costruire tutto questo e così possiamo leggere
tutte queste cose ma vogliamo essere in grado di
in realtà l’output in qualche forma che è
bello per l’umano guardare così noi
potrebbe semplicemente scaricare tutto in forma di testo o
qualcosa di simile, ma sta andando a
prendi un sacco di lavoro da interpretare e noi
idealmente vorrebbe qualcosa di più simile
questo e come un passo intermedio I
produrre qualcosa come questo che non lo è
molto leggibile, ma questo è un open
programma sorgente chiamato graphviz e tu
dagli in pratica gli dai una lista
di nodi e tu gli dai una lista di
connessioni e tu dici che questo nodo ha
questa etichetta ed è collegata a questi
nodi e questo nodo ha questa etichetta e
è collegato a questi nodi e quando
lo consegni a quel programma e
ti restituisce cose come questa che è
davvero fantastico e leggibile e puoi andare
attraverso e guarda questo è che ho scritto a
semplice programma C che crea un po ‘
struttura nella memoria e poi la passa
fuori al mio programma di dumper e quello
genera la roba di graphviz e quindi
il grafico lo trasforma in un PDF che sembra
così possiamo attraversare il possibile
leggi possiamo vedere che abbiamo iniziato con a
pointer
in alto a cui punta il puntatore
qualche memoria malloc che contiene questo
e quelli puntano a più memoria malloc
quale punto a più memoria malloc e
abbiamo un paio di corde al
fondo e siamo in grado di passare attraverso di vedere questo
tutta la struttura visivamente che è fredda
quindi questo ci aiuta a capire cosa sta succedendo
su così è la teoria di cosa sia un come
stiamo guardando queste cose quindi facciamolo
effettivamente passare e guardarli e
guarda cosa sta succedendo con questa roba
in che modo Swift rappresenta le cose
memoria come si rappresenta C ricorda
cose in memoria come rappresenta c ++
le cose in modo rapido note, questo è tutto molto
Architetture specifiche Ho fatto questa roba
su Mac su x86 64 è probabile che sia a 64 bit
essere molto simile a Swift su Linux a 64 bit
probabilmente simile ma questa è roba
questo è molto utile per il debug di esso
molto utile per capire come il
il sistema funziona, non è una buona idea
scrivi qualsiasi codice che si basi su questa roba
a meno che non sia una specie di progetto per hobby o
una cosa sperimentale che non vuoi
scrivere qualsiasi codice di produzione che si basa su
questa roba perché le dimensioni di offset il
il significato di vari campi è tutto soggetto
cambiare da un tetto per una versione
alla prossima quindi è roba davvero utile
ma non si vuole per incorporare questa
in te sai quella libreria che sei
scrivere per il lavoro che verrà spedito a
utenti con cui il mio telefono non collabora
io oggi ci andiamo bene prendiamo
uno sguardo ad alcune strutture c è molto
semplice nel modo in cui espone le cose
la memoria è un po ‘il suo fascino e
daremo un’occhiata a questo vero veloce I
crea una struttura AC che contenga solo tre
lunghi campi XY e Z ho scritto un po ‘
un po ‘di codice che li riempie con uno due
e tre e poi l’ho scaricato
memoria usando il mio simpatico scaricatore grafico
ed è quello che ci troviamo qui nel
ciotola e tu puoi vederlo essenzialmente
li stende solo in sequenza, abbiamo ottenuto 1
seguito da 2 seguito da 3 e c’è
un mucchio di spazio vuoto perché è lungo
un valore di 8 byte e questi sono piccoli
numeri così hanno un sacco di partenza
zeri e li mette fuori uno per uno
diventa più interessante quando ottieni
diverse dimensioni quindi questa è una struttura che
ha un mucchio di campi di diverse dimensioni
a attraverso H alcuni di loro sono un byte
il suo carattere alcuni di loro sono due byte
quelli sono brevi alcuni di loro sono quattro
sono interi e alcuni di loro lo sono
otto byte che è lungo e di nuovo il
il compilatore li distingue uno per uno
puoi vedere uno due tre quattro cinque sei
sette otto ma se guardi da vicino
vedrai che alcuni di loro riprendono
più spazio di quello che dovrebbero forse
il numero tre per esempio tre è uno
byte corrisponde a C che è uno
campo byte ma se guardi qui hai
ottenuto tre seguito da zero seguito da
quattro quindi c’è uno spazio in più lì dentro
la ragione per quella è quella struttura
i campi si riempiono l’idea è che è
più efficiente per accedere ai dati quando è
su un indirizzo di memoria che è divisibile
per la sua dimensione o almeno quale è
divisibile per qualunque sia l’hardware
l’architettura ama averlo
tipicamente è la sua dimensione quindi un due byte
il valore vuole essere su un numero pari
indirizzo a un valore di quattro byte vuole essere acceso
un indirizzo divisibile per quattro e cosa
il compilatore lo sprecherà
essenzialmente spreca memoria ma commercia
spegne la memoria contro il tempo espandendo
questi campi aggiungono un po ‘
spazio tra loro quando necessario
assicurati che si allineino così bene
che sono veloci da accedere e questo è
davvero per CC tipo ha camion e
questo è tutto e fa solo cose
fuori in sequenza e non c’è
i metadati non sono noti impliciti
puntatori o qualcosa del genere vedere cosa
vedi è quello che ottieni
C ++ diventa più interessante anche se qui
una semplice classe C ++ ne ho tre
metodi virtuali su di esso ha un campo
Creo uno e inizializzarlo e discarica
fuori e questo è quello che ottengo così possiamo
vedi ora non è solo una bolla è
ho un sacco di cose diverse e lo farò
ingrandirlo in modo che possiamo vedere cosa c’è
andare avanti fino in cima è il
oggetto reale è la cosa che ho creato
che contiene nel suo singolo campo
contiene il valore uno e possiamo vedere
che ha più di così semplicemente
aveva un campo ma qui ne abbiamo di più
roba in alto
il programma ha esplorato questo e ha rilevato che
a quella cosa in cima c’era un puntatore
che indica qui e poi quei punti
a più cose e così quella cosa al
top è un puntatore vtable quindi in C ++
come si fa metodo virtuale spedizione è
il primo pezzo di dimensioni puntatore di un
oggetto è un puntatore a una tabella V che
è una tabella di puntatori di funzione, quindi quando
chiama a qualcosa come te
conosci l’oggetto punto X cosa fa effettivamente
è che usa quella tabella per cercare il
implementazione di X per quell’oggetto e
è così che l’ereditarietà viene implementata se
allora sottoclassi qualcosa di override
quello genera una nuova tabella e quella nuova
la tabella contiene nuove voci per quelli
implementazioni del metodo in modo che il codice
sa che cosa ha bisogno di chiamare, quindi ecco un
esempio di questo
rapida sottoclasse di C ++ che eredita dal
quello precedente aggiunge un nuovo campo che aggiunge
un paio di nuovi metodi e quando tu
butta fuori che si ottiene un po ‘di più
roba e di nuovo zoomerò così qui
abbiamo l’oggetto in alto come
prima che tu abbia questo puntatore da tavolo V
e poi hai i campi e se
ti ricorderai che il campo numero uno era
dal campo della superclasse il numero due è
dalla sottoclasse li mette semplicemente
in sequenza quindi l’idea è quella quando
la superclasse sta facendo cose che può
guardalo e vede ciò che pensa sia
se stesso e poi i dati della sottoclasse
presentato in seguito quindi non c’è
conflitto lì, ma sono solo
imballato in modo efficiente nella memoria solo il
stesso e poi il vert il tavolo per il
la sottoclasse si allunga perché c’erano
cinque metodi ora ne avevamo tre dal
superclasse due dalla sottoclasse e
quindi li elenca solo in modo sequenziale
ogni metodo ottiene solo un indice in questo
tabella e sottoclassi ottengono la stessa tabella
è una superclasse, tranne che possono esserlo
potenzialmente più lungo se sono di più
i metodi aggiunti e le voci vengono sostituite
per indicare l’ override diamo un’occhiata
a eredità multipla è qui
le cose si fanno interessanti
C ++ consente a una classe di sottoclasse multiple
classi contemporaneamente così qui è un
seconda superclasse da seguire con la nostra
originale e qui è una sottoclasse di entrambi
quindi ogni superclasse ha alcuni metodi ciascuno
super
il vetro ha un campo che la sottoclasse ha a
campo crealo compilalo con alcuni
dati e questo è ciò che otteniamo è a
un po ‘più complicato il bene
la novità è che la maggior parte di questo è runtime
scrivi informazioni che possiamo gentilmente
di voi non sanno guardare troppo duro cerchiamo di
ingrandire e vedere cosa sta succedendo
quindi nuovamente oggetto è in cima e possiamo
vedere che inizia simile quindi è
ottenuto un puntatore da tavolo V seguito da quello
primo campo che è uno ma poi
succede qualcosa di interessante invece di
facendo solo uno due tre mettendo tutto fuori
i campi sequenzialmente otteniamo un’altra V
puntatore del tavolo nel mezzo del
oggetto e quindi questo è come si implementa
eredità multipla abbiamo una V
puntatore tabella nella parte superiore abbiamo
un altro là e l’idea è
che è un po ‘ come due oggetti incollati
insieme
quindi se prendi questo primo qui
questa è la tabella V che indica che è
un esempio di quella prima superclasse e
poi viene esposta la seconda superclasse
sotto di esso e cosa succede normalmente in Si
e con semplici classi C ++ se si memorizza nella cache
tra i tipi di cui hai un’istanza
una sottoclasse che dici trattalo come se fosse
erano un’istanza della sua superclasse
è proprio come alcuni inganni di contabilità
hai esattamente lo stesso puntatore
e tu dici solo ok, fingi questo
significa qualcos’altro ma quando arrivi
eredità multipla coinvolta all’improvviso
le cose diventano un po ‘più complicate e
se dici prendi questo puntatore e
interpretarlo come un puntatore al suo
superclasse cosa farà effettivamente
sposterà quel puntatore un po ‘
quindi in questo caso aggiungerà 16 a
quell’indirizzo e darti un puntatore
al centro di questo oggetto e perché
quel vtable è proprio lì tutto giusto
tipo di funziona ed è un po ‘di a
sistema pazzo ma ottiene il lavoro fatto
e così puoi vedere l’effetto qui dove
hai essenzialmente la tabella v per
entrambe le classi per la sottoclasse e ognuno di voi
parte di questo oggetto ha ottenuto due tabelle v su
l’oggetto che ognuno punta a a
parte diversa di questa tabella di feed e
tutto è solo un po ‘in linea con
queste molteplici super classi così tutto
funziona molto tempo di compilazione
inganno e quindi l’effetto finale è quello
runtime è tutto ben disposto
amichevole e veloce
amichevole per il computer non per noi ma
di solito è ok, quindi è C ++
ottenere cose pazze con più
eredità, ma di solito
semplicemente di nuovo si ottiene quella V
tavolo in alto che ti dice cosa
tipo di oggetto è e poi tutti
i campi sono appena disposti a volte
ottieni imbottiture a seconda delle loro dimensioni
ma è solo uno dopo l’altro
l’altro è in linea quindi passiamo a
Swift ora e Swift inizia molto
semplice come C e come C ++ così solo per
fai rotolare la palla e crea un
struttura vuota e non indovinerai mai cosa
sembra una struttura vuota contiene
niente è un oggetto di dimensioni zero
caratteristica interessante di questo lo fa
avere ancora un indirizzo in memoria
anche se non contiene nulla
il compilatore gli dà ancora un indirizzo che
Ho pensato che era una sorta di divertente probabilmente
non fa un sacco di senso per
il compilatore per ottimizzare per dimensione zero
struct poiché non li usiamo molto
molto passare ad un esempio più realistico
esempio più utile Ecco una struttura con
tre campi questo è essenzialmente il
equivalente rapido di quello vedere l’esempio I
ha fatto all’inizio tre campi uno
due e tre e sembra questo è il
restituisce l’output nel modo in cui è definito
in memoria assomiglia molto al modo in cui
è stato disposto nella memoria e vede e dentro
infatti non sembra proprio come è
esattamente lo stesso questi due sono disposti
esattamente nello stesso modo in modo Swift è solo
stendendolo uno due tre di fila
così non ci sono metadati fantasiosi
andando avanti non ci sono cose extra è
solo i tuoi campi e poi ho fatto lo stesso
cosa che ho fatto prima con il
più dimensioni e di nuovo otteniamo il
esatti stessi risultati quindi questo è un
struttura complicata con campi diversi
di diverse dimensioni e l’output è
esattamente come in C con uno
eccezione lo noterete dopo le tre
ne prendiamo uno due tre e poi c’è
questa cosa 5f prima delle quattro è giusta
perché il padding che viene inserito
non deve contenere alcun particolare
valore perché non significa niente
il padding è ignorato così prima quando io
corse la cosa su C è appena successo a
contenere
zero e quando l’ho eseguito su questo solo
è successo a contenere cinque F così questo è
è un po ‘come il DNA spazzatura dentro
il tuo programma ma ancora una volta è appena posato
esattamente nello stesso modo in cui C è così
nessun overhead è molto semplice
guardiamo un po ‘più complicato
cosa vediamo come appare una chiusura rapida
così semplice risultato complicato è
non così male come sembra essenzialmente cosa
ci stai arrivando è Swift
ha questa intera gerarchia di cose e questo
rappresenta sa quali tipi significano a
runtime e voglio ingrandire un po ‘
quindi possiamo vedere l’oggetto, ma tutto
questa altra roba sta succedendo è
essenzialmente sta dicendo che la tua classe
è in realtà una sottoclasse di questo nascosto
Classe di oggetti Swift e in quella classe ha
una meta-classe e tutto il resto
ci sono tutti questi metadati che stanno andando
su quello che puoi usare per ispezionare oggetti
e cose del genere, ma possiamo soprattutto
ignoralo
quindi se ignoriamo tutte le altre cose e
tipo di zoom in cui guardiamo l’istanza
dell’oggetto qui e possiamo vedere il
dati disposti in memoria uno due tre
e c’è un’intestazione sopra di esso che è
simile al modo in cui è stato il C ++
in C ++ avevamo una tabella V e poi lì
erano i campi e in Swift abbiamo un
è un puntatore che è essenzialmente il
equivalente rapido di una tabella V punti
alla classe oggetti allora ne abbiamo alcuni
altre cose di cui parlerò in a
momento e poi hai ottenuto i campi così
hai la stessa disposizione di un’intestazione
seguito dai campi appena imballati
memoria piacevole lineare veloce Hardware
amichevole e diamo un’occhiata a
questo è un po ‘più complicato
è l’equivalente di classe di quella struttura
che ho mostrato e finisce per essere il
Esattamente la stessa cosa con quel tipo di
header messo in cima così hai capito
è un puntatore che hai quest’altra roba
che raggiungerò e poi tutto il
i campi sono appena disposti esattamente allo stesso modo
modo in cui sarebbero in una struttura
sequenzialmente con un po ‘di padding da fare
tutto fila bene così questo è
sorta di rappresentazione visiva il
rappresentazione astratta perché quelli
le cose esadecimali ti rendono doloroso
leggere dopo un po ‘quindi questo è quello che
significano se tu effettivamente entri e
interpretalo tu hai il puntatore
quell’altro campo di intestazione che non ho fatto
menziona ancora quelli che ritengono ti conta
può o non può sapere che funziona rapido usando
conteggio automatico dei riferimenti, quindi è necessario
per contare il numero di riferimenti a
ogni oggetto e in Swift quei conteggi
sono memorizzati nell’oggetto stesso
secondo campo di intestazione e quindi il tuo memorizzato
le proprietà vengono appena approntate dopo
il compilatore ne ha appena messo uno a uno
e ho detto che il trattenimento conta così tanto
ci sono in realtà due conteggi in un attimo
oggetto questo è un piccolo interessante
caratterizzare il modo in cui il sistema funziona non c’è
il conteggio forte e il conto debole così
quando fai un riferimento normale a a
oggetto rapido che incrementa il forte
conta e poi se fai un debole
riferimento a un oggetto che aumenta
il conto debole e l’idea è quella in cui
il conteggio forte va a zero se il
il conteggio debole è diverso da zero, quindi l’oggetto è
distrutto ma non è disallocato e
quello potrebbe essere un discorso da solo
Ho un articolo sul blog se qualcuno
importa esattamente come funziona, ma
questo è essenzialmente ciò che stiamo vedendo
lì quindi ci sono due conteggi separati
imballato nello stesso campo ogni uno io
penso che sia come 31 bit o qualcosa del genere
come quella
e poi diamo un’occhiata a che è un
struttura in modo tale che sia una struttura in C ++
la tabella V era solo una lista di metodi
puntatori e Swift è un po ‘
più complicato in parte a causa di
obiettivo-c Interop Swift deve funzionare
con il materiale oggettivo-c di apple e in
Infatti tutte le classi Swift nella memoria sono
anche le classi obiettivo-c come fatto è
nascosto da noi a volte se tu
sottoclasse esplicitamente e rifiuta una classe c
allora si può vedere se si utilizza l’a
l’ annotazione della tabella C è visibile ma
anche se non fai niente di tutto ciò e lo fai
quello che sembra una pura classe Swift è
in realtà una classe obiettivo- solo il
stesso e solo per essere un po ‘di più
è accurata la prima parte di un oggetto
non necessariamente il è un puntatore
a volte è un puntatore lungo
con qualche altra roba questo è solo un modo
per ordinare un pacchetto efficiente
metadata lì Apple lo fa su iOS
64-bit non credo che lo facciano
il Mac al momento è tutto questo soggetto
cambiare ma in fondo possono mettere poco
ci sono due bit di informazione lì dentro
se questo oggetto ne abbia mai avuto
oggetti associati con esso che hanno bisogno di
essere ripulito quando è de-allocato e
cose del genere
solo veri dettagli veloci, quindi cosa fare
queste strutture di classe sembrano da allora
ogni obiettivo da ogni classe veloce
è anche una classe obiettivo-c che significa
che possiamo guardare alla classe Objective C
definizioni per vedere cosa sta succedendo e
Le definizioni della classe C oggettiva fanno parte
del runtime oggettivo-c che è aperto
fonte che è conveniente, quindi possiamo solo
guarda in runtime th nell’open source
scarico lì e se guardiamo lì e noi
vedere cosa sta succedendo questo è ciò che otteniamo
quindi ogni classe è anche un oggetto valido in
memoria quindi se ricordi un oggetto
inizia con un è un puntatore in modo che
significa che ogni classe inizia con un è a
puntatore come pure in modo che ogni classe è anche
un oggetto una classe ha una classe che è
ha chiamato la meta-classe e tu puoi seguire
quel buco coniglio fino in fondo fino
si ottiene molto confuso della classe anche
memorizza la superclasse in modo tale da permetterti di
segui la catena e in sostanza
esplorare gli archivi di classi della gerarchia di classi
il suo nome e memorizza un mucchio di altri
roba memorizza quanto sono grandi i suoi oggetti
memorizza un elenco di variabili di istanza
e metodi e ha una cache che
accelera la spedizione dei metodi e poi
Le lezioni veloci prendono tutto questo e loro
aggiungi altro materiale perché Swift ne ha di più
roba in corso quindi se si guarda nel
Swift open source per vedere cosa è coinvolto
ci abbiamo alcune bandiere abbiamo ottenuto questo
compensa un sacco di cose bizzarre ma
essenzialmente una classe Swift è la
classe Objective-C con più roba sul
fine e quindi questa è una parte interessante
dopo tutti questi campi è una lista di
di nuovo metodi come una serie di metodi
implementazioni così essenzialmente è il
Approccio C ++ vtable di nuovo con alcuni
cose extra in cima che possiamo
ignorare e quindi ciò che significa è quello
quando fai una chiamata al metodo in Swift
traduce essenzialmente in un array
ricerca in modo da scrivere oggetto
Qui
e questo si traduce in codice come questo
quaggiù, quindi in sostanza prendi il
oggetto si ottiene che è un campo fuori di esso
e poi basta indicizzarci per ottenere
il puntatore del metodo e poi si salta a
essenzialmente fai una chiamata di funzione
basato su quello e quindi è veloce è
efficiente in fase di esecuzione diamo un’occhiata
a cosa assomiglia un oggetto quando tu
sottoclassi un sacco di cose così l’ho fatto
quindi una classe una sottoclasse di una sottoclasse di quella
e così via quattro livelli in profondità e questo
sembra esattamente lo stesso, così hai capito
è un puntatore in alto che ti dice
che cosa è che hai i conteggi trattenere
sotto quello e poi il campo di ciascuno di
tutte quelle lezioni vengono appena esposte
in sequenza proprio come in C ++ abbiamo visto
prima di allora in fase di esecuzione è molto semplice
anche se la gerarchia di classe noi
guardato era un po ‘lungo e complesso
diamo un’occhiata agli array e Swift
gli array in Swift sono tipi di valore che
significa che agiscono come primitivi
essenzialmente quando assegni x è uguale a y
ciò crea concettualmente una nuova matrice
che è codificato separato dal
originale questa discarica rivela che è
essenzialmente una bugia sono in effetti
tipi di riferimento sotto il cofano il modo
sono implementati quindi questo array uno
due tre quattro cinque se in effetti guardi
a esso è solo un singolo puntatore e
quello indica uno due tre quattro e
poi cinque dopo quello che ha funzionato
fine quindi è stato troncato e quindi cosa c’è
continuando con quello è ogni matrice consapevole
con cui lavori è in realtà un puntatore
allo stoccaggio e quando ne fai un nuovo
array si ottiene solo un nuovo puntatore al
lo spazio di archiviazione non accade e lo è
solo quando lo modifichi effettivamente lo farà
entrare e vedrà oh qualcun altro
riferimenti questo creerò una copia e
quindi modificare quella copia
quindi fa ancora riferimento sotto il cofano
non lo vedi fino a quando non corri
programma come questo, allora lo vedi
dai un’occhiata ai tipi di protocollo questo è un
aspetto interessante di Swift quindi ecco a
Protocollo Swift ha tre metodi in
qui è una struttura che ne contiene tre
istanze di quel protocollo che puoi
usa un protocollo come tipo stesso e quello
può contenere un’istanza di qualsiasi cosa
implementa quel protocollo
ecco una struttura che la implementa
ha solo implementazioni vuote di
quei tre metodi ha anche un
campo che è solo un numero intero
contenente lo strano valore esadecimale che
il valore esadecimale spiegherà la parola è
piccolo in ASCII fondamentalmente è così
che quando faccio la discarica possiamo identificarci
perché cercherà che
stringa vedrà mostrarlo nel
stampa
ecco un’altra struttura questo è più grande
uno ha quattro campi il primo
spiega bene e gli altri solo
contenere uno due e tre ripetuti solo
in modo che si presentino bene e finalmente
ecco una classe se questo vuole avanzare
sì il mio Wi-Fi non sta collaborando c’è
una classe uguale alla struct
essenzialmente tranne che spiega la lezione
invece e così vogliamo vedere come questi
essere rappresentati così qui creiamo un
istanza di tale titolare del protocollo
contenente un’istanza del piccolo
struct una istanza della struttura grande
in un caso della classe e se noi
buttalo qui è quello che otteniamo
una visione più ampia di questo è molto complicata
ma possiamo vedere quella struttura nell’elenco
di stringhe che ha trovato trovato piccolo
quindi possiamo dire da questo che piccolo
la struttura viene effettivamente memorizzata in linea
protocollo che campo di tipo di protocollo è
in grado di memorizzare quella struttura in linea ma
la grande struttura non viene memorizzata
linea e, naturalmente, la classe no
perché la classe è un riferimento e
dove è andata quella grande struttura perché?
le strutture normalmente vengono memorizzate in linea ma
questo è stato grande finisce per ottenere
immagazzinato qui di lato se insegui
le frecce intorno ed essenzialmente cosa
è successo questo è troppo grande per adattarsi al
il compilatore non può sapere quanto sono grandi queste cose
stanno per essere così posiziona un
limite di dimensioni arbitrarie e quando vai
oltre quel limite quindi il compilatore dietro
le tue scatole posteriori assegnano qualcosa
in modo dinamico e lo memorizza qui così
qui grande
immagazzinati nelle erbacce da qualche parte se
si inseguono in giù in realtà guardano
come queste cose sono implementate un valore
di protocollo di tipo contiene cinque campi che
contiene tre campi di dati arbitrari e
quindi contiene alcuni metadati di tipo che
essenzialmente ti dice di cosa si tratta e
quindi tiene un cavo testimone che è
come una tabella V per il protocollo e
questi tre campi di dati sono indicati
a qualunque sia il tipo ne ha bisogno per così
se hai una struttura che la trattiene
molte cose o meno vengono memorizzate
linea molto efficiente e tutto è
veloce e non appena lo superi
limite improvvisamente deve ottenere scoppiata
viene inscatolato e viene assegnato
in modo dinamico e si perde un sacco di
efficienza e questo è tutto nascosto da
tu non te ne accorgi fino al tuo codice
diventa lento quindi la tabella dei testimoni è
fondamentalmente una tabella V è solo una matrice di
implementazioni come il C ++ V
tavolo e questo significa che quando tu
effettuare una chiamata al metodo su un protocollo digitarlo
sembra molto simile a una chiamata di metodo su un
oggetto perché hai lo speciale
tabella solo per il protocollo così quando tu
fare una chiamata si ottiene un tipo di protocollo come
che fai PG, fai una chiamata che traduce
in qualcosa di simile a ciò che prendi
che tu guardi il tavolo vicino
guardando la quarta parola e il
protocollo e quindi si utilizza l’ offset in
il tavolo che conosci perché
il compilatore sa solo che è quello
metodo e quindi basta effettuare la chiamata
basato sul puntatore della funzione e quindi
se hai una struttura troppo grande
finisce per sembrare così al posto di
avendo campi dati che primo campo dati
è in realtà un puntatore ai dati reali
quindi tutto viene immagazzinato qui
hai il tavolo là e poi
i metodi qui sanno che quando loro
devono fare le loro cose devono andare
su e insegui quel puntatore ed è tutto
appena gestito dietro la schiena ed è
non collaborando di nuovo, anzi, eccoci
in um SAR un caso molto interessante in
Swift Swift ha questi livelli elevati
tipi di enumerazione in cui è possibile avere
dati associati e tutto ciò che o loro possono
solo essere cose molto semplici qui è un
caso semplice solo cinque casi niente
associati a loro solo ABCD ed E
una struttura che manterrà quelli e il
il risultato sono quelli presentati in modo molto sintetico
zero uno due tre quattro ciascuno ottiene a
numero diverso sono lunghi un byte
perché non abbiamo bisogno di più di un byte
per rappresentare cinque valori ed è tutto
molto bello e compatto ecco una versione
con un valore di reggiseno in modo da poter effettivamente andare
attraverso e dico a Swift che voglio i miei casi
per corrispondere a valori specifici , quindi cosa
questo dice che a è 1 B è 2 C è 3
questi 4 e sono 5 e vediamo cosa
sembra e una cosa interessante è
non cambia non va 1 2 3 4 5
va ancora 0 1 2 3 4 tutto bene
a corto di tempo qui, molto velocemente
basta andare per una stringa, se puoi
eseguire stringhe di valori non elaborati in modo tale che a sia tutto
e poi BCD e ottieni quelli predefiniti
sono solo BCD uni e quelli ancora sono 0 1
2 3 4 e in sostanza cosa sta succedendo
qui è possibile salvare il valore grezzo
in una tabella separata da qualche parte il
il compilatore sa che non c’è per
istanza valore grezzo di qualsiasi tipo, quindi può
solo essere 0 1 2 3 4 e da qualche altra parte
c’è una tabella che dice che 0 è qualsiasi cosa
1 è B 2 C e così via, va bene
guarda gli oggetti associati molto velocemente
questo è solo un enume il primo caso ha
un oggetto associato ad esso e il
altri non lo fanno e se lo buttiamo via noi
scoprire che ha ampliato perché
deve essere in grado di memorizzare quell’oggetto
puntatore ma è espanso in modo intelligente
quindi la prima cosa non è solo un raw
puntatore dell’oggetto e poi gli altri
sono solo piccoli numeri interi e il compilatore
è in grado di comprimere questi in modo che sappia 0
2 4 e 6 non possono mai essere un puntatore valido così
è in grado di usarlo per distinguere
tra quelli e poi se ce la facciamo
più grande abbiamo un enum con ABCD ed E
dove hanno tutti gli oggetti associati
con loro e all’improvviso tutto diventa
più grande ogni voce è un puntatore seguito
da un intero così oggetto puntatore 0 oggetto
puntatore 1 oggetto puntatore all’oggetto
puntatore 3 quindi il numero che ottiene
assegnato a ciascuno
caso e il valore associato
essenzialmente vengono disposti accanto a ciascuno
altro il compilatore è in grado di comprimerle
in modo compatto per quel caso specifico ma
non nel senso generale
va tutto bene così, sto andando
per tipo di saltare attraverso questi reali veloci
dato che siamo in ritardo, abbiamo
vera memoria fisica che abbiamo
memoria concettuale e quindi abbiamo
una sorta di reale si conosce il
l’architettura di tutto vede solo
cose belle e semplici con
un po ‘di riempimento oggetti C ++
sarà tavolo negli oggetti più veloci
ottenere lo stesso tipo di cosa, ma con più
roba in corso
i valori del protocollo finiscono col prenderne cinque
parole di memoria a volte possono essere archiviate
dati in linea ma se diventi troppo grande loro
no e le enumerazioni finiscono per essere confezionate
molti modi diversi a seconda di cosa è
andando avanti c’è la nostra rapida somma su cui
Ho appena detto e quindi puoi imparare a
molto spaccando è molto divertente
e qualche volta è utile e come loro
mi ha chiesto di ricordartelo e come ho fatto io
prima di ricordare di valutare la sessione in
l’app e basta così se c’è
domande che possiamo o se non abbiamo tempo
per domande o ok puoi usare Swift
angolo squadra con Pio e Xcode quando
debugging Non penso che ce ne sia
modo integrato per farlo, ma ciò che puoi
fare è semplicemente copia incolla sul comando
linea
manger rapidamente dovrebbe essere disponibile in
il terminale se lo volevi, ne sono sicuro
potresti costruire un piccolo script che conosci
lld b è scriptable attraverso python così
potresti farlo se ciò si rivelasse essere
utile sì va bene così la domanda è qualsiasi
contro qualsiasi oggetto in Swift tre e
se ci sono cambiamenti basati su
se tu importi una fondazione, io no
penso che ci sarebbero cambiamenti nel
layout basato su cosa si importa perché
ci deve essere compatibilità incrociata
tra i file che importano Foundation
file che non sono così sarebbero ancora
deve essere lo stesso ma qualsiasi in in Swift
tre oggetti obiettivo-c
gli oggetti non tipizzati ora entrano come qualsiasi
invece di qualsiasi oggetto quindi c’è
sicuramente un cambiamento lì
Credo che sia essenzialmente un
fase di traduzione qualsiasi è penso sembra
come uno dei tipi di protocollo in cui
è una cosa da cinque parole che ha tre in
linea e qualunque cosa ed è essenzialmente
immagazzinando le cose in quel modo e poi c’è
solo un passo in cui lo prende
Puntatore Objective C che arriva e
solo tipo di metterlo in uno di quelli
cose il codice sorgente è online per il mio
cosa dovrebbe finire più o meno fuori
della scatola quindi se vuoi sperimentare
e vedere che cosa fa sai sente
liberare tutto il resto no, va bene oh si
certo sì , la domanda riguarda il nuovo
funzioni di debug della memoria in xcode 8
e come si confronta con la mia roba in modo che
nuova roba di debug della memoria è davvero
cool puoi passare e sarà solo
essenzialmente ti mostra una specie di grafici come
Ho mostrato qui eccetto che sono in diretta che
è davvero pulito e non ho giocato con
è un sacco ma sono sicuro che lo sarà
davvero utile è un po ‘di più
limitato da quel poco che ho fatto
con esso in quanto cerca di bene è
devo lavorare al runtime per farti sapere
deve essere un po ‘limitato in questo
rispetto credo che non traccerà come
vedi puntatori e cose del genere a
almeno non oltre un certo punto è
non sta andando a tracciare i simboli globali
e cose del genere ma per quanto possibile
guardando giocare Swift oggetti è
veramente bello ti mostrerà gli alberi
sapere come mostrarti questo oggetto punti
a quell’oggetto e penso che accadrà
saltare le cose come i puntatori fino a
le classi quindi non ti danno
tutto tranne per quello che ti interessa
è tutto molto bello
davvero utile sembra proprio
è grazie mille per essere venuti
e goditi il ​​resto della conferenza
tu

Please follow and like us: