mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8371789: C2: More explicit dump results for TypePtr
Reviewed-by: chagedorn, vlivanov
This commit is contained in:
parent
2177260094
commit
8bafc2f0ae
@ -45,6 +45,8 @@
|
||||
#include "opto/type.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "utilities/checkedCast.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
#include "utilities/stringUtils.hpp"
|
||||
|
||||
@ -2979,15 +2981,22 @@ const char *const TypePtr::ptr_msg[TypePtr::lastPTR] = {
|
||||
|
||||
#ifndef PRODUCT
|
||||
void TypePtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
if( _ptr == Null ) st->print("null");
|
||||
else st->print("%s *", ptr_msg[_ptr]);
|
||||
if( _offset == OffsetTop ) st->print("+top");
|
||||
else if( _offset == OffsetBot ) st->print("+bot");
|
||||
else if( _offset ) st->print("+%d", _offset);
|
||||
st->print("ptr:%s", ptr_msg[_ptr]);
|
||||
dump_offset(st);
|
||||
dump_inline_depth(st);
|
||||
dump_speculative(st);
|
||||
}
|
||||
|
||||
void TypePtr::dump_offset(outputStream* st) const {
|
||||
if (_offset == OffsetBot) {
|
||||
st->print("+bot");
|
||||
} else if (_offset == OffsetTop) {
|
||||
st->print("+top");
|
||||
} else {
|
||||
st->print("+%d", _offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*dump the speculative part of the type
|
||||
*/
|
||||
@ -3159,11 +3168,12 @@ uint TypeRawPtr::hash(void) const {
|
||||
|
||||
//------------------------------dump2------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
if( _ptr == Constant )
|
||||
st->print(INTPTR_FORMAT, p2i(_bits));
|
||||
else
|
||||
void TypeRawPtr::dump2(Dict& d, uint depth, outputStream* st) const {
|
||||
if (_ptr == Constant) {
|
||||
st->print("rawptr:Constant:" INTPTR_FORMAT, p2i(_bits));
|
||||
} else {
|
||||
st->print("rawptr:%s", ptr_msg[_ptr]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3798,24 +3808,29 @@ uint TypeOopPtr::hash(void) const {
|
||||
|
||||
//------------------------------dump2------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
void TypeOopPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
void TypeOopPtr::dump2(Dict& d, uint depth, outputStream* st) const {
|
||||
st->print("oopptr:%s", ptr_msg[_ptr]);
|
||||
if( _klass_is_exact ) st->print(":exact");
|
||||
if( const_oop() ) st->print(INTPTR_FORMAT, p2i(const_oop()));
|
||||
switch( _offset ) {
|
||||
case OffsetTop: st->print("+top"); break;
|
||||
case OffsetBot: st->print("+any"); break;
|
||||
case 0: break;
|
||||
default: st->print("+%d",_offset); break;
|
||||
if (_klass_is_exact) {
|
||||
st->print(":exact");
|
||||
}
|
||||
if (_instance_id == InstanceTop)
|
||||
st->print(",iid=top");
|
||||
else if (_instance_id != InstanceBot)
|
||||
st->print(",iid=%d",_instance_id);
|
||||
|
||||
if (const_oop() != nullptr) {
|
||||
st->print(":" INTPTR_FORMAT, p2i(const_oop()));
|
||||
}
|
||||
dump_offset(st);
|
||||
dump_instance_id(st);
|
||||
dump_inline_depth(st);
|
||||
dump_speculative(st);
|
||||
}
|
||||
|
||||
void TypeOopPtr::dump_instance_id(outputStream* st) const {
|
||||
if (_instance_id == InstanceTop) {
|
||||
st->print(",iid=top");
|
||||
} else if (_instance_id == InstanceBot) {
|
||||
st->print(",iid=bot");
|
||||
} else {
|
||||
st->print(",iid=%d", _instance_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------singleton--------------------------------------
|
||||
@ -4453,50 +4468,30 @@ bool TypeInstPtr::maybe_java_subtype_of_helper(const TypeOopPtr* other, bool thi
|
||||
#ifndef PRODUCT
|
||||
void TypeInstPtr::dump2(Dict &d, uint depth, outputStream* st) const {
|
||||
// Print the name of the klass.
|
||||
st->print("instptr:");
|
||||
klass()->print_name_on(st);
|
||||
_interfaces->dump(st);
|
||||
|
||||
switch( _ptr ) {
|
||||
case Constant:
|
||||
if (WizardMode || Verbose) {
|
||||
ResourceMark rm;
|
||||
stringStream ss;
|
||||
if (_ptr == Constant && (WizardMode || Verbose)) {
|
||||
ResourceMark rm;
|
||||
stringStream ss;
|
||||
|
||||
st->print(" ");
|
||||
const_oop()->print_oop(&ss);
|
||||
// 'const_oop->print_oop()' may emit newlines('\n') into ss.
|
||||
// suppress newlines from it so -XX:+Verbose -XX:+PrintIdeal dumps one-liner for each node.
|
||||
char* buf = ss.as_string(/* c_heap= */false);
|
||||
StringUtils::replace_no_expand(buf, "\n", "");
|
||||
st->print_raw(buf);
|
||||
}
|
||||
case BotPTR:
|
||||
if (!WizardMode && !Verbose) {
|
||||
if( _klass_is_exact ) st->print(":exact");
|
||||
break;
|
||||
}
|
||||
case TopPTR:
|
||||
case AnyNull:
|
||||
case NotNull:
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
if( _klass_is_exact ) st->print(":exact");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
st->print(" ");
|
||||
const_oop()->print_oop(&ss);
|
||||
// 'const_oop->print_oop()' may emit newlines('\n') into ss.
|
||||
// suppress newlines from it so -XX:+Verbose -XX:+PrintIdeal dumps one-liner for each node.
|
||||
char* buf = ss.as_string(/* c_heap= */false);
|
||||
StringUtils::replace_no_expand(buf, "\n", "");
|
||||
st->print_raw(buf);
|
||||
}
|
||||
|
||||
if( _offset ) { // Dump offset, if any
|
||||
if( _offset == OffsetBot ) st->print("+any");
|
||||
else if( _offset == OffsetTop ) st->print("+unknown");
|
||||
else st->print("+%d", _offset);
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
if (_klass_is_exact) {
|
||||
st->print(":exact");
|
||||
}
|
||||
|
||||
st->print(" *");
|
||||
if (_instance_id == InstanceTop)
|
||||
st->print(",iid=top");
|
||||
else if (_instance_id != InstanceBot)
|
||||
st->print(",iid=%d",_instance_id);
|
||||
|
||||
dump_offset(st);
|
||||
dump_instance_id(st);
|
||||
dump_inline_depth(st);
|
||||
dump_speculative(st);
|
||||
}
|
||||
@ -5089,26 +5084,17 @@ const Type *TypeAryPtr::xdual() const {
|
||||
//------------------------------dump2------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
_ary->dump2(d,depth,st);
|
||||
st->print("aryptr:");
|
||||
_ary->dump2(d, depth, st);
|
||||
_interfaces->dump(st);
|
||||
|
||||
switch( _ptr ) {
|
||||
case Constant:
|
||||
if (_ptr == Constant) {
|
||||
const_oop()->print(st);
|
||||
break;
|
||||
case BotPTR:
|
||||
if (!WizardMode && !Verbose) {
|
||||
if( _klass_is_exact ) st->print(":exact");
|
||||
break;
|
||||
}
|
||||
case TopPTR:
|
||||
case AnyNull:
|
||||
case NotNull:
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
if( _klass_is_exact ) st->print(":exact");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
if (_klass_is_exact) {
|
||||
st->print(":exact");
|
||||
}
|
||||
|
||||
if( _offset != 0 ) {
|
||||
@ -5126,12 +5112,8 @@ void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
st->print(" *");
|
||||
if (_instance_id == InstanceTop)
|
||||
st->print(",iid=top");
|
||||
else if (_instance_id != InstanceBot)
|
||||
st->print(",iid=%d",_instance_id);
|
||||
|
||||
dump_instance_id(st);
|
||||
dump_inline_depth(st);
|
||||
dump_speculative(st);
|
||||
}
|
||||
@ -5490,13 +5472,10 @@ const Type *TypeMetadataPtr::xdual() const {
|
||||
#ifndef PRODUCT
|
||||
void TypeMetadataPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
st->print("metadataptr:%s", ptr_msg[_ptr]);
|
||||
if( metadata() ) st->print(INTPTR_FORMAT, p2i(metadata()));
|
||||
switch( _offset ) {
|
||||
case OffsetTop: st->print("+top"); break;
|
||||
case OffsetBot: st->print("+any"); break;
|
||||
case 0: break;
|
||||
default: st->print("+%d",_offset); break;
|
||||
if (metadata() != nullptr) {
|
||||
st->print(":" INTPTR_FORMAT, p2i(metadata()));
|
||||
}
|
||||
dump_offset(st);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -5644,44 +5623,6 @@ intptr_t TypeKlassPtr::get_con() const {
|
||||
return (intptr_t)k->constant_encoding();
|
||||
}
|
||||
|
||||
//------------------------------dump2------------------------------------------
|
||||
// Dump Klass Type
|
||||
#ifndef PRODUCT
|
||||
void TypeKlassPtr::dump2(Dict & d, uint depth, outputStream *st) const {
|
||||
switch(_ptr) {
|
||||
case Constant:
|
||||
st->print("precise ");
|
||||
case NotNull:
|
||||
{
|
||||
const char *name = klass()->name()->as_utf8();
|
||||
if (name) {
|
||||
st->print("%s: " INTPTR_FORMAT, name, p2i(klass()));
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
_interfaces->dump(st);
|
||||
}
|
||||
case BotPTR:
|
||||
if (!WizardMode && !Verbose && _ptr != Constant) break;
|
||||
case TopPTR:
|
||||
case AnyNull:
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
if (_ptr == Constant) st->print(":exact");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (_offset) { // Dump offset, if any
|
||||
if (_offset == OffsetBot) { st->print("+any"); }
|
||||
else if (_offset == OffsetTop) { st->print("+unknown"); }
|
||||
else { st->print("+%d", _offset); }
|
||||
}
|
||||
|
||||
st->print(" *");
|
||||
}
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Convenience common pre-built types.
|
||||
|
||||
@ -6036,6 +5977,15 @@ const TypeKlassPtr* TypeInstKlassPtr::try_improve() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void TypeInstKlassPtr::dump2(Dict& d, uint depth, outputStream* st) const {
|
||||
st->print("instklassptr:");
|
||||
klass()->print_name_on(st);
|
||||
_interfaces->dump(st);
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
dump_offset(st);
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
const TypeAryKlassPtr *TypeAryKlassPtr::make(PTR ptr, const Type* elem, ciKlass* k, int offset) {
|
||||
return (TypeAryKlassPtr*)(new TypeAryKlassPtr(ptr, elem, k, offset))->hashcons();
|
||||
@ -6507,34 +6457,11 @@ ciKlass* TypeAryKlassPtr::klass() const {
|
||||
// Dump Klass Type
|
||||
#ifndef PRODUCT
|
||||
void TypeAryKlassPtr::dump2( Dict & d, uint depth, outputStream *st ) const {
|
||||
switch( _ptr ) {
|
||||
case Constant:
|
||||
st->print("precise ");
|
||||
case NotNull:
|
||||
{
|
||||
st->print("[");
|
||||
_elem->dump2(d, depth, st);
|
||||
_interfaces->dump(st);
|
||||
st->print(": ");
|
||||
}
|
||||
case BotPTR:
|
||||
if( !WizardMode && !Verbose && _ptr != Constant ) break;
|
||||
case TopPTR:
|
||||
case AnyNull:
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
if( _ptr == Constant ) st->print(":exact");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( _offset ) { // Dump offset, if any
|
||||
if( _offset == OffsetBot ) { st->print("+any"); }
|
||||
else if( _offset == OffsetTop ) { st->print("+unknown"); }
|
||||
else { st->print("+%d", _offset); }
|
||||
}
|
||||
|
||||
st->print(" *");
|
||||
st->print("aryklassptr:[");
|
||||
_elem->dump2(d, depth, st);
|
||||
_interfaces->dump(st);
|
||||
st->print(":%s", ptr_msg[_ptr]);
|
||||
dump_offset(st);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1176,15 +1176,15 @@ protected:
|
||||
int hash_speculative() const;
|
||||
const TypePtr* add_offset_speculative(intptr_t offset) const;
|
||||
const TypePtr* with_offset_speculative(intptr_t offset) const;
|
||||
#ifndef PRODUCT
|
||||
void dump_speculative(outputStream *st) const;
|
||||
#endif
|
||||
|
||||
// utility methods to work on the inline depth of the type
|
||||
int dual_inline_depth() const;
|
||||
int meet_inline_depth(int depth) const;
|
||||
|
||||
#ifndef PRODUCT
|
||||
void dump_inline_depth(outputStream *st) const;
|
||||
void dump_speculative(outputStream* st) const;
|
||||
void dump_inline_depth(outputStream* st) const;
|
||||
void dump_offset(outputStream* st) const;
|
||||
#endif
|
||||
|
||||
// TypeInstPtr (TypeAryPtr resp.) and TypeInstKlassPtr (TypeAryKlassPtr resp.) implement very similar meet logic.
|
||||
@ -1364,6 +1364,10 @@ protected:
|
||||
virtual ciKlass* exact_klass_helper() const { return nullptr; }
|
||||
virtual ciKlass* klass() const { return _klass; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
void dump_instance_id(outputStream* st) const;
|
||||
#endif // PRODUCT
|
||||
|
||||
public:
|
||||
|
||||
bool is_java_subtype_of(const TypeOopPtr* other) const {
|
||||
@ -1832,9 +1836,6 @@ public:
|
||||
|
||||
virtual const TypeKlassPtr* try_improve() const { return this; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
|
||||
#endif
|
||||
private:
|
||||
virtual bool is_meet_subtype_of(const TypePtr* other) const {
|
||||
return is_meet_subtype_of_helper(other->is_klassptr(), klass_is_exact(), other->is_klassptr()->klass_is_exact());
|
||||
@ -1914,6 +1915,11 @@ public:
|
||||
// Convenience common pre-built types.
|
||||
static const TypeInstKlassPtr* OBJECT; // Not-null object klass or below
|
||||
static const TypeInstKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump2(Dict& d, uint depth, outputStream* st) const;
|
||||
#endif // PRODUCT
|
||||
|
||||
private:
|
||||
virtual bool is_meet_subtype_of_helper(const TypeKlassPtr* other, bool this_xk, bool other_xk) const;
|
||||
};
|
||||
|
||||
@ -3208,16 +3208,26 @@ public class IRNode {
|
||||
}
|
||||
|
||||
// Typename in load/store have the structure:
|
||||
// @fully/qualified/package/name/to/TheClass+12 *
|
||||
// @ptrtype:fully/qualified/package/name/to/TheClass:ptrlattice+12
|
||||
// with ptrtype being the kind of the type such as instptr, aryptr, etc, and ptrlattice being
|
||||
// the kind of the value such as BotPTR, NotNull, etc.
|
||||
// And variation:
|
||||
// - after @, we can have "stable:" or other labels, with optional space after ':'
|
||||
// - the class can actually be a subclass, with $ separator (and it must be ok to give only the deepest one
|
||||
// - after ptrtype, we can have "stable:" or other labels, with optional space after ':'
|
||||
// - the class can actually be a nested class, with $ separator (and it must be ok to give only the deepest one
|
||||
// - after the class name, we can have a comma-separated list of implemented interfaces enclosed in parentheses
|
||||
// - before the offset, we can have something like ":NotNull", either way, seeing "+" or ":" means the end of the type
|
||||
// Worst case, it can be something like:
|
||||
// @bla: bli:a/b/c$d$e (f/g,h/i/j):NotNull+24 *
|
||||
private static final String LOAD_STORE_PREFIX = "@(\\w+: ?)*[\\w/\\$]*\\b";
|
||||
private static final String LOAD_STORE_SUFFIX = "( \\([^\\)]+\\))?(:|\\+)\\S* \\*";
|
||||
// @bla: bli:a/b/c$d$e (f/g,h/i/j):NotNull+24
|
||||
|
||||
// @ matches the start character of the pattern
|
||||
// (\w+: ?)+ tries to match the pattern 'ptrtype:' or 'stable:' with optional trailing whitespaces
|
||||
// (\w/)* tries to match the pattern 'a/b/`
|
||||
// (\w$)* tries to match the pattern 'c$d$'
|
||||
// \b asserts that the next character is a word character
|
||||
private static final String LOAD_STORE_PREFIX = "@(\\w+: ?)+(\\w/)*(\\w$)*\\b";
|
||||
// ( \([^\)]+\))? tries to match the pattern ' (f/g,h/i/j)'
|
||||
// :\w+ tries to match the pattern ':NotNull'
|
||||
// .* tries to match the remaining of the pattern
|
||||
private static final String LOAD_STORE_SUFFIX = "( \\([^\\)]+\\))?:\\w+.*";
|
||||
|
||||
private static void loadOfNodes(String irNodePlaceholder, String irNodeRegex) {
|
||||
String regex = START + irNodeRegex + MID + LOAD_STORE_PREFIX + IS_REPLACED + LOAD_STORE_SUFFIX + END;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user