blockOop.hpp

Go to the documentation of this file.
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 

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