1. A method performed by a memory controller implemented as part of a coherent memory architecture employing multiple levels of caches, comprising: controlling access to system memory, the accesses including memory writes and memory reads; monitoring patterns of accesses to the system memory, including monitoring bursts of writes to the system memory, the bursts of writes corresponding to function calls from an execution thread written to sequential address; detecting that a new stack frame corresponding to a called function is added to a stack for the execution thread, the new stack frame beginning with a frame pointer; updating a current frame-pointer for the stack to the frame-pointer for the new stack frame; detecting a return address for a function call in the system memory; and preventing the return address from being overwritten unless the memory controller determines overwriting the return address is safe.