84 RetTableEntry* find_jsrs_for_target(int targBci);
85 };
86
87 //
88 // CellTypeState
89 //
90 class CellTypeState VALUE_OBJ_CLASS_SPEC {
91 private:
92 unsigned int _state;
93
94 // Masks for separating the BITS and INFO portions of a CellTypeState
95 enum { info_mask = right_n_bits(27),
96 bits_mask = (int)(~info_mask) };
97
98 // These constant are used for manipulating the BITS portion of a
99 // CellTypeState
100 enum { uninit_bit = (int)(nth_bit(31)),
101 ref_bit = nth_bit(30),
102 val_bit = nth_bit(29),
103 addr_bit = nth_bit(28),
104 valuetype_bit = nth_bit(27),
105 live_bits_mask = (int)(bits_mask & ~uninit_bit) };
106
107 // These constants are used for manipulating the INFO portion of a
108 // CellTypeState
109 enum { top_info_bit = nth_bit(26),
110 not_bottom_info_bit = nth_bit(25),
111 info_data_mask = right_n_bits(25),
112 info_conflict = info_mask };
113
114 // Within the INFO data, these values are used to distinguish different
115 // kinds of references.
116 enum { ref_not_lock_bit = nth_bit(24), // 0 if this reference is locked as a monitor
117 ref_slot_bit = nth_bit(23), // 1 if this reference is a "slot" reference,
118 // 0 if it is a "line" reference.
119 ref_data_mask = right_n_bits(23) };
120
121 // Within the INFO data, these values are used to distinguish different
122 // kinds of value types.
123 enum { valuetype_slot_bit = nth_bit(24), // 1 if this reference is a "slot" value type,
124 // 0 if it is a "line" value type.
125 valuetype_data_mask = right_n_bits(24) };
126
127 // These values are used to initialize commonly used CellTypeState
128 // constants.
129 enum { bottom_value = 0,
130 uninit_value = (int)(uninit_bit | info_conflict),
131 ref_value = ref_bit,
132 ref_conflict = ref_bit | info_conflict,
133 val_value = val_bit | info_conflict,
134 valuetype_conflict = valuetype_bit | info_conflict,
135 addr_value = addr_bit,
136 addr_conflict = addr_bit | info_conflict };
137
138 public:
139
140 // Since some C++ constructors generate poor code for declarations of the
141 // form...
142 //
143 // CellTypeState vector[length];
144 //
145 // ...we avoid making a constructor for this class. CellTypeState values
146 // should be constructed using one of the make_* methods:
147
148 static CellTypeState make_any(int state) {
149 CellTypeState s;
150 s._state = state;
151 // Causes SS10 warning.
152 // assert(s.is_valid_state(), "check to see if CellTypeState is valid");
153 return s;
154 }
166 return make_any(addr_bit | not_bottom_info_bit | (bci & info_data_mask));
167 }
168
169 static CellTypeState make_slot_ref(int slot_num) {
170 assert(slot_num >= 0 && slot_num < ref_data_mask, "slot out of range");
171 return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit | ref_slot_bit |
172 (slot_num & ref_data_mask));
173 }
174
175 static CellTypeState make_line_ref(int bci) {
176 assert(bci >= 0 && bci < ref_data_mask, "line out of range");
177 return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit |
178 (bci & ref_data_mask));
179 }
180
181 static CellTypeState make_lock_ref(int bci) {
182 assert(bci >= 0 && bci < ref_data_mask, "line out of range");
183 return make_any(ref_bit | not_bottom_info_bit | (bci & ref_data_mask));
184 }
185
186
187 static CellTypeState make_slot_valuetype(int slot_num) {
188 assert(slot_num >= 0 && slot_num < valuetype_data_mask, "slot out of range");
189 return make_any(valuetype_bit | not_bottom_info_bit | valuetype_slot_bit |
190 (slot_num & valuetype_data_mask));
191 }
192
193 static CellTypeState make_line_valuetype(int bci) {
194 assert(bci >= 0 && bci < valuetype_data_mask, "line out of range");
195 return make_any(valuetype_bit | not_bottom_info_bit |
196 (bci & valuetype_data_mask));
197 }
198
199 // Query methods:
200 bool is_bottom() const { return _state == 0; }
201 bool is_live() const { return ((_state & live_bits_mask) != 0); }
202 bool is_valid_state() const {
203 // Uninitialized and value cells must contain no data in their info field:
204 if ((can_be_uninit() || can_be_value()) && !is_info_top()) {
205 return false;
206 }
207 // The top bit is only set when all info bits are set:
208 if (is_info_top() && ((_state & info_mask) != info_mask)) {
209 return false;
210 }
211 // The not_bottom_bit must be set when any other info bit is set:
212 if (is_info_bottom() && ((_state & info_mask) != 0)) {
213 return false;
214 }
215 return true;
216 }
217
218 bool is_address() const { return ((_state & bits_mask) == addr_bit); }
219 bool is_reference() const { return ((_state & bits_mask) == ref_bit); }
220 bool is_value() const { return ((_state & bits_mask) == val_bit); }
221 bool is_valuetype() const { return ((_state & bits_mask) == valuetype_bit); }
222 bool is_uninit() const { return ((_state & bits_mask) == (uint)uninit_bit); }
223
224 bool can_be_address() const { return ((_state & addr_bit) != 0); }
225 bool can_be_reference() const { return ((_state & ref_bit) != 0); }
226 bool can_be_value() const { return ((_state & val_bit) != 0); }
227 bool can_be_valuetype() const { return ((_state & valuetype_bit) != 0); }
228 bool can_be_uninit() const { return ((_state & uninit_bit) != 0); }
229
230 bool is_info_bottom() const { return ((_state & not_bottom_info_bit) == 0); }
231 bool is_info_top() const { return ((_state & top_info_bit) != 0); }
232 int get_info() const {
233 assert((!is_info_top() && !is_info_bottom()),
234 "check to make sure top/bottom info is not used");
235 return (_state & info_data_mask);
236 }
237
238 bool is_good_address() const { return is_address() && !is_info_top(); }
239 bool is_lock_reference() const {
240 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == ref_bit);
241 }
242 bool is_nonlock_reference() const {
243 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == (ref_bit | ref_not_lock_bit));
244 }
245
246 bool equal(CellTypeState a) const { return _state == a._state; }
247 bool equal_kind(CellTypeState a) const {
248 return (_state & bits_mask) == (a._state & bits_mask);
249 }
250
251 char to_char() const;
252
253 // Merge
254 CellTypeState merge (CellTypeState cts, int slot) const;
255
256 // Debugging output
257 void print(outputStream *os);
258
259 // Default values of common values
260 static CellTypeState bottom;
261 static CellTypeState uninit;
262 static CellTypeState ref;
263 static CellTypeState value;
264 static CellTypeState valuetype;
265 static CellTypeState refOrValueType;
266 static CellTypeState refUninit;
267 static CellTypeState varUninit;
268 static CellTypeState top;
269 static CellTypeState addr;
270 };
271
272
273 //
274 // BasicBlockStruct
275 //
276 class BasicBlock: ResourceObj {
277 private:
278 bool _changed; // Reached a fixpoint or not
279 public:
280 enum Constants {
281 _dead_basic_block = -2,
282 _unreached = -1 // Alive but not yet reached by analysis
283 // >=0 // Alive and has a merged state
284 };
285
400
401 // Interpretation methods (primary)
402 void do_interpretation ();
403 void init_basic_blocks ();
404 void setup_method_entry_state ();
405 void interp_all ();
406
407 // Interpretation methods (secondary)
408 void interp1 (BytecodeStream *itr);
409 void do_exception_edge (BytecodeStream *itr);
410 void check_type (CellTypeState expected, CellTypeState actual);
411 void ppstore (CellTypeState *in, int loc_no);
412 void ppload (CellTypeState *out, int loc_no);
413 void ppush1 (CellTypeState in);
414 void ppush (CellTypeState *in);
415 void ppop1 (CellTypeState out);
416 void ppop (CellTypeState *out);
417 void ppop_any (int poplen);
418 void pp (CellTypeState *in, CellTypeState *out);
419 void pp_new_ref (CellTypeState *in, int bci);
420 void pp_new_valuetype (CellTypeState *in, int bci);
421 void ppdupswap (int poplen, const char *out);
422 void do_ldc (int bci);
423 void do_astore (int idx);
424 void do_vstore (int idx);
425 void do_jsr (int delta);
426 void do_field (int is_get, int is_static, int idx, int bci);
427 void do_method (int is_static, int idx, int bci);
428 void do_vwithfield (int idx, int bci);
429 void do_multianewarray (int dims, int bci);
430 void do_monitorenter (int bci);
431 void do_monitorexit (int bci);
432 void do_return_monitor_check ();
433 void do_checkcast ();
434 CellTypeState *sigchar_to_effect (char sigch, int bci, CellTypeState *out);
435 int copy_cts (CellTypeState *dst, CellTypeState *src);
436
437 // Error handling
438 void error_work (const char *format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
439 void report_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
440 void verify_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
441 bool got_error() { return _got_error; }
442
443 // Create result set
444 bool _report_result;
445 bool _report_result_for_send; // Unfortunatly, stackmaps for sends are special, so we need some extra
446 BytecodeStream *_itr_send; // variables to handle them properly.
447
448 void report_result ();
|
84 RetTableEntry* find_jsrs_for_target(int targBci);
85 };
86
87 //
88 // CellTypeState
89 //
90 class CellTypeState VALUE_OBJ_CLASS_SPEC {
91 private:
92 unsigned int _state;
93
94 // Masks for separating the BITS and INFO portions of a CellTypeState
95 enum { info_mask = right_n_bits(27),
96 bits_mask = (int)(~info_mask) };
97
98 // These constant are used for manipulating the BITS portion of a
99 // CellTypeState
100 enum { uninit_bit = (int)(nth_bit(31)),
101 ref_bit = nth_bit(30),
102 val_bit = nth_bit(29),
103 addr_bit = nth_bit(28),
104 live_bits_mask = (int)(bits_mask & ~uninit_bit) };
105
106 // These constants are used for manipulating the INFO portion of a
107 // CellTypeState
108 enum { top_info_bit = nth_bit(26),
109 not_bottom_info_bit = nth_bit(25),
110 info_data_mask = right_n_bits(25),
111 info_conflict = info_mask };
112
113 // Within the INFO data, these values are used to distinguish different
114 // kinds of references.
115 enum { ref_not_lock_bit = nth_bit(24), // 0 if this reference is locked as a monitor
116 ref_slot_bit = nth_bit(23), // 1 if this reference is a "slot" reference,
117 // 0 if it is a "line" reference.
118 ref_data_mask = right_n_bits(23) };
119
120 // Within the INFO data, these values are used to distinguish different
121 // kinds of value types.
122 enum { valuetype_slot_bit = nth_bit(24), // 1 if this reference is a "slot" value type,
123 // 0 if it is a "line" value type.
124 valuetype_data_mask = right_n_bits(24) };
125
126 // These values are used to initialize commonly used CellTypeState
127 // constants.
128 enum { bottom_value = 0,
129 uninit_value = (int)(uninit_bit | info_conflict),
130 ref_value = ref_bit,
131 ref_conflict = ref_bit | info_conflict,
132 val_value = val_bit | info_conflict,
133 addr_value = addr_bit,
134 addr_conflict = addr_bit | info_conflict };
135
136 public:
137
138 // Since some C++ constructors generate poor code for declarations of the
139 // form...
140 //
141 // CellTypeState vector[length];
142 //
143 // ...we avoid making a constructor for this class. CellTypeState values
144 // should be constructed using one of the make_* methods:
145
146 static CellTypeState make_any(int state) {
147 CellTypeState s;
148 s._state = state;
149 // Causes SS10 warning.
150 // assert(s.is_valid_state(), "check to see if CellTypeState is valid");
151 return s;
152 }
164 return make_any(addr_bit | not_bottom_info_bit | (bci & info_data_mask));
165 }
166
167 static CellTypeState make_slot_ref(int slot_num) {
168 assert(slot_num >= 0 && slot_num < ref_data_mask, "slot out of range");
169 return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit | ref_slot_bit |
170 (slot_num & ref_data_mask));
171 }
172
173 static CellTypeState make_line_ref(int bci) {
174 assert(bci >= 0 && bci < ref_data_mask, "line out of range");
175 return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit |
176 (bci & ref_data_mask));
177 }
178
179 static CellTypeState make_lock_ref(int bci) {
180 assert(bci >= 0 && bci < ref_data_mask, "line out of range");
181 return make_any(ref_bit | not_bottom_info_bit | (bci & ref_data_mask));
182 }
183
184 // Query methods:
185 bool is_bottom() const { return _state == 0; }
186 bool is_live() const { return ((_state & live_bits_mask) != 0); }
187 bool is_valid_state() const {
188 // Uninitialized and value cells must contain no data in their info field:
189 if ((can_be_uninit() || can_be_value()) && !is_info_top()) {
190 return false;
191 }
192 // The top bit is only set when all info bits are set:
193 if (is_info_top() && ((_state & info_mask) != info_mask)) {
194 return false;
195 }
196 // The not_bottom_bit must be set when any other info bit is set:
197 if (is_info_bottom() && ((_state & info_mask) != 0)) {
198 return false;
199 }
200 return true;
201 }
202
203 bool is_address() const { return ((_state & bits_mask) == addr_bit); }
204 bool is_reference() const { return ((_state & bits_mask) == ref_bit); }
205 bool is_value() const { return ((_state & bits_mask) == val_bit); }
206 bool is_uninit() const { return ((_state & bits_mask) == (uint)uninit_bit); }
207
208 bool can_be_address() const { return ((_state & addr_bit) != 0); }
209 bool can_be_reference() const { return ((_state & ref_bit) != 0); }
210 bool can_be_value() const { return ((_state & val_bit) != 0); }
211 bool can_be_uninit() const { return ((_state & uninit_bit) != 0); }
212
213 bool is_info_bottom() const { return ((_state & not_bottom_info_bit) == 0); }
214 bool is_info_top() const { return ((_state & top_info_bit) != 0); }
215 int get_info() const {
216 assert((!is_info_top() && !is_info_bottom()),
217 "check to make sure top/bottom info is not used");
218 return (_state & info_data_mask);
219 }
220
221 bool is_good_address() const { return is_address() && !is_info_top(); }
222 bool is_lock_reference() const {
223 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == ref_bit);
224 }
225 bool is_nonlock_reference() const {
226 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == (ref_bit | ref_not_lock_bit));
227 }
228
229 bool equal(CellTypeState a) const { return _state == a._state; }
230 bool equal_kind(CellTypeState a) const {
231 return (_state & bits_mask) == (a._state & bits_mask);
232 }
233
234 char to_char() const;
235
236 // Merge
237 CellTypeState merge (CellTypeState cts, int slot) const;
238
239 // Debugging output
240 void print(outputStream *os);
241
242 // Default values of common values
243 static CellTypeState bottom;
244 static CellTypeState uninit;
245 static CellTypeState ref;
246 static CellTypeState value;
247 static CellTypeState refUninit;
248 static CellTypeState varUninit;
249 static CellTypeState top;
250 static CellTypeState addr;
251 };
252
253
254 //
255 // BasicBlockStruct
256 //
257 class BasicBlock: ResourceObj {
258 private:
259 bool _changed; // Reached a fixpoint or not
260 public:
261 enum Constants {
262 _dead_basic_block = -2,
263 _unreached = -1 // Alive but not yet reached by analysis
264 // >=0 // Alive and has a merged state
265 };
266
381
382 // Interpretation methods (primary)
383 void do_interpretation ();
384 void init_basic_blocks ();
385 void setup_method_entry_state ();
386 void interp_all ();
387
388 // Interpretation methods (secondary)
389 void interp1 (BytecodeStream *itr);
390 void do_exception_edge (BytecodeStream *itr);
391 void check_type (CellTypeState expected, CellTypeState actual);
392 void ppstore (CellTypeState *in, int loc_no);
393 void ppload (CellTypeState *out, int loc_no);
394 void ppush1 (CellTypeState in);
395 void ppush (CellTypeState *in);
396 void ppop1 (CellTypeState out);
397 void ppop (CellTypeState *out);
398 void ppop_any (int poplen);
399 void pp (CellTypeState *in, CellTypeState *out);
400 void pp_new_ref (CellTypeState *in, int bci);
401 void ppdupswap (int poplen, const char *out);
402 void do_ldc (int bci);
403 void do_astore (int idx);
404 void do_jsr (int delta);
405 void do_field (int is_get, int is_static, int idx, int bci);
406 void do_method (int is_static, int idx, int bci);
407 void do_withfield (int idx, int bci);
408 void do_multianewarray (int dims, int bci);
409 void do_monitorenter (int bci);
410 void do_monitorexit (int bci);
411 void do_return_monitor_check ();
412 void do_checkcast ();
413 CellTypeState *sigchar_to_effect (char sigch, int bci, CellTypeState *out);
414 int copy_cts (CellTypeState *dst, CellTypeState *src);
415
416 // Error handling
417 void error_work (const char *format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
418 void report_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
419 void verify_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3);
420 bool got_error() { return _got_error; }
421
422 // Create result set
423 bool _report_result;
424 bool _report_result_for_send; // Unfortunatly, stackmaps for sends are special, so we need some extra
425 BytecodeStream *_itr_send; // variables to handle them properly.
426
427 void report_result ();
|