Är ”call site” någon autokod som genereras av kompilatorn – jag stöter på den här termen ofta och det låter som att callmetoden helt enkelt kallas ”call site” – som bokstavligen låter bra men jag tror att det har lite djupare intrikat. Och om ”samtalswebbplats” är kompilatorgenererad kod – under vilka omständigheter krävs detta?
Även om jag pratar i samband med C # .Net, men det ser ut att vara standardterminologi. Skulle uppskatta någon tydlig / exakt förklaring med några exempel.
Kommentarer
- Det finns en uppfattning om samtalswebbplats både i källkoden och i auto -genererad objektkod.
- Du kanske vill se hur samtalswebbplatser genereras för en dynamisk operation i C # 4 och högre. De är ganska intressanta.
- @EricLippert Tack. Lyckligtvis hittade jag länk där du beskrev den ganska vackert. Jag kunde dock inte hitta någon blogg som du specifikt beskriver när det gäller generering av samtalswebbplatser.
Svar
”Ring webbplats ”Avser den plats där en funktion eller metod anropas. Det är en vanlig term inom kompilatorkonstruktion och inte specifik för C #.
foo(); // call site void foo() { ... } // function definition
Samtalssidan är ingen speciell genererad kod. Men på samtalsplatsen avger kompilatorn instruktioner för att ringa funktionen. Vanligtvis dessa:
- Spara det aktuella sammanhanget i en stapelram.
- Lagra alla argument enligt målfunktionens anropskonvention.
- Ring målfunktionen, vilket kan kräva att metoden skickas.
- Hämta returvärdet enligt anropskonventionen.
- Återställ sammanhanget från stackramen.
Metodavsändning kan kräva komplicerad kod för att kunna hitta den funktion som egentligen ska kallas. Detta är nödvändigt när du anropar virtual
-metoder, särskilt metoder via ett gränssnitt. Det fullständiga metodutskickningsförfarandet kan vara ganska kostsamt (ofta O (n) i antalet implementerade gränssnitt, eller O (n) i antalet tillgängliga metoder). Men oftast (vanligtvis 70–90%) kommer en samtalswebbplats att se objekt av samma typ. Det är sedan vettigt att cache-resultatet av metodens sökning. Kompilatorn kan då generera kod så här på samtalsplatsen:
static lastType = null; static lastMethod = null; if (type(instance) != lastType) { lastType = type(instance); lastMethod = performMethodLookup(instance, methodName); } result = lastMethod(instance, args);
Detta är känt som en monomorf inbyggt cache . .NET CLR utvecklade ett lite mer komplicerat tillvägagångssätt som heter Virtual Stub Dispatch . Istället för att göra sändningen på samtalswebbplatsen sammanställer JIT-körningsmetoderna runtime. Det finns olika stubbar för att göra hela metoden för utsändning och för att använda en cachad metod. På samtalsplatsen ringer vi bara till stubben och stubben vidarebefordrar samtalet till det faktiska målet. Beroende på statistiken för den här samtalswebbplatsen lappas maskinkoden på samtalswebbplatsen så att den använder en annan stub.
Svar
Den mest typiska användningen av call-site är förmodligen att som för närvarande förklaras på Wikipedia : det är inget annat än platsen i någon kod där ett samtal till en funktion eller subrutin görs. Det är en helt allmän term som kan tillämpas på alla typer av språk (och absolut inget att göra med dynamisk programmering!).
Jag hör vanligtvis termen som används (i motsats till bara term ”samtal”) för att göra det tydligt att man diskuterar syntaxen och semantiken för koden där en funktion / metod / underrutin kallas, i motsats till den underliggande semantiken för samtalet, eller semantiken vid funktion / metoddefinition: i på det här sättet handlar det absolut inte om kompilatorn eller någon genereringskod (även om termen fortfarande kommer att gälla för koden som genereras av kompilatorn / runtime, som jag tror amon redan har diskuterat), det är om att föra den specifika koden som översätts till ett samtal i sitt sammanhang, och ibland koden i omedelbar närhet.
Det här är den typ av bild jag har i mitt huvud:
call-site call call-target/method definition --> --> int.TryParse(str, out i); (runtime) public static bool TryPars(...
” Call-site ”är en användbar term för att tala om syntax för att ringa samtal och semantiken som påverkar den som ringer (detaljerad av amon). Tänk till exempel på den nya in
modifieraren i C #, ett ”samtal” som skickar ett argument som ”in” har vissa semantik associerade med sig (det skickas av ref, möjligen efter en kopia), men detta är inte nödvändigtvis klart från syntaxen ”vid samtalsplatsen”, där in
inte är obligatoriskt. Tanken är att semantiken för anropssidan (dvs. beteendet som påverkar den som ringer / anropssidan) för att skicka ett argument med referens med in
är nära tillräckligt för de som passerar värde att det inte behöver tydas av syntax på samtalsplatsen .Jag håller inte med detta påstående och jag skulle ha svårt att diskutera det utan en term som ”call-site”!
Ett annat exempel: ett dynamiskt samtal (t.ex. för en virtuell / gränssnittsmetod) har något komplicerade körtidsbeteenden (igen, detaljerad av amon) och det är inte känt vid sammanställningstid vilken metod som kommer att kallas, men allt ”call-site” bryr sig om är semantiken för att skicka det samtalet: om du ringer ToString()
på en object
, bryr du dig inte verkligen om att det faktiskt är en string
på samtalsplatsen; du bryr dig bara om att object
exponerar en virtuell ToString()
-metod (det är upp till körtiden för att räkna ut vilken metod du faktiskt ska ringa). På samtalsplatsen (t.ex. i C #) är det inte nödvändigtvis tydligt från syntaxen om detta är ett virtuellt samtal: skillnaden mellan ett virtuellt och icke-virtuellt samtal anses ofta vara tillräckligt viktigt vid samtalet- webbplats att den inte behöver vara otydlig för programmeraren på samtalsplatsen (även om det är mycket viktigt för kompilatorn / körtiden att ringa ett meningsfullt samtal)
Ett sista exempel: överväga C # ”s ref
och C ++” s &
: semantiken på samtalsplatsen i båda språk är ungefär desamma på båda språken: en referens skickas snarare än ett värde, men varje språk har olika syntax på samtalsplatsen, där C # kräver ref
och C ++ inte kräver &
(eller något liknande). Återigen har språkdesignerna tagit några syntaxbeslut om hur samtal representeras på samtalsplatsen, informerade av semantiken på samtalsplatsen. (Jag föredrar C # syntax för call-site eftersom den exponerar semantiken för call-site, vilket jag tror att jag som programmerare borde behöva erkänna när jag ringde ett sådant samtal). Det är förhoppningsvis uppenbart att metoddefinitionen behöver veta att den tar emot en parameter som referens, eftersom den ändrar beteendet för att ändra den (t.ex. med =
). Du kan dock argumentera för att runtime inte bryr sig (på sådana statiskt skrivna språk, där runtime-utsändning är nominellt informerad): det måste bara få detta värde från den som ringer till callee , det bryr sig inte om det är en referens eller inte, det är ett problem för samtalsplatsen och samtalsmålet.
Mer löst kan ”call-site” hänvisa till koden som indikerar ett samtal såväl som den ”associerade” koden runt det (i motsats till bara ”samtalet”). I C # kan man till exempel hänvisa till att definiera en dummyvariabel ”vid” en samtalsplats, t.ex. när du ringer till en TryParse
metod:
int dummy; bool looksLikeAnInt = int.TryParse(str, out dummy);
Hela detta ”block” kan betraktas som en del av samtalsplatsen. Jag anser att detta är en mindre ”exakt” mening, men det hindrar mig inte från att använda det.