00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.43 $ */ 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 // A blockClosureOop is the oop of a block closure, i.e., the object created 00025 // when a block literal like [3 + 4] is evaluated. Blocks can be "clean" 00026 // (have no free variables, like [3 + 4]), in which case their _lexical_scope 00027 // pointer contains nil or self, or they can be full blocks (like [x + 4]) 00028 // in which case their _lexical_scope is used to resolve accesses 00029 // to free variables. 00030 00031 class blockClosureOopDesc: public memOopDesc { 00032 private: 00033 oop _methodOrJumpAddr; // block method (if interpreted), jumpTable stub address (if compiled) 00034 contextOop _lexical_scope; // lexical context or nil (if no free variables) 00035 blockClosureOop addr() const { return blockClosureOop(memOopDesc::addr()); } 00036 public: 00037 // field offsets for code generation 00038 static int method_or_entry_byte_offset() { return (2 * oopSize) - Mem_Tag; } 00039 static int context_byte_offset() { return (3 * oopSize) - Mem_Tag; } 00040 00041 friend blockClosureOop as_blockClosureOop(void* p) { return blockClosureOop(as_memOop(p)); } 00042 00043 static blockClosureOop create_clean_block(int nofArgs, char* entry_point); // create a clean block 00044 00045 inline bool isCompiledBlock() const { return !oop(addr()->_methodOrJumpAddr)->is_mem(); } 00046 void set_method(methodOop m) { STORE_OOP(&addr()->_methodOrJumpAddr, m); } 00047 void set_jumpAddr(void* jmp_addr) { 00048 assert(!oop(jmp_addr)->is_mem(), "not properly aligned"); 00049 addr()->_methodOrJumpAddr = (oop)jmp_addr; 00050 } 00051 methodOop method() const; 00052 00053 #ifdef DELTA_COMPILER 00054 jumpTableEntry* jump_table_entry() const; 00055 #endif 00056 00057 // returns the number of arguments for the method oop belonging to this closure 00058 int number_of_arguments(); 00059 00060 // sizing 00061 static int header_size() { return sizeof(blockClosureOopDesc)/oopSize; } 00062 static int object_size() { return header_size(); } 00063 00064 void set_lexical_scope(contextOop l) { STORE_OOP(&addr()->_lexical_scope, l); } 00065 contextOop lexical_scope() const { return addr()->_lexical_scope; } 00066 00067 bool is_pure() const; 00068 00069 // deoptimization 00070 void deoptimize(); 00071 00072 char* name() const { return "blockClosure"; } 00073 void verify(); 00074 00075 friend blockClosureKlass; 00076 }; 00077 00078 // Contexts contain the heap-allocated local variables of a method, i.e., the locals 00079 // and arguments that are uplevel-accessed by blocks. They are variable-length, what's 00080 // shown below is just the common prefix which is followed by the words containing the 00081 // actual data. 00082 00083 class contextOopDesc: public memOopDesc { 00084 private: 00085 smiOop _parent; 00086 // 00087 // %note: Robert please describe the parent states in excruciating details. 00088 // The description below is far from complete (Lars, 1/9/96). 00089 // 00090 // Contains either: 00091 // - the frame (if the activation creating the block is alive and a first-level block) 00092 // - smiOop_zero (when the activation creating the block is dead) 00093 // - outer context (if the corresponding method is a block method??) 00094 // The transition from frame to smiOop_zero happens when the block is zapped 00095 // by the epilog code of the method or a non local return. 00096 // NOTE: the frame is needed in case of a non local return. 00097 contextOop addr() const { return contextOop(memOopDesc::addr()); } 00098 public: 00099 friend contextOop as_contextOop(void* p) { return contextOop(as_memOop(p)); } 00100 00101 void set_parent(oop h) { STORE_OOP(&addr()->_parent, h); } 00102 oop parent() const { return addr()->_parent; } 00103 00104 // Test operations on home 00105 bool is_dead() const; 00106 bool has_parent_fp() const; 00107 bool has_outer_context() const; 00108 00109 int* parent_fp() const { return has_parent_fp() ? (int*) parent() : NULL; } 00110 void set_home_fp(int* fp) { 00111 assert(oop(fp)->is_smi(), "checking alignment"); 00112 set_parent(oop(fp)); 00113 } 00114 00115 // Returns the outer context if any 00116 contextOop outer_context() const; // NULL if is_dead or has_frame 00117 00118 // Sets the home to smiOop_zero 00119 void kill() { set_parent(smiOop_zero); } 00120 00121 static int header_size() { return sizeof(contextOopDesc)/oopSize; } 00122 int object_size() { return header_size() + length(); } 00123 00124 oop* obj_addr_at(int index) { return oops(header_size() + index); } 00125 oop obj_at(int index) { return raw_at(header_size() + index); } 00126 void obj_at_put(int index, oop value) { raw_at_put(header_size() + index, value); } 00127 int length() { return mark()->hash() - 1; } 00128 00129 // constants for code generation 00130 static int parent_word_offset() { return 2; } // word offset of parent context 00131 static int temp0_word_offset() { return 3; } // word offset of first context temp 00132 static int parent_byte_offset() { return byteOffset(parent_word_offset()); } 00133 static int temp0_byte_offset() { return byteOffset(temp0_word_offset()); } 00134 00135 // Accessors for storing and reading the forward reference 00136 // to the unoptimized context (Used during deoptimization). 00137 void set_unoptimized_context(contextOop con); 00138 contextOop unoptimized_context(); 00139 00140 // Returns the length of the context chain. 00141 int chain_length() const; 00142 00143 // Print the contents of home 00144 void print_home_on(outputStream* st); 00145 00146 friend contextKlass; 00147 }; 00148