25 #include "precompiled.hpp"
26 #include "ci/bcEscapeAnalyzer.hpp"
27 #include "ci/ciConstant.hpp"
28 #include "ci/ciField.hpp"
29 #include "ci/ciMethodBlocks.hpp"
30 #include "ci/ciStreams.hpp"
31 #include "interpreter/bytecode.hpp"
32 #include "utilities/bitMap.inline.hpp"
33
34
35
36 #ifndef PRODUCT
37 #define TRACE_BCEA(level, code) \
38 if (EstimateArgEscape && BCEATraceLevel >= level) { \
39 code; \
40 }
41 #else
42 #define TRACE_BCEA(level, code)
43 #endif
44
45 // Maintain a map of which aguments a local variable or
46 // stack slot may contain. In addition to tracking
47 // arguments, it tracks two special values, "allocated"
48 // which represents any object allocated in the current
49 // method, and "unknown" which is any other object.
50 // Up to 30 arguments are handled, with the last one
51 // representing summary information for any extra arguments
52 class BCEscapeAnalyzer::ArgumentMap {
53 uint _bits;
54 enum {MAXBIT = 29,
55 ALLOCATED = 1,
56 UNKNOWN = 2};
57
58 uint int_to_bit(uint e) const {
59 if (e > MAXBIT)
60 e = MAXBIT;
61 return (1 << (e + 2));
62 }
63
64 public:
65 ArgumentMap() { _bits = 0;}
301 if (target->is_loaded() && klass->is_loaded()
302 && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
303 && target->is_loaded()) {
304 if (code == Bytecodes::_invokestatic
305 || code == Bytecodes::_invokespecial
306 || code == Bytecodes::_invokevirtual && target->is_final_method()) {
307 inline_target = target;
308 } else {
309 inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
310 }
311 }
312
313 if (inline_target != NULL && !is_recursive_call(inline_target)) {
314 // analyze callee
315 BCEscapeAnalyzer analyzer(inline_target, this);
316
317 // adjust escape state of actual parameters
318 bool must_record_dependencies = false;
319 for (i = arg_size - 1; i >= 0; i--) {
320 ArgumentMap arg = state.raw_pop();
321 if (!is_argument(arg))
322 continue;
323 for (int j = 0; j < _arg_size; j++) {
324 if (arg.contains(j)) {
325 _arg_modified[j] |= analyzer._arg_modified[i];
326 }
327 }
328 if (!is_arg_stack(arg)) {
329 // arguments have already been recognized as escaping
330 } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
331 set_method_escape(arg);
332 must_record_dependencies = true;
333 } else {
334 set_global_escape(arg);
335 }
336 }
337 _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects();
338
339 // record dependencies if at least one parameter retained stack-allocatable
340 if (must_record_dependencies) {
341 if (code == Bytecodes::_invokeinterface || code == Bytecodes::_invokevirtual && !target->is_final_method()) {
342 _dependencies.append(actual_recv);
343 _dependencies.append(inline_target);
344 }
345 _dependencies.appendAll(analyzer.dependencies());
346 }
347 } else {
348 TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.",
|
25 #include "precompiled.hpp"
26 #include "ci/bcEscapeAnalyzer.hpp"
27 #include "ci/ciConstant.hpp"
28 #include "ci/ciField.hpp"
29 #include "ci/ciMethodBlocks.hpp"
30 #include "ci/ciStreams.hpp"
31 #include "interpreter/bytecode.hpp"
32 #include "utilities/bitMap.inline.hpp"
33
34
35
36 #ifndef PRODUCT
37 #define TRACE_BCEA(level, code) \
38 if (EstimateArgEscape && BCEATraceLevel >= level) { \
39 code; \
40 }
41 #else
42 #define TRACE_BCEA(level, code)
43 #endif
44
45 // Maintain a map of which arguments a local variable or
46 // stack slot may contain. In addition to tracking
47 // arguments, it tracks two special values, "allocated"
48 // which represents any object allocated in the current
49 // method, and "unknown" which is any other object.
50 // Up to 30 arguments are handled, with the last one
51 // representing summary information for any extra arguments
52 class BCEscapeAnalyzer::ArgumentMap {
53 uint _bits;
54 enum {MAXBIT = 29,
55 ALLOCATED = 1,
56 UNKNOWN = 2};
57
58 uint int_to_bit(uint e) const {
59 if (e > MAXBIT)
60 e = MAXBIT;
61 return (1 << (e + 2));
62 }
63
64 public:
65 ArgumentMap() { _bits = 0;}
301 if (target->is_loaded() && klass->is_loaded()
302 && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
303 && target->is_loaded()) {
304 if (code == Bytecodes::_invokestatic
305 || code == Bytecodes::_invokespecial
306 || code == Bytecodes::_invokevirtual && target->is_final_method()) {
307 inline_target = target;
308 } else {
309 inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
310 }
311 }
312
313 if (inline_target != NULL && !is_recursive_call(inline_target)) {
314 // analyze callee
315 BCEscapeAnalyzer analyzer(inline_target, this);
316
317 // adjust escape state of actual parameters
318 bool must_record_dependencies = false;
319 for (i = arg_size - 1; i >= 0; i--) {
320 ArgumentMap arg = state.raw_pop();
321 // Check if callee arg is a caller arg or an allocated object
322 bool allocated = arg.contains_allocated();
323 if (!(is_argument(arg) || allocated))
324 continue;
325 for (int j = 0; j < _arg_size; j++) {
326 if (arg.contains(j)) {
327 _arg_modified[j] |= analyzer._arg_modified[i];
328 }
329 }
330 if (!(is_arg_stack(arg) || allocated)) {
331 // arguments have already been recognized as escaping
332 } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
333 set_method_escape(arg);
334 must_record_dependencies = true;
335 } else {
336 set_global_escape(arg);
337 }
338 }
339 _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects();
340
341 // record dependencies if at least one parameter retained stack-allocatable
342 if (must_record_dependencies) {
343 if (code == Bytecodes::_invokeinterface || code == Bytecodes::_invokevirtual && !target->is_final_method()) {
344 _dependencies.append(actual_recv);
345 _dependencies.append(inline_target);
346 }
347 _dependencies.appendAll(analyzer.dependencies());
348 }
349 } else {
350 TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.",
|