< 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 >