src/share/vm/opto/escape.hpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
7147744 Cdiff src/share/vm/opto/escape.hpp
src/share/vm/opto/escape.hpp
Print this page
*** 118,160 ****
class PointsToNode;
class Type;
class TypePtr;
class VectorSet;
- // Wrapper for GrowableArray
- class PointsToList {
- GrowableArray<PointsToNode*> _list; // List of nodes this node points to
- public:
- uint count() const { return _list.length(); }
- PointsToNode* element(uint e) const { return _list.at(e); }
-
- bool add(PointsToNode* elem) {
- // Returns TRUE if elem is added.
- bool missed = !_list.contains(elem);
- if (missed)
- _list.append(elem); // Add new element
- return missed;
- }
- };
-
class JavaObjectNode;
class LocalVarNode;
class FieldNode;
class ArraycopyNode;
// ConnectionGraph nodes
class PointsToNode : public ResourceObj {
! PointsToList _edges; // List of nodes this node points to
! PointsToList _uses; // List of nodes which point to this node
const u1 _type; // NodeType
u1 _flags; // NodeFlags
u1 _escape; // EscapeState of object
u1 _fields_escape; // EscapeState of object's fields
! const Node* _node; // Ideal node corresponding to this PointsTo node.
! const uint _idx; // Cached ideal node's _idx
public:
typedef enum {
UnknownType = 0,
JavaObject = 1,
--- 118,144 ----
class PointsToNode;
class Type;
class TypePtr;
class VectorSet;
class JavaObjectNode;
class LocalVarNode;
class FieldNode;
class ArraycopyNode;
// ConnectionGraph nodes
class PointsToNode : public ResourceObj {
! GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
! GrowableArray<PointsToNode*> _uses; // List of nodes which point to this node
const u1 _type; // NodeType
u1 _flags; // NodeFlags
u1 _escape; // EscapeState of object
u1 _fields_escape; // EscapeState of object's fields
! Node* const _node; // Ideal node corresponding to this PointsTo node.
! const int _idx; // Cached ideal node's _idx
public:
typedef enum {
UnknownType = 0,
JavaObject = 1,
*** 179,199 ****
ArraycopySrc = 4, // Has edge from Arraycopy node
ArraycopyDst = 8 // Has edge to Arraycopy node
} NodeFlags;
! PointsToNode(Node* n, EscapeState es, NodeType type):
_node(n),
_idx(n->_idx),
_type((u1)type),
_escape((u1)es),
_fields_escape((u1)es),
_flags(ScalarReplaceable) {
assert(n != NULL && es != UnknownEscape, "sanity");
}
! Node* ideal_node() const { return (Node*)_node; }
int idx() const { return _idx; }
bool is_JavaObject() const { return _type == (u1)JavaObject; }
bool is_LocalVar() const { return _type == (u1)LocalVar; }
bool is_Field() const { return _type == (u1)Field; }
--- 163,185 ----
ArraycopySrc = 4, // Has edge from Arraycopy node
ArraycopyDst = 8 // Has edge to Arraycopy node
} NodeFlags;
! PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
! _edges(C->comp_arena(), 2, 0, NULL),
! _uses (C->comp_arena(), 2, 0, NULL),
_node(n),
_idx(n->_idx),
_type((u1)type),
_escape((u1)es),
_fields_escape((u1)es),
_flags(ScalarReplaceable) {
assert(n != NULL && es != UnknownEscape, "sanity");
}
! Node* ideal_node() const { return _node; }
int idx() const { return _idx; }
bool is_JavaObject() const { return _type == (u1)JavaObject; }
bool is_LocalVar() const { return _type == (u1)LocalVar; }
bool is_Field() const { return _type == (u1)Field; }
*** 224,251 ****
_flags |= ScalarReplaceable;
else
_flags &= ~ScalarReplaceable;
}
! uint edge_count() const { return _edges.count(); }
! PointsToNode* edge(uint e) const { return _edges.element(e); }
! bool add_edge(PointsToNode* edge) { return _edges.add(edge); }
! uint use_count() const { return _uses.count(); }
! PointsToNode* use(uint e) const { return _uses.element(e); }
! bool add_use(PointsToNode* use) { return _uses.add(use); }
// Mark base edge use to distinguish from stored value edge.
! bool add_base_use(FieldNode* use) { return _uses.add((PointsToNode*)((intptr_t)use + 1)); }
static bool is_base_use(PointsToNode* use) { return (((intptr_t)use) & 1); }
static PointsToNode* get_use_node(PointsToNode* use) { return (PointsToNode*)(((intptr_t)use) & ~1); }
// Return true if this node points to specified node or nodes it points to.
bool points_to(JavaObjectNode* ptn) const;
! // Return true if nodes points only to non-escaped allocations.
! bool not_escaped_allocation();
// Return true if one node points to an other.
bool meet(PointsToNode* ptn);
#ifndef PRODUCT
--- 210,237 ----
_flags |= ScalarReplaceable;
else
_flags &= ~ScalarReplaceable;
}
! int edge_count() const { return _edges.length(); }
! PointsToNode* edge(int e) const { return _edges.at(e); }
! bool add_edge(PointsToNode* edge) { return _edges.append_if_missing(edge); }
! int use_count() const { return _uses.length(); }
! PointsToNode* use(int e) const { return _uses.at(e); }
! bool add_use(PointsToNode* use) { return _uses.append_if_missing(use); }
// Mark base edge use to distinguish from stored value edge.
! bool add_base_use(FieldNode* use) { return _uses.append_if_missing((PointsToNode*)((intptr_t)use + 1)); }
static bool is_base_use(PointsToNode* use) { return (((intptr_t)use) & 1); }
static PointsToNode* get_use_node(PointsToNode* use) { return (PointsToNode*)(((intptr_t)use) & ~1); }
// Return true if this node points to specified node or nodes it points to.
bool points_to(JavaObjectNode* ptn) const;
! // Return true if this node points only to non-escaping allocations.
! bool non_escaping_allocation();
// Return true if one node points to an other.
bool meet(PointsToNode* ptn);
#ifndef PRODUCT
*** 255,319 ****
};
class LocalVarNode: public PointsToNode {
public:
! LocalVarNode(Node* n, EscapeState es):
! PointsToNode(n, es, LocalVar) {}
};
class JavaObjectNode: public PointsToNode {
public:
! JavaObjectNode(Node* n, EscapeState es):
! PointsToNode(n, es, JavaObject) {
if (es > NoEscape)
set_scalar_replaceable(false);
}
};
class FieldNode: public PointsToNode {
! PointsToList _bases; // List of JavaObject nodes which point to this node
const int _offset; // Field's offset.
const bool _is_oop; // Field points to object
bool _has_unknown_base; // Has phantom_object base
public:
! FieldNode(Node* n, EscapeState es, int offs, bool is_oop):
! PointsToNode(n, es, Field),
_offset(offs), _is_oop(is_oop),
_has_unknown_base(false) {}
int offset() const { return _offset;}
bool is_oop() const { return _is_oop;}
bool has_unknown_base() const { return _has_unknown_base; }
void set_has_unknown_base() { _has_unknown_base = true; }
! uint base_count() const { return _bases.count(); }
! PointsToNode* base(uint e) const { return _bases.element(e); }
! bool add_base(PointsToNode* base) { return _bases.add(base); }
#ifdef ASSERT
// Return true if bases points to this java object.
bool has_base(JavaObjectNode* ptn) const;
#endif
};
class ArraycopyNode: public PointsToNode {
public:
! ArraycopyNode(Node* n, EscapeState es):
! PointsToNode(n, es, Arraycopy) {}
};
// Iterators for PointsTo node's edges:
// for (EdgeIterator i(n); i.has_next(); i.next()) {
// PointsToNode* u = i.get();
class PointsToIterator: public StackObj {
protected:
const PointsToNode* node;
! const uint cnt;
! uint i;
public:
! inline PointsToIterator(const PointsToNode* n, uint cnt) : node(n), cnt(cnt), i(0) { }
inline bool has_next() const { return i < cnt; }
inline void next() { i++; }
PointsToNode* get() const { ShouldNotCallThis(); return NULL; }
};
--- 241,305 ----
};
class LocalVarNode: public PointsToNode {
public:
! LocalVarNode(Compile *C, Node* n, EscapeState es):
! PointsToNode(C, n, es, LocalVar) {}
};
class JavaObjectNode: public PointsToNode {
public:
! JavaObjectNode(Compile *C, Node* n, EscapeState es):
! PointsToNode(C, n, es, JavaObject) {
if (es > NoEscape)
set_scalar_replaceable(false);
}
};
class FieldNode: public PointsToNode {
! GrowableArray<PointsToNode*> _bases; // List of JavaObject nodes which point to this node
const int _offset; // Field's offset.
const bool _is_oop; // Field points to object
bool _has_unknown_base; // Has phantom_object base
public:
! FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
! PointsToNode(C, n, es, Field),
_offset(offs), _is_oop(is_oop),
_has_unknown_base(false) {}
int offset() const { return _offset;}
bool is_oop() const { return _is_oop;}
bool has_unknown_base() const { return _has_unknown_base; }
void set_has_unknown_base() { _has_unknown_base = true; }
! int base_count() const { return _bases.length(); }
! PointsToNode* base(int e) const { return _bases.at(e); }
! bool add_base(PointsToNode* base) { return _bases.append_if_missing(base); }
#ifdef ASSERT
// Return true if bases points to this java object.
bool has_base(JavaObjectNode* ptn) const;
#endif
};
class ArraycopyNode: public PointsToNode {
public:
! ArraycopyNode(Compile *C, Node* n, EscapeState es):
! PointsToNode(C, n, es, Arraycopy) {}
};
// Iterators for PointsTo node's edges:
// for (EdgeIterator i(n); i.has_next(); i.next()) {
// PointsToNode* u = i.get();
class PointsToIterator: public StackObj {
protected:
const PointsToNode* node;
! const int cnt;
! int i;
public:
! inline PointsToIterator(const PointsToNode* n, int cnt) : node(n), cnt(cnt), i(0) { }
inline bool has_next() const { return i < cnt; }
inline void next() { i++; }
PointsToNode* get() const { ShouldNotCallThis(); return NULL; }
};
*** 358,368 ****
PhaseIterGVN* _igvn; // Value numbering
Unique_Node_List ideal_nodes; // Used by CG construction and types splitting.
// Address of an element in _nodes. Used when the element is to be modified
! PointsToNode* ptnode_adr(uint idx) const {
// There should be no new ideal nodes during ConnectionGraph build,
// growableArray::at() will throw assert otherwise.
return _nodes.at(idx);
}
uint nodes_size() const { return _nodes.length(); }
--- 344,354 ----
PhaseIterGVN* _igvn; // Value numbering
Unique_Node_List ideal_nodes; // Used by CG construction and types splitting.
// Address of an element in _nodes. Used when the element is to be modified
! PointsToNode* ptnode_adr(int idx) const {
// There should be no new ideal nodes during ConnectionGraph build,
// growableArray::at() will throw assert otherwise.
return _nodes.at(idx);
}
uint nodes_size() const { return _nodes.length(); }
*** 372,382 ****
void add_java_object(Node* n, PointsToNode::EscapeState es);
void add_field(Node* n, PointsToNode::EscapeState es, int offset);
void add_arraycopy(Node* n, PointsToNode::EscapeState es, PointsToNode* src, PointsToNode* dst);
// Compute the escape state for arguments to a call.
! void process_call_arguments(CallNode *call, PhaseGVN *igvn);
// Add PointsToNode node corresponding to a call
void add_call_node(CallNode* call);
// Map ideal node to existing PointsTo node (usually phantom_object).
--- 358,368 ----
void add_java_object(Node* n, PointsToNode::EscapeState es);
void add_field(Node* n, PointsToNode::EscapeState es, int offset);
void add_arraycopy(Node* n, PointsToNode::EscapeState es, PointsToNode* src, PointsToNode* dst);
// Compute the escape state for arguments to a call.
! void process_call_arguments(CallNode *call);
// Add PointsToNode node corresponding to a call
void add_call_node(CallNode* call);
// Map ideal node to existing PointsTo node (usually phantom_object).
*** 448,458 ****
ptn->set_fields_escape_state(esc);
}
}
// Propagate GlobalEscape and ArgEscape escape states to all nodes
! // and check that we still have non escaped java objects.
bool find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
GrowableArray<JavaObjectNode*>& non_escaped_worklist);
// Adjust scalar_replaceable state after Connection Graph is built.
void adjust_scalar_replaceable_state(JavaObjectNode* jobj);
--- 434,444 ----
ptn->set_fields_escape_state(esc);
}
}
// Propagate GlobalEscape and ArgEscape escape states to all nodes
! // and check that we still have non-escaping java objects.
bool find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
GrowableArray<JavaObjectNode*>& non_escaped_worklist);
// Adjust scalar_replaceable state after Connection Graph is built.
void adjust_scalar_replaceable_state(JavaObjectNode* jobj);
*** 540,556 ****
// Propagate unique types created for unescaped allocated objects
// through the graph
void split_unique_types(GrowableArray<Node *> &alloc_worklist);
// Helper methods for unique types split.
! bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
! PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
! PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
! void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *igvn);
! Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
Node* step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop);
GrowableArray<MergeMemNode*> _mergemem_worklist; // List of all MergeMem nodes
--- 526,542 ----
// Propagate unique types created for unescaped allocated objects
// through the graph
void split_unique_types(GrowableArray<Node *> &alloc_worklist);
// Helper methods for unique types split.
! bool split_AddP(Node *addp, Node *base);
! PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, bool &new_created);
! PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist);
! void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis);
! Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist);
Node* step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop);
GrowableArray<MergeMemNode*> _mergemem_worklist; // List of all MergeMem nodes
src/share/vm/opto/escape.hpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File