aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/opto
diff options
context:
space:
mode:
authorcoleenp <none@none>2012-09-01 13:25:18 -0400
committercoleenp <none@none>2012-09-01 13:25:18 -0400
commitc4f2a125e3006c1715c12ec6ec682389b24d7cac (patch)
tree00340ce50c7adf1b8db7e987946c2c9d747f37a3 /src/share/vm/opto
parentab8cad1d47e8e46e6e633ee5eb4cb0cdb7a0e7bb (diff)
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com> --HG-- rename : src/cpu/sparc/vm/dump_sparc.cpp => src/cpu/sparc/vm/metaspaceShared_sparc.cpp rename : src/cpu/x86/vm/dump_x86_32.cpp => src/cpu/x86/vm/metaspaceShared_x86_32.cpp rename : src/cpu/x86/vm/dump_x86_64.cpp => src/cpu/x86/vm/metaspaceShared_x86_64.cpp rename : src/cpu/zero/vm/dump_zero.cpp => src/cpu/zero/vm/metaspaceShared_zero.cpp rename : src/share/vm/oops/compiledICHolderOop.cpp => src/share/vm/oops/compiledICHolder.cpp rename : src/share/vm/oops/compiledICHolderOop.hpp => src/share/vm/oops/compiledICHolder.hpp rename : src/share/vm/oops/constMethodOop.cpp => src/share/vm/oops/constMethod.cpp rename : src/share/vm/oops/constMethodOop.hpp => src/share/vm/oops/constMethod.hpp rename : src/share/vm/oops/constantPoolOop.cpp => src/share/vm/oops/constantPool.cpp rename : src/share/vm/oops/constantPoolOop.hpp => src/share/vm/oops/constantPool.hpp rename : src/share/vm/oops/cpCacheOop.cpp => src/share/vm/oops/cpCache.cpp rename : src/share/vm/oops/cpCacheOop.hpp => src/share/vm/oops/cpCache.hpp rename : src/share/vm/oops/methodOop.cpp => src/share/vm/oops/method.cpp rename : src/share/vm/oops/methodOop.hpp => src/share/vm/oops/method.hpp rename : src/share/vm/oops/methodDataOop.cpp => src/share/vm/oops/methodData.cpp rename : src/share/vm/oops/methodDataOop.hpp => src/share/vm/oops/methodData.hpp
Diffstat (limited to 'src/share/vm/opto')
-rw-r--r--src/share/vm/opto/callGenerator.cpp10
-rw-r--r--src/share/vm/opto/callnode.cpp13
-rw-r--r--src/share/vm/opto/cfgnode.cpp4
-rw-r--r--src/share/vm/opto/compile.cpp40
-rw-r--r--src/share/vm/opto/compile.hpp39
-rw-r--r--src/share/vm/opto/connode.cpp9
-rw-r--r--src/share/vm/opto/doCall.cpp11
-rw-r--r--src/share/vm/opto/graphKit.cpp6
-rw-r--r--src/share/vm/opto/graphKit.hpp2
-rw-r--r--src/share/vm/opto/idealGraphPrinter.cpp4
-rw-r--r--src/share/vm/opto/library_call.cpp22
-rw-r--r--src/share/vm/opto/machnode.cpp4
-rw-r--r--src/share/vm/opto/machnode.hpp8
-rw-r--r--src/share/vm/opto/macro.cpp4
-rw-r--r--src/share/vm/opto/matcher.cpp4
-rw-r--r--src/share/vm/opto/matcher.hpp1
-rw-r--r--src/share/vm/opto/memnode.cpp20
-rw-r--r--src/share/vm/opto/multnode.cpp4
-rw-r--r--src/share/vm/opto/node.cpp2
-rw-r--r--src/share/vm/opto/output.cpp12
-rw-r--r--src/share/vm/opto/parse1.cpp6
-rw-r--r--src/share/vm/opto/parse2.cpp4
-rw-r--r--src/share/vm/opto/parseHelper.cpp30
-rw-r--r--src/share/vm/opto/reg_split.cpp2
-rw-r--r--src/share/vm/opto/runtime.cpp42
-rw-r--r--src/share/vm/opto/runtime.hpp16
-rw-r--r--src/share/vm/opto/subnode.cpp12
-rw-r--r--src/share/vm/opto/type.cpp497
-rw-r--r--src/share/vm/opto/type.hpp134
29 files changed, 593 insertions, 369 deletions
diff --git a/src/share/vm/opto/callGenerator.cpp b/src/share/vm/opto/callGenerator.cpp
index 0935f5f3e..1c7b9ffee 100644
--- a/src/share/vm/opto/callGenerator.cpp
+++ b/src/share/vm/opto/callGenerator.cpp
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "ci/bcEscapeAnalyzer.hpp"
#include "ci/ciCallSite.hpp"
-#include "ci/ciCPCache.hpp"
+#include "ci/ciObjArray.hpp"
#include "ci/ciMemberName.hpp"
#include "ci/ciMethodHandle.hpp"
#include "classfile/javaClasses.hpp"
@@ -167,7 +167,7 @@ public:
VirtualCallGenerator(ciMethod* method, int vtable_index)
: CallGenerator(method), _vtable_index(vtable_index)
{
- assert(vtable_index == methodOopDesc::invalid_vtable_index ||
+ assert(vtable_index == Method::invalid_vtable_index ||
vtable_index >= 0, "either invalid or usable");
}
virtual bool is_virtual() const { return true; }
@@ -217,7 +217,7 @@ JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
assert(!method()->is_static(), "virtual call must not be to static");
assert(!method()->is_final(), "virtual call should not be to final");
assert(!method()->is_private(), "virtual call should not be to private");
- assert(_vtable_index == methodOopDesc::invalid_vtable_index || !UseInlineCaches,
+ assert(_vtable_index == Method::invalid_vtable_index || !UseInlineCaches,
"no vtable calls if +UseInlineCaches ");
address target = SharedRuntime::get_resolve_virtual_call_stub();
// Normal inline cache used for call
@@ -603,7 +603,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove
- const int vtable_index = methodOopDesc::invalid_vtable_index;
+ const int vtable_index = Method::invalid_vtable_index;
CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS);
if (cg != NULL && cg->is_inline())
return cg;
@@ -653,7 +653,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
}
}
}
- const int vtable_index = methodOopDesc::invalid_vtable_index;
+ const int vtable_index = Method::invalid_vtable_index;
const bool call_is_virtual = target->is_abstract(); // FIXME workaround
CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS);
if (cg != NULL && cg->is_inline())
diff --git a/src/share/vm/opto/callnode.cpp b/src/share/vm/opto/callnode.cpp
index 2fdacf9f5..398497f9b 100644
--- a/src/share/vm/opto/callnode.cpp
+++ b/src/share/vm/opto/callnode.cpp
@@ -83,7 +83,7 @@ Node *StartNode::match( const ProjNode *proj, const Matcher *match ) {
const Type *t = _domain->field_at(proj->_con);
if (t->base() == Type::Half) // 2nd half of Longs and Doubles
return new (match->C, 1) ConNode(Type::TOP);
- uint ideal_reg = Matcher::base2reg[t->base()];
+ uint ideal_reg = t->ideal_reg();
RegMask &rm = match->_calling_convention_mask[parm_num];
return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
}
@@ -131,7 +131,7 @@ uint ParmNode::ideal_reg() const {
case TypeFunc::Parms : {
// Type of argument being passed
const Type *t = in(0)->as_Start()->_domain->field_at(_con);
- return Matcher::base2reg[t->base()];
+ return t->ideal_reg();
}
}
ShouldNotReachHere();
@@ -344,10 +344,15 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c
st->print(" %s%d]=#NULL",msg,i);
break;
case Type::AryPtr:
- case Type::KlassPtr:
case Type::InstPtr:
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
break;
+ case Type::KlassPtr:
+ st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_klassptr()->klass());
+ break;
+ case Type::MetadataPtr:
+ st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_metadataptr()->metadata());
+ break;
case Type::NarrowOop:
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop());
break;
@@ -628,7 +633,7 @@ Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
return new (match->C, 1) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad);
case TypeFunc::Parms: { // Normal returns
- uint ideal_reg = Matcher::base2reg[tf()->range()->field_at(TypeFunc::Parms)->base()];
+ uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg();
OptoRegPair regs = is_CallRuntime()
? match->c_return_value(ideal_reg,true) // Calls into C runtime
: match-> return_value(ideal_reg,true); // Calls into compiled Java code
diff --git a/src/share/vm/opto/cfgnode.cpp b/src/share/vm/opto/cfgnode.cpp
index 4f01e8548..795673da2 100644
--- a/src/share/vm/opto/cfgnode.cpp
+++ b/src/share/vm/opto/cfgnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1936,7 +1936,7 @@ const RegMask &PhiNode::in_RegMask(uint i) const {
}
const RegMask &PhiNode::out_RegMask() const {
- uint ideal_reg = Matcher::base2reg[_type->base()];
+ uint ideal_reg = _type->ideal_reg();
assert( ideal_reg != Node::NotAMachineReg, "invalid type at Phi" );
if( ideal_reg == 0 ) return RegMask::Empty;
return *(Compile::current()->matcher()->idealreg2spillmask[ideal_reg]);
diff --git a/src/share/vm/opto/compile.cpp b/src/share/vm/opto/compile.cpp
index 01e4b3462..292c52412 100644
--- a/src/share/vm/opto/compile.cpp
+++ b/src/share/vm/opto/compile.cpp
@@ -925,17 +925,6 @@ Compile::Compile( ciEnv* ci_env,
}
}
-#ifndef PRODUCT
-void print_opto_verbose_signature( const TypeFunc *j_sig, const char *stub_name ) {
- if(PrintOpto && Verbose) {
- tty->print("%s ", stub_name); j_sig->print_flattened(); tty->cr();
- }
-}
-#endif
-
-void Compile::print_codes() {
-}
-
//------------------------------Init-------------------------------------------
// Prepare for a single compilation
void Compile::Init(int aliaslevel) {
@@ -963,7 +952,7 @@ void Compile::Init(int aliaslevel) {
set_recent_alloc(NULL, NULL);
// Create Debug Information Recorder to record scopes, oopmaps, etc.
- env()->set_oop_recorder(new OopRecorder(comp_arena()));
+ env()->set_oop_recorder(new OopRecorder(env()->arena()));
env()->set_debug_info(new DebugInformationRecorder(env()->oop_recorder()));
env()->set_dependencies(new Dependencies(env()));
@@ -1182,7 +1171,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
// space to include all of the array body. Only the header, klass
// and array length can be accessed un-aliased.
if( offset != Type::OffsetBot ) {
- if( ta->const_oop() ) { // methodDataOop or methodOop
+ if( ta->const_oop() ) { // MethodData* or Method*
offset = Type::OffsetBot; // Flatten constant access into array body
tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset);
} else if( offset == arrayOopDesc::length_offset_in_bytes() ) {
@@ -3026,12 +3015,13 @@ bool Compile::Constant::operator==(const Constant& other) {
if (can_be_reused() != other.can_be_reused()) return false;
// For floating point values we compare the bit pattern.
switch (type()) {
- case T_FLOAT: return (_value.i == other._value.i);
+ case T_FLOAT: return (_v._value.i == other._v._value.i);
case T_LONG:
- case T_DOUBLE: return (_value.j == other._value.j);
+ case T_DOUBLE: return (_v._value.j == other._v._value.j);
case T_OBJECT:
- case T_ADDRESS: return (_value.l == other._value.l);
- case T_VOID: return (_value.l == other._value.l); // jump-table entries
+ case T_METADATA: return (_v._metadata == other._v._metadata);
+ case T_ADDRESS: return (_v._value.l == other._v._value.l);
+ case T_VOID: return (_v._value.l == other._v._value.l); // jump-table entries
default: ShouldNotReachHere();
}
return false;
@@ -3042,6 +3032,7 @@ static int type_to_size_in_bytes(BasicType t) {
case T_LONG: return sizeof(jlong );
case T_FLOAT: return sizeof(jfloat );
case T_DOUBLE: return sizeof(jdouble);
+ case T_METADATA: return sizeof(Metadata*);
// We use T_VOID as marker for jump-table entries (labels) which
// need an internal word relocation.
case T_VOID:
@@ -3135,6 +3126,12 @@ void Compile::ConstantTable::emit(CodeBuffer& cb) {
}
break;
}
+ case T_METADATA: {
+ Metadata* obj = con.get_metadata();
+ int metadata_index = _masm.oop_recorder()->find_index(obj);
+ constant_addr = _masm.address_constant((address) obj, metadata_Relocation::spec(metadata_index));
+ break;
+ }
default: ShouldNotReachHere();
}
assert(constant_addr, "consts section too small");
@@ -3168,6 +3165,12 @@ Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType typ
return con;
}
+Compile::Constant Compile::ConstantTable::add(Metadata* metadata) {
+ Constant con(metadata);
+ add(con);
+ return con;
+}
+
Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, MachOper* oper) {
jvalue value;
BasicType type = oper->type()->basic_type();
@@ -3177,7 +3180,8 @@ Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, MachOper* ope
case T_DOUBLE: value.d = oper->constantD(); break;
case T_OBJECT:
case T_ADDRESS: value.l = (jobject) oper->constant(); break;
- default: ShouldNotReachHere();
+ case T_METADATA: return add((Metadata*)oper->constant()); break;
+ default: guarantee(false, err_msg_res("unhandled type: %s", type2name(type)));
}
return add(n, type, value);
}
diff --git a/src/share/vm/opto/compile.hpp b/src/share/vm/opto/compile.hpp
index 5e85802f9..a594b0913 100644
--- a/src/share/vm/opto/compile.hpp
+++ b/src/share/vm/opto/compile.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -141,36 +141,51 @@ class Compile : public Phase {
};
struct AliasCacheEntry { const TypePtr* _adr_type; int _index; }; // simple duple type
enum {
- trapHistLength = methodDataOopDesc::_trap_hist_limit
+ trapHistLength = MethodData::_trap_hist_limit
};
// Constant entry of the constant table.
class Constant {
private:
BasicType _type;
+ union {
jvalue _value;
+ Metadata* _metadata;
+ } _v;
int _offset; // offset of this constant (in bytes) relative to the constant table base.
float _freq;
bool _can_be_reused; // true (default) if the value can be shared with other users.
public:
- Constant() : _type(T_ILLEGAL), _offset(-1), _freq(0.0f), _can_be_reused(true) { _value.l = 0; }
+ Constant() : _type(T_ILLEGAL), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; }
Constant(BasicType type, jvalue value, float freq = 0.0f, bool can_be_reused = true) :
_type(type),
- _value(value),
_offset(-1),
_freq(freq),
_can_be_reused(can_be_reused)
- {}
+ {
+ assert(type != T_METADATA, "wrong constructor");
+ _v._value = value;
+ }
+ Constant(Metadata* metadata, bool can_be_reused = true) :
+ _type(T_METADATA),
+ _offset(-1),
+ _freq(0.0f),
+ _can_be_reused(can_be_reused)
+ {
+ _v._metadata = metadata;
+ }
bool operator==(const Constant& other);
BasicType type() const { return _type; }
- jlong get_jlong() const { return _value.j; }
- jfloat get_jfloat() const { return _value.f; }
- jdouble get_jdouble() const { return _value.d; }
- jobject get_jobject() const { return _value.l; }
+ jlong get_jlong() const { return _v._value.j; }
+ jfloat get_jfloat() const { return _v._value.f; }
+ jdouble get_jdouble() const { return _v._value.d; }
+ jobject get_jobject() const { return _v._value.l; }
+
+ Metadata* get_metadata() const { return _v._metadata; }
int offset() const { return _offset; }
void set_offset(int offset) { _offset = offset; }
@@ -219,6 +234,7 @@ class Compile : public Phase {
void add(Constant& con);
Constant add(MachConstantNode* n, BasicType type, jvalue value);
+ Constant add(Metadata* metadata);
Constant add(MachConstantNode* n, MachOper* oper);
Constant add(MachConstantNode* n, jfloat f) {
jvalue value; value.f = f;
@@ -270,7 +286,7 @@ class Compile : public Phase {
bool _do_scheduling; // True if we intend to do scheduling
bool _do_freq_based_layout; // True if we intend to do frequency based block layout
bool _do_count_invocations; // True if we generate code to count invocations
- bool _do_method_data_update; // True if we generate code to update methodDataOops
+ bool _do_method_data_update; // True if we generate code to update MethodData*s
int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
bool _print_assembly; // True if we should dump assembly code for this compilation
#ifndef PRODUCT
@@ -896,9 +912,6 @@ class Compile : public Phase {
// graph is strongly connected from root in both directions.
void verify_graph_edges(bool no_dead_code = false) PRODUCT_RETURN;
- // Print bytecodes, including the scope inlining tree
- void print_codes();
-
// End-of-run dumps.
static void print_statistics() PRODUCT_RETURN;
diff --git a/src/share/vm/opto/connode.cpp b/src/share/vm/opto/connode.cpp
index 7e072ff44..e038ccbc2 100644
--- a/src/share/vm/opto/connode.cpp
+++ b/src/share/vm/opto/connode.cpp
@@ -50,10 +50,11 @@ ConNode *ConNode::make( Compile* C, const Type *t ) {
case T_FLOAT: return new (C, 1) ConFNode( t->is_float_constant() );
case T_DOUBLE: return new (C, 1) ConDNode( t->is_double_constant() );
case T_VOID: return new (C, 1) ConNode ( Type::TOP );
- case T_OBJECT: return new (C, 1) ConPNode( t->is_oopptr() );
+ case T_OBJECT: return new (C, 1) ConPNode( t->is_ptr() );
case T_ARRAY: return new (C, 1) ConPNode( t->is_aryptr() );
case T_ADDRESS: return new (C, 1) ConPNode( t->is_ptr() );
case T_NARROWOOP: return new (C, 1) ConNNode( t->is_narrowoop() );
+ case T_METADATA: return new (C, 1) ConPNode( t->is_ptr() );
// Expected cases: TypePtr::NULL_PTR, any is_rawptr()
// Also seen: AnyPtr(TopPTR *+top); from command line:
// r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660
@@ -526,8 +527,8 @@ const Type *CheckCastPPNode::Value( PhaseTransform *phase ) const {
// // If either input is an 'interface', return destination type
// assert (in_oop == NULL || in_oop->klass() != NULL, "");
// assert (my_oop == NULL || my_oop->klass() != NULL, "");
- // if( (in_oop && in_oop->klass()->klass_part()->is_interface())
- // ||(my_oop && my_oop->klass()->klass_part()->is_interface()) ) {
+ // if( (in_oop && in_oop->klass()->is_interface())
+ // ||(my_oop && my_oop->klass()->is_interface()) ) {
// TypePtr::PTR in_ptr = in->isa_ptr() ? in->is_ptr()->_ptr : TypePtr::BotPTR;
// // Preserve cast away nullness for interfaces
// if( in_ptr == TypePtr::NotNull && my_oop && my_oop->_ptr == TypePtr::BotPTR ) {
@@ -604,7 +605,7 @@ const Type *EncodePNode::Value( PhaseTransform *phase ) const {
if (t == Type::TOP) return Type::TOP;
if (t == TypePtr::NULL_PTR) return TypeNarrowOop::NULL_PTR;
- assert(t->isa_oopptr(), "only oopptr here");
+ assert(t->isa_oop_ptr() || UseCompressedKlassPointers && t->isa_klassptr(), "only oopptr here");
return t->make_narrowoop();
}
diff --git a/src/share/vm/opto/doCall.cpp b/src/share/vm/opto/doCall.cpp
index a34870509..c8576dc50 100644
--- a/src/share/vm/opto/doCall.cpp
+++ b/src/share/vm/opto/doCall.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
*/
#include "precompiled.hpp"
-#include "ci/ciCPCache.hpp"
#include "ci/ciCallSite.hpp"
#include "ci/ciMethodHandle.hpp"
#include "classfile/vmSymbols.hpp"
@@ -392,7 +391,7 @@ void Parse::do_call() {
// Choose call strategy.
bool call_is_virtual = is_virtual_or_interface;
- int vtable_index = methodOopDesc::invalid_vtable_index;
+ int vtable_index = Method::invalid_vtable_index;
ciMethod* callee = orig_callee;
// Try to get the most accurate receiver type
@@ -539,7 +538,7 @@ void Parse::do_call() {
}
}
} else {
- assert(ct == rt, err_msg_res("unexpected mismatch rt=%d, ct=%d", rt, ct));
+ assert(ct == rt, err_msg("unexpected mismatch rt=%d, ct=%d", rt, ct));
// push a zero; it's better than getting an oop/int mismatch
retnode = pop_node(rt);
retnode = zerocon(ct);
@@ -836,9 +835,9 @@ void Parse::count_compiled_calls(bool at_method_entry, bool is_inline) {
if( at_method_entry ) {
// bump invocation counter if top method (for statistics)
if (CountCompiledCalls && depth() == 1) {
- const TypeOopPtr* addr_type = TypeOopPtr::make_from_constant(method());
+ const TypePtr* addr_type = TypeMetadataPtr::make(method());
Node* adr1 = makecon(addr_type);
- Node* adr2 = basic_plus_adr(adr1, adr1, in_bytes(methodOopDesc::compiled_invocation_counter_offset()));
+ Node* adr2 = basic_plus_adr(adr1, adr1, in_bytes(Method::compiled_invocation_counter_offset()));
increment_counter(adr2);
}
} else if (is_inline) {
diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp
index f844eaaa4..200122620 100644
--- a/src/share/vm/opto/graphKit.cpp
+++ b/src/share/vm/opto/graphKit.cpp
@@ -3446,12 +3446,6 @@ void GraphKit::write_barrier_post(Node* oop_store,
if (t == TypePtr::NULL_PTR || t == Type::TOP)
// stores of null never (?) need barriers
return;
- ciObject* con = t->is_oopptr()->const_oop();
- if (con != NULL
- && con->is_perm()
- && Universe::heap()->can_elide_permanent_oop_store_barriers())
- // no store barrier needed, because no old-to-new ref created
- return;
}
if (use_ReduceInitialCardMarks()
diff --git a/src/share/vm/opto/graphKit.hpp b/src/share/vm/opto/graphKit.hpp
index c32575d07..2c09486c3 100644
--- a/src/share/vm/opto/graphKit.hpp
+++ b/src/share/vm/opto/graphKit.hpp
@@ -743,7 +743,7 @@ class GraphKit : public Phase {
void shared_unlock(Node* box, Node* obj);
// helper functions for the fast path/slow path idioms
- Node* fast_and_slow(Node* in, const Type *result_type, Node* null_result, IfNode* fast_test, Node* fast_result, address slow_call, const TypeFunc *slow_call_type, Node* slow_arg, klassOop ex_klass, Node* slow_result);
+ Node* fast_and_slow(Node* in, const Type *result_type, Node* null_result, IfNode* fast_test, Node* fast_result, address slow_call, const TypeFunc *slow_call_type, Node* slow_arg, Klass* ex_klass, Node* slow_result);
// Generate an instance-of idiom. Used by both the instance-of bytecode
// and the reflective instance-of call.
diff --git a/src/share/vm/opto/idealGraphPrinter.cpp b/src/share/vm/opto/idealGraphPrinter.cpp
index b3919a654..0928704d9 100644
--- a/src/share/vm/opto/idealGraphPrinter.cpp
+++ b/src/share/vm/opto/idealGraphPrinter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -407,7 +407,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
node->_in_dump_cnt++;
print_prop(NODE_NAME_PROPERTY, (const char *)node->Name());
const Type *t = node->bottom_type();
- print_prop("type", (const char *)Type::msg[t->base()]);
+ print_prop("type", t->msg());
print_prop("idx", node->_idx);
#ifdef ASSERT
print_prop("debug_idx", node->_debug_idx);
diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp
index 3ae12baa7..832799a58 100644
--- a/src/share/vm/opto/library_call.cpp
+++ b/src/share/vm/opto/library_call.cpp
@@ -2904,11 +2904,11 @@ bool LibraryCallKit::inline_unsafe_allocate() {
// Note: The argument might still be an illegal value like
// Serializable.class or Object[].class. The runtime will handle it.
// But we must make an explicit check for initialization.
- Node* insp = basic_plus_adr(kls, in_bytes(instanceKlass::init_state_offset()));
- // Use T_BOOLEAN for instanceKlass::_init_state so the compiler
+ Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
+ // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
// can generate code to load it as unsigned byte.
Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
- Node* bits = intcon(instanceKlass::fully_initialized);
+ Node* bits = intcon(InstanceKlass::fully_initialized);
Node* test = _gvn.transform( new (C, 3) SubINode(inst, bits) );
// The 'test' is non-zero if we need to take a slow path.
@@ -3475,7 +3475,7 @@ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region,
if (layout_val == NULL) {
bool query = (obj_array
? Klass::layout_helper_is_objArray(layout_con)
- : Klass::layout_helper_is_javaArray(layout_con));
+ : Klass::layout_helper_is_array(layout_con));
if (query == not_array) {
return NULL; // never a branch
} else { // always a branch
@@ -3710,15 +3710,15 @@ Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
RegionNode* slow_region) {
ciMethod* method = callee();
int vtable_index = method->vtable_index();
- // Get the methodOop out of the appropriate vtable entry.
- int entry_offset = (instanceKlass::vtable_start_offset() +
+ // Get the Method* out of the appropriate vtable entry.
+ int entry_offset = (InstanceKlass::vtable_start_offset() +
vtable_index*vtableEntry::size()) * wordSize +
vtableEntry::method_offset_in_bytes();
Node* entry_addr = basic_plus_adr(obj_klass, entry_offset);
Node* target_call = make_load(NULL, entry_addr, TypeInstPtr::NOTNULL, T_OBJECT);
// Compare the target method with the expected method (e.g., Object.hashCode).
- const TypeInstPtr* native_call_addr = TypeInstPtr::make(method);
+ const TypePtr* native_call_addr = TypeMetadataPtr::make(method);
Node* native_call = makecon(native_call_addr);
Node* chk_native = _gvn.transform( new(C, 3) CmpPNode(target_call, native_call) );
@@ -3753,7 +3753,7 @@ LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual
method, bci());
} else if (is_virtual) {
null_check_receiver(method);
- int vtable_index = methodOopDesc::invalid_vtable_index;
+ int vtable_index = Method::invalid_vtable_index;
if (UseInlineCaches) {
// Suppress the vtable call
} else {
@@ -4266,8 +4266,8 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
instanceOopDesc::base_offset_in_bytes();
// base_off:
// 8 - 32-bit VM
- // 12 - 64-bit VM, compressed oops
- // 16 - 64-bit VM, normal oops
+ // 12 - 64-bit VM, compressed klass
+ // 16 - 64-bit VM, normal klass
if (base_off % BytesPerLong != 0) {
assert(UseCompressedOops, "");
if (is_array) {
@@ -4899,7 +4899,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
// further to JVM_ArrayCopy on the first per-oop check that fails.
// (Actually, we don't move raw bits only; the GC requires card marks.)
- // Get the klassOop for both src and dest
+ // Get the Klass* for both src and dest
Node* src_klass = load_object_klass(src);
Node* dest_klass = load_object_klass(dest);
diff --git a/src/share/vm/opto/machnode.cpp b/src/share/vm/opto/machnode.cpp
index 88bb23b37..2a5d96369 100644
--- a/src/share/vm/opto/machnode.cpp
+++ b/src/share/vm/opto/machnode.cpp
@@ -38,7 +38,7 @@ int MachOper::reg(PhaseRegAlloc *ra_, const Node *node, int idx) const {
return (int)(ra_->get_encode(node->in(idx)));
}
intptr_t MachOper::constant() const { return 0x00; }
-bool MachOper::constant_is_oop() const { return false; }
+relocInfo::relocType MachOper::constant_reloc() const { return relocInfo::none; }
jdouble MachOper::constantD() const { ShouldNotReachHere(); return 0.0; }
jfloat MachOper::constantF() const { ShouldNotReachHere(); return 0.0; }
jlong MachOper::constantL() const { ShouldNotReachHere(); return CONST64(0) ; }
@@ -54,7 +54,7 @@ int MachOper::constant_disp() const { return 0; }
int MachOper::base_position() const { return -1; } // no base input
int MachOper::index_position() const { return -1; } // no index input
// Check for PC-Relative displacement
-bool MachOper::disp_is_oop() const { return false; }
+relocInfo::relocType MachOper::disp_reloc() const { return relocInfo::none; }
// Return the label
Label* MachOper::label() const { ShouldNotReachHere(); return 0; }
intptr_t MachOper::method() const { ShouldNotReachHere(); return 0; }
diff --git a/src/share/vm/opto/machnode.hpp b/src/share/vm/opto/machnode.hpp
index 4db1154e8..5b630e45c 100644
--- a/src/share/vm/opto/machnode.hpp
+++ b/src/share/vm/opto/machnode.hpp
@@ -104,7 +104,7 @@ public:
#endif
virtual intptr_t constant() const;
- virtual bool constant_is_oop() const;
+ virtual relocInfo::relocType constant_reloc() const;
virtual jdouble constantD() const;
virtual jfloat constantF() const;
virtual jlong constantL() const;
@@ -118,7 +118,7 @@ public:
// Parameters needed to support MEMORY_INTERFACE access to stackSlot
virtual int disp (PhaseRegAlloc *ra_, const Node *node, int idx) const;
// Check for PC-Relative displacement
- virtual bool disp_is_oop() const;
+ virtual relocInfo::relocType disp_reloc() const;
virtual int constant_disp() const; // usu. 0, may return Type::OffsetBot
virtual int base_position() const; // base edge position, or -1
virtual int index_position() const; // index edge position, or -1
@@ -247,7 +247,7 @@ public:
// Bottom_type call; value comes from operand0
virtual const class Type *bottom_type() const { return _opnds[0]->type(); }
- virtual uint ideal_reg() const { const Type *t = _opnds[0]->type(); return t == TypeInt::CC ? Op_RegFlags : Matcher::base2reg[t->base()]; }
+ virtual uint ideal_reg() const { const Type *t = _opnds[0]->type(); return t == TypeInt::CC ? Op_RegFlags : t->ideal_reg(); }
// If this is a memory op, return the base pointer and fixed offset.
// If there are no such, return NULL. If there are multiple addresses
@@ -498,7 +498,7 @@ public:
virtual const RegMask &out_RegMask() const { return *_out; }
virtual const RegMask &in_RegMask(uint) const { return *_in; }
virtual const class Type *bottom_type() const { return _type; }
- virtual uint ideal_reg() const { return Matcher::base2reg[_type->base()]; }
+ virtual uint ideal_reg() const { return _type->ideal_reg(); }
virtual uint oper_input_base() const { return 1; }
uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const;
diff --git a/src/share/vm/opto/macro.cpp b/src/share/vm/opto/macro.cpp
index fee17c48a..a5250292b 100644
--- a/src/share/vm/opto/macro.cpp
+++ b/src/share/vm/opto/macro.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1567,7 +1567,7 @@ PhaseMacroExpand::initialize_object(AllocateNode* alloc,
}
rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, T_ADDRESS);
- rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_OBJECT);
+ rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_METADATA);
int header_size = alloc->minimum_header_size(); // conservatively small
// Array length
diff --git a/src/share/vm/opto/matcher.cpp b/src/share/vm/opto/matcher.cpp
index d5f14f4f6..bf4a345ce 100644
--- a/src/share/vm/opto/matcher.cpp
+++ b/src/share/vm/opto/matcher.cpp
@@ -198,7 +198,7 @@ void Matcher::match( ) {
const TypeTuple *range = C->tf()->range();
if( range->cnt() > TypeFunc::Parms ) { // If not a void function
// Get ideal-register return type
- int ireg = base2reg[range->field_at(TypeFunc::Parms)->base()];
+ int ireg = range->field_at(TypeFunc::Parms)->ideal_reg();
// Get machine return register
uint sop = C->start()->Opcode();
OptoRegPair regs = return_value(ireg, false);
@@ -1285,7 +1285,7 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
// a little in-place argument insertion.
// FIXME: Is this still necessary?
int regs_per_word = NOT_LP64(1) LP64_ONLY(2); // %%% make a global const!
- out_arg_limit_per_call += methodOopDesc::extra_stack_entries() * regs_per_word;
+ out_arg_limit_per_call += Method::extra_stack_entries() * regs_per_word;
// Do not update mcall->_argsize because (a) the extra space is not
// pushed as arguments and (b) _argsize is dead (not used anywhere).
}
diff --git a/src/share/vm/opto/matcher.hpp b/src/share/vm/opto/matcher.hpp
index 0597cb543..51282db37 100644
--- a/src/share/vm/opto/matcher.hpp
+++ b/src/share/vm/opto/matcher.hpp
@@ -123,7 +123,6 @@ class Matcher : public PhaseTransform {
public:
int LabelRootDepth;
- static const int base2reg[]; // Map Types to machine register types
// Convert ideal machine register to a register mask for spill-loads
static const RegMask *idealreg2regmask[];
RegMask *idealreg2spillmask [_last_machine_leaf];
diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp
index 799c2ba14..1cbe31756 100644
--- a/src/share/vm/opto/memnode.cpp
+++ b/src/share/vm/opto/memnode.cpp
@@ -841,7 +841,7 @@ uint LoadNode::cmp( const Node &n ) const
{ return !Type::cmp( _type, ((LoadNode&)n)._type ); }
const Type *LoadNode::bottom_type() const { return _type; }
uint LoadNode::ideal_reg() const {
- return Matcher::base2reg[_type->base()];
+ return _type->ideal_reg();
}
#ifndef PRODUCT
@@ -1660,7 +1660,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
return TypeInt::make(klass->super_check_offset());
}
// Compute index into primary_supers array
- juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(klassOop);
+ juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(Klass*);
// Check for overflowing; use unsigned compare to handle the negative case.
if( depth < ciKlass::primary_super_limit() ) {
// The field is an element of Klass::_primary_supers. Return its (constant) value.
@@ -1690,13 +1690,13 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
// shallow enough depth. Even though the klass is not exact, entries less
// than or equal to its super depth are correct.
if (klass->is_loaded() ) {
- ciType *inner = klass->klass();
+ ciType *inner = klass;
while( inner->is_obj_array_klass() )
inner = inner->as_obj_array_klass()->base_element_type();
if( inner->is_instance_klass() &&
!inner->as_instance_klass()->flags().is_interface() ) {
// Compute index into primary_supers array
- juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(klassOop);
+ juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(Klass*);
// Check for overflowing; use unsigned compare to handle the negative case.
if( depth < ciKlass::primary_super_limit() &&
depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case
@@ -1891,10 +1891,11 @@ Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* a
Compile* C = gvn.C;
Node *ctl = NULL;
// sanity check the alias category against the created node type
- const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr();
- assert(adr_type != NULL, "expecting TypeOopPtr");
+ const TypePtr *adr_type = adr->bottom_type()->isa_ptr();
+ assert(adr_type != NULL, "expecting TypeKlassPtr");
#ifdef _LP64
if (adr_type->is_ptr_to_narrowoop()) {
+ assert(UseCompressedKlassPointers, "no compressed klasses");
Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
}
@@ -2065,7 +2066,7 @@ Node* LoadNode::klass_identity_common(PhaseTransform *phase ) {
}
}
- // Simplify k.java_mirror.as_klass to plain k, where k is a klassOop.
+ // Simplify k.java_mirror.as_klass to plain k, where k is a Klass*.
// Simplify ak.component_mirror.array_klass to plain ak, ak an arrayKlass.
// See inline_native_Class_query for occurrences of these patterns.
// Java Example: x.getClass().isAssignableFrom(y)
@@ -2074,7 +2075,7 @@ Node* LoadNode::klass_identity_common(PhaseTransform *phase ) {
// This improves reflective code, often making the Class
// mirror go completely dead. (Current exception: Class
// mirrors may appear in debug info, but we could clean them out by
- // introducing a new debug info operator for klassOop.java_mirror).
+ // introducing a new debug info operator for Klass*.java_mirror).
if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
&& (offset == java_lang_Class::klass_offset_in_bytes() ||
offset == java_lang_Class::array_klass_offset_in_bytes())) {
@@ -2223,11 +2224,12 @@ StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, cons
case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val);
case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val);
case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val);
+ case T_METADATA:
case T_ADDRESS:
case T_OBJECT:
#ifdef _LP64
if (adr->bottom_type()->is_ptr_to_narrowoop() ||
- (UseCompressedOops && val->bottom_type()->isa_klassptr() &&
+ (UseCompressedKlassPointers && val->bottom_type()->isa_klassptr() &&
adr->bottom_type()->isa_rawptr())) {
val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop()));
return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val);
diff --git a/src/share/vm/opto/multnode.cpp b/src/share/vm/opto/multnode.cpp
index fb29e1ea4..280414106 100644
--- a/src/share/vm/opto/multnode.cpp
+++ b/src/share/vm/opto/multnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -130,5 +130,5 @@ const RegMask &ProjNode::out_RegMask() const {
//------------------------------ideal_reg--------------------------------------
uint ProjNode::ideal_reg() const {
- return Matcher::base2reg[bottom_type()->base()];
+ return bottom_type()->ideal_reg();
}
diff --git a/src/share/vm/opto/node.cpp b/src/share/vm/opto/node.cpp
index 2cb44ad0e..880576016 100644
--- a/src/share/vm/opto/node.cpp
+++ b/src/share/vm/opto/node.cpp
@@ -2057,5 +2057,5 @@ const Type *TypeNode::Value( PhaseTransform * ) const { return _type; }
//------------------------------ideal_reg--------------------------------------
uint TypeNode::ideal_reg() const {
- return Matcher::base2reg[_type->base()];
+ return _type->ideal_reg();
}
diff --git a/src/share/vm/opto/output.cpp b/src/share/vm/opto/output.cpp
index 261792e49..89b62127e 100644
--- a/src/share/vm/opto/output.cpp
+++ b/src/share/vm/opto/output.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -626,7 +626,7 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation.");
sv = new ObjectValue(spobj->_idx,
- new ConstantOopWriteValue(cik->constant_encoding()));
+ new ConstantOopWriteValue(cik->java_mirror()->constant_encoding()));
Compile::set_sv_for_object_node(objs, sv);
uint first_ind = spobj->first_index();
@@ -715,8 +715,7 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
array->append(new ConstantOopWriteValue(NULL));
break;
case Type::AryPtr:
- case Type::InstPtr:
- case Type::KlassPtr: // fall through
+ case Type::InstPtr: // fall through
array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->constant_encoding()));
break;
case Type::NarrowOop:
@@ -902,7 +901,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation.");
ObjectValue* sv = new ObjectValue(spobj->_idx,
- new ConstantOopWriteValue(cik->constant_encoding()));
+ new ConstantOopWriteValue(cik->java_mirror()->constant_encoding()));
Compile::set_sv_for_object_node(objs, sv);
uint first_ind = spobj->first_index();
@@ -1658,8 +1657,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
"");
}
if (method() != NULL) {
- method()->print_oop();
- print_codes();
+ method()->print_metadata();
}
dump_asm(node_offsets, node_offset_limit);
if (xtty != NULL) {
diff --git a/src/share/vm/opto/parse1.cpp b/src/share/vm/opto/parse1.cpp
index 79fab69c1..8eb86d7bf 100644
--- a/src/share/vm/opto/parse1.cpp
+++ b/src/share/vm/opto/parse1.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "compiler/compileLog.hpp"
#include "interpreter/linkResolver.hpp"
-#include "oops/methodOop.hpp"
+#include "oops/method.hpp"
#include "opto/addnode.hpp"
#include "opto/idealGraphPrinter.hpp"
#include "opto/locknode.hpp"
@@ -492,7 +492,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
if (PrintOpto && (Verbose || WizardMode)) {
tty->print_cr("OSR @%d type flow bailout: %s", _entry_bci, _flow->failure_reason());
if (Verbose) {
- method()->print_oop();
+ method()->print();
method()->print_codes();
_flow->print();
}
diff --git a/src/share/vm/opto/parse2.cpp b/src/share/vm/opto/parse2.cpp
index 4982a1d76..af514850b 100644
--- a/src/share/vm/opto/parse2.cpp
+++ b/src/share/vm/opto/parse2.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1447,7 +1447,7 @@ void Parse::do_one_bytecode() {
NULL, tag.internal_name());
break;
}
- assert(constant.basic_type() != T_OBJECT || !constant.as_object()->is_klass(),
+ assert(constant.basic_type() != T_OBJECT || constant.as_object()->is_instance(),
"must be java_mirror of klass");
bool pushed = push_constant(constant, true);
guarantee(pushed, "must be possible to push this constant");
diff --git a/src/share/vm/opto/parseHelper.cpp b/src/share/vm/opto/parseHelper.cpp
index 26a146f5e..e562d2772 100644
--- a/src/share/vm/opto/parseHelper.cpp
+++ b/src/share/vm/opto/parseHelper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@ void GraphKit::make_dtrace_method_entry_exit(ciMethod* method, bool is_entry) {
Node* thread = _gvn.transform( new (C, 1) ThreadLocalNode() );
// Get method
- const TypeInstPtr* method_type = TypeInstPtr::make(TypePtr::Constant, method->klass(), true, method, 0);
+ const TypePtr* method_type = TypeMetadataPtr::make(method);
Node *method_node = _gvn.transform( ConNode::make(C, method_type) );
kill_dead_locals();
@@ -220,7 +220,7 @@ void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
_gvn.set_type(merge, Type::CONTROL);
Node* kls = makecon(TypeKlassPtr::make(klass));
- Node* init_thread_offset = _gvn.MakeConX(in_bytes(instanceKlass::init_thread_offset()));
+ Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS);
Node *tst = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
@@ -228,12 +228,12 @@ void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
set_control(IfTrue(iff));
merge->set_req(1, IfFalse(iff));
- Node* init_state_offset = _gvn.MakeConX(in_bytes(instanceKlass::init_state_offset()));
+ Node* init_state_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_state_offset()));
adr_node = basic_plus_adr(kls, kls, init_state_offset);
- // Use T_BOOLEAN for instanceKlass::_init_state so the compiler
+ // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
// can generate code to load it as unsigned byte.
Node* init_state = make_load(NULL, adr_node, TypeInt::UBYTE, T_BOOLEAN);
- Node* being_init = _gvn.intcon(instanceKlass::being_initialized);
+ Node* being_init = _gvn.intcon(InstanceKlass::being_initialized);
tst = Bool( CmpI( init_state, being_init), BoolTest::eq);
iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
set_control(IfTrue(iff));
@@ -336,13 +336,13 @@ void Parse::test_counter_against_threshold(Node* cnt, int limit) {
void Parse::increment_and_test_invocation_counter(int limit) {
if (!count_invocations()) return;
- // Get the methodOop node.
- const TypePtr* adr_type = TypeOopPtr::make_from_constant(method());
- Node *methodOop_node = makecon(adr_type);
+ // Get the Method* node.
+ const TypePtr* adr_type = TypeMetadataPtr::make(method());
+ Node *method_node = makecon(adr_type);
- // Load the interpreter_invocation_counter from the methodOop.
- int offset = methodOopDesc::interpreter_invocation_counter_offset_in_bytes();
- Node* adr_node = basic_plus_adr(methodOop_node, methodOop_node, offset);
+ // Load the interpreter_invocation_counter from the Method*.
+ int offset = Method::interpreter_invocation_counter_offset_in_bytes();
+ Node* adr_node = basic_plus_adr(method_node, method_node, offset);
Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type);
test_counter_against_threshold(cnt, limit);
@@ -354,8 +354,8 @@ void Parse::increment_and_test_invocation_counter(int limit) {
//----------------------------method_data_addressing---------------------------
Node* Parse::method_data_addressing(ciMethodData* md, ciProfileData* data, ByteSize counter_offset, Node* idx, uint stride) {
- // Get offset within methodDataOop of the data array
- ByteSize data_offset = methodDataOopDesc::data_offset();
+ // Get offset within MethodData* of the data array
+ ByteSize data_offset = MethodData::data_offset();
// Get cell offset of the ProfileData within data array
int cell_offset = md->dp_to_di(data->dp());
@@ -363,7 +363,7 @@ Node* Parse::method_data_addressing(ciMethodData* md, ciProfileData* data, ByteS
// Add in counter_offset, the # of bytes into the ProfileData of counter or flag
int offset = in_bytes(data_offset) + cell_offset + in_bytes(counter_offset);
- const TypePtr* adr_type = TypeOopPtr::make_from_constant(md);
+ const TypePtr* adr_type = TypeMetadataPtr::make(md);
Node* mdo = makecon(adr_type);
Node* ptr = basic_plus_adr(mdo, mdo, offset);
diff --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp
index 2c488894a..5e0dad80d 100644
--- a/src/share/vm/opto/reg_split.cpp
+++ b/src/share/vm/opto/reg_split.cpp
@@ -1196,7 +1196,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
if( OptoReg::is_stack(uselrg.reg()) &&
uselrg.reg() < LRG::SPILL_REG && // USE is from stack
deflrg.reg() != uselrg.reg() ) { // Not trivially removed
- uint def_ideal_reg = Matcher::base2reg[n->bottom_type()->base()];
+ uint def_ideal_reg = n->bottom_type()->ideal_reg();
const RegMask &def_rm = *Matcher::idealreg2regmask[def_ideal_reg];
const RegMask &use_rm = n->in_RegMask(copyidx);
if( def_rm.overlap(use_rm) && n->is_SpillCopy() ) { // Bug 4707800, 'n' may be a storeSSL
diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp
index 75e6d7515..f6364a7b7 100644
--- a/src/share/vm/opto/runtime.cpp
+++ b/src/share/vm/opto/runtime.cpp
@@ -228,7 +228,7 @@ void OptoRuntime::new_store_pre_barrier(JavaThread* thread) {
}
// object allocation
-JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThread* thread))
+JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thread))
JRT_BLOCK;
#ifndef PRODUCT
SharedRuntime::_new_instance_ctr++; // new instance requires GC
@@ -238,11 +238,11 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThrea
// These checks are cheap to make and support reflective allocation.
int lh = Klass::cast(klass)->layout_helper();
if (Klass::layout_helper_needs_slow_path(lh)
- || !instanceKlass::cast(klass)->is_initialized()) {
+ || !InstanceKlass::cast(klass)->is_initialized()) {
KlassHandle kh(THREAD, klass);
kh->check_valid_for_instantiation(false, THREAD);
if (!HAS_PENDING_EXCEPTION) {
- instanceKlass::cast(kh())->initialize(THREAD);
+ InstanceKlass::cast(kh())->initialize(THREAD);
}
if (!HAS_PENDING_EXCEPTION) {
klass = kh();
@@ -253,7 +253,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThrea
if (klass != NULL) {
// Scavenge and allocate an instance.
- oop result = instanceKlass::cast(klass)->allocate_instance(THREAD);
+ oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
thread->set_vm_result(result);
// Pass oops back through thread local storage. Our apparent type to Java
@@ -273,7 +273,7 @@ JRT_END
// array allocation
-JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(klassOopDesc* array_type, int len, JavaThread *thread))
+JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread *thread))
JRT_BLOCK;
#ifndef PRODUCT
SharedRuntime::_new_array_ctr++; // new array requires GC
@@ -292,7 +292,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(klassOopDesc* array_type, int len
// Although the oopFactory likes to work with the elem_type,
// the compiler prefers the array_type, since it must already have
// that latter value in hand for the fast path.
- klassOopDesc* elem_type = objArrayKlass::cast(array_type)->element_klass();
+ Klass* elem_type = objArrayKlass::cast(array_type)->element_klass();
result = oopFactory::new_objArray(elem_type, len, THREAD);
}
@@ -311,7 +311,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(klassOopDesc* array_type, int len
JRT_END
// array allocation without zeroing
-JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(klassOopDesc* array_type, int len, JavaThread *thread))
+JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread *thread))
JRT_BLOCK;
#ifndef PRODUCT
SharedRuntime::_new_array_ctr++; // new array requires GC
@@ -361,12 +361,12 @@ JRT_END
// Note: multianewarray for one dimension is handled inline by GraphKit::new_array.
// multianewarray for 2 dimensions
-JRT_ENTRY(void, OptoRuntime::multianewarray2_C(klassOopDesc* elem_type, int len1, int len2, JavaThread *thread))
+JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int len2, JavaThread *thread))
#ifndef PRODUCT
SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension
#endif
assert(check_compiled_frame(thread), "incorrect caller");
- assert(oop(elem_type)->is_klass(), "not a class");
+ assert(elem_type->is_klass(), "not a class");
jint dims[2];
dims[0] = len1;
dims[1] = len2;
@@ -376,12 +376,12 @@ JRT_ENTRY(void, OptoRuntime::multianewarray2_C(klassOopDesc* elem_type, int len1
JRT_END
// multianewarray for 3 dimensions
-JRT_ENTRY(void, OptoRuntime::multianewarray3_C(klassOopDesc* elem_type, int len1, int len2, int len3, JavaThread *thread))
+JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int len2, int len3, JavaThread *thread))
#ifndef PRODUCT
SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension
#endif
assert(check_compiled_frame(thread), "incorrect caller");
- assert(oop(elem_type)->is_klass(), "not a class");
+ assert(elem_type->is_klass(), "not a class");
jint dims[3];
dims[0] = len1;
dims[1] = len2;
@@ -392,12 +392,12 @@ JRT_ENTRY(void, OptoRuntime::multianewarray3_C(klassOopDesc* elem_type, int len1
JRT_END
// multianewarray for 4 dimensions
-JRT_ENTRY(void, OptoRuntime::multianewarray4_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, JavaThread *thread))
+JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int len2, int len3, int len4, JavaThread *thread))
#ifndef PRODUCT
SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension
#endif
assert(check_compiled_frame(thread), "incorrect caller");
- assert(oop(elem_type)->is_klass(), "not a class");
+ assert(elem_type->is_klass(), "not a class");
jint dims[4];
dims[0] = len1;
dims[1] = len2;
@@ -409,12 +409,12 @@ JRT_ENTRY(void, OptoRuntime::multianewarray4_C(klassOopDesc* elem_type, int len1
JRT_END
// multianewarray for 5 dimensions
-JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread))
+JRT_ENTRY(void, OptoRuntime::multianewarray5_C(Klass* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread))
#ifndef PRODUCT
SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension
#endif
assert(check_compiled_frame(thread), "incorrect caller");
- assert(oop(elem_type)->is_klass(), "not a class");
+ assert(elem_type->is_klass(), "not a class");
jint dims[5];
dims[0] = len1;
dims[1] = len2;
@@ -426,9 +426,9 @@ JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1
thread->set_vm_result(obj);
JRT_END
-JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(klassOopDesc* elem_type, arrayOopDesc* dims, JavaThread *thread))
+JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread *thread))
assert(check_compiled_frame(thread), "incorrect caller");
- assert(oop(elem_type)->is_klass(), "not a class");
+ assert(elem_type->is_klass(), "not a class");
assert(oop(dims)->is_typeArray(), "not an array");
ResourceMark rm;
@@ -844,7 +844,7 @@ const TypeFunc* OptoRuntime::profile_receiver_type_Type() {
JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver))
if (receiver == NULL) return;
- klassOop receiver_klass = receiver->klass();
+ Klass* receiver_klass = receiver->klass();
intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells();
int empty_row = -1; // free row, if any is encountered
@@ -1148,7 +1148,7 @@ const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
// create input type (domain)
const Type **fields = TypeTuple::fields(2);
fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
- fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // methodOop; Method we are entering
+ fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // Method*; Method we are entering
const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
// create result type (range)
@@ -1178,8 +1178,8 @@ const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread))
assert(obj->is_oop(), "must be a valid oop");
- assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise");
- instanceKlass::register_finalizer(instanceOop(obj), CHECK);
+ assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
+ InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
JRT_END
//-----------------------------------------------------------------------------
diff --git a/src/share/vm/opto/runtime.hpp b/src/share/vm/opto/runtime.hpp
index 6037d19f2..c70777267 100644
--- a/src/share/vm/opto/runtime.hpp
+++ b/src/share/vm/opto/runtime.hpp
@@ -140,11 +140,11 @@ class OptoRuntime : public AllStatic {
// =================================
// Allocate storage for a Java instance.
- static void new_instance_C(klassOopDesc* instance_klass, JavaThread *thread);
+ static void new_instance_C(Klass* instance_klass, JavaThread *thread);
// Allocate storage for a objArray or typeArray
- static void new_array_C(klassOopDesc* array_klass, int len, JavaThread *thread);
- static void new_array_nozero_C(klassOopDesc* array_klass, int len, JavaThread *thread);
+ static void new_array_C(Klass* array_klass, int len, JavaThread *thread);
+ static void new_array_nozero_C(Klass* array_klass, int len, JavaThread *thread);
// Post-slow-path-allocation, pre-initializing-stores step for
// implementing ReduceInitialCardMarks
@@ -152,11 +152,11 @@ class OptoRuntime : public AllStatic {
// Allocate storage for a multi-dimensional arrays
// Note: needs to be fixed for arbitrary number of dimensions
- static void multianewarray2_C(klassOopDesc* klass, int len1, int len2, JavaThread *thread);
- static void multianewarray3_C(klassOopDesc* klass, int len1, int len2, int len3, JavaThread *thread);
- static void multianewarray4_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, JavaThread *thread);
- static void multianewarray5_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, int len5, JavaThread *thread);
- static void multianewarrayN_C(klassOopDesc* klass, arrayOopDesc* dims, JavaThread *thread);
+ static void multianewarray2_C(Klass* klass, int len1, int len2, JavaThread *thread);
+ static void multianewarray3_C(Klass* klass, int len1, int len2, int len3, JavaThread *thread);
+ static void multianewarray4_C(Klass* klass, int len1, int len2, int len3, int len4, JavaThread *thread);
+ static void multianewarray5_C(Klass* klass, int len1, int len2, int len3, int len4, int len5, JavaThread *thread);
+ static void multianewarrayN_C(Klass* klass, arrayOopDesc* dims, JavaThread *thread);
static void g1_wb_pre_C(oopDesc* orig, JavaThread* thread);
static void g1_wb_post_C(void* card_addr, JavaThread* thread);
diff --git a/src/share/vm/opto/subnode.cpp b/src/share/vm/opto/subnode.cpp
index 02a6a6495..9ecd2db7d 100644
--- a/src/share/vm/opto/subnode.cpp
+++ b/src/share/vm/opto/subnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -664,9 +664,7 @@ const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const {
// See if neither subclasses the other, or if the class on top
// is precise. In either of these cases, the compare is known
// to fail if at least one of the pointers is provably not null.
- if (klass0->equals(klass1) || // if types are unequal but klasses are
- !klass0->is_java_klass() || // types not part of Java language?
- !klass1->is_java_klass()) { // types not part of Java language?
+ if (klass0->equals(klass1)) { // if types are unequal but klasses are equal
// Do nothing; we know nothing for imprecise types
} else if (klass0->is_subtype_of(klass1)) {
// If klass1's type is PRECISE, then classes are unrelated.
@@ -744,7 +742,7 @@ static inline Node* isa_const_java_mirror(PhaseGVN* phase, Node* n) {
}
// return the ConP(Foo.klass)
- assert(mirror_type->is_klass(), "mirror_type should represent a klassOop");
+ assert(mirror_type->is_klass(), "mirror_type should represent a Klass*");
return phase->makecon(TypeKlassPtr::make(mirror_type->as_klass()));
}
@@ -891,9 +889,7 @@ const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
// See if neither subclasses the other, or if the class on top
// is precise. In either of these cases, the compare is known
// to fail if at least one of the pointers is provably not null.
- if (klass0->equals(klass1) || // if types are unequal but klasses are
- !klass0->is_java_klass() || // types not part of Java language?
- !klass1->is_java_klass()) { // types not part of Java language?
+ if (klass0->equals(klass1)) { // if types are unequal but klasses are equal
// Do nothing; we know nothing for imprecise types
} else if (klass0->is_subtype_of(klass1)) {
// If klass1's type is PRECISE, then classes are unrelated.
diff --git a/src/share/vm/opto/type.cpp b/src/share/vm/opto/type.cpp
index 80d583042..7ce52ce32 100644
--- a/src/share/vm/opto/type.cpp
+++ b/src/share/vm/opto/type.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "ci/ciMethodData.hpp"
#include "ci/ciTypeFlow.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
@@ -33,7 +34,6 @@
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
-#include "oops/klassKlass.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/typeArrayKlass.hpp"
#include "opto/matcher.hpp"
@@ -49,40 +49,46 @@
Dict* Type::_shared_type_dict = NULL;
// Array which maps compiler types to Basic Types
-const BasicType Type::_basic_type[Type::lastype] = {
- T_ILLEGAL, // Bad
- T_ILLEGAL, // Control
- T_VOID, // Top
- T_INT, // Int
- T_LONG, // Long
- T_VOID, // Half
- T_NARROWOOP, // NarrowOop
-
- T_ILLEGAL, // Tuple
- T_ARRAY, // Array
- T_ILLEGAL, // VectorS
- T_ILLEGAL, // VectorD
- T_ILLEGAL, // VectorX
- T_ILLEGAL, // VectorY
-
- T_ADDRESS, // AnyPtr // shows up in factory methods for NULL_PTR
- T_ADDRESS, // RawPtr
- T_OBJECT, // OopPtr
- T_OBJECT, // InstPtr
- T_OBJECT, // AryPtr
- T_OBJECT, // KlassPtr
-
- T_OBJECT, // Function
- T_ILLEGAL, // Abio
- T_ADDRESS, // Return_Address
- T_ILLEGAL, // Memory
- T_FLOAT, // FloatTop
- T_FLOAT, // FloatCon
- T_FLOAT, // FloatBot
- T_DOUBLE, // DoubleTop
- T_DOUBLE, // DoubleCon
- T_DOUBLE, // DoubleBot
- T_ILLEGAL, // Bottom
+Type::TypeInfo Type::_type_info[Type::lastype] = {
+ { Bad, T_ILLEGAL, "bad", false, Node::NotAMachineReg, relocInfo::none }, // Bad
+ { Control, T_ILLEGAL, "control", false, 0, relocInfo::none }, // Control
+ { Bottom, T_VOID, "top", false, 0, relocInfo::none }, // Top
+ { Bad, T_INT, "int:", false, Op_RegI, relocInfo::none }, // Int
+ { Bad, T_LONG, "long:", false, Op_RegL, relocInfo::none }, // Long
+ { Half, T_VOID, "half", false, 0, relocInfo::none }, // Half
+ { Bad, T_NARROWOOP, "narrowoop:", false, Op_RegN, relocInfo::none }, // NarrowOop
+ { Bad, T_ILLEGAL, "tuple:", false, Node::NotAMachineReg, relocInfo::none }, // Tuple
+ { Bad, T_ARRAY, "array:", false, Node::NotAMachineReg, relocInfo::none }, // Array
+
+#if defined(IA32) || defined(AMD64)
+ { Bad, T_ILLEGAL, "vectors:", false, Op_VecS, relocInfo::none }, // VectorS
+ { Bad, T_ILLEGAL, "vectord:", false, Op_VecD, relocInfo::none }, // VectorD
+ { Bad, T_ILLEGAL, "vectorx:", false, Op_VecX, relocInfo::none }, // VectorX
+ { Bad, T_ILLEGAL, "vectory:", false, Op_VecY, relocInfo::none }, // VectorY
+#else
+ { Bad, T_ILLEGAL, "vectors:", false, 0, relocInfo::none }, // VectorS
+ { Bad, T_ILLEGAL, "vectord:", false, Op_RegD, relocInfo::none }, // VectorD
+ { Bad, T_ILLEGAL, "vectorx:", false, 0, relocInfo::none }, // VectorX
+ { Bad, T_ILLEGAL, "vectory:", false, 0, relocInfo::none }, // VectorY
+#endif // IA32 || AMD64
+ { Bad, T_ADDRESS, "anyptr:", false, Op_RegP, relocInfo::none }, // AnyPtr
+ { Bad, T_ADDRESS, "rawptr:", false, Op_RegP, relocInfo::none }, // RawPtr
+ { Bad, T_OBJECT, "oop:", true, Op_RegP, relocInfo::oop_type }, // OopPtr
+ { Bad, T_OBJECT, "inst:", true, Op_RegP, relocInfo::oop_type }, // InstPtr
+ { Bad, T_OBJECT, "ary:", true, Op_RegP, relocInfo::oop_type }, // AryPtr
+ { Bad, T_METADATA, "metadata:", false, Op_RegP, relocInfo::metadata_type }, // MetadataPtr
+ { Bad, T_METADATA, "klass:", false, Op_RegP, relocInfo::metadata_type }, // KlassPtr
+ { Bad, T_OBJECT, "func", false, 0, relocInfo::none }, // Function
+ { Abio, T_ILLEGAL, "abIO", false, 0, relocInfo::none }, // Abio
+ { Return_Address, T_ADDRESS, "return_address",false, Op_RegP, relocInfo::none }, // Return_Address
+ { Memory, T_ILLEGAL, "memory", false, 0, relocInfo::none }, // Memory
+ { FloatBot, T_FLOAT, "float_top", false, Op_RegF, relocInfo::none }, // FloatTop
+ { FloatCon, T_FLOAT, "ftcon:", false, Op_RegF, relocInfo::none }, // FloatCon
+ { FloatTop, T_FLOAT, "float", false, Op_RegF, relocInfo::none }, // FloatBot
+ { DoubleBot, T_DOUBLE, "double_top", false, Op_RegD, relocInfo::none }, // DoubleTop
+ { DoubleCon, T_DOUBLE, "dblcon:", false, Op_RegD, relocInfo::none }, // DoubleCon
+ { DoubleTop, T_DOUBLE, "double", false, Op_RegD, relocInfo::none }, // DoubleBot
+ { Top, T_ILLEGAL, "bottom", false, 0, relocInfo::none } // Bottom
};
// Map ideal registers (machine types) to ideal types
@@ -321,6 +327,8 @@ void Type::Initialize_shared(Compile* current) {
false, 0, oopDesc::klass_offset_in_bytes());
TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot);
+ TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot);
+
TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR );
TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
@@ -340,6 +348,7 @@ void Type::Initialize_shared(Compile* current) {
#ifdef _LP64
if (UseCompressedOops) {
+ assert(TypeAryPtr::NARROWOOPS->is_ptr_to_narrowoop(), "array of narrow oops must be ptr to narrow oop");
TypeAryPtr::OOPS = TypeAryPtr::NARROWOOPS;
} else
#endif
@@ -372,7 +381,7 @@ void Type::Initialize_shared(Compile* current) {
TypeKlassPtr::OBJECT_OR_NULL = TypeKlassPtr::make( TypePtr::BotPTR, current->env()->Object_klass(), 0 );
const Type **fi2c = TypeTuple::fields(2);
- fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // methodOop
+ fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // Method*
fi2c[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // argument pointer
TypeTuple::START_I2C = TypeTuple::make(TypeFunc::Parms+2, fi2c);
@@ -461,10 +470,6 @@ void Type::Initialize(Compile* current) {
Type* t = (Type*)i._value;
tdic->Insert(t,t); // New Type, insert into Type table
}
-
-#ifdef ASSERT
- verify_lastype();
-#endif
}
//------------------------------hashcons---------------------------------------
@@ -620,6 +625,7 @@ const Type *Type::xmeet( const Type *t ) const {
case InstPtr:
return t->xmeet(this);
+ case MetadataPtr:
case KlassPtr:
return t->xmeet(this);
@@ -700,6 +706,8 @@ const Type::TYPES Type::dual_type[Type::lastype] = {
Bad, // OopPtr - handled in v-call
Bad, // InstPtr - handled in v-call
Bad, // AryPtr - handled in v-call
+
+ Bad, // MetadataPtr - handled in v-call
Bad, // KlassPtr - handled in v-call
Bad, // Function - handled in v-call
@@ -717,8 +725,8 @@ const Type::TYPES Type::dual_type[Type::lastype] = {
const Type *Type::xdual() const {
// Note: the base() accessor asserts the sanity of _base.
- assert(dual_type[base()] != Bad, "implement with v-call");
- return new Type(dual_type[_base]);
+ assert(_type_info[base()].dual_type != Bad, "implement with v-call");
+ return new Type(_type_info[_base].dual_type);
}
//------------------------------has_memory-------------------------------------
@@ -738,7 +746,7 @@ bool Type::has_memory() const {
#ifndef PRODUCT
//------------------------------dump2------------------------------------------
void Type::dump2( Dict &d, uint depth, outputStream *st ) const {
- st->print(msg[_base]);
+ st->print(_type_info[_base].msg);
}
//------------------------------dump-------------------------------------------
@@ -750,17 +758,6 @@ void Type::dump_on(outputStream *st) const {
st->print(" [narrow]");
}
}
-
-//------------------------------data-------------------------------------------
-const char * const Type::msg[Type::lastype] = {
- "bad","control","top","int:","long:","half", "narrowoop:",
- "tuple:", "array:", "vectors:", "vectord:", "vectorx:", "vectory:",
- "anyptr:", "rawptr:", "java:", "inst:", "aryptr:", "klass:",
- "func", "abIO", "return_address", "memory",
- "float_top", "ftcon:", "float",
- "double_top", "dblcon:", "double",
- "bottom"
-};
#endif
//------------------------------singleton--------------------------------------
@@ -813,31 +810,6 @@ void Type::typerr( const Type *t ) const {
ShouldNotReachHere();
}
-//------------------------------isa_oop_ptr------------------------------------
-// Return true if type is an oop pointer type. False for raw pointers.
-static char isa_oop_ptr_tbl[Type::lastype] = {
- 0,0,0,0,0,0,0/*narrowoop*/,0/*tuple*/, 0/*array*/, 0, 0, 0, 0/*vector*/,
- 0/*anyptr*/,0/*rawptr*/,1/*OopPtr*/,1/*InstPtr*/,1/*AryPtr*/,1/*KlassPtr*/,
- 0/*func*/,0,0/*return_address*/,0,
- /*floats*/0,0,0, /*doubles*/0,0,0,
- 0
-};
-bool Type::isa_oop_ptr() const {
- return isa_oop_ptr_tbl[_base] != 0;
-}
-
-//------------------------------dump_stats-------------------------------------
-// // Check that arrays match type enum
-#ifndef PRODUCT
-void Type::verify_lastype() {
- // Check that arrays match enumeration
- assert( Type::dual_type [Type::lastype - 1] == Type::Top, "did not update array");
- assert( strcmp(Type::msg [Type::lastype - 1],"bottom") == 0, "did not update array");
- // assert( PhiNode::tbl [Type::lastype - 1] == NULL, "did not update array");
- assert( Matcher::base2reg[Type::lastype - 1] == 0, "did not update array");
- assert( isa_oop_ptr_tbl [Type::lastype - 1] == (char)0, "did not update array");
-}
-#endif
//=============================================================================
// Convenience common pre-built types.
@@ -862,8 +834,9 @@ const Type *TypeF::xmeet( const Type *t ) const {
case RawPtr: // reuses local variables
case OopPtr:
case InstPtr:
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
case NarrowOop:
case Int:
case Long:
@@ -978,8 +951,9 @@ const Type *TypeD::xmeet( const Type *t ) const {
case RawPtr: // reuses local variables
case OopPtr:
case InstPtr:
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
case NarrowOop:
case Int:
case Long:
@@ -1131,8 +1105,9 @@ const Type *TypeInt::xmeet( const Type *t ) const {
case RawPtr: // reuses local variables
case OopPtr:
case InstPtr:
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
case NarrowOop:
case Long:
case FloatTop:
@@ -1387,8 +1362,9 @@ const Type *TypeLong::xmeet( const Type *t ) const {
case RawPtr: // reuses local variables
case OopPtr:
case InstPtr:
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
case NarrowOop:
case Int:
case FloatTop:
@@ -2132,8 +2108,9 @@ const Type *TypePtr::xmeet( const Type *t ) const {
case RawPtr: // For these, flip the call around to cut down
case OopPtr:
case InstPtr: // on the cases I have to handle.
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
return t->xmeet(this); // Call in reverse direction
default: // All else is a mistake
typerr(t);
@@ -2288,8 +2265,9 @@ const Type *TypeRawPtr::xmeet( const Type *t ) const {
case OopPtr:
case InstPtr:
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
return TypePtr::BOTTOM; // Oop meet raw is not well defined
default: // All else is a mistake
typerr(t);
@@ -2375,11 +2353,12 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
_instance_id(instance_id) {
#ifdef _LP64
if (UseCompressedOops && _offset != 0) {
- if (klass() == NULL) {
+ if (_offset == oopDesc::klass_offset_in_bytes()) {
+ _is_ptr_to_narrowoop = UseCompressedKlassPointers;
+ } else if (klass() == NULL) {
+ // Array with unknown body type
assert(this->isa_aryptr(), "only arrays without klass");
_is_ptr_to_narrowoop = true;
- } else if (_offset == oopDesc::klass_offset_in_bytes()) {
- _is_ptr_to_narrowoop = true;
} else if (this->isa_aryptr()) {
_is_ptr_to_narrowoop = (klass()->is_obj_array_klass() &&
_offset != arrayOopDesc::length_offset_in_bytes());
@@ -2399,7 +2378,7 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
_offset == java_lang_Class::array_klass_offset_in_bytes())) {
// Special hidden fields from the Class.
assert(this->isa_instptr(), "must be an instance ptr.");
- _is_ptr_to_narrowoop = true;
+ _is_ptr_to_narrowoop = false;
} else if (klass() == ciEnv::current()->Class_klass() &&
_offset >= instanceMirrorKlass::offset_of_static_fields()) {
// Static fields
@@ -2423,7 +2402,6 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
_is_ptr_to_narrowoop = true;
} else {
// Type for the copy start in LibraryCallKit::inline_native_clone().
- assert(!klass_is_exact(), "only non-exact klass");
_is_ptr_to_narrowoop = true;
}
}
@@ -2437,7 +2415,7 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
const TypeOopPtr *TypeOopPtr::make(PTR ptr,
int offset, int instance_id) {
assert(ptr != Constant, "no constant generic pointers");
- ciKlass* k = ciKlassKlass::make();
+ ciKlass* k = Compile::current()->env()->Object_klass();
bool xk = false;
ciObject* o = NULL;
return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id))->hashcons();
@@ -2472,7 +2450,7 @@ const Type *TypeOopPtr::cast_to_exactness(bool klass_is_exact) const {
const TypeKlassPtr* TypeOopPtr::as_klass_type() const {
ciKlass* k = klass();
bool xk = klass_is_exact();
- if (k == NULL || !k->is_java_klass())
+ if (k == NULL)
return TypeKlassPtr::OBJECT;
else
return TypeKlassPtr::make(xk? Constant: NotNull, k, 0);
@@ -2506,6 +2484,8 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const {
typerr(t);
case RawPtr:
+ case MetadataPtr:
+ case KlassPtr:
return TypePtr::BOTTOM; // Oop meet raw is not well defined
case AnyPtr: {
@@ -2536,7 +2516,6 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const {
}
case InstPtr: // For these, flip the call around to cut down
- case KlassPtr: // on the cases I have to handle.
case AryPtr:
return t->xmeet(this); // Call in reverse direction
@@ -2548,7 +2527,7 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const {
//------------------------------xdual------------------------------------------
// Dual of a pure heap pointer. No relevant klass or oop information.
const Type *TypeOopPtr::xdual() const {
- assert(klass() == ciKlassKlass::make(), "no klasses here");
+ assert(klass() == Compile::current()->env()->Object_klass(), "no klasses here");
assert(const_oop() == NULL, "no constants here");
return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id() );
}
@@ -2556,7 +2535,6 @@ const Type *TypeOopPtr::xdual() const {
//--------------------------make_from_klass_common-----------------------------
// Computes the element-type given a klass.
const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_change, bool try_for_exact) {
- assert(klass->is_java_klass(), "must be java language klass");
if (klass->is_instance_klass()) {
Compile* C = Compile::current();
Dependencies* deps = C->dependencies();
@@ -2613,24 +2591,6 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_
//------------------------------make_from_constant-----------------------------
// Make a java pointer from an oop constant
const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
- if (o->is_method_data() || o->is_method()) {
- // Treat much like a typeArray of bytes, like below, but fake the type...
- const BasicType bt = T_BYTE;
- const Type* etype = get_const_basic_type(bt);
- const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
- ciKlass* klass = ciArrayKlass::make(ciType::make(bt));
- assert(o->can_be_constant(), "should be tenured");
- return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
- } else if (o->is_cpcache()) {
- // Treat much like a objArray, like below, but fake the type...
- const BasicType bt = T_OBJECT;
- const Type* etype = get_const_basic_type(bt);
- const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
- ciKlass* klass = ciArrayKlass::make(ciType::make(bt));
- assert(o->can_be_constant(), "should be tenured");
- return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
- } else {
- assert(o->is_java_object(), "must be java language object");
assert(!o->is_null_object(), "null object not yet handled here.");
ciKlass* klass = o->klass();
if (klass->is_instance_klass()) {
@@ -2643,7 +2603,8 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
return TypeInstPtr::make(o);
} else if (klass->is_obj_array_klass()) {
// Element is an object array. Recursively call ourself.
- const Type *etype = make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
+ const Type *etype =
+ TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
// We used to pass NotNull in here, asserting that the sub-arrays
// are all not-null. This is not true in generally, as code can
@@ -2653,10 +2614,12 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
} else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
}
- return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
+ const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
+ return arr;
} else if (klass->is_type_array_klass()) {
// Element is an typeArray
- const Type* etype = get_const_basic_type(klass->as_type_array_klass()->element_type());
+ const Type* etype =
+ (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
// We used to pass NotNull in here, asserting that the array pointer
// is not-null. That was not true in general.
@@ -2665,8 +2628,8 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
} else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
}
- return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
- }
+ const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
+ return arr;
}
fatal("unhandled object type");
@@ -2845,8 +2808,7 @@ const TypeInstPtr *TypeInstPtr::make(PTR ptr,
ciObject* o,
int offset,
int instance_id) {
- assert( !k->is_loaded() || k->is_instance_klass() ||
- k->is_method_klass(), "Must be for instance or method");
+ assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance");
// Either const_oop() is NULL or else ptr is Constant
assert( (!o && ptr != Constant) || (o && ptr == Constant),
"constant pointers must have a value supplied" );
@@ -2971,6 +2933,8 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const {
default: // All else is a mistake
typerr(t);
+ case MetadataPtr:
+ case KlassPtr:
case RawPtr: return TypePtr::BOTTOM;
case AryPtr: { // All arrays inherit from Object class
@@ -3237,9 +3201,6 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const {
return make( ptr, k, false, NULL, off, instance_id );
} // End of case InstPtr
- case KlassPtr:
- return TypeInstPtr::BOTTOM;
-
} // End of switch
return this; // Return the double constant
}
@@ -3516,6 +3477,8 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
}
}
+ case MetadataPtr:
+ case KlassPtr:
case RawPtr: return TypePtr::BOTTOM;
case AryPtr: { // Meeting 2 references?
@@ -3634,10 +3597,6 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
default: typerr(t);
}
}
-
- case KlassPtr:
- return TypeInstPtr::BOTTOM;
-
}
return this; // Lint noise
}
@@ -3768,8 +3727,9 @@ const Type *TypeNarrowOop::xmeet( const Type *t ) const {
case RawPtr:
case OopPtr:
case InstPtr:
- case KlassPtr:
case AryPtr:
+ case MetadataPtr:
+ case KlassPtr:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
@@ -3829,6 +3789,183 @@ void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
#endif
+
+//------------------------------eq---------------------------------------------
+// Structural equality check for Type representations
+bool TypeMetadataPtr::eq( const Type *t ) const {
+ const TypeMetadataPtr *a = (const TypeMetadataPtr*)t;
+ ciMetadata* one = metadata();
+ ciMetadata* two = a->metadata();
+ if (one == NULL || two == NULL) {
+ return (one == two) && TypePtr::eq(t);
+ } else {
+ return one->equals(two) && TypePtr::eq(t);
+ }
+}
+
+//------------------------------hash-------------------------------------------
+// Type-specific hashing function.
+int TypeMetadataPtr::hash(void) const {
+ return
+ (metadata() ? metadata()->hash() : 0) +
+ TypePtr::hash();
+}
+
+//------------------------------singleton--------------------------------------
+// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple
+// constants
+bool TypeMetadataPtr::singleton(void) const {
+ // detune optimizer to not generate constant metadta + constant offset as a constant!
+ // TopPTR, Null, AnyNull, Constant are all singletons
+ return (_offset == 0) && !below_centerline(_ptr);
+}
+
+//------------------------------add_offset-------------------------------------
+const TypePtr *TypeMetadataPtr::add_offset( intptr_t offset ) const {
+ return make( _ptr, _metadata, xadd_offset(offset));
+}
+
+//-----------------------------filter------------------------------------------
+// Do not allow interface-vs.-noninterface joins to collapse to top.
+const Type *TypeMetadataPtr::filter( const Type *kills ) const {
+ const TypeMetadataPtr* ft = join(kills)->isa_metadataptr();
+ if (ft == NULL || ft->empty())
+ return Type::TOP; // Canonical empty value
+ return ft;
+}
+
+ //------------------------------get_con----------------------------------------
+intptr_t TypeMetadataPtr::get_con() const {
+ assert( _ptr == Null || _ptr == Constant, "" );
+ assert( _offset >= 0, "" );
+
+ if (_offset != 0) {
+ // After being ported to the compiler interface, the compiler no longer
+ // directly manipulates the addresses of oops. Rather, it only has a pointer
+ // to a handle at compile time. This handle is embedded in the generated
+ // code and dereferenced at the time the nmethod is made. Until that time,
+ // it is not reasonable to do arithmetic with the addresses of oops (we don't
+ // have access to the addresses!). This does not seem to currently happen,
+ // but this assertion here is to help prevent its occurence.
+ tty->print_cr("Found oop constant with non-zero offset");
+ ShouldNotReachHere();
+ }
+
+ return (intptr_t)metadata()->constant_encoding();
+}
+
+//------------------------------cast_to_ptr_type-------------------------------
+const Type *TypeMetadataPtr::cast_to_ptr_type(PTR ptr) const {
+ if( ptr == _ptr ) return this;
+ return make(ptr, metadata(), _offset);
+}
+
+//------------------------------meet-------------------------------------------
+// Compute the MEET of two types. It returns a new Type object.
+const Type *TypeMetadataPtr::xmeet( const Type *t ) const {
+ // Perform a fast test for common case; meeting the same types together.
+ if( this == t ) return this; // Meeting same type-rep?
+
+ // Current "this->_base" is OopPtr
+ switch (t->base()) { // switch on original type
+
+ case Int: // Mixing ints & oops happens when javac
+ case Long: // reuses local variables
+ case FloatTop:
+ case FloatCon:
+ case FloatBot:
+ case DoubleTop:
+ case DoubleCon:
+ case DoubleBot:
+ case NarrowOop:
+ case Bottom: // Ye Olde Default
+ return Type::BOTTOM;
+ case Top:
+ return this;
+
+ default: // All else is a mistake
+ typerr(t);
+
+ case AnyPtr: {
+ // Found an AnyPtr type vs self-OopPtr type
+ const TypePtr *tp = t->is_ptr();
+ int offset = meet_offset(tp->offset());
+ PTR ptr = meet_ptr(tp->ptr());
+ switch (tp->ptr()) {
+ case Null:
+ if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset);
+ // else fall through:
+ case TopPTR:
+ case AnyNull: {
+ return make(ptr, NULL, offset);
+ }
+ case BotPTR:
+ case NotNull:
+ return TypePtr::make(AnyPtr, ptr, offset);
+ default: typerr(t);
+ }
+ }
+
+ case RawPtr:
+ case KlassPtr:
+ case OopPtr:
+ case InstPtr:
+ case AryPtr:
+ return TypePtr::BOTTOM; // Oop meet raw is not well defined
+
+ case MetadataPtr:
+ ShouldNotReachHere();
+ break;
+
+ } // End of switch
+ return this; // Return the double constant
+}
+
+
+//------------------------------xdual------------------------------------------
+// Dual of a pure metadata pointer.
+const Type *TypeMetadataPtr::xdual() const {
+ return new TypeMetadataPtr(dual_ptr(), metadata(), dual_offset());
+}
+
+//------------------------------dump2------------------------------------------
+#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, metadata());
+ switch( _offset ) {
+ case OffsetTop: st->print("+top"); break;
+ case OffsetBot: st->print("+any"); break;
+ case 0: break;
+ default: st->print("+%d",_offset); break;
+ }
+}
+#endif
+
+
+//=============================================================================
+// Convenience common pre-built type.
+const TypeMetadataPtr *TypeMetadataPtr::BOTTOM;
+
+TypeMetadataPtr::TypeMetadataPtr(PTR ptr, ciMetadata* metadata, int offset):
+ TypePtr(MetadataPtr, ptr, offset), _metadata(metadata) {
+}
+
+const TypeMetadataPtr* TypeMetadataPtr::make(ciMethod* m) {
+ return make(Constant, m, 0);
+}
+const TypeMetadataPtr* TypeMetadataPtr::make(ciMethodData* m) {
+ return make(Constant, m, 0);
+}
+
+//------------------------------make-------------------------------------------
+// Create a meta data constant
+const TypeMetadataPtr *TypeMetadataPtr::make(PTR ptr, ciMetadata* m, int offset) {
+ assert(m == NULL || !m->is_klass(), "wrong type");
+ return (TypeMetadataPtr*)(new TypeMetadataPtr(ptr, m, offset))->hashcons();
+}
+
+
//=============================================================================
// Convenience common pre-built types.
@@ -3836,17 +3973,16 @@ void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
const TypeKlassPtr *TypeKlassPtr::OBJECT;
const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL;
-//------------------------------TypeKlasPtr------------------------------------
+//------------------------------TypeKlassPtr-----------------------------------
TypeKlassPtr::TypeKlassPtr( PTR ptr, ciKlass* klass, int offset )
- : TypeOopPtr(KlassPtr, ptr, klass, (ptr==Constant), (ptr==Constant ? klass : NULL), offset, 0) {
+ : TypePtr(KlassPtr, ptr, offset), _klass(klass), _klass_is_exact(ptr == Constant) {
}
//------------------------------make-------------------------------------------
// ptr to klass 'k', if Constant, or possibly to a sub-klass if not a Constant
const TypeKlassPtr *TypeKlassPtr::make( PTR ptr, ciKlass* k, int offset ) {
assert( k != NULL, "Expect a non-NULL klass");
- assert(k->is_instance_klass() || k->is_array_klass() ||
- k->is_method_klass(), "Incorrect type of klass oop");
+ assert(k->is_instance_klass() || k->is_array_klass(), "Incorrect type of klass oop");
TypeKlassPtr *r =
(TypeKlassPtr*)(new TypeKlassPtr(ptr, k, offset))->hashcons();
@@ -3859,15 +3995,23 @@ bool TypeKlassPtr::eq( const Type *t ) const {
const TypeKlassPtr *p = t->is_klassptr();
return
klass()->equals(p->klass()) &&
- TypeOopPtr::eq(p);
+ TypePtr::eq(p);
}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
int TypeKlassPtr::hash(void) const {
- return klass()->hash() + TypeOopPtr::hash();
+ return klass()->hash() + TypePtr::hash();
}
+//------------------------------singleton--------------------------------------
+// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple
+// constants
+bool TypeKlassPtr::singleton(void) const {
+ // detune optimizer to not generate constant klass + constant offset as a constant!
+ // TopPTR, Null, AnyNull, Constant are all singletons
+ return (_offset == 0) && !below_centerline(_ptr);
+}
//----------------------compute_klass------------------------------------------
// Compute the defining klass for this class
@@ -4018,24 +4162,6 @@ const Type *TypeKlassPtr::xmeet( const Type *t ) const {
default: // All else is a mistake
typerr(t);
- case RawPtr: return TypePtr::BOTTOM;
-
- case OopPtr: { // Meeting to OopPtrs
- // Found a OopPtr type vs self-KlassPtr type
- const TypePtr *tp = t->is_oopptr();
- int offset = meet_offset(tp->offset());
- PTR ptr = meet_ptr(tp->ptr());
- switch (tp->ptr()) {
- case TopPTR:
- case AnyNull:
- return make(ptr, klass(), offset);
- case BotPTR:
- case NotNull:
- return TypePtr::make(AnyPtr, ptr, offset);
- default: typerr(t);
- }
- }
-
case AnyPtr: { // Meeting to AnyPtrs
// Found an AnyPtr type vs self-KlassPtr type
const TypePtr *tp = t->is_ptr();
@@ -4055,9 +4181,12 @@ const Type *TypeKlassPtr::xmeet( const Type *t ) const {
}
}
+ case RawPtr:
+ case MetadataPtr:
+ case OopPtr:
case AryPtr: // Meet with AryPtr
case InstPtr: // Meet with InstPtr
- return TypeInstPtr::BOTTOM;
+ return TypePtr::BOTTOM;
//
// A-top }
@@ -4112,17 +4241,11 @@ const Type *TypeKlassPtr::xmeet( const Type *t ) const {
// If the klasses are equal, the constants may still differ. Fall to
// NotNull if they do (neither constant is NULL; that is a special case
// handled elsewhere).
- ciObject* o = NULL; // Assume not constant when done
- ciObject* this_oop = const_oop();
- ciObject* tkls_oop = tkls->const_oop();
if( ptr == Constant ) {
- if (this_oop != NULL && tkls_oop != NULL &&
- this_oop->equals(tkls_oop) )
- o = this_oop;
- else if (above_centerline(this->ptr()))
- o = tkls_oop;
- else if (above_centerline(tkls->ptr()))
- o = this_oop;
+ if (this->_ptr == Constant && tkls->_ptr == Constant &&
+ this->klass()->equals(tkls->klass()));
+ else if (above_centerline(this->ptr()));
+ else if (above_centerline(tkls->ptr()));
else
ptr = NotNull;
}
@@ -4148,6 +4271,25 @@ const Type *TypeKlassPtr::xdual() const {
return new TypeKlassPtr( dual_ptr(), klass(), dual_offset() );
}
+//------------------------------get_con----------------------------------------
+intptr_t TypeKlassPtr::get_con() const {
+ assert( _ptr == Null || _ptr == Constant, "" );
+ assert( _offset >= 0, "" );
+
+ if (_offset != 0) {
+ // After being ported to the compiler interface, the compiler no longer
+ // directly manipulates the addresses of oops. Rather, it only has a pointer
+ // to a handle at compile time. This handle is embedded in the generated
+ // code and dereferenced at the time the nmethod is made. Until that time,
+ // it is not reasonable to do arithmetic with the addresses of oops (we don't
+ // have access to the addresses!). This does not seem to currently happen,
+ // but this assertion here is to help prevent its occurence.
+ tty->print_cr("Found oop constant with non-zero offset");
+ ShouldNotReachHere();
+ }
+
+ return (intptr_t)klass()->constant_encoding();
+}
//------------------------------dump2------------------------------------------
// Dump Klass Type
#ifndef PRODUCT
@@ -4280,35 +4422,6 @@ void TypeFunc::dump2( Dict &d, uint depth, outputStream *st ) const {
}
st->print(" )");
}
-
-//------------------------------print_flattened--------------------------------
-// Print a 'flattened' signature
-static const char * const flat_type_msg[Type::lastype] = {
- "bad","control","top","int","long","_", "narrowoop",
- "tuple:", "array:", "vectors:", "vectord:", "vectorx:", "vectory:",
- "ptr", "rawptr", "ptr", "ptr", "ptr", "ptr",
- "func", "abIO", "return_address", "mem",
- "float_top", "ftcon:", "flt",
- "double_top", "dblcon:", "dbl",
- "bottom"
-};
-
-void TypeFunc::print_flattened() const {
- if( _range->_cnt <= Parms )
- tty->print("void");
- else {
- uint i;
- for (i = Parms; i < _range->_cnt-1; i++)
- tty->print("%s/",flat_type_msg[_range->field_at(i)->base()]);
- tty->print("%s",flat_type_msg[_range->field_at(i)->base()]);
- }
- tty->print(" ( ");
- if (Parms < _domain->_cnt)
- tty->print("%s",flat_type_msg[_domain->field_at(Parms)->base()]);
- for (uint i = Parms+1; i < _domain->_cnt; i++)
- tty->print(", %s",flat_type_msg[_domain->field_at(i)->base()]);
- tty->print(" )");
-}
#endif
//------------------------------singleton--------------------------------------
diff --git a/src/share/vm/opto/type.hpp b/src/share/vm/opto/type.hpp
index a4b5487d7..666c78f5c 100644
--- a/src/share/vm/opto/type.hpp
+++ b/src/share/vm/opto/type.hpp
@@ -62,6 +62,7 @@ class TypeOopPtr;
class TypeInstPtr;
class TypeAryPtr;
class TypeKlassPtr;
+class TypeMetadataPtr;
//------------------------------Type-------------------------------------------
// Basic Type object, represents a set of primitive Values.
@@ -93,9 +94,11 @@ public:
OopPtr, // Any and all Java heap entities
InstPtr, // Instance pointers (non-array objects)
AryPtr, // Array pointers
- KlassPtr, // Klass pointers
// (Ptr order matters: See is_ptr, isa_ptr, is_oopptr, isa_oopptr.)
+ MetadataPtr, // Generic metadata
+ KlassPtr, // Klass pointers
+
Function, // Function signature
Abio, // Abstract I/O
Return_Address, // Subroutine return address
@@ -123,8 +126,18 @@ public:
};
private:
+ typedef struct {
+ const TYPES dual_type;
+ const BasicType basic_type;
+ const char* msg;
+ const bool isa_oop;
+ const int ideal_reg;
+ const relocInfo::relocType reloc;
+ } TypeInfo;
+
// Dictionary of types shared among compilations.
static Dict* _shared_type_dict;
+ static TypeInfo _type_info[];
static int uhash( const Type *const t );
// Structural equality check. Assumes that cmp() has already compared
@@ -241,12 +254,16 @@ public:
const TypeNarrowOop *isa_narrowoop() const; // Returns NULL if not oop ptr type
const TypeOopPtr *isa_oopptr() const; // Returns NULL if not oop ptr type
const TypeOopPtr *is_oopptr() const; // Java-style GC'd pointer
- const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr
- const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr
const TypeInstPtr *isa_instptr() const; // Returns NULL if not InstPtr
const TypeInstPtr *is_instptr() const; // Instance
const TypeAryPtr *isa_aryptr() const; // Returns NULL if not AryPtr
const TypeAryPtr *is_aryptr() const; // Array oop
+
+ const TypeMetadataPtr *isa_metadataptr() const; // Returns NULL if not oop ptr type
+ const TypeMetadataPtr *is_metadataptr() const; // Java-style GC'd pointer
+ const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr
+ const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr
+
virtual bool is_finite() const; // Has a finite value
virtual bool is_nan() const; // Is not a number (NaN)
@@ -267,9 +284,6 @@ public:
// Do you have memory, directly or through a tuple?
bool has_memory( ) const;
- // Are you a pointer type or not?
- bool isa_oop_ptr() const;
-
// TRUE if type is a singleton
virtual bool singleton(void) const;
@@ -284,7 +298,6 @@ public:
static const Type *mreg2type[];
// Printing, statistics
- static const char * const msg[lastype]; // Printable strings
#ifndef PRODUCT
void dump_on(outputStream *st) const;
void dump() const {
@@ -292,7 +305,6 @@ public:
}
virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
static void dump_stats();
- static void verify_lastype(); // Check that arrays match type enum
#endif
void typerr(const Type *t) const; // Mixing types error
@@ -336,7 +348,11 @@ public:
static const Type *TOP;
// Mapping from compiler type to VM BasicType
- BasicType basic_type() const { return _basic_type[_base]; }
+ BasicType basic_type() const { return _type_info[_base].basic_type; }
+ int ideal_reg() const { return _type_info[_base].ideal_reg; }
+ const char* msg() const { return _type_info[_base].msg; }
+ bool isa_oop_ptr() const { return _type_info[_base].isa_oop; }
+ relocInfo::relocType reloc() const { return _type_info[_base].reloc; }
// Mapping from CI type system to compiler type:
static const Type* get_typeflow_type(ciType* type);
@@ -842,7 +858,7 @@ public:
//------------------------------TypeInstPtr------------------------------------
// Class of Java object pointers, pointing either to non-array Java instances
-// or to a klassOop (including array klasses).
+// or to a Klass* (including array klasses).
class TypeInstPtr : public TypeOopPtr {
TypeInstPtr( PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id );
virtual bool eq( const Type *t ) const;
@@ -859,7 +875,6 @@ class TypeInstPtr : public TypeOopPtr {
static const TypeInstPtr *make(ciObject* o) {
return make(TypePtr::Constant, o->klass(), true, o, 0);
}
-
// Make a pointer to a constant oop with offset.
static const TypeInstPtr *make(ciObject* o, int offset) {
return make(TypePtr::Constant, o->klass(), true, o, offset);
@@ -992,18 +1007,92 @@ public:
#endif
};
+//------------------------------TypeMetadataPtr-------------------------------------
+// Some kind of metadata, either Method*, MethodData* or CPCacheOop
+class TypeMetadataPtr : public TypePtr {
+protected:
+ TypeMetadataPtr(PTR ptr, ciMetadata* metadata, int offset);
+public:
+ virtual bool eq( const Type *t ) const;
+ virtual int hash() const; // Type specific hashing
+ virtual bool singleton(void) const; // TRUE if type is a singleton
+
+private:
+ ciMetadata* _metadata;
+
+public:
+ static const TypeMetadataPtr* make(PTR ptr, ciMetadata* m, int offset);
+
+ static const TypeMetadataPtr* make(ciMethod* m);
+ static const TypeMetadataPtr* make(ciMethodData* m);
+
+ ciMetadata* metadata() const { return _metadata; }
+
+ virtual const Type *cast_to_ptr_type(PTR ptr) const;
+
+ virtual const TypePtr *add_offset( intptr_t offset ) const;
+
+ virtual const Type *xmeet( const Type *t ) const;
+ virtual const Type *xdual() const; // Compute dual right now.
+
+ virtual intptr_t get_con() const;
+
+ // Do not allow interface-vs.-noninterface joins to collapse to top.
+ virtual const Type *filter( const Type *kills ) const;
+
+ // Convenience common pre-built types.
+ static const TypeMetadataPtr *BOTTOM;
+
+#ifndef PRODUCT
+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
+#endif
+};
+
//------------------------------TypeKlassPtr-----------------------------------
// Class of Java Klass pointers
-class TypeKlassPtr : public TypeOopPtr {
+class TypeKlassPtr : public TypePtr {
TypeKlassPtr( PTR ptr, ciKlass* klass, int offset );
+ public:
virtual bool eq( const Type *t ) const;
virtual int hash() const; // Type specific hashing
+ virtual bool singleton(void) const; // TRUE if type is a singleton
+ private:
+
+ static const TypeKlassPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
+
+ ciKlass* _klass;
+
+ // Does the type exclude subclasses of the klass? (Inexact == polymorphic.)
+ bool _klass_is_exact;
public:
- ciSymbol* name() const { return _klass->name(); }
+ ciSymbol* name() const { return klass()->name(); }
- bool is_loaded() const { return _klass->is_loaded(); }
+ ciKlass* klass() const { return _klass; }
+ bool klass_is_exact() const { return _klass_is_exact; }
+
+ bool is_loaded() const { return klass()->is_loaded(); }
+
+ // Creates a type given a klass. Correctly handles multi-dimensional arrays
+ // Respects UseUniqueSubclasses.
+ // If the klass is final, the resulting type will be exact.
+ static const TypeKlassPtr* make_from_klass(ciKlass* klass) {
+ return make_from_klass_common(klass, true, false);
+ }
+ // Same as before, but will produce an exact type, even if
+ // the klass is not final, as long as it has exactly one implementation.
+ static const TypeKlassPtr* make_from_klass_unique(ciKlass* klass) {
+ return make_from_klass_common(klass, true, true);
+ }
+ // Same as before, but does not respects UseUniqueSubclasses.
+ // Use this only for creating array element types.
+ static const TypeKlassPtr* make_from_klass_raw(ciKlass* klass) {
+ return make_from_klass_common(klass, false, false);
+ }
+
+ // Make a generic (unclassed) pointer to metadata.
+ static const TypeKlassPtr* make(PTR ptr, int offset);
// ptr to klass 'k'
static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); }
@@ -1023,6 +1112,8 @@ public:
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
+ virtual intptr_t get_con() const;
+
// Convenience common pre-built types.
static const TypeKlassPtr* OBJECT; // Not-null object klass or below
static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
@@ -1117,7 +1208,6 @@ public:
#ifndef PRODUCT
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
- void print_flattened() const; // Print a 'flattened' signature
#endif
// Convenience common pre-built types.
};
@@ -1209,13 +1299,13 @@ inline const TypePtr *Type::isa_ptr() const {
inline const TypeOopPtr *Type::is_oopptr() const {
// OopPtr is the first and KlassPtr the last, with no non-oops between.
- assert(_base >= OopPtr && _base <= KlassPtr, "Not a Java pointer" ) ;
+ assert(_base >= OopPtr && _base <= AryPtr, "Not a Java pointer" ) ;
return (TypeOopPtr*)this;
}
inline const TypeOopPtr *Type::isa_oopptr() const {
// OopPtr is the first and KlassPtr the last, with no non-oops between.
- return (_base >= OopPtr && _base <= KlassPtr) ? (TypeOopPtr*)this : NULL;
+ return (_base >= OopPtr && _base <= AryPtr) ? (TypeOopPtr*)this : NULL;
}
inline const TypeRawPtr *Type::isa_rawptr() const {
@@ -1256,6 +1346,16 @@ inline const TypeNarrowOop *Type::isa_narrowoop() const {
return (_base == NarrowOop) ? (TypeNarrowOop*)this : NULL;
}
+inline const TypeMetadataPtr *Type::is_metadataptr() const {
+ // MetadataPtr is the first and CPCachePtr the last
+ assert(_base == MetadataPtr, "Not a metadata pointer" ) ;
+ return (TypeMetadataPtr*)this;
+}
+
+inline const TypeMetadataPtr *Type::isa_metadataptr() const {
+ return (_base == MetadataPtr) ? (TypeMetadataPtr*)this : NULL;
+}
+
inline const TypeKlassPtr *Type::isa_klassptr() const {
return (_base == KlassPtr) ? (TypeKlassPtr*)this : NULL;
}