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 } |