< prev index next >

src/share/vm/opto/library_call.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -44,10 +44,11 @@
 #include "opto/movenode.hpp"
 #include "opto/mulnode.hpp"
 #include "opto/narrowptrnode.hpp"
 #include "opto/opaquenode.hpp"
 #include "opto/parse.hpp"
+#include "opto/rootnode.hpp"
 #include "opto/runtime.hpp"
 #include "opto/subnode.hpp"
 #include "prims/nativeLookup.hpp"
 #include "prims/unsafe.hpp"
 #include "runtime/sharedRuntime.hpp"

@@ -182,10 +183,12 @@
                                     RegionNode* region);
   Node* generate_interface_guard(Node* kls, RegionNode* region);
   Node* generate_array_guard(Node* kls, RegionNode* region) {
     return generate_array_guard_common(kls, region, false, false);
   }
+  void generate_runtime_limit_guard(Node* array, Node* offset, Node* subseq_length);
+  void generate_runtime_negative_guard(Node* array, Node* index);
   Node* generate_non_array_guard(Node* kls, RegionNode* region) {
     return generate_array_guard_common(kls, region, false, true);
   }
   Node* generate_objArray_guard(Node* kls, RegionNode* region) {
     return generate_array_guard_common(kls, region, true, false);

@@ -1665,11 +1668,22 @@
   // Java method would constant fold nicely instead.
   if (!is_store && value->is_Con() && index->is_Con()) {
     return false;
   }
 
+#ifdef ASSERT
+  // Range checks are done by caller. Verify only in debug VM.
+  generate_runtime_negative_guard(value, index);
+  Node* byte_index = _gvn.transform(new LShiftINode(index, intcon(1)));
+  generate_runtime_limit_guard(value, byte_index, intcon(2));
+  if (stopped()) return true;
+#endif
+
   Node* adr = array_element_address(value, index, T_CHAR);
+  if (adr->is_top()) {
+    return false;
+  }
   if (is_store) {
     (void) store_to_memory(control(), adr, ch, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered,
                            false, false, true /* mismatched */);
   } else {
     ch = make_load(control(), adr, TypeInt::CHAR, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered,

@@ -3820,10 +3834,53 @@
   if (not_array)  btest = BoolTest(btest).negate();
   Node* bol = _gvn.transform(new BoolNode(cmp, btest));
   return generate_fair_guard(bol, region);
 }
 
+void LibraryCallKit::generate_runtime_limit_guard(Node* array, Node* offset, Node* subseq_length) {
+  RegionNode* bailout = new RegionNode(1);
+  record_for_igvn(bailout);
+
+  generate_limit_guard(offset, subseq_length, load_array_length(array), bailout);
+  if (bailout->req() > 1) {
+    PreserveJVMState pjvms(this);
+    set_control(_gvn.transform(bailout));
+    Node* call = make_runtime_call(RC_NO_LEAF,
+                                   OptoRuntime::array_out_of_bounds_Type(),
+                                   OptoRuntime::array_out_of_bounds_Java(),
+                                   "array index out of bounds",
+                                   TypeRawPtr::BOTTOM,
+                                   offset, load_array_length(array));
+    call->set_req(TypeFunc::ReturnAdr, returnadr());
+    HaltNode* halt = new HaltNode(control(), frameptr());
+    root()->add_req(halt);
+    _gvn.transform(halt);
+    stop_and_kill_map();
+  }
+}
+
+void LibraryCallKit::generate_runtime_negative_guard(Node* array, Node* index) {
+  RegionNode* bailout = new RegionNode(1);
+  record_for_igvn(bailout);
+
+  generate_negative_guard(index, bailout);
+  if (bailout->req() > 1) {
+    PreserveJVMState pjvms(this);
+    set_control(_gvn.transform(bailout));
+    Node* call = make_runtime_call(RC_NO_LEAF,
+                                   OptoRuntime::array_out_of_bounds_Type(),
+                                   OptoRuntime::array_out_of_bounds_Java(),
+                                   "array index out of bounds",
+                                   TypeRawPtr::BOTTOM,
+                                   index, load_array_length(array));
+    call->set_req(TypeFunc::ReturnAdr, returnadr());
+    HaltNode* halt = new HaltNode(control(), frameptr());
+    root()->add_req(halt);
+    _gvn.transform(halt);
+    stop_and_kill_map();
+  }
+}
 
 //-----------------------inline_native_newArray--------------------------
 // private static native Object java.lang.reflect.newArray(Class<?> componentType, int length);
 // private        native Object Unsafe.allocateUninitializedArray0(Class<?> cls, int size);
 bool LibraryCallKit::inline_unsafe_newArray(bool uninitialized) {
< prev index next >