--- a/src/hotspot/share/opto/memnode.cpp Wed Jun 12 13:49:43 2019 +0200
+++ b/src/hotspot/share/opto/memnode.cpp Wed Jun 12 14:06:16 2019 +0200
@@ -44,6 +44,7 @@
#include "opto/narrowptrnode.hpp"
#include "opto/phaseX.hpp"
#include "opto/regmask.hpp"
+#include "opto/rootnode.hpp"
#include "utilities/align.hpp"
#include "utilities/copy.hpp"
#include "utilities/macros.hpp"
@@ -328,6 +329,24 @@
const Type *t_adr = phase->type(address);
if (t_adr == Type::TOP) return NodeSentinel; // caller will return NULL
+ if (can_reshape && is_unsafe_access() && (t_adr == TypePtr::NULL_PTR)) {
+ // Unsafe off-heap access with zero address. Remove access and other control users
+ // to not confuse optimizations and add a HaltNode to fail if this is ever executed.
+ assert(ctl != NULL, "unsafe accesses should be control dependent");
+ for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) {
+ Node* u = ctl->fast_out(i);
+ if (u != ctl) {
+ igvn->rehash_node_delayed(u);
+ int nb = u->replace_edge(ctl, phase->C->top());
+ --i, imax -= nb;
+ }
+ }
+ Node* frame = igvn->transform(new ParmNode(phase->C->start(), TypeFunc::FramePtr));
+ Node* halt = igvn->transform(new HaltNode(ctl, frame));
+ phase->C->root()->add_req(halt);
+ return this;
+ }
+
if (can_reshape && igvn != NULL &&
(igvn->_worklist.member(address) ||
(igvn->_worklist.size() > 0 && t_adr != adr_type())) ) {