comparison src/share/vm/ci/bcEscapeAnalyzer.cpp @ 1648:8099e71601df

6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies Summary: Use GrowableArray and VectorSet allocated in ciEnv arena. Reviewed-by: never, twisti
author kvn
date Wed, 14 Jul 2010 14:47:34 -0700
parents c18cbe5936b8
children 53dbe853fb3a
comparison
equal deleted inserted replaced
1647:079980c86f33 1648:8099e71601df
104 }; 104 };
105 105
106 void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { 106 void BCEscapeAnalyzer::set_returned(ArgumentMap vars) {
107 for (int i = 0; i < _arg_size; i++) { 107 for (int i = 0; i < _arg_size; i++) {
108 if (vars.contains(i)) 108 if (vars.contains(i))
109 _arg_returned.set_bit(i); 109 _arg_returned.set(i);
110 } 110 }
111 _return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated()); 111 _return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated());
112 _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars()); 112 _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars());
113 } 113 }
114 114
124 // return true if any element of vars is an arg_stack argument 124 // return true if any element of vars is an arg_stack argument
125 bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){ 125 bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
126 if (_conservative) 126 if (_conservative)
127 return true; 127 return true;
128 for (int i = 0; i < _arg_size; i++) { 128 for (int i = 0; i < _arg_size; i++) {
129 if (vars.contains(i) && _arg_stack.at(i)) 129 if (vars.contains(i) && _arg_stack.test(i))
130 return true; 130 return true;
131 } 131 }
132 return false; 132 return false;
133 } 133 }
134 134
135 void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) { 135 void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
136 for (int i = 0; i < _arg_size; i++) { 136 for (int i = 0; i < _arg_size; i++) {
137 if (vars.contains(i)) { 137 if (vars.contains(i)) {
138 bm.clear_bit(i); 138 bm >>= i;
139 } 139 }
140 } 140 }
141 } 141 }
142 142
143 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { 143 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) {
1155 1155
1156 // initialize escape state of object parameters 1156 // initialize escape state of object parameters
1157 ciSignature* sig = method()->signature(); 1157 ciSignature* sig = method()->signature();
1158 int j = 0; 1158 int j = 0;
1159 if (!method()->is_static()) { 1159 if (!method()->is_static()) {
1160 _arg_local.set_bit(0); 1160 _arg_local.set(0);
1161 _arg_stack.set_bit(0); 1161 _arg_stack.set(0);
1162 j++; 1162 j++;
1163 } 1163 }
1164 for (i = 0; i < sig->count(); i++) { 1164 for (i = 0; i < sig->count(); i++) {
1165 ciType* t = sig->type_at(i); 1165 ciType* t = sig->type_at(i);
1166 if (!t->is_primitive_type()) { 1166 if (!t->is_primitive_type()) {
1167 _arg_local.set_bit(j); 1167 _arg_local.set(j);
1168 _arg_stack.set_bit(j); 1168 _arg_stack.set(j);
1169 } 1169 }
1170 j += t->size(); 1170 j += t->size();
1171 } 1171 }
1172 assert(j == _arg_size, "just checking"); 1172 assert(j == _arg_size, "just checking");
1173 1173
1196 var.clear(); 1196 var.clear();
1197 var.set(i); 1197 var.set(i);
1198 set_modified(var, OFFSET_ANY, 4); 1198 set_modified(var, OFFSET_ANY, 4);
1199 set_global_escape(var); 1199 set_global_escape(var);
1200 } 1200 }
1201 _arg_local.clear(); 1201 _arg_local.Clear();
1202 _arg_stack.clear(); 1202 _arg_stack.Clear();
1203 _arg_returned.clear(); 1203 _arg_returned.Clear();
1204 _return_local = false; 1204 _return_local = false;
1205 _return_allocated = false; 1205 _return_allocated = false;
1206 _allocated_escapes = true; 1206 _allocated_escapes = true;
1207 _unknown_modified = true; 1207 _unknown_modified = true;
1208 } 1208 }
1252 1252
1253 initialize(); 1253 initialize();
1254 1254
1255 // Do not scan method if it has no object parameters and 1255 // Do not scan method if it has no object parameters and
1256 // does not returns an object (_return_allocated is set in initialize()). 1256 // does not returns an object (_return_allocated is set in initialize()).
1257 if (_arg_local.is_empty() && !_return_allocated) { 1257 if (_arg_local.Size() == 0 && !_return_allocated) {
1258 // Clear all info since method's bytecode was not analysed and 1258 // Clear all info since method's bytecode was not analysed and
1259 // set pessimistic escape information. 1259 // set pessimistic escape information.
1260 clear_escape_info(); 1260 clear_escape_info();
1261 methodData()->set_eflag(methodDataOopDesc::allocated_escapes); 1261 methodData()->set_eflag(methodDataOopDesc::allocated_escapes);
1262 methodData()->set_eflag(methodDataOopDesc::unknown_modified); 1262 methodData()->set_eflag(methodDataOopDesc::unknown_modified);
1273 // don't store interprocedural escape information if it introduces 1273 // don't store interprocedural escape information if it introduces
1274 // dependencies or if method data is empty 1274 // dependencies or if method data is empty
1275 // 1275 //
1276 if (!has_dependencies() && !methodData()->is_empty()) { 1276 if (!has_dependencies() && !methodData()->is_empty()) {
1277 for (i = 0; i < _arg_size; i++) { 1277 for (i = 0; i < _arg_size; i++) {
1278 if (_arg_local.at(i)) { 1278 if (_arg_local.test(i)) {
1279 assert(_arg_stack.at(i), "inconsistent escape info"); 1279 assert(_arg_stack.test(i), "inconsistent escape info");
1280 methodData()->set_arg_local(i); 1280 methodData()->set_arg_local(i);
1281 methodData()->set_arg_stack(i); 1281 methodData()->set_arg_stack(i);
1282 } else if (_arg_stack.at(i)) { 1282 } else if (_arg_stack.test(i)) {
1283 methodData()->set_arg_stack(i); 1283 methodData()->set_arg_stack(i);
1284 } 1284 }
1285 if (_arg_returned.at(i)) { 1285 if (_arg_returned.test(i)) {
1286 methodData()->set_arg_returned(i); 1286 methodData()->set_arg_returned(i);
1287 } 1287 }
1288 methodData()->set_arg_modified(i, _arg_modified[i]); 1288 methodData()->set_arg_modified(i, _arg_modified[i]);
1289 } 1289 }
1290 if (_return_local) { 1290 if (_return_local) {
1306 void BCEscapeAnalyzer::read_escape_info() { 1306 void BCEscapeAnalyzer::read_escape_info() {
1307 assert(methodData()->has_escape_info(), "no escape info available"); 1307 assert(methodData()->has_escape_info(), "no escape info available");
1308 1308
1309 // read escape information from method descriptor 1309 // read escape information from method descriptor
1310 for (int i = 0; i < _arg_size; i++) { 1310 for (int i = 0; i < _arg_size; i++) {
1311 _arg_local.at_put(i, methodData()->is_arg_local(i)); 1311 if (methodData()->is_arg_local(i))
1312 _arg_stack.at_put(i, methodData()->is_arg_stack(i)); 1312 _arg_local.set(i);
1313 _arg_returned.at_put(i, methodData()->is_arg_returned(i)); 1313 if (methodData()->is_arg_stack(i))
1314 _arg_stack.set(i);
1315 if (methodData()->is_arg_returned(i))
1316 _arg_returned.set(i);
1314 _arg_modified[i] = methodData()->arg_modified(i); 1317 _arg_modified[i] = methodData()->arg_modified(i);
1315 } 1318 }
1316 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); 1319 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local);
1317 _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated); 1320 _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated);
1318 _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes); 1321 _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes);
1356 } 1359 }
1357 #endif 1360 #endif
1358 1361
1359 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) 1362 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
1360 : _conservative(method == NULL || !EstimateArgEscape) 1363 : _conservative(method == NULL || !EstimateArgEscape)
1364 , _arena(CURRENT_ENV->arena())
1361 , _method(method) 1365 , _method(method)
1362 , _methodData(method ? method->method_data() : NULL) 1366 , _methodData(method ? method->method_data() : NULL)
1363 , _arg_size(method ? method->arg_size() : 0) 1367 , _arg_size(method ? method->arg_size() : 0)
1364 , _stack() 1368 , _arg_local(_arena)
1365 , _arg_local(_arg_size) 1369 , _arg_stack(_arena)
1366 , _arg_stack(_arg_size) 1370 , _arg_returned(_arena)
1367 , _arg_returned(_arg_size) 1371 , _dirty(_arena)
1368 , _dirty(_arg_size)
1369 , _return_local(false) 1372 , _return_local(false)
1370 , _return_allocated(false) 1373 , _return_allocated(false)
1371 , _allocated_escapes(false) 1374 , _allocated_escapes(false)
1372 , _unknown_modified(false) 1375 , _unknown_modified(false)
1373 , _dependencies() 1376 , _dependencies(_arena, 4, 0, NULL)
1374 , _parent(parent) 1377 , _parent(parent)
1375 , _level(parent == NULL ? 0 : parent->level() + 1) { 1378 , _level(parent == NULL ? 0 : parent->level() + 1) {
1376 if (!_conservative) { 1379 if (!_conservative) {
1377 _arg_local.clear(); 1380 _arg_local.Clear();
1378 _arg_stack.clear(); 1381 _arg_stack.Clear();
1379 _arg_returned.clear(); 1382 _arg_returned.Clear();
1380 _dirty.clear(); 1383 _dirty.Clear();
1381 Arena* arena = CURRENT_ENV->arena(); 1384 Arena* arena = CURRENT_ENV->arena();
1382 _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint)); 1385 _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint));
1383 Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint)); 1386 Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint));
1384 1387
1385 if (methodData() == NULL) 1388 if (methodData() == NULL)
1412 // Also record evol dependencies so redefinition of the 1415 // Also record evol dependencies so redefinition of the
1413 // callee will trigger recompilation. 1416 // callee will trigger recompilation.
1414 deps->assert_evol_method(method()); 1417 deps->assert_evol_method(method());
1415 } 1418 }
1416 for (int i = 0; i < _dependencies.length(); i+=2) { 1419 for (int i = 0; i < _dependencies.length(); i+=2) {
1417 ciKlass *k = _dependencies[i]->as_klass(); 1420 ciKlass *k = _dependencies.at(i)->as_klass();
1418 ciMethod *m = _dependencies[i+1]->as_method(); 1421 ciMethod *m = _dependencies.at(i+1)->as_method();
1419 deps->assert_unique_concrete_method(k, m); 1422 deps->assert_unique_concrete_method(k, m);
1420 } 1423 }
1421 } 1424 }