1 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.43 $ */
2 /* Copyright (c) 2006, Sun Microsystems, Inc.
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6 following conditions are met:
8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
10 disclaimer in the documentation and/or other materials provided with the distribution.
11 * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived
12 from this software without specific prior written permission.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
15 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
16 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
19 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
24 // A blockClosureOop is the oop of a block closure, i.e., the object created
25 // when a block literal like [3 + 4] is evaluated. Blocks can be "clean"
26 // (have no free variables, like [3 + 4]), in which case their _lexical_scope
27 // pointer contains nil or self, or they can be full blocks (like [x + 4])
28 // in which case their _lexical_scope is used to resolve accesses
31 class blockClosureOopDesc
: public memOopDesc
{
33 oop _methodOrJumpAddr
; // block method (if interpreted), jumpTable stub address (if compiled)
34 contextOop _lexical_scope
; // lexical context or nil (if no free variables)
35 blockClosureOop
addr() const { return blockClosureOop(memOopDesc::addr()); }
37 // field offsets for code generation
38 static int method_or_entry_byte_offset() { return (2 * oopSize
) - Mem_Tag
; }
39 static int context_byte_offset() { return (3 * oopSize
) - Mem_Tag
; }
41 friend blockClosureOop
as_blockClosureOop(void* p
) { return blockClosureOop(as_memOop(p
)); }
43 static blockClosureOop
create_clean_block(int nofArgs
, char* entry_point
); // create a clean block
45 inline bool isCompiledBlock() const { return !oop(addr()->_methodOrJumpAddr
)->is_mem(); }
46 void set_method(methodOop m
) { STORE_OOP(&addr()->_methodOrJumpAddr
, m
); }
47 void set_jumpAddr(void* jmp_addr
) {
48 assert(!oop(jmp_addr
)->is_mem(), "not properly aligned");
49 addr()->_methodOrJumpAddr
= (oop
)jmp_addr
;
51 methodOop
method() const;
54 jumpTableEntry
* jump_table_entry() const;
57 // returns the number of arguments for the method oop belonging to this closure
58 int number_of_arguments();
61 static int header_size() { return sizeof(blockClosureOopDesc
)/oopSize
; }
62 static int object_size() { return header_size(); }
64 void set_lexical_scope(contextOop l
) { STORE_OOP(&addr()->_lexical_scope
, l
); }
65 contextOop
lexical_scope() const { return addr()->_lexical_scope
; }
72 char* name() const { return "blockClosure"; }
75 friend blockClosureKlass
;
78 // Contexts contain the heap-allocated local variables of a method, i.e., the locals
79 // and arguments that are uplevel-accessed by blocks. They are variable-length, what's
80 // shown below is just the common prefix which is followed by the words containing the
83 class contextOopDesc
: public memOopDesc
{
87 // %note: Robert please describe the parent states in excruciating details.
88 // The description below is far from complete (Lars, 1/9/96).
91 // - the frame (if the activation creating the block is alive and a first-level block)
92 // - smiOop_zero (when the activation creating the block is dead)
93 // - outer context (if the corresponding method is a block method??)
94 // The transition from frame to smiOop_zero happens when the block is zapped
95 // by the epilog code of the method or a non local return.
96 // NOTE: the frame is needed in case of a non local return.
97 contextOop
addr() const { return contextOop(memOopDesc::addr()); }
99 friend contextOop
as_contextOop(void* p
) { return contextOop(as_memOop(p
)); }
101 void set_parent(oop h
) { STORE_OOP(&addr()->_parent
, h
); }
102 oop
parent() const { return addr()->_parent
; }
104 // Test operations on home
105 bool is_dead() const;
106 bool has_parent_fp() const;
107 bool has_outer_context() const;
109 int* parent_fp() const { return has_parent_fp() ? (int*) parent() : NULL
; }
110 void set_home_fp(int* fp
) {
111 assert(oop(fp
)->is_smi(), "checking alignment");
115 // Returns the outer context if any
116 contextOop
outer_context() const; // NULL if is_dead or has_frame
118 // Sets the home to smiOop_zero
119 void kill() { set_parent(smiOop_zero
); }
121 static int header_size() { return sizeof(contextOopDesc
)/oopSize
; }
122 int object_size() { return header_size() + length(); }
124 oop
* obj_addr_at(int index
) { return oops(header_size() + index
); }
125 oop
obj_at(int index
) { return raw_at(header_size() + index
); }
126 void obj_at_put(int index
, oop value
) { raw_at_put(header_size() + index
, value
); }
127 int length() { return mark()->hash() - 1; }
129 // constants for code generation
130 static int parent_word_offset() { return 2; } // word offset of parent context
131 static int temp0_word_offset() { return 3; } // word offset of first context temp
132 static int parent_byte_offset() { return byteOffset(parent_word_offset()); }
133 static int temp0_byte_offset() { return byteOffset(temp0_word_offset()); }
135 // Accessors for storing and reading the forward reference
136 // to the unoptimized context (Used during deoptimization).
137 void set_unoptimized_context(contextOop con
);
138 contextOop
unoptimized_context();
140 // Returns the length of the context chain.
141 int chain_length() const;
143 // Print the contents of home
144 void print_home_on(outputStream
* st
);