Mercurial > hg > graal-compiler
annotate src/share/vm/classfile/stackMapFrame.hpp @ 1751:2528b5bd749c
6980262: Memory leak when exception is thrown in static initializer
Summary: Use resource memory instead of c-heap for the exception message
Reviewed-by: phh, jmasa
author | kamg |
---|---|
date | Fri, 27 Aug 2010 15:05:28 -0400 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2003, 2006, 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 | |
25 // A StackMapFrame represents one frame in the stack map attribute. | |
26 | |
27 enum { | |
28 FLAG_THIS_UNINIT = 0x01 | |
29 }; | |
30 | |
31 class StackMapFrame : public ResourceObj { | |
32 private: | |
33 int32_t _offset; | |
34 | |
35 // See comment in StackMapTable about _frame_count about why these | |
36 // fields are int32_t instead of u2. | |
37 int32_t _locals_size; // number of valid type elements in _locals | |
38 int32_t _stack_size; // number of valid type elements in _stack | |
39 | |
40 int32_t _max_locals; | |
41 int32_t _max_stack; | |
42 | |
43 u1 _flags; | |
44 VerificationType* _locals; // local variable type array | |
45 VerificationType* _stack; // operand stack type array | |
46 | |
47 ClassVerifier* _verifier; // the verifier verifying this method | |
48 | |
49 public: | |
50 // constructors | |
51 | |
52 // This constructor is used by the type checker to allocate frames | |
53 // in type state, which have _max_locals and _max_stack array elements | |
54 // in _locals and _stack. | |
55 StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* verifier); | |
56 | |
57 // This constructor is used to initialize stackmap frames in stackmap table, | |
58 // which have _locals_size and _stack_size array elements in _locals and _stack. | |
59 StackMapFrame(int32_t offset, | |
60 u1 flags, | |
61 u2 locals_size, | |
62 u2 stack_size, | |
63 u2 max_locals, | |
64 u2 max_stack, | |
65 VerificationType* locals, | |
66 VerificationType* stack, | |
67 ClassVerifier* v) : _offset(offset), _flags(flags), | |
68 _locals_size(locals_size), | |
69 _stack_size(stack_size), | |
70 _max_locals(max_locals), | |
71 _max_stack(max_stack), | |
72 _locals(locals), _stack(stack), | |
73 _verifier(v) { } | |
74 | |
75 inline void set_offset(int32_t offset) { _offset = offset; } | |
76 inline void set_verifier(ClassVerifier* v) { _verifier = v; } | |
77 inline void set_flags(u1 flags) { _flags = flags; } | |
78 inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; } | |
79 inline void set_stack_size(u2 stack_size) { _stack_size = stack_size; } | |
80 inline void clear_stack() { _stack_size = 0; } | |
81 inline int32_t offset() const { return _offset; } | |
82 inline ClassVerifier* verifier() const { return _verifier; } | |
83 inline u1 flags() const { return _flags; } | |
84 inline int32_t locals_size() const { return _locals_size; } | |
85 inline VerificationType* locals() const { return _locals; } | |
86 inline int32_t stack_size() const { return _stack_size; } | |
87 inline VerificationType* stack() const { return _stack; } | |
88 inline int32_t max_locals() const { return _max_locals; } | |
89 inline int32_t max_stack() const { return _max_stack; } | |
90 inline bool flag_this_uninit() const { return _flags & FLAG_THIS_UNINIT; } | |
91 | |
92 // Set locals and stack types to bogus | |
93 inline void reset() { | |
94 int32_t i; | |
95 for (i = 0; i < _max_locals; i++) { | |
96 _locals[i] = VerificationType::bogus_type(); | |
97 } | |
98 for (i = 0; i < _max_stack; i++) { | |
99 _stack[i] = VerificationType::bogus_type(); | |
100 } | |
101 } | |
102 | |
103 // Return a StackMapFrame with the same local variable array and empty stack. | |
104 // Stack array is allocate with unused one element. | |
105 StackMapFrame* frame_in_exception_handler(u1 flags); | |
106 | |
107 // Set local variable type array based on m's signature. | |
108 VerificationType set_locals_from_arg( | |
109 const methodHandle m, VerificationType thisKlass, TRAPS); | |
110 | |
111 // Search local variable type array and stack type array. | |
112 // Return true if an uninitialized object is found. | |
113 bool has_new_object() const; | |
114 | |
115 // Search local variable type array and stack type array. | |
116 // Set every element with type of old_object to new_object. | |
117 void initialize_object( | |
118 VerificationType old_object, VerificationType new_object); | |
119 | |
120 // Copy local variable type array in src into this local variable type array. | |
121 void copy_locals(const StackMapFrame* src); | |
122 | |
123 // Copy stack type array in src into this stack type array. | |
124 void copy_stack(const StackMapFrame* src); | |
125 | |
126 // Return true if this stack map frame is assignable to target. | |
127 bool is_assignable_to(const StackMapFrame* target, TRAPS) const; | |
128 | |
129 // Push type into stack type array. | |
130 inline void push_stack(VerificationType type, TRAPS) { | |
131 assert(!type.is_check(), "Must be a real type"); | |
132 if (_stack_size >= _max_stack) { | |
133 verifier()->verify_error(_offset, "Operand stack overflow"); | |
134 return; | |
135 } | |
136 _stack[_stack_size++] = type; | |
137 } | |
138 | |
139 inline void push_stack_2( | |
140 VerificationType type1, VerificationType type2, TRAPS) { | |
141 assert(type1.is_long() || type1.is_double(), "must be long/double"); | |
142 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); | |
143 if (_stack_size >= _max_stack - 1) { | |
144 verifier()->verify_error(_offset, "Operand stack overflow"); | |
145 return; | |
146 } | |
147 _stack[_stack_size++] = type1; | |
148 _stack[_stack_size++] = type2; | |
149 } | |
150 | |
151 // Pop and return the top type on stack without verifying. | |
152 inline VerificationType pop_stack(TRAPS) { | |
153 if (_stack_size <= 0) { | |
154 verifier()->verify_error(_offset, "Operand stack underflow"); | |
155 return VerificationType::bogus_type(); | |
156 } | |
157 // Put bogus type to indicate it's no longer valid. | |
158 // Added to make it consistent with the other pop_stack method. | |
159 VerificationType top = _stack[--_stack_size]; | |
160 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) | |
161 return top; | |
162 } | |
163 | |
164 // Pop and return the top type on stack type array after verifying it | |
165 // is assignable to type. | |
166 inline VerificationType pop_stack(VerificationType type, TRAPS) { | |
167 if (_stack_size != 0) { | |
168 VerificationType top = _stack[_stack_size - 1]; | |
169 bool subtype = type.is_assignable_from( | |
170 top, verifier()->current_class(), | |
171 CHECK_(VerificationType::bogus_type())); | |
172 if (subtype) { | |
173 _stack_size --; | |
174 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) | |
175 return top; | |
176 } | |
177 } | |
178 return pop_stack_ex(type, THREAD); | |
179 } | |
180 | |
181 inline void pop_stack_2( | |
182 VerificationType type1, VerificationType type2, TRAPS) { | |
183 assert(type1.is_long2() || type1.is_double2(), "must be long/double"); | |
184 assert(type2.is_long() || type2.is_double(), "must be long/double_2"); | |
185 if (_stack_size >= 2) { | |
186 VerificationType top1 = _stack[_stack_size - 1]; | |
187 bool subtype1 = type1.is_assignable_from( | |
188 top1, verifier()->current_class(), CHECK); | |
189 VerificationType top2 = _stack[_stack_size - 2]; | |
190 bool subtype2 = type2.is_assignable_from( | |
191 top2, verifier()->current_class(), CHECK); | |
192 if (subtype1 && subtype2) { | |
193 _stack_size -= 2; | |
194 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) | |
195 NOT_PRODUCT( _stack[_stack_size+1] = VerificationType::bogus_type(); ) | |
196 return; | |
197 } | |
198 } | |
199 pop_stack_ex(type1, THREAD); | |
200 pop_stack_ex(type2, THREAD); | |
201 } | |
202 | |
203 // Uncommon case that throws exceptions. | |
204 VerificationType pop_stack_ex(VerificationType type, TRAPS); | |
205 | |
206 // Return the type at index in local variable array after verifying | |
207 // it is assignable to type. | |
208 VerificationType get_local(int32_t index, VerificationType type, TRAPS); | |
209 // For long/double. | |
210 void get_local_2( | |
211 int32_t index, VerificationType type1, VerificationType type2, TRAPS); | |
212 | |
213 // Set element at index in local variable array to type. | |
214 void set_local(int32_t index, VerificationType type, TRAPS); | |
215 // For long/double. | |
216 void set_local_2( | |
217 int32_t index, VerificationType type1, VerificationType type2, TRAPS); | |
218 | |
219 // Private auxiliary method used only in is_assignable_to(StackMapFrame). | |
220 // Returns true if src is assignable to target. | |
221 bool is_assignable_to( | |
222 VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; | |
223 | |
224 // Debugging | |
225 void print() const PRODUCT_RETURN; | |
226 }; |