1 /* 2 * Copyright 2010 Google, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 /** 29 * The JVM Continuation class. The API design is still in progress. 30 * 31 * @author Hiroshi Yamauchi 32 */ 33 public class Continuation { 34 35 private static native void registerNatives(); 36 static { 37 registerNatives(); 38 } 39 40 /** 41 * The stack frames data 42 */ 43 protected volatile Object stack; 44 45 /** 46 * The list of compiled code PCs in the stack. Needed to reclaim 47 * the compiled code in the code cache. 48 */ 49 protected volatile long[] pcs; 50 51 /** 52 * A data field for convenience. This field is set to the second 53 * <code>data</code> parameter to {@link #enter} upon a {@link 54 * #save} call. 55 * 56 * <p>For example, this field can be used to pass some data from 57 * a scope entry point (a {@link #enter} call site) to the 58 * continuation resume point. 59 */ 60 protected volatile Object data1; 61 62 /** 63 * A simple data field for convenience. For example, this field 64 * can be used to pass some data from the continuation save 65 * point to the continuation resume point. 66 */ 67 protected volatile Object data2; // the user-defined data 68 69 public Object data1() { synchronized(this) { return data1; } } 70 public Object data2() { synchronized(this) { return data2; } } 71 public void set_data1(Object o) { synchronized(this) { data1 = o; } } 72 public void set_data2(Object o) { synchronized(this) { data2 = o; } } 73 public boolean isSaved() { return stack != null; } 74 75 /** 76 * The continuation may save the compiled stack frames. The 77 * reference count of the compiled code (nmethod) is incremented 78 * upon a continuation save and decremented by this finalizer. 79 */ 80 protected void finalize() throws Throwable { 81 if (pcs == null || pcs.length == 0) { 82 return; 83 } 84 for (long pc : pcs) { 85 dec_code_cache_ref_count(pc); 86 } 87 } 88 89 /** 90 * Copies the stack frames in the current scope, and stores them 91 * in this object. This method must be called in an enclosing 92 * scope. Calling this method causes the stack frames in the 93 * scope to suspend (including the current frame) and the enter 94 * call at the entry of the current scope to return. 95 * 96 * @return the parameter passed to the resume call when the saved stack 97 * frames are resumed in the future. 98 */ 99 public Object save() { 100 return save_cont(this); 101 } 102 103 /** 104 * Reactivates the stack frames saved in this object on the 105 * current thread. Overwrites the stack frames in the current 106 * scope with the saved stack frames. This method must be 107 * called in an enclosing scope. Calling this method causes the 108 * suspended save call to resume from the point where it was 109 * suspended. 110 * 111 * @param rv the value to be returned from the resumed save call site. 112 */ 113 public void resume(Object rv) { 114 if (stack == null) { 115 throw new IllegalArgumentException( 116 "Continuation hasn't been saved or tried to resume for a second time."); 117 } 118 Object s = stack; 119 stack = null; // resumable only once 120 resume_cont(s, rv); 121 } 122 123 /** 124 * Marks the beginning of a new 'scope' in preparation for stack 125 * save/resume. Executes the given Runnable. 126 * 127 * @param data any user defined data to be passed from this call 128 * site to the point where {@link #resume} is called 129 * for convenience. The {@link #data1} field will be 130 * set to this object. 131 * @return the Continuation object after the scope was saved 132 * into a Continuation object or null if it wasn't and 133 * simply returned 134 */ 135 public static Object enter(Runnable r, Object data) { 136 Object rv = enter0(r, data); 137 return rv; 138 } 139 140 /* 141 * This method currently exists just for convenience for the 142 * continuation implementation in the JVM. This method along with 143 * enter() above will never be jitted. This may go away in the 144 * future. 145 */ 146 private static Object enter0(Runnable r, Object data) { 147 Object rv = enter1(r, data); 148 return rv; 149 } 150 151 /* 152 * This method currently exists just for convenience for the 153 * continuation implementation in the JVM. This may go away in the 154 * future. 155 */ 156 private static Object enter1(Runnable r, Object data) { 157 r.run(); 158 return null; // If saved, this will return the CSE. 159 } 160 161 private static native Object save_cont(Continuation cont); 162 private static native void resume_cont(Object stack, Object rv); 163 private static native void dec_code_cache_ref_count(long pc); 164 }