Mercurial > hg > truffle
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 } |