0

Is 'call site' some auto code generated by compiler - I come across this term frequently and it sounds like calling method is simply referred as 'call site' - which literally sounds fine but I believe it has some deeper intricacies. And if 'call site' is compiler generated code - under what circumstances this is required?

Though I am talking in context of C#.Net, but this looks to be standard terminology. Would appreciate any clear/precise explanation with some examples.

3
  • 1
    There is a notion of call site both in the source code and in the auto-generated object code.
    – Erik Eidt
    Commented Feb 11, 2018 at 15:14
  • You might want to look into how call sites are generated for a dynamic operation in C# 4 and above. They are quite interesting. Commented Feb 12, 2018 at 19:28
  • @EricLippert Thanks. Fortunately I found link where you described it quite beautifully. However I could not find any blog by you specifically detailing around call site generation. Commented Feb 16, 2018 at 13:46

2 Answers 2

6

“Call site” refers to the place where a function or method is called. It is a common term in compiler construction, and not specific to C#.

foo();  // call site

void foo() { ... } // function definition

The call site is not any special generated code. But at the call site, the compiler emits instructions to call the function. Typically, these:

  • Save the current context in a stack frame.
  • Store all arguments according to the calling convention of the target function.
  • Call the target function, which may require method dispatch.
  • Retrieve the return value according to the calling convention.
  • Restore the context from the stack frame.

Method dispatch may require complicated code to run in order to find the function that should actually be called. This is necessary when calling virtual methods, especially methods through an interface. The complete method dispatch procedure may be rather costly (often O(n) in the number of implemented interfaces, or O(n) in the number of available methods). But most of the time (typically 70–90%), a call site will see objects of the same type. It then makes sense to cache the result of the method lookup. The compiler might then generate code like this at the call site:

static lastType = null;
static lastMethod = null;
if (type(instance) != lastType) {
  lastType = type(instance);
  lastMethod = performMethodLookup(instance, methodName);
}
result = lastMethod(instance, args);

This is known as a monomorphic inline cache. The .NET CLR developed a slightly more complicated approach called Virtual Stub Dispatch. Instead of doing the dispatch at the call site, the runtime JIT-compiles stub methods. There are different stubs for doing the full method dispatch procedure and for using a cached method. At the call site, we then only have a call to the stub, and the stub will forward the call to the actual target. Depending on the statistics for this call site, the machine code at the call site will be patched to use a different stub.

1

The most typical use of call-site is probably that as presently declared on Wikipedia: it is nothing more than the place in some code where a call to a function or subroutine is made. It is a completely general term that can be applied to all manner of languages (and certainly nothing to do with dynamic programming!).


I usually hear the term used (as oppose to just the term "call") to make it clear that one is discussing the syntax and semantics of the code where a function/method/subroutine is called, as oppose to the underlying semantics of the call, or the semantics at function/method definition: in this way, it is absolutely not about the compiler or any generate code (even though the term will still apply to the code generated by the compiler/runtime, as I think amon has already discussed), it is about bringing the specific code that translates to a call into context, and sometimes the code in the immediate vicinity.

This is the sort of picture I have in my head:

  call-site                         call           call-target/method definition
                            -->              -->
int.TryParse(str, out i);         (runtime)        public static bool TryPars(...

The 'call-site' is a useful term to talk about syntax of making a call, and the semantics which affect the caller (detailed by amon). Consider, for example, the new in modifier in C#, a 'call' which passes an argument as 'in' has certain semantics associated with it (it is passed by ref, possibly after a copy), but this isn't necessarily clear from the syntax 'at the call site', where in isn't mandatory. The idea is that the call-site semantics (i.e. the behaviour which influences the caller/call-site) of passing an argument by reference with in are close enough to those of passing by value that it doesn't need to disambiguated by syntax at the call-site. I disagree with this claim, and I'd have a hard time discussing it without a term like 'call-site'!

Another example: a dynamic call (e.g. for a virtual/interface method) has somewhat complicated runtime behaviours (again, detailed by amon) and it isn't known at compile time which method will be called, but all the 'call-site' cares about is the semantics of dispatching that call: if you are calling ToString() on an object, you don't really care that it is actually a string at the call-site; you only care that object exposes a virtual ToString() method (it's up to the runtime to work out which method to actually call). Indeed, at the call-site (e.g. in C#) it isn't necessarily clear from the syntax whether this is a virtual call: the distinction between a virtual and non-virtual call is often considered unimportant enough at the call-site that it doesn't need to be disambiguated for the programmer at the call-site (even though it is vitally important for the compiler/runtime to make a meaningful call)

One last example: consider C#'s ref and C++'s &: the semantics at the call-site in both language are just about the same in both languages: a reference is passed rather than a value, but each language has different syntax at the call-site, where C# requires ref and C++ does not require & (or something like that). Again, the language designers have made some syntax decisions about how calls are represented at the call-site, informed by the semantics at the call-site. (I prefer the C# call-site syntax because it exposes the call-site semantics, which I believe I as a programmer should have to acknowledge when I made such a call). It is hopefully obvious that the method definition needs to know it is receiving a parameter by reference, because it changes the behaviour of modifying it (e.g. with =). You could argue, however, that the runtime doesn't care (in such statically typed languages, where runtime-dispatch is nominally-informed): it just has to get this value from the caller to the callee, it doesn't care whether it is a reference or not, that is a concern for the call-site and call-target.


More loosely, 'call-site' might refer to the code which indicates a call as well as the 'associated' code around it (as opposed to just the 'call'). In C#, for example, one might refer to defining a dummy variable 'at' a call-site, e.g. when calling a TryParse method:

int dummy;
bool looksLikeAnInt = int.TryParse(str, out dummy);

This whole 'block' could be considered part of the call-site. I'd consider this a less 'precise' meaning, but that doesn't stop me using it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.