--- old/src/share/vm/opto/memnode.cpp 2017-07-10 18:11:43.685490691 +0200 +++ new/src/share/vm/opto/memnode.cpp 2017-07-10 18:11:39.343510140 +0200 @@ -42,6 +42,7 @@ #include "opto/narrowptrnode.hpp" #include "opto/phaseX.hpp" #include "opto/regmask.hpp" +#include "opto/valuetypenode.hpp" #include "utilities/copy.hpp" // Portions of code courtesy of Clifford Click @@ -1092,6 +1093,20 @@ //------------------------------Identity--------------------------------------- // Loads are identity if previous store is to same address Node* LoadNode::Identity(PhaseGVN* phase) { + // Loading from a ValueTypePtr? The ValueTypePtr has the values of + // all fields as input. Look for the field with matching offset. + Node* addr = in(Address); + intptr_t offset; + Node* base = AddPNode::Ideal_base_and_offset(addr, phase, offset); + if (base != NULL && base->is_ValueTypePtr()) { + Node* value = base->as_ValueTypePtr()->field_value_by_offset((int)offset, true); + if (bottom_type()->isa_narrowoop()) { + assert(!phase->type(value)->isa_narrowoop(), "should already be decoded"); + value = phase->transform(new EncodePNode(value, bottom_type())); + } + return value; + } + // If the previous store-maker is the right kind of Store, and the store is // to the same address, then we are equal to the value stored. Node* mem = in(Memory);