Mercurial > hg > truffle
diff src/share/vm/opto/memnode.cpp @ 164:c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
Summary: Add LoadNKlass and CMoveN nodes, use CmpN and ConN nodes to generate narrow oops compare instructions.
Reviewed-by: never, rasbold
author | kvn |
---|---|
date | Wed, 21 May 2008 13:46:23 -0700 |
parents | 885ed790ecf0 |
children | 7793bd37a336 |
line wrap: on
line diff
--- a/src/share/vm/opto/memnode.cpp Wed May 21 10:45:07 2008 -0700 +++ b/src/share/vm/opto/memnode.cpp Wed May 21 13:46:23 2008 -0700 @@ -671,11 +671,13 @@ case Op_LoadP: // Loading from within a klass case Op_LoadN: // Loading from within a klass case Op_LoadKlass: // Loading from within a klass + case Op_LoadNKlass: // Loading from within a klass case Op_ConP: // Loading from a klass case Op_ConN: // Loading from a klass case Op_CreateEx: // Sucking up the guts of an exception oop case Op_Con: // Reading from TLS case Op_CMoveP: // CMoveP is pinned + case Op_CMoveN: // CMoveN is pinned break; // No progress case Op_Proj: // Direct call to an allocation routine @@ -1610,8 +1612,35 @@ } //============================================================================= +//----------------------------LoadKlassNode::make------------------------------ +// Polymorphic factory method: +Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) { + 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"); +#ifdef _LP64 + if (adr_type->is_ptr_to_narrowoop()) { + const TypeNarrowOop* narrowtype = tk->is_oopptr()->make_narrowoop(); + Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, narrowtype)); + return DecodeNNode::decode(&gvn, load_klass); + } else +#endif + { + assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); + return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk); + } + ShouldNotReachHere(); + return (LoadKlassNode*)NULL; +} + //------------------------------Value------------------------------------------ const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { + return klass_value_common(phase); +} + +const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP const Type *t1 = phase->type( in(MemNode::Memory) ); if (t1 == Type::TOP) return Type::TOP; @@ -1743,6 +1772,10 @@ // To clean up reflective code, simplify k.java_mirror.as_klass to plain k. // Also feed through the klass in Allocate(...klass...)._klass. Node* LoadKlassNode::Identity( PhaseTransform *phase ) { + return klass_identity_common(phase); +} + +Node* LoadNode::klass_identity_common(PhaseTransform *phase ) { Node* x = LoadNode::Identity(phase); if (x != this) return x; @@ -1801,6 +1834,34 @@ return this; } + +//------------------------------Value------------------------------------------ +const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const { + const Type *t = klass_value_common(phase); + + if (t == TypePtr::NULL_PTR) { + return TypeNarrowOop::NULL_PTR; + } + if (t != Type::TOP && !t->isa_narrowoop()) { + assert(t->is_oopptr(), "sanity"); + t = t->is_oopptr()->make_narrowoop(); + } + return t; +} + +//------------------------------Identity--------------------------------------- +// To clean up reflective code, simplify k.java_mirror.as_klass to narrow k. +// Also feed through the klass in Allocate(...klass...)._klass. +Node* LoadNKlassNode::Identity( PhaseTransform *phase ) { + Node *x = klass_identity_common(phase); + + const Type *t = phase->type( x ); + if( t == Type::TOP ) return x; + if( t->isa_narrowoop()) return x; + + return EncodePNode::encode(phase, x); +} + //------------------------------Value----------------------------------------- const Type *LoadRangeNode::Value( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP