Chapter 01 / 10 · Foundations

From source code to a running process

Before pricing anything, know what actually happens between hitting run and code executing.

Type python app.py or click Run, and something happens that most working engineers never look at directly. This chapter looks at it once, properly — because every debugging session, every performance question, and every security conversation in this pathway stands on this floor.

What a CPU actually executes

A CPU understands a few hundred primitive instructions: load a value from memory into a register, add two registers, compare, jump to another instruction if the comparison said so. That is the entire vocabulary. Everything you have ever written — classes, closures, async handlers — is eventually this, executed billions of times a second in a loop the hardware never leaves: fetch the next instruction, decode it, execute it, repeat. There is no “if statement” in silicon; there is a compare and a conditional jump. Holding that picture is what lets the later chapters talk about branch prediction and instruction cost without hand-waving.

The three roads from source to instructions

StrategyHowYou feel it as
Ahead-of-time compileC, C++, Rust, Go — translated to machine code before shippingfast start, fast run; a build step; per-platform binaries
Interpretclassic Python, Ruby — a program reads your program and does what it saysinstant start, 10–100× slower inner loops
Bytecode + JITJava, C#, JavaScript — compile to a portable form, then compile the hot parts to machine code at runtimeslower warm-up, near-native steady state

The rows blur in practice — Python compiles to bytecode, JavaScript engines interpret first and JIT later — but the model explains real behaviour: why a Java service needs a warm-up before benchmarking, why a Python hot loop is worth pushing into a library written in C, why “compiled vs interpreted” is a property of the implementation, not the language.

From file on disk to process

An executable is mostly a labelled box: machine code in one section, constants in another, a note of which shared libraries it needs. Running it asks the OS to create a process — a fresh virtual address space (next chapters’ subject) — into which the loader maps the code and libraries, then jumps to the entry point. From that moment the program computes privately until it needs the outside world: reading a file, opening a socket, even asking the time. Each of those is a system call — a controlled trap into the kernel, the only door out of the sandbox. User code computes; the kernel does I/O; the boundary between them costs real time and appears on every profile you will ever read.

The call stack, physically

When a() calls b(), the machine pushes a stack frame: the return address, the arguments, b’s local variables. Return pops it. That is the whole mechanism — and it makes several familiar things suddenly literal. A stack trace is the machine reading you its frames, top of the stack first. A stack overflow is unbounded recursion running out of frame space. And the reason local variables are so much cheaper than heap objects (the previous chapter’s ladder) is that a frame is allocated by moving one pointer.

Where it bites

  • Benchmarking a JIT runtime cold — the first thousand iterations measure the compiler, not your code.
  • A hot loop making a syscall per iteration (one byte per read()) — the kernel boundary tax, paid maximally.
  • Reading a stack trace bottom-up and “fixing” the frame that merely called the broken one.
  • Treating “Python is slow” as a law rather than a boundary question — the fast path is putting the loop on the other side of it (NumPy, the database, a compiled extension).