1 /*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
29 #include "compiler/compileBroker.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "opto/addnode.hpp"
34 #include "opto/arraycopynode.hpp"
35 #include "opto/c2compiler.hpp"
36 #include "opto/callGenerator.hpp"
37 #include "opto/castnode.hpp"
38 #include "opto/cfgnode.hpp"
39 #include "opto/convertnode.hpp"
40 #include "opto/countbitsnode.hpp"
41 #include "opto/intrinsicnode.hpp"
42 #include "opto/idealKit.hpp"
43 #include "opto/mathexactnode.hpp"
44 #include "opto/movenode.hpp"
45 #include "opto/mulnode.hpp"
46 #include "opto/narrowptrnode.hpp"
47 #include "opto/opaquenode.hpp"
48 #include "opto/parse.hpp"
49 #include "opto/runtime.hpp"
50 #include "opto/subnode.hpp"
51 #include "prims/nativeLookup.hpp"
52 #include "prims/unsafe.hpp"
53 #include "runtime/sharedRuntime.hpp"
54 #ifdef TRACE_HAVE_INTRINSICS
55 #include "trace/traceMacros.hpp"
56 #endif
57
58 class LibraryIntrinsic : public InlineCallGenerator {
59 // Extend the set of intrinsics known to the runtime:
60 public:
61 private:
62 bool _is_virtual;
63 bool _does_virtual_dispatch;
64 int8_t _predicates_count; // Intrinsic is predicated by several conditions
65 int8_t _last_predicate; // Last generated predicate
66 vmIntrinsics::ID _intrinsic_id;
67
68 public:
167 RegionNode* region, int null_path) {
168 int offset = java_lang_Class::klass_offset_in_bytes();
169 return load_klass_from_mirror_common(mirror, never_see_null,
170 region, null_path,
171 offset);
172 }
173 Node* load_array_klass_from_mirror(Node* mirror, bool never_see_null,
174 RegionNode* region, int null_path) {
175 int offset = java_lang_Class::array_klass_offset_in_bytes();
176 return load_klass_from_mirror_common(mirror, never_see_null,
177 region, null_path,
178 offset);
179 }
180 Node* generate_access_flags_guard(Node* kls,
181 int modifier_mask, int modifier_bits,
182 RegionNode* region);
183 Node* generate_interface_guard(Node* kls, RegionNode* region);
184 Node* generate_array_guard(Node* kls, RegionNode* region) {
185 return generate_array_guard_common(kls, region, false, false);
186 }
187 Node* generate_non_array_guard(Node* kls, RegionNode* region) {
188 return generate_array_guard_common(kls, region, false, true);
189 }
190 Node* generate_objArray_guard(Node* kls, RegionNode* region) {
191 return generate_array_guard_common(kls, region, true, false);
192 }
193 Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
194 return generate_array_guard_common(kls, region, true, true);
195 }
196 Node* generate_array_guard_common(Node* kls, RegionNode* region,
197 bool obj_array, bool not_array);
198 Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
199 CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
200 bool is_virtual = false, bool is_static = false);
201 CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
202 return generate_method_call(method_id, false, true);
203 }
204 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
205 return generate_method_call(method_id, true, false);
206 }
1650 // static char StringUTF16.getChar(byte[] val, int index)
1651 bool LibraryCallKit::inline_string_char_access(bool is_store) {
1652 Node* value = argument(0);
1653 Node* index = argument(1);
1654 Node* ch = is_store ? argument(2) : NULL;
1655
1656 // This intrinsic accesses byte[] array as char[] array. Computing the offsets
1657 // correctly requires matched array shapes.
1658 assert (arrayOopDesc::base_offset_in_bytes(T_CHAR) == arrayOopDesc::base_offset_in_bytes(T_BYTE),
1659 "sanity: byte[] and char[] bases agree");
1660 assert (type2aelembytes(T_CHAR) == type2aelembytes(T_BYTE)*2,
1661 "sanity: byte[] and char[] scales agree");
1662
1663 // Bail when getChar over constants is requested: constant folding would
1664 // reject folding mismatched char access over byte[]. A normal inlining for getChar
1665 // Java method would constant fold nicely instead.
1666 if (!is_store && value->is_Con() && index->is_Con()) {
1667 return false;
1668 }
1669
1670 Node* adr = array_element_address(value, index, T_CHAR);
1671 if (is_store) {
1672 (void) store_to_memory(control(), adr, ch, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered,
1673 false, false, true /* mismatched */);
1674 } else {
1675 ch = make_load(control(), adr, TypeInt::CHAR, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered,
1676 LoadNode::DependsOnlyOnTest, false, false, true /* mismatched */);
1677 set_result(ch);
1678 }
1679 return true;
1680 }
1681
1682 //--------------------------round_double_node--------------------------------
1683 // Round a double node if necessary.
1684 Node* LibraryCallKit::round_double_node(Node* n) {
1685 if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1686 n = _gvn.transform(new RoundDoubleNode(0, n));
1687 return n;
1688 }
1689
1690 //------------------------------inline_math-----------------------------------
3805 Node* always_branch = control();
3806 if (region != NULL)
3807 region->add_req(always_branch);
3808 set_control(top());
3809 return always_branch;
3810 }
3811 }
3812 // Now test the correct condition.
3813 jint nval = (obj_array
3814 ? (jint)(Klass::_lh_array_tag_type_value
3815 << Klass::_lh_array_tag_shift)
3816 : Klass::_lh_neutral_value);
3817 Node* cmp = _gvn.transform(new CmpINode(layout_val, intcon(nval)));
3818 BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array
3819 // invert the test if we are looking for a non-array
3820 if (not_array) btest = BoolTest(btest).negate();
3821 Node* bol = _gvn.transform(new BoolNode(cmp, btest));
3822 return generate_fair_guard(bol, region);
3823 }
3824
3825
3826 //-----------------------inline_native_newArray--------------------------
3827 // private static native Object java.lang.reflect.newArray(Class<?> componentType, int length);
3828 // private native Object Unsafe.allocateUninitializedArray0(Class<?> cls, int size);
3829 bool LibraryCallKit::inline_unsafe_newArray(bool uninitialized) {
3830 Node* mirror;
3831 Node* count_val;
3832 if (uninitialized) {
3833 mirror = argument(1);
3834 count_val = argument(2);
3835 } else {
3836 mirror = argument(0);
3837 count_val = argument(1);
3838 }
3839
3840 mirror = null_check(mirror);
3841 // If mirror or obj is dead, only null-path is taken.
3842 if (stopped()) return true;
3843
3844 enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT };
|
1 /*
2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
29 #include "compiler/compileBroker.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "opto/addnode.hpp"
34 #include "opto/arraycopynode.hpp"
35 #include "opto/c2compiler.hpp"
36 #include "opto/callGenerator.hpp"
37 #include "opto/castnode.hpp"
38 #include "opto/cfgnode.hpp"
39 #include "opto/convertnode.hpp"
40 #include "opto/countbitsnode.hpp"
41 #include "opto/intrinsicnode.hpp"
42 #include "opto/idealKit.hpp"
43 #include "opto/mathexactnode.hpp"
44 #include "opto/movenode.hpp"
45 #include "opto/mulnode.hpp"
46 #include "opto/narrowptrnode.hpp"
47 #include "opto/opaquenode.hpp"
48 #include "opto/parse.hpp"
49 #include "opto/rootnode.hpp"
50 #include "opto/runtime.hpp"
51 #include "opto/subnode.hpp"
52 #include "prims/nativeLookup.hpp"
53 #include "prims/unsafe.hpp"
54 #include "runtime/sharedRuntime.hpp"
55 #ifdef TRACE_HAVE_INTRINSICS
56 #include "trace/traceMacros.hpp"
57 #endif
58
59 class LibraryIntrinsic : public InlineCallGenerator {
60 // Extend the set of intrinsics known to the runtime:
61 public:
62 private:
63 bool _is_virtual;
64 bool _does_virtual_dispatch;
65 int8_t _predicates_count; // Intrinsic is predicated by several conditions
66 int8_t _last_predicate; // Last generated predicate
67 vmIntrinsics::ID _intrinsic_id;
68
69 public:
168 RegionNode* region, int null_path) {
169 int offset = java_lang_Class::klass_offset_in_bytes();
170 return load_klass_from_mirror_common(mirror, never_see_null,
171 region, null_path,
172 offset);
173 }
174 Node* load_array_klass_from_mirror(Node* mirror, bool never_see_null,
175 RegionNode* region, int null_path) {
176 int offset = java_lang_Class::array_klass_offset_in_bytes();
177 return load_klass_from_mirror_common(mirror, never_see_null,
178 region, null_path,
179 offset);
180 }
181 Node* generate_access_flags_guard(Node* kls,
182 int modifier_mask, int modifier_bits,
183 RegionNode* region);
184 Node* generate_interface_guard(Node* kls, RegionNode* region);
185 Node* generate_array_guard(Node* kls, RegionNode* region) {
186 return generate_array_guard_common(kls, region, false, false);
187 }
188 void generate_runtime_limit_guard(Node* array, Node* offset, Node* subseq_length);
189 void generate_runtime_negative_guard(Node* array, Node* index);
190 Node* generate_non_array_guard(Node* kls, RegionNode* region) {
191 return generate_array_guard_common(kls, region, false, true);
192 }
193 Node* generate_objArray_guard(Node* kls, RegionNode* region) {
194 return generate_array_guard_common(kls, region, true, false);
195 }
196 Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
197 return generate_array_guard_common(kls, region, true, true);
198 }
199 Node* generate_array_guard_common(Node* kls, RegionNode* region,
200 bool obj_array, bool not_array);
201 Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
202 CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
203 bool is_virtual = false, bool is_static = false);
204 CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
205 return generate_method_call(method_id, false, true);
206 }
207 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
208 return generate_method_call(method_id, true, false);
209 }
1653 // static char StringUTF16.getChar(byte[] val, int index)
1654 bool LibraryCallKit::inline_string_char_access(bool is_store) {
1655 Node* value = argument(0);
1656 Node* index = argument(1);
1657 Node* ch = is_store ? argument(2) : NULL;
1658
1659 // This intrinsic accesses byte[] array as char[] array. Computing the offsets
1660 // correctly requires matched array shapes.
1661 assert (arrayOopDesc::base_offset_in_bytes(T_CHAR) == arrayOopDesc::base_offset_in_bytes(T_BYTE),
1662 "sanity: byte[] and char[] bases agree");
1663 assert (type2aelembytes(T_CHAR) == type2aelembytes(T_BYTE)*2,
1664 "sanity: byte[] and char[] scales agree");
1665
1666 // Bail when getChar over constants is requested: constant folding would
1667 // reject folding mismatched char access over byte[]. A normal inlining for getChar
1668 // Java method would constant fold nicely instead.
1669 if (!is_store && value->is_Con() && index->is_Con()) {
1670 return false;
1671 }
1672
1673 #ifdef ASSERT
1674 // Range checks are done by caller. Verify only in debug VM.
1675 generate_runtime_negative_guard(value, index);
1676 Node* byte_index = _gvn.transform(new LShiftINode(index, intcon(1)));
1677 generate_runtime_limit_guard(value, byte_index, intcon(2));
1678 if (stopped()) return true;
1679 #endif
1680
1681 Node* adr = array_element_address(value, index, T_CHAR);
1682 if (adr->is_top()) {
1683 return false;
1684 }
1685 if (is_store) {
1686 (void) store_to_memory(control(), adr, ch, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered,
1687 false, false, true /* mismatched */);
1688 } else {
1689 ch = make_load(control(), adr, TypeInt::CHAR, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered,
1690 LoadNode::DependsOnlyOnTest, false, false, true /* mismatched */);
1691 set_result(ch);
1692 }
1693 return true;
1694 }
1695
1696 //--------------------------round_double_node--------------------------------
1697 // Round a double node if necessary.
1698 Node* LibraryCallKit::round_double_node(Node* n) {
1699 if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1700 n = _gvn.transform(new RoundDoubleNode(0, n));
1701 return n;
1702 }
1703
1704 //------------------------------inline_math-----------------------------------
3819 Node* always_branch = control();
3820 if (region != NULL)
3821 region->add_req(always_branch);
3822 set_control(top());
3823 return always_branch;
3824 }
3825 }
3826 // Now test the correct condition.
3827 jint nval = (obj_array
3828 ? (jint)(Klass::_lh_array_tag_type_value
3829 << Klass::_lh_array_tag_shift)
3830 : Klass::_lh_neutral_value);
3831 Node* cmp = _gvn.transform(new CmpINode(layout_val, intcon(nval)));
3832 BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array
3833 // invert the test if we are looking for a non-array
3834 if (not_array) btest = BoolTest(btest).negate();
3835 Node* bol = _gvn.transform(new BoolNode(cmp, btest));
3836 return generate_fair_guard(bol, region);
3837 }
3838
3839 void LibraryCallKit::generate_runtime_limit_guard(Node* array, Node* offset, Node* subseq_length) {
3840 RegionNode* bailout = new RegionNode(1);
3841 record_for_igvn(bailout);
3842
3843 generate_limit_guard(offset, subseq_length, load_array_length(array), bailout);
3844 if (bailout->req() > 1) {
3845 PreserveJVMState pjvms(this);
3846 set_control(_gvn.transform(bailout));
3847 Node* call = make_runtime_call(RC_NO_LEAF,
3848 OptoRuntime::array_out_of_bounds_Type(),
3849 OptoRuntime::array_out_of_bounds_Java(),
3850 "array index out of bounds",
3851 TypeRawPtr::BOTTOM,
3852 offset, load_array_length(array));
3853 call->set_req(TypeFunc::ReturnAdr, returnadr());
3854 HaltNode* halt = new HaltNode(control(), frameptr());
3855 root()->add_req(halt);
3856 _gvn.transform(halt);
3857 stop_and_kill_map();
3858 }
3859 }
3860
3861 void LibraryCallKit::generate_runtime_negative_guard(Node* array, Node* index) {
3862 RegionNode* bailout = new RegionNode(1);
3863 record_for_igvn(bailout);
3864
3865 generate_negative_guard(index, bailout);
3866 if (bailout->req() > 1) {
3867 PreserveJVMState pjvms(this);
3868 set_control(_gvn.transform(bailout));
3869 Node* call = make_runtime_call(RC_NO_LEAF,
3870 OptoRuntime::array_out_of_bounds_Type(),
3871 OptoRuntime::array_out_of_bounds_Java(),
3872 "array index out of bounds",
3873 TypeRawPtr::BOTTOM,
3874 index, load_array_length(array));
3875 call->set_req(TypeFunc::ReturnAdr, returnadr());
3876 HaltNode* halt = new HaltNode(control(), frameptr());
3877 root()->add_req(halt);
3878 _gvn.transform(halt);
3879 stop_and_kill_map();
3880 }
3881 }
3882
3883 //-----------------------inline_native_newArray--------------------------
3884 // private static native Object java.lang.reflect.newArray(Class<?> componentType, int length);
3885 // private native Object Unsafe.allocateUninitializedArray0(Class<?> cls, int size);
3886 bool LibraryCallKit::inline_unsafe_newArray(bool uninitialized) {
3887 Node* mirror;
3888 Node* count_val;
3889 if (uninitialized) {
3890 mirror = argument(1);
3891 count_val = argument(2);
3892 } else {
3893 mirror = argument(0);
3894 count_val = argument(1);
3895 }
3896
3897 mirror = null_check(mirror);
3898 // If mirror or obj is dead, only null-path is taken.
3899 if (stopped()) return true;
3900
3901 enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT };
|