提交 c5224ef9 编写于 作者: K kvn

6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies

Summary: Use GrowableArray and VectorSet allocated in ciEnv arena.
Reviewed-by: never, twisti
上级 8dfee536
......@@ -106,7 +106,7 @@ public:
void BCEscapeAnalyzer::set_returned(ArgumentMap vars) {
for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i))
_arg_returned.set_bit(i);
_arg_returned.set(i);
}
_return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated());
_return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars());
......@@ -126,16 +126,16 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
if (_conservative)
return true;
for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i) && _arg_stack.at(i))
if (vars.contains(i) && _arg_stack.test(i))
return true;
}
return false;
}
void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) {
void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i)) {
bm.clear_bit(i);
bm >>= i;
}
}
}
......@@ -1157,15 +1157,15 @@ void BCEscapeAnalyzer::initialize() {
ciSignature* sig = method()->signature();
int j = 0;
if (!method()->is_static()) {
_arg_local.set_bit(0);
_arg_stack.set_bit(0);
_arg_local.set(0);
_arg_stack.set(0);
j++;
}
for (i = 0; i < sig->count(); i++) {
ciType* t = sig->type_at(i);
if (!t->is_primitive_type()) {
_arg_local.set_bit(j);
_arg_stack.set_bit(j);
_arg_local.set(j);
_arg_stack.set(j);
}
j += t->size();
}
......@@ -1198,9 +1198,9 @@ void BCEscapeAnalyzer::clear_escape_info() {
set_modified(var, OFFSET_ANY, 4);
set_global_escape(var);
}
_arg_local.clear();
_arg_stack.clear();
_arg_returned.clear();
_arg_local.Clear();
_arg_stack.Clear();
_arg_returned.Clear();
_return_local = false;
_return_allocated = false;
_allocated_escapes = true;
......@@ -1254,7 +1254,7 @@ void BCEscapeAnalyzer::compute_escape_info() {
// Do not scan method if it has no object parameters and
// does not returns an object (_return_allocated is set in initialize()).
if (_arg_local.is_empty() && !_return_allocated) {
if (_arg_local.Size() == 0 && !_return_allocated) {
// Clear all info since method's bytecode was not analysed and
// set pessimistic escape information.
clear_escape_info();
......@@ -1275,14 +1275,14 @@ void BCEscapeAnalyzer::compute_escape_info() {
//
if (!has_dependencies() && !methodData()->is_empty()) {
for (i = 0; i < _arg_size; i++) {
if (_arg_local.at(i)) {
assert(_arg_stack.at(i), "inconsistent escape info");
if (_arg_local.test(i)) {
assert(_arg_stack.test(i), "inconsistent escape info");
methodData()->set_arg_local(i);
methodData()->set_arg_stack(i);
} else if (_arg_stack.at(i)) {
} else if (_arg_stack.test(i)) {
methodData()->set_arg_stack(i);
}
if (_arg_returned.at(i)) {
if (_arg_returned.test(i)) {
methodData()->set_arg_returned(i);
}
methodData()->set_arg_modified(i, _arg_modified[i]);
......@@ -1308,9 +1308,12 @@ void BCEscapeAnalyzer::read_escape_info() {
// read escape information from method descriptor
for (int i = 0; i < _arg_size; i++) {
_arg_local.at_put(i, methodData()->is_arg_local(i));
_arg_stack.at_put(i, methodData()->is_arg_stack(i));
_arg_returned.at_put(i, methodData()->is_arg_returned(i));
if (methodData()->is_arg_local(i))
_arg_local.set(i);
if (methodData()->is_arg_stack(i))
_arg_stack.set(i);
if (methodData()->is_arg_returned(i))
_arg_returned.set(i);
_arg_modified[i] = methodData()->arg_modified(i);
}
_return_local = methodData()->eflag_set(methodDataOopDesc::return_local);
......@@ -1358,26 +1361,26 @@ void BCEscapeAnalyzer::dump() {
BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
: _conservative(method == NULL || !EstimateArgEscape)
, _arena(CURRENT_ENV->arena())
, _method(method)
, _methodData(method ? method->method_data() : NULL)
, _arg_size(method ? method->arg_size() : 0)
, _stack()
, _arg_local(_arg_size)
, _arg_stack(_arg_size)
, _arg_returned(_arg_size)
, _dirty(_arg_size)
, _arg_local(_arena)
, _arg_stack(_arena)
, _arg_returned(_arena)
, _dirty(_arena)
, _return_local(false)
, _return_allocated(false)
, _allocated_escapes(false)
, _unknown_modified(false)
, _dependencies()
, _dependencies(_arena, 4, 0, NULL)
, _parent(parent)
, _level(parent == NULL ? 0 : parent->level() + 1) {
if (!_conservative) {
_arg_local.clear();
_arg_stack.clear();
_arg_returned.clear();
_dirty.clear();
_arg_local.Clear();
_arg_stack.Clear();
_arg_returned.Clear();
_dirty.Clear();
Arena* arena = CURRENT_ENV->arena();
_arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint));
Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint));
......@@ -1414,8 +1417,8 @@ void BCEscapeAnalyzer::copy_dependencies(Dependencies *deps) {
deps->assert_evol_method(method());
}
for (int i = 0; i < _dependencies.length(); i+=2) {
ciKlass *k = _dependencies[i]->as_klass();
ciMethod *m = _dependencies[i+1]->as_method();
ciKlass *k = _dependencies.at(i)->as_klass();
ciMethod *m = _dependencies.at(i+1)->as_method();
deps->assert_unique_concrete_method(k, m);
}
}
......@@ -22,9 +22,6 @@
*
*/
define_array(ciObjectArray, ciObject*);
define_stack(ciObjectList, ciObjectArray);
// This class implements a fast, conservative analysis of effect of methods
// on the escape state of their arguments. The analysis is at the bytecode
// level.
......@@ -34,18 +31,17 @@ class ciBlock;
class BCEscapeAnalyzer : public ResourceObj {
private:
Arena* _arena; // ciEnv arena
bool _conservative; // If true, return maximally
// conservative results.
ciMethod* _method;
ciMethodData* _methodData;
int _arg_size;
intStack _stack;
BitMap _arg_local;
BitMap _arg_stack;
BitMap _arg_returned;
BitMap _dirty;
VectorSet _arg_local;
VectorSet _arg_stack;
VectorSet _arg_returned;
VectorSet _dirty;
enum{ ARG_OFFSET_MAX = 31};
uint *_arg_modified;
......@@ -54,7 +50,7 @@ class BCEscapeAnalyzer : public ResourceObj {
bool _allocated_escapes;
bool _unknown_modified;
ciObjectList _dependencies;
GrowableArray<ciObject *> _dependencies;
ciMethodBlocks *_methodBlocks;
......@@ -68,20 +64,10 @@ class BCEscapeAnalyzer : public ResourceObj {
private:
// helper functions
bool is_argument(int i) { return i >= 0 && i < _arg_size; }
void raw_push(int i) { _stack.push(i); }
int raw_pop() { return _stack.is_empty() ? -1 : _stack.pop(); }
void apush(int i) { raw_push(i); }
void spush() { raw_push(-1); }
void lpush() { spush(); spush(); }
int apop() { return raw_pop(); }
void spop() { assert(_stack.is_empty() || _stack.top() == -1, ""); raw_pop(); }
void lpop() { spop(); spop(); }
void set_returned(ArgumentMap vars);
bool is_argument(ArgumentMap vars);
bool is_arg_stack(ArgumentMap vars);
void clear_bits(ArgumentMap vars, BitMap &bs);
void clear_bits(ArgumentMap vars, VectorSet &bs);
void set_method_escape(ArgumentMap vars);
void set_global_escape(ArgumentMap vars);
void set_dirty(ArgumentMap vars);
......@@ -116,25 +102,25 @@ class BCEscapeAnalyzer : public ResourceObj {
ciMethodData* methodData() const { return _methodData; }
BCEscapeAnalyzer* parent() const { return _parent; }
int level() const { return _level; }
ciObjectList* dependencies() { return &_dependencies; }
GrowableArray<ciObject *>* dependencies() { return &_dependencies; }
bool has_dependencies() const { return !_dependencies.is_empty(); }
// retrieval of interprocedural escape information
// The given argument does not escape the callee.
bool is_arg_local(int i) const {
return !_conservative && _arg_local.at(i);
return !_conservative && _arg_local.test(i);
}
// The given argument escapes the callee, but does not become globally
// reachable.
bool is_arg_stack(int i) const {
return !_conservative && _arg_stack.at(i);
return !_conservative && _arg_stack.test(i);
}
// The given argument does not escape globally, and may be returned.
bool is_arg_returned(int i) const {
return !_conservative && _arg_returned.at(i); }
return !_conservative && _arg_returned.test(i); }
// True iff only input arguments are returned.
bool is_return_local() const {
......
......@@ -54,10 +54,10 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
_code = NULL;
_exception_handlers = NULL;
_liveness = NULL;
_bcea = NULL;
_method_blocks = NULL;
#ifdef COMPILER2
_flow = NULL;
_bcea = NULL;
#endif // COMPILER2
ciEnv *env = CURRENT_ENV;
......@@ -121,11 +121,11 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
_intrinsic_id = vmIntrinsics::_none;
_liveness = NULL;
_can_be_statically_bound = false;
_bcea = NULL;
_method_blocks = NULL;
_method_data = NULL;
#ifdef COMPILER2
_flow = NULL;
_bcea = NULL;
#endif // COMPILER2
}
......@@ -1033,10 +1033,15 @@ bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor)
bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); }
BCEscapeAnalyzer *ciMethod::get_bcea() {
#ifdef COMPILER2
if (_bcea == NULL) {
_bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL);
}
return _bcea;
#else // COMPILER2
ShouldNotReachHere();
return NULL;
#endif // COMPILER2
}
ciMethodBlocks *ciMethod::get_method_blocks() {
......
......@@ -48,7 +48,6 @@ class ciMethod : public ciObject {
ciInstanceKlass* _holder;
ciSignature* _signature;
ciMethodData* _method_data;
BCEscapeAnalyzer* _bcea;
ciMethodBlocks* _method_blocks;
// Code attributes.
......@@ -72,7 +71,8 @@ class ciMethod : public ciObject {
// Optional liveness analyzer.
MethodLiveness* _liveness;
#ifdef COMPILER2
ciTypeFlow* _flow;
ciTypeFlow* _flow;
BCEscapeAnalyzer* _bcea;
#endif
ciMethod(methodHandle h_m);
......
......@@ -89,6 +89,21 @@ adlcVMDeps.hpp allocation.hpp
allocation.hpp c2_globals.hpp
bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp
bcEscapeAnalyzer.cpp bitMap.inline.hpp
bcEscapeAnalyzer.cpp bytecode.hpp
bcEscapeAnalyzer.cpp ciConstant.hpp
bcEscapeAnalyzer.cpp ciField.hpp
bcEscapeAnalyzer.cpp ciMethodBlocks.hpp
bcEscapeAnalyzer.cpp ciStreams.hpp
bcEscapeAnalyzer.hpp allocation.hpp
bcEscapeAnalyzer.hpp ciMethod.hpp
bcEscapeAnalyzer.hpp ciMethodData.hpp
bcEscapeAnalyzer.hpp dependencies.hpp
bcEscapeAnalyzer.hpp growableArray.hpp
bcEscapeAnalyzer.hpp vectset.hpp
block.cpp allocation.inline.hpp
block.cpp block.hpp
block.cpp cfgnode.hpp
......@@ -239,6 +254,7 @@ chaitin_<os_family>.cpp machnode.hpp
ciEnv.cpp compileLog.hpp
ciEnv.cpp runtime.hpp
ciMethod.cpp bcEscapeAnalyzer.hpp
ciMethod.cpp ciTypeFlow.hpp
ciMethod.cpp methodOop.hpp
......
......@@ -301,20 +301,6 @@ barrierSet.hpp oopsHierarchy.hpp
barrierSet.inline.hpp barrierSet.hpp
barrierSet.inline.hpp cardTableModRefBS.hpp
bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp
bcEscapeAnalyzer.cpp bitMap.inline.hpp
bcEscapeAnalyzer.cpp bytecode.hpp
bcEscapeAnalyzer.cpp ciConstant.hpp
bcEscapeAnalyzer.cpp ciField.hpp
bcEscapeAnalyzer.cpp ciMethodBlocks.hpp
bcEscapeAnalyzer.cpp ciStreams.hpp
bcEscapeAnalyzer.hpp allocation.hpp
bcEscapeAnalyzer.hpp ciMethod.hpp
bcEscapeAnalyzer.hpp ciMethodData.hpp
bcEscapeAnalyzer.hpp dependencies.hpp
bcEscapeAnalyzer.hpp growableArray.hpp
biasedLocking.cpp biasedLocking.hpp
biasedLocking.cpp klass.inline.hpp
biasedLocking.cpp markOop.hpp
......@@ -665,7 +651,6 @@ ciKlassKlass.hpp ciSymbol.hpp
ciMethod.cpp abstractCompiler.hpp
ciMethod.cpp allocation.inline.hpp
ciMethod.cpp bcEscapeAnalyzer.hpp
ciMethod.cpp bitMap.inline.hpp
ciMethod.cpp ciCallProfile.hpp
ciMethod.cpp ciExceptionHandler.hpp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册