--- /dev/null 2010-01-11 13:24:46.000000000 -0800 +++ new/src/share/classes/sun/misc/Continuation.java 2010-08-30 12:48:09.280229000 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright 2010 Google, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.misc; + +/** + * The JVM Continuation class. The API design is still in progress. + * + * @author Hiroshi Yamauchi + */ +public class Continuation { + + private static native void registerNatives(); + static { + registerNatives(); + } + + /** + * The stack frames data + */ + protected volatile Object stack; + + /** + * The list of compiled code PCs in the stack. Needed to reclaim + * the compiled code in the code cache. + */ + protected volatile long[] pcs; + + /** + * A data field for convenience. This field is set to the second + * data parameter to {@link #enter} upon a {@link + * #save} call. + * + *

For example, this field can be used to pass some data from + * a scope entry point (a {@link #enter} call site) to the + * continuation resume point. + */ + protected volatile Object data1; + + /** + * A simple data field for convenience. For example, this field + * can be used to pass some data from the continuation save + * point to the continuation resume point. + */ + protected volatile Object data2; // the user-defined data + + public Object data1() { synchronized(this) { return data1; } } + public Object data2() { synchronized(this) { return data2; } } + public void set_data1(Object o) { synchronized(this) { data1 = o; } } + public void set_data2(Object o) { synchronized(this) { data2 = o; } } + public boolean isSaved() { return stack != null; } + + /** + * The continuation may save the compiled stack frames. The + * reference count of the compiled code (nmethod) is incremented + * upon a continuation save and decremented by this finalizer. + */ + protected void finalize() throws Throwable { + if (pcs == null || pcs.length == 0) { + return; + } + for (long pc : pcs) { + dec_code_cache_ref_count(pc); + } + } + + /** + * Copies the stack frames in the current scope, and stores them + * in this object. This method must be called in an enclosing + * scope. Calling this method causes the stack frames in the + * scope to suspend (including the current frame) and the enter + * call at the entry of the current scope to return. + * + * @return the parameter passed to the resume call when the saved stack + * frames are resumed in the future. + */ + public Object save() { + return save_cont(this); + } + + /** + * Reactivates the stack frames saved in this object on the + * current thread. Overwrites the stack frames in the current + * scope with the saved stack frames. This method must be + * called in an enclosing scope. Calling this method causes the + * suspended save call to resume from the point where it was + * suspended. + * + * @param rv the value to be returned from the resumed save call site. + */ + public void resume(Object rv) { + if (stack == null) { + throw new IllegalArgumentException( + "Continuation hasn't been saved or tried to resume for a second time."); + } + Object s = stack; + stack = null; // resumable only once + resume_cont(s, rv); + } + + /** + * Marks the beginning of a new 'scope' in preparation for stack + * save/resume. Executes the given Runnable. + * + * @param data any user defined data to be passed from this call + * site to the point where {@link #resume} is called + * for convenience. The {@link #data1} field will be + * set to this object. + * @return the Continuation object after the scope was saved + * into a Continuation object or null if it wasn't and + * simply returned + */ + public static Object enter(Runnable r, Object data) { + Object rv = enter0(r, data); + return rv; + } + + /* + * This method currently exists just for convenience for the + * continuation implementation in the JVM. This method along with + * enter() above will never be jitted. This may go away in the + * future. + */ + private static Object enter0(Runnable r, Object data) { + Object rv = enter1(r, data); + return rv; + } + + /* + * This method currently exists just for convenience for the + * continuation implementation in the JVM. This may go away in the + * future. + */ + private static Object enter1(Runnable r, Object data) { + r.run(); + return null; // If saved, this will return the CSE. + } + + private static native Object save_cont(Continuation cont); + private static native void resume_cont(Object stack, Object rv); + private static native void dec_code_cache_ref_count(long pc); +}