Mercurial > hg > truffle
annotate src/share/vm/classfile/stackMapFrame.hpp @ 4988:eb5b24d1499f
Merge
author | Christian Haeubl <christian.haeubl@oracle.com> |
---|---|
date | Mon, 27 Feb 2012 15:06:36 -0800 |
parents | 3449f5e02cc4 |
children | 4ee06e614636 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2303
diff
changeset
|
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP |
26 #define SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP | |
27 | |
28 #include "classfile/verificationType.hpp" | |
29 #include "classfile/verifier.hpp" | |
30 #include "oops/methodOop.hpp" | |
31 #include "runtime/handles.hpp" | |
32 #include "runtime/signature.hpp" | |
33 #include "utilities/exceptions.hpp" | |
34 | |
0 | 35 // A StackMapFrame represents one frame in the stack map attribute. |
36 | |
37 enum { | |
38 FLAG_THIS_UNINIT = 0x01 | |
39 }; | |
40 | |
41 class StackMapFrame : public ResourceObj { | |
42 private: | |
43 int32_t _offset; | |
44 | |
45 // See comment in StackMapTable about _frame_count about why these | |
46 // fields are int32_t instead of u2. | |
47 int32_t _locals_size; // number of valid type elements in _locals | |
48 int32_t _stack_size; // number of valid type elements in _stack | |
49 | |
50 int32_t _max_locals; | |
51 int32_t _max_stack; | |
52 | |
53 u1 _flags; | |
54 VerificationType* _locals; // local variable type array | |
55 VerificationType* _stack; // operand stack type array | |
56 | |
57 ClassVerifier* _verifier; // the verifier verifying this method | |
58 | |
59 public: | |
60 // constructors | |
61 | |
62 // This constructor is used by the type checker to allocate frames | |
63 // in type state, which have _max_locals and _max_stack array elements | |
64 // in _locals and _stack. | |
65 StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* verifier); | |
66 | |
67 // This constructor is used to initialize stackmap frames in stackmap table, | |
68 // which have _locals_size and _stack_size array elements in _locals and _stack. | |
69 StackMapFrame(int32_t offset, | |
70 u1 flags, | |
71 u2 locals_size, | |
72 u2 stack_size, | |
73 u2 max_locals, | |
74 u2 max_stack, | |
75 VerificationType* locals, | |
76 VerificationType* stack, | |
77 ClassVerifier* v) : _offset(offset), _flags(flags), | |
78 _locals_size(locals_size), | |
79 _stack_size(stack_size), | |
80 _max_locals(max_locals), | |
81 _max_stack(max_stack), | |
82 _locals(locals), _stack(stack), | |
83 _verifier(v) { } | |
84 | |
85 inline void set_offset(int32_t offset) { _offset = offset; } | |
86 inline void set_verifier(ClassVerifier* v) { _verifier = v; } | |
87 inline void set_flags(u1 flags) { _flags = flags; } | |
88 inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; } | |
89 inline void set_stack_size(u2 stack_size) { _stack_size = stack_size; } | |
90 inline void clear_stack() { _stack_size = 0; } | |
91 inline int32_t offset() const { return _offset; } | |
92 inline ClassVerifier* verifier() const { return _verifier; } | |
93 inline u1 flags() const { return _flags; } | |
94 inline int32_t locals_size() const { return _locals_size; } | |
95 inline VerificationType* locals() const { return _locals; } | |
96 inline int32_t stack_size() const { return _stack_size; } | |
97 inline VerificationType* stack() const { return _stack; } | |
98 inline int32_t max_locals() const { return _max_locals; } | |
99 inline int32_t max_stack() const { return _max_stack; } | |
100 inline bool flag_this_uninit() const { return _flags & FLAG_THIS_UNINIT; } | |
101 | |
102 // Set locals and stack types to bogus | |
103 inline void reset() { | |
104 int32_t i; | |
105 for (i = 0; i < _max_locals; i++) { | |
106 _locals[i] = VerificationType::bogus_type(); | |
107 } | |
108 for (i = 0; i < _max_stack; i++) { | |
109 _stack[i] = VerificationType::bogus_type(); | |
110 } | |
111 } | |
112 | |
113 // Return a StackMapFrame with the same local variable array and empty stack. | |
114 // Stack array is allocate with unused one element. | |
115 StackMapFrame* frame_in_exception_handler(u1 flags); | |
116 | |
117 // Set local variable type array based on m's signature. | |
118 VerificationType set_locals_from_arg( | |
119 const methodHandle m, VerificationType thisKlass, TRAPS); | |
120 | |
121 // Search local variable type array and stack type array. | |
122 // Return true if an uninitialized object is found. | |
123 bool has_new_object() const; | |
124 | |
125 // Search local variable type array and stack type array. | |
126 // Set every element with type of old_object to new_object. | |
127 void initialize_object( | |
128 VerificationType old_object, VerificationType new_object); | |
129 | |
130 // Copy local variable type array in src into this local variable type array. | |
131 void copy_locals(const StackMapFrame* src); | |
132 | |
133 // Copy stack type array in src into this stack type array. | |
134 void copy_stack(const StackMapFrame* src); | |
135 | |
136 // Return true if this stack map frame is assignable to target. | |
2472
7144a1d6e0a9
7030388: JCK test failed to reject invalid class check01304m10n.
kamg
parents:
2303
diff
changeset
|
137 bool is_assignable_to(const StackMapFrame* target, |
7144a1d6e0a9
7030388: JCK test failed to reject invalid class check01304m10n.
kamg
parents:
2303
diff
changeset
|
138 bool is_exception_handler, TRAPS) const; |
0 | 139 |
140 // Push type into stack type array. | |
141 inline void push_stack(VerificationType type, TRAPS) { | |
142 assert(!type.is_check(), "Must be a real type"); | |
143 if (_stack_size >= _max_stack) { | |
144 verifier()->verify_error(_offset, "Operand stack overflow"); | |
145 return; | |
146 } | |
147 _stack[_stack_size++] = type; | |
148 } | |
149 | |
150 inline void push_stack_2( | |
151 VerificationType type1, VerificationType type2, TRAPS) { | |
152 assert(type1.is_long() || type1.is_double(), "must be long/double"); | |
153 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); | |
154 if (_stack_size >= _max_stack - 1) { | |
155 verifier()->verify_error(_offset, "Operand stack overflow"); | |
156 return; | |
157 } | |
158 _stack[_stack_size++] = type1; | |
159 _stack[_stack_size++] = type2; | |
160 } | |
161 | |
162 // Pop and return the top type on stack without verifying. | |
163 inline VerificationType pop_stack(TRAPS) { | |
164 if (_stack_size <= 0) { | |
165 verifier()->verify_error(_offset, "Operand stack underflow"); | |
166 return VerificationType::bogus_type(); | |
167 } | |
168 // Put bogus type to indicate it's no longer valid. | |
169 // Added to make it consistent with the other pop_stack method. | |
170 VerificationType top = _stack[--_stack_size]; | |
171 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) | |
172 return top; | |
173 } | |
174 | |
175 // Pop and return the top type on stack type array after verifying it | |
176 // is assignable to type. | |
177 inline VerificationType pop_stack(VerificationType type, TRAPS) { | |
178 if (_stack_size != 0) { | |
179 VerificationType top = _stack[_stack_size - 1]; | |
180 bool subtype = type.is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
181 top, verifier(), CHECK_(VerificationType::bogus_type())); |
0 | 182 if (subtype) { |
183 _stack_size --; | |
184 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) | |
185 return top; | |
186 } | |
187 } | |
188 return pop_stack_ex(type, THREAD); | |
189 } | |
190 | |
191 inline void pop_stack_2( | |
192 VerificationType type1, VerificationType type2, TRAPS) { | |
193 assert(type1.is_long2() || type1.is_double2(), "must be long/double"); | |
194 assert(type2.is_long() || type2.is_double(), "must be long/double_2"); | |
195 if (_stack_size >= 2) { | |
196 VerificationType top1 = _stack[_stack_size - 1]; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
197 bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK); |
0 | 198 VerificationType top2 = _stack[_stack_size - 2]; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
199 bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK); |
0 | 200 if (subtype1 && subtype2) { |
201 _stack_size -= 2; | |
202 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) | |
203 NOT_PRODUCT( _stack[_stack_size+1] = VerificationType::bogus_type(); ) | |
204 return; | |
205 } | |
206 } | |
207 pop_stack_ex(type1, THREAD); | |
208 pop_stack_ex(type2, THREAD); | |
209 } | |
210 | |
211 // Uncommon case that throws exceptions. | |
212 VerificationType pop_stack_ex(VerificationType type, TRAPS); | |
213 | |
214 // Return the type at index in local variable array after verifying | |
215 // it is assignable to type. | |
216 VerificationType get_local(int32_t index, VerificationType type, TRAPS); | |
217 // For long/double. | |
218 void get_local_2( | |
219 int32_t index, VerificationType type1, VerificationType type2, TRAPS); | |
220 | |
221 // Set element at index in local variable array to type. | |
222 void set_local(int32_t index, VerificationType type, TRAPS); | |
223 // For long/double. | |
224 void set_local_2( | |
225 int32_t index, VerificationType type1, VerificationType type2, TRAPS); | |
226 | |
227 // Private auxiliary method used only in is_assignable_to(StackMapFrame). | |
228 // Returns true if src is assignable to target. | |
229 bool is_assignable_to( | |
230 VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; | |
231 | |
2303
c1a6154012c8
7020118: Alter frame assignability to allow for exception handler coverage of invokespecial <init>
kamg
parents:
2177
diff
changeset
|
232 bool has_flag_match_exception(const StackMapFrame* target) const; |
c1a6154012c8
7020118: Alter frame assignability to allow for exception handler coverage of invokespecial <init>
kamg
parents:
2177
diff
changeset
|
233 |
0 | 234 // Debugging |
235 void print() const PRODUCT_RETURN; | |
236 }; | |
1972 | 237 |
238 #endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP |