/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* <h1>Code Eviction in the Maxine VM</h1>
* Maxine features no interpreter but instead employs only <a href="http://en.wikipedia.org/wiki/Just-in-time_compilation">just-in-time compilation</a>.
* This implies considerable amounts of machine code are created in the course of executing an application. Machine code can become outdated:
* methods may, after their first execution, later be recompiled by the optimizing compiler, and static class initializers are even executed only once.
* To address the memory requirement issue, <i>code eviction</i> was introduced to Maxine in Fall 2011 for baseline code,
* that is, machine code generated by the <a href="https://wikis.oracle.com/display/MaxineVM/T1X">T1X compiler</a>.
*
* <h2>Baseline Code Cache Management</h2>
* Prior to the introduction of code eviction, Maxine featured two <i>unmanaged</i> code caches, that is, memory areas where machine code is placed.
* The boot code region contains all machine code belonging to the VM, it is filled during
* <a href="https://wikis.oracle.com/display/MaxineVM/Boot+Image">boot image building</a>.
* The run-time code region was the one where all code generated by either of the JIT compilers went. After introducing code eviction,
* the boot code and run-time code regions still exist and are unmanaged, but the latter now only contains code generated by the optimizing compiler.
* One managed code region for baseline code was added. It adopts a <i>semi-space</i> scheme as known from garbage collection.
* The most important benefit of this scheme is that it implicitly compacts memory upon collection, so that bump-pointer allocation can be applied.
* The {@linkplain com.sun.max.vm.code.SemiSpaceCodeRegion semi-space code region} <i>to-space</i> is where newly allocated code is placed
* (and where code surviving an eviction cycle is moved); its <i>from-space</i> is where code subject to eviction is found.
*
* <h2>Code Eviction Workflow</h2>
* An <i>eviction cycle</i> is triggered when the VM's attempt to allocate space in the baseline code region fails.
* If that happens, all threads are suspended (eviction is a {@link com.sun.max.vm.runtime.VmOperation stop-the-world VM Operation}).
* The workflow is controlled from the {@link com.sun.max.vm.code.CodeEviction#doIt()} method, and
* proceeds in the following steps.
*
* <h3>Identify Survivors</h3>
* The eviction logic needs to know which machine code survives the eviction cycle. This takes place in two steps:
* <ol>
* <li>walk all suspended threads' call stacks and mark the baseline methods currently executing as <i>live</i>.
* Likewise, their direct callees, if they are baseline methods as well, are marked as live.
* This ensures that code of methods currently being run in any of the threads will not be evicted, and also that code of methods
* that are very likely to be invoked again survives.</li>
* <li>iterate over the current to-space and mark methods as live that need to be protected from eviction for other reasons than
* being executed or likely to be invoked; namely, methods that
* <ul>
* <li>have just been compiled but were not yet placed in the baseline code cache (such methods are typically the reason for an eviction
* cycle to be triggered in the first place)</li>
* <li>have an invocation counter within optimization threshold and/or a type profile (such methods might soon be recompiled by the
* optimizing compiler, and the profile information gathered for them should not be lost)</li>
* </ul>
* </li>
* </ol>
*
* <h3>Invalidate Non-live Methods</h3>
* Invalidation takes place in three steps:
* <ol>
* <li>the machine code of non-live methods in the baseline code region is overwritten with trap instructions.
* This is not strictly necessary but greatly helps in debugging</li>
* <li>all entries in <i>vtables</i> and <i>itables</i> pointing to these methods are invalidated by letting them point to the respective
* <a href="https://wikis.oracle.com/display/MaxineVM/Glossary">trampolines</a> again.
* This is facilitated by iterating over the hubs of all loaded classes</li>
* <li>all direct calls to non-live methods are invalidated by letting them reference trampolines again as well.
* This implies iterating over all machine code in the three different code regions and checking direct call sites.
* Direct calls from the boot code region to baseline code are rare, so there is an optimization in place that collects all
* such calls (they are established at run-time) and thereby avoids iterating over the entire boot code region</li>
* </ol>
*
* <h3>Move Live Methods</h3>
* This is the step where semi-space functionality is actually applied.
* This affects methods that have not been wiped in the previous step. In particular, this involves the following steps for
* each live method:
* <ol>
* <li>Invalidate <i>vtable</i> and <i>itable</i> entries.</li>
* <li>Copy the method's entire bytes (code and literals arrays) over to to-space.</li>
* <li>Wipe the machine code and literal arrays as described above.</li>
* <li>Memoise the old start of the method in from-space, and set new values for its start and end in to-space.</li>
* <li>Compute and set new values for the code and literals arrays and for the {@linkplain com.sun.max.vm.compiler.target.TargetMethod#codeStart codeStart}
* pointer.</li>
* <li>Advance the to-space allocation mark by the method's size.</li>
* <li>Fix direct calls in and to moved code.<br>
* Direct call sites are relative calls. Hence, <b>all</b> direct calls <b>in</b> moved code have to be adjusted. This is
* achieved by iterating over all baseline methods (at this point, only methods surviving eviction are affected) and fixing all
* direct call sites contained therein.<br>
* Also, direct calls <b>to</b> moved code have to be adjusted. This is achieved by iterating over the optimized and boot code
* regions and fixing all direct calls to moved code.</li>
* <li>Compact the baseline code region's {@linkplain com.sun.max.vm.code.SemiSpaceCodeRegion#targetMethods target methods array}<br>
* by removing entries for wiped (stale) methods.</li>
* <li>Fix return addresses on call stacks, and code pointers in local variables.<br>
* Walk all threads' call stacks once more and fix return addresses that point to moved code. Likewise, fix pointers to machine
* code held in {@link com.sun.max.unsafe.CodePointer}s in the frames of the methods. This logic makes use of the saved old code start of moved
* methods.</li>
* </ol>
* <p>
* <h2>Tracing and Logging</h2>
* The eviction algorithm contains copious logging capability using the {@link com.sun.max.vm.log.VMLogger} mechanism.
* There are two distinct capabilities; <i>logging</i> the flow of the algorithm and <i>dumping</i> pertinent state
* of the VM before and after the algorithm executes. Dumping is very verbose and does not place data in the
* {@link com.sun.max.vm.log.VMLog VM log buffer}. However, it is defined as an logging operation so that it can be
* enabled using a consistent mechanism.
* <p>
* The loggable operations are separated into four areas, statistics, algorithmic details, code moving and dumping,
* with the operations names prefixed by {@code Stats_}, {@code Details_}, {@code Move_} and {@code Dump}, respectively.
* The VM option {@code -XX:+LogCodeEviction} is used to enable logging, with tracing to the
* log file enabled with {@code -XX:+TraceCodeEviction}. The options {@code -XX:+LogCodeEvictionInclude} and
* {@code -XX:+LogCodeEvictionExclude} can be used to fine control which options are logged/traced.
* The operation prefixes can be used in regular expressions to enable all operations in a particular area, for example:
* {@code -XX:+LogCodeEvictionExclude=Stats_.*}. Note that dumping must be explicitly enabled with {@code -XX:+LogCodeEvictionInclude=Dump}
*
*/
package com.sun.max.vm.code;