00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.26 $ */ 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/_block_prims.cpp.incl" 00026 00027 TRACE_FUNC(TraceBlockPrims, "block") 00028 00029 static inline void inc_calls() {} 00030 00031 static inline void inc_block_counter() { 00032 #ifdef ASSERT 00033 NumberOfBlockAllocations++; 00034 #endif 00035 } 00036 00037 static inline void inc_context_counter() { 00038 #ifdef ASSERT 00039 NumberOfContextAllocations++; 00040 #endif 00041 } 00042 00043 extern "C" blockClosureOop allocateTenuredBlock(smiOop nofArgs) { 00044 PROLOGUE_1("allocateBlock", nofArgs); 00045 blockClosureOop blk = 00046 as_blockClosureOop(Universe::allocate_tenured(sizeof(blockClosureOopDesc)/oopSize)); 00047 blk->init_mark(); 00048 blk->set_klass_field(blockClosureKlass::blockKlassFor(nofArgs->value())); 00049 inc_block_counter(); 00050 return blk; 00051 } 00052 00053 // TODO: Implement the following function (gri) 00054 extern "C" blockClosureOop allocateBlock(smiOop nofArgs) { 00055 PROLOGUE_1("allocateBlock", nofArgs); 00056 blockClosureOop blk = 00057 as_blockClosureOop(Universe::allocate(sizeof(blockClosureOopDesc)/oopSize)); 00058 blk->init_mark(); 00059 blk->set_klass_field(blockClosureKlass::blockKlassFor(nofArgs->value())); 00060 inc_block_counter(); 00061 return blk; 00062 } 00063 00064 /* 00065 extern "C" blockClosureOop allocateBlock0() { 00066 PROLOGUE_0("allocateBlock0"); 00067 blockClosureOop blk = 00068 as_blockClosureOop(Universe::allocate(sizeof(blockClosureOopDesc)/oopSize)); 00069 blk->init_mark(); 00070 blk->set_klass_field(Universe::zeroArgumentBlockKlassObj()); 00071 inc_block_counter(); 00072 return oop(blk); 00073 } 00074 00075 extern "C" blockClosureOop allocateBlock1() { 00076 PROLOGUE_0("allocateBlock1"); 00077 blockClosureOop blk = 00078 as_blockClosureOop(Universe::allocate(sizeof(blockClosureOopDesc)/oopSize)); 00079 blk->init_mark(); 00080 blk->set_klass_field(Universe::oneArgumentBlockKlassObj()); 00081 inc_block_counter(); 00082 return oop(blk); 00083 } 00084 00085 extern "C" blockClosureOop allocateBlock2() { 00086 PROLOGUE_0("allocateBlock2"); 00087 blockClosureOop blk = 00088 as_blockClosureOop(Universe::allocate(sizeof(blockClosureOopDesc)/oopSize)); 00089 blk->init_mark(); 00090 blk->set_klass_field(Universe::twoArgumentBlockKlassObj()); 00091 inc_block_counter(); 00092 return oop(blk); 00093 } 00094 */ 00095 00096 /* 00097 extern "C" contextOop allocateContext(smiOop nofVars) { 00098 PROLOGUE_1("allocateContext", nofVars); 00099 contextKlass* ok = (contextKlass*) contextKlassObj->klass_part(); 00100 inc_context_counter(); 00101 return ok->allocateObjectSize(nofVars->value()); 00102 } 00103 00104 extern "C" contextOop allocateContext0() { 00105 PROLOGUE_0("allocateContext0"); 00106 // allocate 00107 contextOop obj = as_contextOop(Universe::allocate(contextOopDesc::header_size())); 00108 // header 00109 obj->set_klass_field(contextKlassObj); 00110 //%clean this up later 00111 // hash value must by convention be different from 0 (check markOop.hpp) 00112 obj->set_mark(markOopDesc::tagged_prototype()->set_hash(0 + 1)); 00113 00114 inc_context_counter(); 00115 00116 return obj; 00117 } 00118 00119 extern "C" contextOop allocateContext1() { 00120 PROLOGUE_0("allocateContext1"); 00121 contextKlass* ok = (contextKlass*) contextKlassObj->klass_part(); 00122 inc_context_counter(); 00123 return ok->allocateObjectSize(1); 00124 } 00125 extern "C" contextOop allocateContext2() { 00126 PROLOGUE_0("allocateContext2"); 00127 contextKlass* ok = (contextKlass*) contextKlassObj->klass_part(); 00128 inc_context_counter(); 00129 return ok->allocateObjectSize(2); 00130 } 00131 00132 */ 00133 00134 extern "C" bool have_nlr_through_C; 00135 extern "C" oop nlr_result; 00136 00137 PRIM_DECL_2(unwindprotect, oop receiver, oop protectBlock) { 00138 PROLOGUE_2("unwindprotect", receiver, protectBlock); 00139 oop res = Delta::call(receiver, vmSymbols::value()); 00140 00141 if (have_nlr_through_C) { 00142 unwindInfo enabler; 00143 res = Delta::call(protectBlock, vmSymbols::value(), nlr_result); 00144 // Now since we have to continue the first non-local-return 00145 // the nlr_result must be correct. 00146 } 00147 00148 return res; 00149 } 00150 00151 PRIM_DECL_1(blockRepeat, oop receiver) { 00152 PROLOGUE_1("blockRepeat", receiver); 00153 do Delta::call(receiver, vmSymbols::value()); 00154 while (!have_nlr_through_C); 00155 return smiOop_zero; // The return value is ignored by the NLR 00156 } 00157 00158 PRIM_DECL_1(block_method, oop receiver){ 00159 PROLOGUE_1("block_method", receiver); 00160 return blockClosureOop(receiver)->method(); 00161 } 00162 00163 PRIM_DECL_1(block_is_optimized, oop receiver){ 00164 PROLOGUE_1("blockRepeat", receiver); 00165 return blockClosureOop(receiver)->isCompiledBlock() ? trueObj : falseObj; 00166 }