process_prims.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.24 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_process_prims.cpp.incl"
00026 
00027 TRACE_FUNC(TraceProcessPrims, "process")
00028 
00029 int processOopPrimitives::number_of_calls;
00030 
00031 #define ASSERT_RECEIVER assert(receiver->is_process(), "receiver must be process")
00032 
00033 PRIM_DECL_2(processOopPrimitives::create, oop receiver, oop block) {
00034   PROLOGUE_2("create", receiver, block)
00035   assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_process(), "must be process class");
00036   if (block->klass() != Universe::zeroArgumentBlockKlassObj())
00037     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00038   processOop process = processOop(receiver->primitive_allocate());
00039   assert(process->is_process(), "must be process");
00040  
00041   DeltaProcess* p = new DeltaProcess(block, oopFactory::new_symbol("value"));
00042   process->set_process(p);
00043   p->set_processObj(process);
00044   return process;
00045 }
00046 
00047 PRIM_DECL_0(processOopPrimitives::yield) {
00048   PROLOGUE_0("yield");
00049   if (!DeltaProcess::active()->is_scheduler()) {
00050     DeltaProcess::active()->suspend(yielded);
00051   }
00052   return DeltaProcess::active()->processObj();
00053 }
00054 
00055 PRIM_DECL_0(processOopPrimitives::stop) {
00056   PROLOGUE_0("stop");
00057   if (!DeltaProcess::active()->is_scheduler()) {
00058     DeltaProcess::active()->suspend(stopped);
00059   }
00060   return DeltaProcess::active()->processObj();
00061 }
00062 
00063 PRIM_DECL_1(processOopPrimitives::transferTo, oop process) {
00064   PROLOGUE_1("transferTo", process);
00065 
00066   // Check if argument is a processOop
00067   if (!process->is_process())
00068     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00069 
00070   // Check if we are in the scheduler
00071   if (!DeltaProcess::active()->is_scheduler())
00072     return markSymbol(vmSymbols::not_in_scheduler());
00073 
00074   // Make sure process is not dead
00075   if (!processOop(process)->is_live())
00076     return markSymbol(vmSymbols::dead());
00077 
00078   DeltaProcess* proc = processOop(process)->process();
00079 
00080   // Do the transfer (remember transfer_to is a no-op if process is in async DLL)
00081   ProcessState state = DeltaProcess::scheduler()->transfer_to(proc);
00082 
00083   // Please be careful here since a scavenge/garbage collect can happen!
00084 
00085   return DeltaProcess::symbol_from_state(state);
00086 }
00087 
00088 PRIM_DECL_3(processOopPrimitives::set_mode, oop process, oop mode, oop value) {
00089   PROLOGUE_3("set_mode", process, mode, value);
00090 
00091   // Check if argument is a processOop
00092   if (!process->is_process())
00093     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00094 
00095   // Check if we are in the scheduler
00096   if (!DeltaProcess::active()->is_scheduler())
00097     return markSymbol(vmSymbols::not_in_scheduler());
00098 
00099   // Make sure process is not dead
00100   if (!processOop(process)->is_live())
00101     return markSymbol(vmSymbols::dead());
00102 
00103   DeltaProcess* proc = processOop(process)->process();
00104 
00105   // FIX THIS
00106   //  proc->set_single_step_mode();
00107 
00108   // Do the transfer (remember transfer_to is a no-op if process is in async DLL)
00109   ProcessState state = DeltaProcess::scheduler()->transfer_to(proc);
00110 
00111   // Please be careful here since a scavenge/garbage collect can happen!
00112 
00113   // FIX THIS
00114   //  proc->set_normal_mode();
00115 
00116   return DeltaProcess::symbol_from_state(state);
00117 }
00118 
00119 PRIM_DECL_1(processOopPrimitives::start_evaluator, oop process) {
00120   PROLOGUE_1("start_evaluator", process);
00121 
00122   // Check if argument is a processOop
00123   if (!process->is_process())
00124     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00125 
00126   // Check if we are in the scheduler
00127   if (!DeltaProcess::active()->is_scheduler())
00128     return markSymbol(vmSymbols::not_in_scheduler());
00129 
00130   // Make sure process is not dead
00131   if (!processOop(process)->is_live())
00132     return markSymbol(vmSymbols::dead());
00133 
00134   DeltaProcess* proc = processOop(process)->process();
00135   {
00136     ResourceMark rm;
00137     dispatchTable::intercept_for_step();
00138   }
00139   ProcessState state = DeltaProcess::scheduler()->transfer_to(proc);
00140 
00141   return DeltaProcess::symbol_from_state(state);
00142 }
00143 
00144 PRIM_DECL_1(processOopPrimitives::terminate, oop receiver) {
00145   PROLOGUE_1("terminate", receiver);
00146   ASSERT_RECEIVER;
00147 
00148   // Make sure process is not dead
00149   if (!processOop(receiver)->is_live())
00150     return markSymbol(vmSymbols::dead());
00151 
00152   DeltaProcess* proc = processOop(receiver)->process();
00153   if (proc == DeltaProcess::active()) {
00154     // Start the abort now
00155     ErrorHandler::abort_current_process();
00156   } else {
00157     proc->set_terminating();
00158   }
00159   return receiver;
00160 }
00161 
00162 PRIM_DECL_0(processOopPrimitives::activeProcess) {
00163   PROLOGUE_0("activeProcess");
00164 
00165   processOop p = DeltaProcess::active()->processObj();
00166   assert(p->is_process(), "must be process");
00167 
00168   return p;
00169 }
00170 
00171 PRIM_DECL_1(processOopPrimitives::status, oop process) {
00172   PROLOGUE_1("status", process);
00173 
00174   // Check if argument is a processOop
00175   if (!process->is_process())
00176     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00177 
00178   return processOop(process)->status_symbol();
00179 }
00180 
00181 PRIM_DECL_1(processOopPrimitives::scheduler_wait, oop milliseconds) {
00182   PROLOGUE_1("scheduler_wait", milliseconds);
00183 
00184   // Check if argument is a smi
00185   if (!milliseconds->is_smi())
00186     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00187 
00188   return DeltaProcess::wait_for_async_dll(smiOop(milliseconds)->value()) ? trueObj : falseObj;
00189 }
00190 
00191 PRIM_DECL_2(processOopPrimitives::trace_stack, oop receiver, oop size) {
00192   PROLOGUE_2("trace_stack", receiver, size);
00193   ASSERT_RECEIVER;
00194 
00195   // Check argument
00196   if (!size->is_smi())
00197     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00198 
00199   // Make sure process is not dead
00200   if (!processOop(receiver)->is_live())
00201     return markSymbol(vmSymbols::dead());
00202 
00203   // Print the stack
00204   { ResourceMark rm; 
00205     processOop(receiver)->process()->trace_top(1, smiOop(size)->value());
00206   }
00207 
00208   return receiver;
00209 }
00210 
00211 PRIM_DECL_0(processOopPrimitives::enter_critical) {
00212   PROLOGUE_0("enter_critical");
00213   // %fix this when implementing preemption
00214   return DeltaProcess::active()->processObj();
00215 }
00216 
00217 PRIM_DECL_0(processOopPrimitives::leave_critical) {
00218   PROLOGUE_0("leave_critical");
00219   // %fix this when implementing preemption
00220   return DeltaProcess::active()->processObj();
00221 }
00222 
00223 PRIM_DECL_0(processOopPrimitives::yield_in_critical) {
00224   PROLOGUE_0("yield_in_critical");
00225   // %fix this when implementing preemption
00226   if (!DeltaProcess::active()->is_scheduler()) {
00227     DeltaProcess::active()->suspend(yielded);
00228   }
00229   return DeltaProcess::active()->processObj();
00230 }
00231 
00232 PRIM_DECL_1(processOopPrimitives::user_time, oop receiver) {
00233   PROLOGUE_1("enter_critical", receiver);
00234   ASSERT_RECEIVER;
00235   return oopFactory::new_double(processOop(receiver)->user_time());
00236 }
00237 
00238 PRIM_DECL_1(processOopPrimitives::system_time, oop receiver) {
00239   PROLOGUE_1("enter_critical", receiver);
00240   ASSERT_RECEIVER;
00241   return oopFactory::new_double(processOop(receiver)->system_time());
00242 }
00243 
00244 PRIM_DECL_2(processOopPrimitives::stack, oop receiver, oop limit) {
00245   PROLOGUE_2("stack", receiver, limit);
00246   ASSERT_RECEIVER;
00247 
00248   // Check type of limit
00249   if (!limit->is_smi())
00250     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00251 
00252   // Make sure process is not dead
00253   if (!processOop(receiver)->is_live())
00254     return markSymbol(vmSymbols::dead());
00255 
00256   // Make sure we are not retrieving activation for the current process
00257   if (processOop(receiver)->process() == DeltaProcess::active())
00258     return markSymbol(vmSymbols::running());
00259 
00260 
00261   ResourceMark rm;
00262   BlockScavenge bs;
00263 
00264   int                     l = smiOop(limit)->value();
00265   processOop        process = processOop(receiver);
00266   GrowableArray<oop>* stack = new GrowableArray<oop> (100);
00267   
00268   vframe* vf = processOop(receiver)->process()->last_delta_vframe();
00269 
00270   for (int index = 1; index <= l && vf; index++) {
00271     stack->push(oopFactory::new_vframe(process, index));
00272     vf = vf->sender();
00273   }
00274   return oopFactory::new_objArray(stack);
00275 }

Generated on Mon Oct 9 13:37:25 2006 for Strongtalk VM by  doxygen 1.4.7