Wed, 14 Jul 2010 14:47:34 -0700
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
Summary: Use GrowableArray and VectorSet allocated in ciEnv arena.
Reviewed-by: never, twisti
1.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jul 14 14:29:14 2010 -0700 1.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jul 14 14:47:34 2010 -0700 1.3 @@ -106,7 +106,7 @@ 1.4 void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { 1.5 for (int i = 0; i < _arg_size; i++) { 1.6 if (vars.contains(i)) 1.7 - _arg_returned.set_bit(i); 1.8 + _arg_returned.set(i); 1.9 } 1.10 _return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated()); 1.11 _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars()); 1.12 @@ -126,16 +126,16 @@ 1.13 if (_conservative) 1.14 return true; 1.15 for (int i = 0; i < _arg_size; i++) { 1.16 - if (vars.contains(i) && _arg_stack.at(i)) 1.17 + if (vars.contains(i) && _arg_stack.test(i)) 1.18 return true; 1.19 } 1.20 return false; 1.21 } 1.22 1.23 -void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) { 1.24 +void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { 1.25 for (int i = 0; i < _arg_size; i++) { 1.26 if (vars.contains(i)) { 1.27 - bm.clear_bit(i); 1.28 + bm >>= i; 1.29 } 1.30 } 1.31 } 1.32 @@ -1157,15 +1157,15 @@ 1.33 ciSignature* sig = method()->signature(); 1.34 int j = 0; 1.35 if (!method()->is_static()) { 1.36 - _arg_local.set_bit(0); 1.37 - _arg_stack.set_bit(0); 1.38 + _arg_local.set(0); 1.39 + _arg_stack.set(0); 1.40 j++; 1.41 } 1.42 for (i = 0; i < sig->count(); i++) { 1.43 ciType* t = sig->type_at(i); 1.44 if (!t->is_primitive_type()) { 1.45 - _arg_local.set_bit(j); 1.46 - _arg_stack.set_bit(j); 1.47 + _arg_local.set(j); 1.48 + _arg_stack.set(j); 1.49 } 1.50 j += t->size(); 1.51 } 1.52 @@ -1198,9 +1198,9 @@ 1.53 set_modified(var, OFFSET_ANY, 4); 1.54 set_global_escape(var); 1.55 } 1.56 - _arg_local.clear(); 1.57 - _arg_stack.clear(); 1.58 - _arg_returned.clear(); 1.59 + _arg_local.Clear(); 1.60 + _arg_stack.Clear(); 1.61 + _arg_returned.Clear(); 1.62 _return_local = false; 1.63 _return_allocated = false; 1.64 _allocated_escapes = true; 1.65 @@ -1254,7 +1254,7 @@ 1.66 1.67 // Do not scan method if it has no object parameters and 1.68 // does not returns an object (_return_allocated is set in initialize()). 1.69 - if (_arg_local.is_empty() && !_return_allocated) { 1.70 + if (_arg_local.Size() == 0 && !_return_allocated) { 1.71 // Clear all info since method's bytecode was not analysed and 1.72 // set pessimistic escape information. 1.73 clear_escape_info(); 1.74 @@ -1275,14 +1275,14 @@ 1.75 // 1.76 if (!has_dependencies() && !methodData()->is_empty()) { 1.77 for (i = 0; i < _arg_size; i++) { 1.78 - if (_arg_local.at(i)) { 1.79 - assert(_arg_stack.at(i), "inconsistent escape info"); 1.80 + if (_arg_local.test(i)) { 1.81 + assert(_arg_stack.test(i), "inconsistent escape info"); 1.82 methodData()->set_arg_local(i); 1.83 methodData()->set_arg_stack(i); 1.84 - } else if (_arg_stack.at(i)) { 1.85 + } else if (_arg_stack.test(i)) { 1.86 methodData()->set_arg_stack(i); 1.87 } 1.88 - if (_arg_returned.at(i)) { 1.89 + if (_arg_returned.test(i)) { 1.90 methodData()->set_arg_returned(i); 1.91 } 1.92 methodData()->set_arg_modified(i, _arg_modified[i]); 1.93 @@ -1308,9 +1308,12 @@ 1.94 1.95 // read escape information from method descriptor 1.96 for (int i = 0; i < _arg_size; i++) { 1.97 - _arg_local.at_put(i, methodData()->is_arg_local(i)); 1.98 - _arg_stack.at_put(i, methodData()->is_arg_stack(i)); 1.99 - _arg_returned.at_put(i, methodData()->is_arg_returned(i)); 1.100 + if (methodData()->is_arg_local(i)) 1.101 + _arg_local.set(i); 1.102 + if (methodData()->is_arg_stack(i)) 1.103 + _arg_stack.set(i); 1.104 + if (methodData()->is_arg_returned(i)) 1.105 + _arg_returned.set(i); 1.106 _arg_modified[i] = methodData()->arg_modified(i); 1.107 } 1.108 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); 1.109 @@ -1358,26 +1361,26 @@ 1.110 1.111 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) 1.112 : _conservative(method == NULL || !EstimateArgEscape) 1.113 + , _arena(CURRENT_ENV->arena()) 1.114 , _method(method) 1.115 , _methodData(method ? method->method_data() : NULL) 1.116 , _arg_size(method ? method->arg_size() : 0) 1.117 - , _stack() 1.118 - , _arg_local(_arg_size) 1.119 - , _arg_stack(_arg_size) 1.120 - , _arg_returned(_arg_size) 1.121 - , _dirty(_arg_size) 1.122 + , _arg_local(_arena) 1.123 + , _arg_stack(_arena) 1.124 + , _arg_returned(_arena) 1.125 + , _dirty(_arena) 1.126 , _return_local(false) 1.127 , _return_allocated(false) 1.128 , _allocated_escapes(false) 1.129 , _unknown_modified(false) 1.130 - , _dependencies() 1.131 + , _dependencies(_arena, 4, 0, NULL) 1.132 , _parent(parent) 1.133 , _level(parent == NULL ? 0 : parent->level() + 1) { 1.134 if (!_conservative) { 1.135 - _arg_local.clear(); 1.136 - _arg_stack.clear(); 1.137 - _arg_returned.clear(); 1.138 - _dirty.clear(); 1.139 + _arg_local.Clear(); 1.140 + _arg_stack.Clear(); 1.141 + _arg_returned.Clear(); 1.142 + _dirty.Clear(); 1.143 Arena* arena = CURRENT_ENV->arena(); 1.144 _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint)); 1.145 Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint)); 1.146 @@ -1414,8 +1417,8 @@ 1.147 deps->assert_evol_method(method()); 1.148 } 1.149 for (int i = 0; i < _dependencies.length(); i+=2) { 1.150 - ciKlass *k = _dependencies[i]->as_klass(); 1.151 - ciMethod *m = _dependencies[i+1]->as_method(); 1.152 + ciKlass *k = _dependencies.at(i)->as_klass(); 1.153 + ciMethod *m = _dependencies.at(i+1)->as_method(); 1.154 deps->assert_unique_concrete_method(k, m); 1.155 } 1.156 }
2.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 14 14:29:14 2010 -0700 2.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 14 14:47:34 2010 -0700 2.3 @@ -22,9 +22,6 @@ 2.4 * 2.5 */ 2.6 2.7 -define_array(ciObjectArray, ciObject*); 2.8 -define_stack(ciObjectList, ciObjectArray); 2.9 - 2.10 // This class implements a fast, conservative analysis of effect of methods 2.11 // on the escape state of their arguments. The analysis is at the bytecode 2.12 // level. 2.13 @@ -34,18 +31,17 @@ 2.14 2.15 class BCEscapeAnalyzer : public ResourceObj { 2.16 private: 2.17 + Arena* _arena; // ciEnv arena 2.18 + 2.19 bool _conservative; // If true, return maximally 2.20 // conservative results. 2.21 ciMethod* _method; 2.22 ciMethodData* _methodData; 2.23 int _arg_size; 2.24 - 2.25 - intStack _stack; 2.26 - 2.27 - BitMap _arg_local; 2.28 - BitMap _arg_stack; 2.29 - BitMap _arg_returned; 2.30 - BitMap _dirty; 2.31 + VectorSet _arg_local; 2.32 + VectorSet _arg_stack; 2.33 + VectorSet _arg_returned; 2.34 + VectorSet _dirty; 2.35 enum{ ARG_OFFSET_MAX = 31}; 2.36 uint *_arg_modified; 2.37 2.38 @@ -54,7 +50,7 @@ 2.39 bool _allocated_escapes; 2.40 bool _unknown_modified; 2.41 2.42 - ciObjectList _dependencies; 2.43 + GrowableArray<ciObject *> _dependencies; 2.44 2.45 ciMethodBlocks *_methodBlocks; 2.46 2.47 @@ -68,20 +64,10 @@ 2.48 private: 2.49 // helper functions 2.50 bool is_argument(int i) { return i >= 0 && i < _arg_size; } 2.51 - 2.52 - void raw_push(int i) { _stack.push(i); } 2.53 - int raw_pop() { return _stack.is_empty() ? -1 : _stack.pop(); } 2.54 - void apush(int i) { raw_push(i); } 2.55 - void spush() { raw_push(-1); } 2.56 - void lpush() { spush(); spush(); } 2.57 - int apop() { return raw_pop(); } 2.58 - void spop() { assert(_stack.is_empty() || _stack.top() == -1, ""); raw_pop(); } 2.59 - void lpop() { spop(); spop(); } 2.60 - 2.61 void set_returned(ArgumentMap vars); 2.62 bool is_argument(ArgumentMap vars); 2.63 bool is_arg_stack(ArgumentMap vars); 2.64 - void clear_bits(ArgumentMap vars, BitMap &bs); 2.65 + void clear_bits(ArgumentMap vars, VectorSet &bs); 2.66 void set_method_escape(ArgumentMap vars); 2.67 void set_global_escape(ArgumentMap vars); 2.68 void set_dirty(ArgumentMap vars); 2.69 @@ -116,25 +102,25 @@ 2.70 ciMethodData* methodData() const { return _methodData; } 2.71 BCEscapeAnalyzer* parent() const { return _parent; } 2.72 int level() const { return _level; } 2.73 - ciObjectList* dependencies() { return &_dependencies; } 2.74 + GrowableArray<ciObject *>* dependencies() { return &_dependencies; } 2.75 bool has_dependencies() const { return !_dependencies.is_empty(); } 2.76 2.77 // retrieval of interprocedural escape information 2.78 2.79 // The given argument does not escape the callee. 2.80 bool is_arg_local(int i) const { 2.81 - return !_conservative && _arg_local.at(i); 2.82 + return !_conservative && _arg_local.test(i); 2.83 } 2.84 2.85 // The given argument escapes the callee, but does not become globally 2.86 // reachable. 2.87 bool is_arg_stack(int i) const { 2.88 - return !_conservative && _arg_stack.at(i); 2.89 + return !_conservative && _arg_stack.test(i); 2.90 } 2.91 2.92 // The given argument does not escape globally, and may be returned. 2.93 bool is_arg_returned(int i) const { 2.94 - return !_conservative && _arg_returned.at(i); } 2.95 + return !_conservative && _arg_returned.test(i); } 2.96 2.97 // True iff only input arguments are returned. 2.98 bool is_return_local() const {
3.1 --- a/src/share/vm/ci/ciMethod.cpp Wed Jul 14 14:29:14 2010 -0700 3.2 +++ b/src/share/vm/ci/ciMethod.cpp Wed Jul 14 14:47:34 2010 -0700 3.3 @@ -54,10 +54,10 @@ 3.4 _code = NULL; 3.5 _exception_handlers = NULL; 3.6 _liveness = NULL; 3.7 - _bcea = NULL; 3.8 _method_blocks = NULL; 3.9 #ifdef COMPILER2 3.10 _flow = NULL; 3.11 + _bcea = NULL; 3.12 #endif // COMPILER2 3.13 3.14 ciEnv *env = CURRENT_ENV; 3.15 @@ -121,11 +121,11 @@ 3.16 _intrinsic_id = vmIntrinsics::_none; 3.17 _liveness = NULL; 3.18 _can_be_statically_bound = false; 3.19 - _bcea = NULL; 3.20 _method_blocks = NULL; 3.21 _method_data = NULL; 3.22 #ifdef COMPILER2 3.23 _flow = NULL; 3.24 + _bcea = NULL; 3.25 #endif // COMPILER2 3.26 } 3.27 3.28 @@ -1033,10 +1033,15 @@ 3.29 bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); } 3.30 3.31 BCEscapeAnalyzer *ciMethod::get_bcea() { 3.32 +#ifdef COMPILER2 3.33 if (_bcea == NULL) { 3.34 _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL); 3.35 } 3.36 return _bcea; 3.37 +#else // COMPILER2 3.38 + ShouldNotReachHere(); 3.39 + return NULL; 3.40 +#endif // COMPILER2 3.41 } 3.42 3.43 ciMethodBlocks *ciMethod::get_method_blocks() {
4.1 --- a/src/share/vm/ci/ciMethod.hpp Wed Jul 14 14:29:14 2010 -0700 4.2 +++ b/src/share/vm/ci/ciMethod.hpp Wed Jul 14 14:47:34 2010 -0700 4.3 @@ -48,7 +48,6 @@ 4.4 ciInstanceKlass* _holder; 4.5 ciSignature* _signature; 4.6 ciMethodData* _method_data; 4.7 - BCEscapeAnalyzer* _bcea; 4.8 ciMethodBlocks* _method_blocks; 4.9 4.10 // Code attributes. 4.11 @@ -72,7 +71,8 @@ 4.12 // Optional liveness analyzer. 4.13 MethodLiveness* _liveness; 4.14 #ifdef COMPILER2 4.15 - ciTypeFlow* _flow; 4.16 + ciTypeFlow* _flow; 4.17 + BCEscapeAnalyzer* _bcea; 4.18 #endif 4.19 4.20 ciMethod(methodHandle h_m);
5.1 --- a/src/share/vm/includeDB_compiler2 Wed Jul 14 14:29:14 2010 -0700 5.2 +++ b/src/share/vm/includeDB_compiler2 Wed Jul 14 14:47:34 2010 -0700 5.3 @@ -89,6 +89,21 @@ 5.4 5.5 allocation.hpp c2_globals.hpp 5.6 5.7 +bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp 5.8 +bcEscapeAnalyzer.cpp bitMap.inline.hpp 5.9 +bcEscapeAnalyzer.cpp bytecode.hpp 5.10 +bcEscapeAnalyzer.cpp ciConstant.hpp 5.11 +bcEscapeAnalyzer.cpp ciField.hpp 5.12 +bcEscapeAnalyzer.cpp ciMethodBlocks.hpp 5.13 +bcEscapeAnalyzer.cpp ciStreams.hpp 5.14 + 5.15 +bcEscapeAnalyzer.hpp allocation.hpp 5.16 +bcEscapeAnalyzer.hpp ciMethod.hpp 5.17 +bcEscapeAnalyzer.hpp ciMethodData.hpp 5.18 +bcEscapeAnalyzer.hpp dependencies.hpp 5.19 +bcEscapeAnalyzer.hpp growableArray.hpp 5.20 +bcEscapeAnalyzer.hpp vectset.hpp 5.21 + 5.22 block.cpp allocation.inline.hpp 5.23 block.cpp block.hpp 5.24 block.cpp cfgnode.hpp 5.25 @@ -239,6 +254,7 @@ 5.26 ciEnv.cpp compileLog.hpp 5.27 ciEnv.cpp runtime.hpp 5.28 5.29 +ciMethod.cpp bcEscapeAnalyzer.hpp 5.30 ciMethod.cpp ciTypeFlow.hpp 5.31 ciMethod.cpp methodOop.hpp 5.32
6.1 --- a/src/share/vm/includeDB_core Wed Jul 14 14:29:14 2010 -0700 6.2 +++ b/src/share/vm/includeDB_core Wed Jul 14 14:47:34 2010 -0700 6.3 @@ -301,20 +301,6 @@ 6.4 barrierSet.inline.hpp barrierSet.hpp 6.5 barrierSet.inline.hpp cardTableModRefBS.hpp 6.6 6.7 -bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp 6.8 -bcEscapeAnalyzer.cpp bitMap.inline.hpp 6.9 -bcEscapeAnalyzer.cpp bytecode.hpp 6.10 -bcEscapeAnalyzer.cpp ciConstant.hpp 6.11 -bcEscapeAnalyzer.cpp ciField.hpp 6.12 -bcEscapeAnalyzer.cpp ciMethodBlocks.hpp 6.13 -bcEscapeAnalyzer.cpp ciStreams.hpp 6.14 - 6.15 -bcEscapeAnalyzer.hpp allocation.hpp 6.16 -bcEscapeAnalyzer.hpp ciMethod.hpp 6.17 -bcEscapeAnalyzer.hpp ciMethodData.hpp 6.18 -bcEscapeAnalyzer.hpp dependencies.hpp 6.19 -bcEscapeAnalyzer.hpp growableArray.hpp 6.20 - 6.21 biasedLocking.cpp biasedLocking.hpp 6.22 biasedLocking.cpp klass.inline.hpp 6.23 biasedLocking.cpp markOop.hpp 6.24 @@ -665,7 +651,6 @@ 6.25 6.26 ciMethod.cpp abstractCompiler.hpp 6.27 ciMethod.cpp allocation.inline.hpp 6.28 -ciMethod.cpp bcEscapeAnalyzer.hpp 6.29 ciMethod.cpp bitMap.inline.hpp 6.30 ciMethod.cpp ciCallProfile.hpp 6.31 ciMethod.cpp ciExceptionHandler.hpp